Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 May 2010 16:00:34 +0000 (09:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 May 2010 16:00:34 +0000 (09:00 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  IB/core: Use kmemdup() instead of kmalloc()+memcpy()
  IB/iser: Fix error flow in iser_create_ib_conn_res()
  IB/iser: Enhance disconnection logic for multi-pathing
  IB/iser: Remove buggy back-pointer setting
  IB/iser: Add asynchronous event handler
  MAINTAINERS: Add cxgb4 and iw_cxgb4 entries
  RDMA/cxgb3: Shrink .text with compile-time init of handlers arrays
  IPoIB: Allow disabling/enabling TSO on the fly through ethtool
  IB/mlx4: Add support for masked atomic operations
  IB/core: Add support for masked atomic operations
  RDMA/cma: Randomize local port allocation
  RDMA/nes: Make unnecessarily global functions static
  RDMA/nes: Make nesadapter->phy_lock usage consistent
  RDMA/cxgb4: Add driver for Chelsio T4 RNIC
  IB/mthca: Use the dma state API instead of pci equivalents
  RDMA/amso1100: Use the dma state API instead of pci equivalents
  RDMA/cxgb3: Don't free skbs on NET_XMIT_* indications from LLD
  RDMA/cxgb3: Use the dma state API instead of pci equivalents
  IB: Explicitly rule out llseek to avoid BKL in default_llseek()

2503 files changed:
Documentation/DocBook/libata.tmpl
Documentation/DocBook/sh.tmpl
Documentation/HOWTO
Documentation/RCU/NMI-RCU.txt
Documentation/RCU/checklist.txt
Documentation/RCU/lockdep.txt
Documentation/RCU/stallwarn.txt
Documentation/RCU/torture.txt
Documentation/RCU/trace.txt
Documentation/RCU/whatisRCU.txt
Documentation/arm/00-INDEX
Documentation/arm/SPEAr/overview.txt [new file with mode: 0644]
Documentation/cgroups/cgroups.txt
Documentation/credentials.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/nfs/nfs41-server.txt
Documentation/filesystems/proc.txt
Documentation/i2c/writing-clients
Documentation/input/elantech.txt
Documentation/input/multi-touch-protocol.txt
Documentation/intel_txt.txt
Documentation/kernel-parameters.txt
Documentation/kprobes.txt
Documentation/networking/timestamping.txt
Documentation/rbtree.txt
Documentation/scheduler/sched-design-CFS.txt
Documentation/scheduler/sched-rt-group.txt
Documentation/spi/spidev_test.c
Documentation/stable_kernel_rules.txt
Documentation/trace/events.txt
Documentation/trace/ftrace.txt
Documentation/trace/kprobetrace.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/atomic.h
arch/alpha/include/asm/bitops.h
arch/alpha/kernel/time.c
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/decompress.c
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/piggy.lzma.S [new file with mode: 0644]
arch/arm/common/Kconfig
arch/arm/common/Makefile
arch/arm/common/clkdev.c
arch/arm/common/icst.c [new file with mode: 0644]
arch/arm/common/icst307.c [deleted file]
arch/arm/common/icst525.c [deleted file]
arch/arm/common/pl330.c [new file with mode: 0644]
arch/arm/common/vic.c
arch/arm/configs/bcmring_defconfig
arch/arm/configs/cns3420vb_defconfig [new file with mode: 0644]
arch/arm/configs/imote2_defconfig
arch/arm/configs/mmp2_defconfig
arch/arm/configs/n8x0_defconfig
arch/arm/configs/omap_zoom2_defconfig
arch/arm/configs/omap_zoom3_defconfig
arch/arm/configs/rx51_defconfig
arch/arm/configs/spear300_defconfig [new file with mode: 0644]
arch/arm/configs/spear310_defconfig [new file with mode: 0644]
arch/arm/configs/spear320_defconfig [new file with mode: 0644]
arch/arm/configs/spear600_defconfig [new file with mode: 0644]
arch/arm/configs/stamp9g20_defconfig [new file with mode: 0644]
arch/arm/include/asm/assembler.h
arch/arm/include/asm/atomic.h
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/elf.h
arch/arm/include/asm/futex.h
arch/arm/include/asm/hardware/arm_timer.h
arch/arm/include/asm/hardware/cache-l2x0.h
arch/arm/include/asm/hardware/icst.h [new file with mode: 0644]
arch/arm/include/asm/hardware/icst307.h [deleted file]
arch/arm/include/asm/hardware/icst525.h [deleted file]
arch/arm/include/asm/hardware/pl330.h [new file with mode: 0644]
arch/arm/include/asm/hardware/sp810.h [new file with mode: 0644]
arch/arm/include/asm/highmem.h
arch/arm/include/asm/ioctls.h
arch/arm/include/asm/kmap_types.h
arch/arm/include/asm/mach/pci.h
arch/arm/include/asm/mach/time.h
arch/arm/include/asm/pci.h
arch/arm/include/asm/perf_event.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/pmu.h
arch/arm/include/asm/scatterlist.h
arch/arm/include/asm/smp.h
arch/arm/include/asm/smp_twd.h
arch/arm/include/asm/system.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/asm/uaccess.h
arch/arm/include/asm/ucontext.h
arch/arm/include/asm/user.h
arch/arm/kernel/bios32.c
arch/arm/kernel/dma.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/ftrace.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/pmu.c
arch/arm/kernel/process.c
arch/arm/kernel/signal.c
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/time.c
arch/arm/lib/backtrace.S
arch/arm/lib/clear_user.S
arch/arm/lib/copy_from_user.S
arch/arm/lib/copy_to_user.S
arch/arm/lib/csumpartialcopyuser.S
arch/arm/lib/getuser.S
arch/arm/lib/putuser.S
arch/arm/lib/strncpy_from_user.S
arch/arm/lib/strnlen_user.S
arch/arm/lib/uaccess.S
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/board-stamp9g20.c [new file with mode: 0644]
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/include/mach/cpu.h
arch/arm/mach-at91/include/mach/system.h
arch/arm/mach-at91/pm_slowclock.S
arch/arm/mach-bcmring/arch.c
arch/arm/mach-bcmring/dma.c
arch/arm/mach-clps711x/mm.c
arch/arm/mach-cns3xxx/Kconfig [new file with mode: 0644]
arch/arm/mach-cns3xxx/Makefile [new file with mode: 0644]
arch/arm/mach-cns3xxx/Makefile.boot [new file with mode: 0644]
arch/arm/mach-cns3xxx/cns3420vb.c [new file with mode: 0644]
arch/arm/mach-cns3xxx/core.c [new file with mode: 0644]
arch/arm/mach-cns3xxx/core.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/cns3xxx.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-cns3xxx/pm.c [new file with mode: 0644]
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/board-da830-evm.c
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/board-dm355-evm.c
arch/arm/mach-davinci/board-dm355-leopard.c
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/board-dm646x-evm.c
arch/arm/mach-davinci/board-neuros-osd2.c
arch/arm/mach-davinci/board-sffsdr.c
arch/arm/mach-davinci/cdce949.c
arch/arm/mach-davinci/clock.c
arch/arm/mach-davinci/clock.h
arch/arm/mach-davinci/common.c
arch/arm/mach-davinci/cp_intc.c
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/devices.c
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-davinci/dma.c
arch/arm/mach-davinci/gpio.c
arch/arm/mach-davinci/include/mach/common.h
arch/arm/mach-davinci/include/mach/cp_intc.h
arch/arm/mach-davinci/include/mach/cputype.h
arch/arm/mach-davinci/include/mach/da8xx.h
arch/arm/mach-davinci/include/mach/dm355.h
arch/arm/mach-davinci/include/mach/dm365.h
arch/arm/mach-davinci/include/mach/dm644x.h
arch/arm/mach-davinci/include/mach/dm646x.h
arch/arm/mach-davinci/include/mach/gpio.h
arch/arm/mach-davinci/include/mach/irqs.h
arch/arm/mach-davinci/include/mach/mux.h
arch/arm/mach-davinci/include/mach/psc.h
arch/arm/mach-davinci/include/mach/serial.h
arch/arm/mach-davinci/include/mach/system.h
arch/arm/mach-davinci/io.c
arch/arm/mach-davinci/irq.c
arch/arm/mach-davinci/mux.c
arch/arm/mach-davinci/mux.h
arch/arm/mach-davinci/psc.c
arch/arm/mach-davinci/serial.c
arch/arm/mach-davinci/time.c
arch/arm/mach-ep93xx/adssphere.c
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/gesbc9312.c
arch/arm/mach-ep93xx/gpio.c
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
arch/arm/mach-ep93xx/include/mach/platform.h
arch/arm/mach-ep93xx/micro9.c
arch/arm/mach-ep93xx/simone.c
arch/arm/mach-ep93xx/snappercl15.c
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-integrator/Kconfig
arch/arm/mach-integrator/Makefile
arch/arm/mach-integrator/clock.c [deleted file]
arch/arm/mach-integrator/common.h [deleted file]
arch/arm/mach-integrator/core.c
arch/arm/mach-integrator/cpu.c
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/include/mach/clkdev.h
arch/arm/mach-integrator/include/mach/entry-macro.S
arch/arm/mach-integrator/include/mach/hardware.h
arch/arm/mach-integrator/include/mach/platform.h
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-integrator/leds.c
arch/arm/mach-integrator/pci_v3.c
arch/arm/mach-iop32x/n2100.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-kirkwood/Kconfig
arch/arm/mach-kirkwood/Makefile
arch/arm/mach-kirkwood/guruplug-setup.c [new file with mode: 0644]
arch/arm/mach-kirkwood/netxbig_v2-setup.c [new file with mode: 0644]
arch/arm/mach-mmp/aspenite.c
arch/arm/mach-mmp/include/mach/gpio.h
arch/arm/mach-mmp/include/mach/irqs.h
arch/arm/mach-mmp/include/mach/mfp-mmp2.h
arch/arm/mach-mmp/include/mach/mmp2.h
arch/arm/mach-mmp/include/mach/pxa168.h
arch/arm/mach-mmp/include/mach/regs-apbc.h
arch/arm/mach-mmp/include/mach/regs-smc.h [new file with mode: 0644]
arch/arm/mach-mmp/include/mach/timex.h
arch/arm/mach-mmp/jasper.c
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-mmp/pxa168.c
arch/arm/mach-msm/Kconfig
arch/arm/mach-msm/Makefile
arch/arm/mach-msm/acpuclock-arm11.c [new file with mode: 0644]
arch/arm/mach-msm/acpuclock.h [new file with mode: 0644]
arch/arm/mach-msm/board-dream.c [deleted file]
arch/arm/mach-msm/board-dream.h [deleted file]
arch/arm/mach-msm/board-halibut.c
arch/arm/mach-msm/board-mahimahi.c [new file with mode: 0644]
arch/arm/mach-msm/board-msm7x27.c [new file with mode: 0644]
arch/arm/mach-msm/board-msm7x30.c [new file with mode: 0644]
arch/arm/mach-msm/board-qsd8x50.c [new file with mode: 0644]
arch/arm/mach-msm/board-sapphire.c [new file with mode: 0644]
arch/arm/mach-msm/board-trout.c [new file with mode: 0644]
arch/arm/mach-msm/board-trout.h [new file with mode: 0644]
arch/arm/mach-msm/clock-7x01a.c [deleted file]
arch/arm/mach-msm/clock-7x30.h [new file with mode: 0644]
arch/arm/mach-msm/clock-pcom.c [new file with mode: 0644]
arch/arm/mach-msm/clock-pcom.h [new file with mode: 0644]
arch/arm/mach-msm/clock.c
arch/arm/mach-msm/clock.h
arch/arm/mach-msm/devices-msm7x00.c [new file with mode: 0644]
arch/arm/mach-msm/devices-msm7x30.c [new file with mode: 0644]
arch/arm/mach-msm/devices-qsd8x50.c [new file with mode: 0644]
arch/arm/mach-msm/devices.c [deleted file]
arch/arm/mach-msm/devices.h
arch/arm/mach-msm/dma.c
arch/arm/mach-msm/gpio.c [new file with mode: 0644]
arch/arm/mach-msm/include/mach/board.h
arch/arm/mach-msm/include/mach/clk.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/dma.h
arch/arm/mach-msm/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/io.h
arch/arm/mach-msm/include/mach/irqs-7x00.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/irqs-7x30.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/irqs-8x50.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_fb.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/msm_iomap-7x00.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/msm_iomap-7x30.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/msm_iomap-8x50.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/msm_iomap.h
arch/arm/mach-msm/include/mach/msm_smd.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/sirc.h [new file with mode: 0644]
arch/arm/mach-msm/include/mach/system.h
arch/arm/mach-msm/include/mach/vreg.h
arch/arm/mach-msm/io.c
arch/arm/mach-msm/irq-vic.c [new file with mode: 0644]
arch/arm/mach-msm/irq.c
arch/arm/mach-msm/last_radio_log.c [new file with mode: 0644]
arch/arm/mach-msm/proc_comm.c
arch/arm/mach-msm/proc_comm.h
arch/arm/mach-msm/sirc.c [new file with mode: 0644]
arch/arm/mach-msm/smd.c [new file with mode: 0644]
arch/arm/mach-msm/smd_debug.c [new file with mode: 0644]
arch/arm/mach-msm/smd_private.h [new file with mode: 0644]
arch/arm/mach-msm/timer.c
arch/arm/mach-msm/vreg.c
arch/arm/mach-mx3/Kconfig
arch/arm/mach-mx3/clock-imx31.c
arch/arm/mach-mx3/devices.c
arch/arm/mach-mx3/devices.h
arch/arm/mach-mx3/mach-armadillo5x0.c
arch/arm/mach-mx3/mach-mx31_3ds.c
arch/arm/mach-mx3/mach-pcm037.c
arch/arm/mach-mx3/mx31lite-db.c
arch/arm/mach-mx5/clock-mx51.c
arch/arm/mach-mx5/cpu.c
arch/arm/mach-mx5/mm.c
arch/arm/mach-nomadik/Kconfig
arch/arm/mach-nomadik/Makefile
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/clock.c
arch/arm/mach-nomadik/clock.h
arch/arm/mach-nomadik/cpu-8815.c
arch/arm/mach-nomadik/gpio.c [deleted file]
arch/arm/mach-nomadik/include/mach/gpio.h
arch/arm/mach-omap1/board-htcherald.c
arch/arm/mach-omap1/timer32k.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-3630sdp.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-n8x0.c
arch/arm/mach-omap2/board-sdp-flash.c
arch/arm/mach-omap2/board-zoom-debugboard.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/clock3xxx_data.c
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/gpmc-nand.c
arch/arm/mach-omap2/include/mach/entry-macro.S
arch/arm/mach-omap2/omap-headsmp.S
arch/arm/mach-omap2/omap44xx-smc.S
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/powerdomain.c
arch/arm/mach-omap2/prcm.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/cm-x300.c
arch/arm/mach-pxa/colibri-pxa3xx.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/corgi_lcd.c [deleted file]
arch/arm/mach-pxa/corgi_pm.c
arch/arm/mach-pxa/corgi_ssp.c [deleted file]
arch/arm/mach-pxa/csb726.c
arch/arm/mach-pxa/em-x270.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/include/mach/colibri.h
arch/arm/mach-pxa/include/mach/corgi.h
arch/arm/mach-pxa/include/mach/hardware.h
arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
arch/arm/mach-pxa/include/mach/mmc.h
arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h [deleted file]
arch/arm/mach-pxa/include/mach/regs-ssp.h [deleted file]
arch/arm/mach-pxa/include/mach/regs-u2d.h
arch/arm/mach-pxa/include/mach/ssp.h [deleted file]
arch/arm/mach-pxa/include/mach/tosa.h
arch/arm/mach-pxa/include/mach/vpac270.h [new file with mode: 0644]
arch/arm/mach-pxa/include/mach/z2.h [new file with mode: 0644]
arch/arm/mach-pxa/littleton.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mfp-pxa2xx.c
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/mxm8x10.c
arch/arm/mach-pxa/palmld.c
arch/arm/mach-pxa/palmt5.c
arch/arm/mach-pxa/palmtc.c
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa3xx.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-pxa/sharpsl.h
arch/arm/mach-pxa/sharpsl_pm.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-pxa/spitz_pm.c
arch/arm/mach-pxa/ssp.c [deleted file]
arch/arm/mach-pxa/stargate2.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-pxa/trizeps4.c
arch/arm/mach-pxa/viper.c
arch/arm/mach-pxa/vpac270.c [new file with mode: 0644]
arch/arm/mach-pxa/z2.c [new file with mode: 0644]
arch/arm/mach-pxa/zeus.c
arch/arm/mach-pxa/zylonite.c
arch/arm/mach-realview/Makefile
arch/arm/mach-realview/clock.c [deleted file]
arch/arm/mach-realview/clock.h [deleted file]
arch/arm/mach-realview/core.c
arch/arm/mach-realview/hotplug.c
arch/arm/mach-realview/include/mach/clkdev.h
arch/arm/mach-realview/include/mach/irqs-pb1176.h
arch/arm/mach-realview/include/mach/irqs-pba8.h
arch/arm/mach-realview/include/mach/irqs-pbx.h
arch/arm/mach-realview/include/mach/platform.h
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pba8.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/Makefile.boot
arch/arm/mach-s3c2410/h1940-bluetooth.c
arch/arm/mach-s3c2410/include/mach/dma.h
arch/arm/mach-s3c2410/include/mach/gpio-fns.h
arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
arch/arm/mach-s3c2410/include/mach/gpio-track.h
arch/arm/mach-s3c2410/include/mach/gpio.h
arch/arm/mach-s3c2410/include/mach/irqs.h
arch/arm/mach-s3c2410/include/mach/map.h
arch/arm/mach-s3c2410/include/mach/regs-clock.h
arch/arm/mach-s3c2410/include/mach/regs-dsc.h
arch/arm/mach-s3c2410/include/mach/regs-gpio.h
arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
arch/arm/mach-s3c2410/include/mach/regs-irq.h
arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h [new file with mode: 0644]
arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h [new file with mode: 0644]
arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
arch/arm/mach-s3c2410/include/mach/ts.h [deleted file]
arch/arm/mach-s3c2410/include/mach/uncompress.h
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/mach-qt2410.c
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-s3c2410/pm.c
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2412/Kconfig
arch/arm/mach-s3c2412/gpio.c
arch/arm/mach-s3c2412/mach-jive.c
arch/arm/mach-s3c2412/mach-smdk2413.c
arch/arm/mach-s3c2416/Kconfig [new file with mode: 0644]
arch/arm/mach-s3c2416/Makefile [new file with mode: 0644]
arch/arm/mach-s3c2416/clock.c [new file with mode: 0644]
arch/arm/mach-s3c2416/irq.c [new file with mode: 0644]
arch/arm/mach-s3c2416/mach-smdk2416.c [new file with mode: 0644]
arch/arm/mach-s3c2416/s3c2416.c [new file with mode: 0644]
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/Makefile
arch/arm/mach-s3c2440/mach-mini2440.c
arch/arm/mach-s3c2440/mach-nexcoder.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/arm/mach-s3c2440/mach-rx1950.c [new file with mode: 0644]
arch/arm/mach-s3c2440/mach-rx3715.c
arch/arm/mach-s3c2440/mach-smdk2440.c
arch/arm/mach-s3c2440/s3c2440.c
arch/arm/mach-s3c2443/Kconfig
arch/arm/mach-s3c2443/clock.c
arch/arm/mach-s3c2443/mach-smdk2443.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/Makefile
arch/arm/mach-s3c64xx/clock.c
arch/arm/mach-s3c64xx/dev-adc.c [deleted file]
arch/arm/mach-s3c64xx/dev-rtc.c [deleted file]
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-s3c64xx/gpiolib.c
arch/arm/mach-s3c64xx/include/mach/map.h
arch/arm/mach-s3c64xx/include/mach/pll.h
arch/arm/mach-s3c64xx/include/mach/regs-clock.h
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s3c64xx/s3c6410.c
arch/arm/mach-s5p6440/Kconfig
arch/arm/mach-s5p6440/Makefile
arch/arm/mach-s5p6440/clock.c
arch/arm/mach-s5p6440/cpu.c
arch/arm/mach-s5p6440/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5p6440/dma.c [new file with mode: 0644]
arch/arm/mach-s5p6440/gpio.c
arch/arm/mach-s5p6440/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s5p6440/include/mach/map.h
arch/arm/mach-s5p6440/include/mach/pwm-clock.h
arch/arm/mach-s5p6440/mach-smdk6440.c
arch/arm/mach-s5p6440/setup-i2c0.c [new file with mode: 0644]
arch/arm/mach-s5p6442/Kconfig
arch/arm/mach-s5p6442/Makefile
arch/arm/mach-s5p6442/cpu.c
arch/arm/mach-s5p6442/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5p6442/dma.c [new file with mode: 0644]
arch/arm/mach-s5p6442/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s5p6442/include/mach/map.h
arch/arm/mach-s5p6442/include/mach/pwm-clock.h
arch/arm/mach-s5p6442/mach-smdk6442.c
arch/arm/mach-s5p6442/setup-i2c0.c [new file with mode: 0644]
arch/arm/mach-s5pc100/Kconfig
arch/arm/mach-s5pc100/Makefile
arch/arm/mach-s5pc100/clock.c [new file with mode: 0644]
arch/arm/mach-s5pc100/gpiolib.c [new file with mode: 0644]
arch/arm/mach-s5pc100/include/mach/gpio.h
arch/arm/mach-s5pc100/include/mach/regs-clock.h [new file with mode: 0644]
arch/arm/mach-s5pc100/include/mach/regs-gpio.h [new file with mode: 0644]
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pc100/setup-fb-24bpp.c [new file with mode: 0644]
arch/arm/mach-s5pc100/setup-i2c0.c [new file with mode: 0644]
arch/arm/mach-s5pc100/setup-i2c1.c [new file with mode: 0644]
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/dev-audio.c [new file with mode: 0644]
arch/arm/mach-s5pv210/dma.c [new file with mode: 0644]
arch/arm/mach-s5pv210/gpiolib.c [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/dma.h [new file with mode: 0644]
arch/arm/mach-s5pv210/include/mach/gpio.h
arch/arm/mach-s5pv210/include/mach/map.h
arch/arm/mach-s5pv210/include/mach/pwm-clock.h
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/setup-i2c0.c [new file with mode: 0644]
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/cpu-sa1110.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-spear3xx/Kconfig [new file with mode: 0644]
arch/arm/mach-spear3xx/Kconfig300 [new file with mode: 0644]
arch/arm/mach-spear3xx/Kconfig310 [new file with mode: 0644]
arch/arm/mach-spear3xx/Kconfig320 [new file with mode: 0644]
arch/arm/mach-spear3xx/Makefile [new file with mode: 0644]
arch/arm/mach-spear3xx/Makefile.boot [new file with mode: 0644]
arch/arm/mach-spear3xx/clock.c [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/generic.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/misc_regs.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/spear.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/spear300.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/spear310.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/spear320.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-spear3xx/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-spear3xx/spear300.c [new file with mode: 0644]
arch/arm/mach-spear3xx/spear300_evb.c [new file with mode: 0644]
arch/arm/mach-spear3xx/spear310.c [new file with mode: 0644]
arch/arm/mach-spear3xx/spear310_evb.c [new file with mode: 0644]
arch/arm/mach-spear3xx/spear320.c [new file with mode: 0644]
arch/arm/mach-spear3xx/spear320_evb.c [new file with mode: 0644]
arch/arm/mach-spear3xx/spear3xx.c [new file with mode: 0644]
arch/arm/mach-spear6xx/Kconfig [new file with mode: 0644]
arch/arm/mach-spear6xx/Kconfig600 [new file with mode: 0644]
arch/arm/mach-spear6xx/Makefile [new file with mode: 0644]
arch/arm/mach-spear6xx/Makefile.boot [new file with mode: 0644]
arch/arm/mach-spear6xx/clock.c [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/generic.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/misc_regs.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/spear.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/spear600.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-spear6xx/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-spear6xx/spear600.c [new file with mode: 0644]
arch/arm/mach-spear6xx/spear600_evb.c [new file with mode: 0644]
arch/arm/mach-spear6xx/spear6xx.c [new file with mode: 0644]
arch/arm/mach-u300/mmc.c
arch/arm/mach-ux500/Kconfig
arch/arm/mach-ux500/Makefile
arch/arm/mach-ux500/board-mop500.c
arch/arm/mach-ux500/board-u5500.c [new file with mode: 0644]
arch/arm/mach-ux500/clock.c
arch/arm/mach-ux500/clock.h [new file with mode: 0644]
arch/arm/mach-ux500/cpu-db5500.c [new file with mode: 0644]
arch/arm/mach-ux500/cpu-db8500.c [new file with mode: 0644]
arch/arm/mach-ux500/cpu-u8500.c [deleted file]
arch/arm/mach-ux500/cpu.c [new file with mode: 0644]
arch/arm/mach-ux500/devices-db5500.c [new file with mode: 0644]
arch/arm/mach-ux500/devices-db8500.c [new file with mode: 0644]
arch/arm/mach-ux500/devices.c [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/db5500-regs.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/db8500-regs.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/debug-macro.S
arch/arm/mach-ux500/include/mach/devices.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/entry-macro.S
arch/arm/mach-ux500/include/mach/gpio.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/hardware.h
arch/arm/mach-ux500/include/mach/irqs.h
arch/arm/mach-ux500/include/mach/setup.h
arch/arm/mach-ux500/platsmp.c
arch/arm/mach-versatile/Makefile
arch/arm/mach-versatile/clock.c [deleted file]
arch/arm/mach-versatile/clock.h [deleted file]
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/include/mach/clkdev.h
arch/arm/mach-versatile/include/mach/entry-macro.S
arch/arm/mach-versatile/include/mach/hardware.h
arch/arm/mach-versatile/include/mach/platform.h
arch/arm/mach-vexpress/Kconfig [new file with mode: 0644]
arch/arm/mach-vexpress/Makefile [new file with mode: 0644]
arch/arm/mach-vexpress/Makefile.boot [new file with mode: 0644]
arch/arm/mach-vexpress/core.h [new file with mode: 0644]
arch/arm/mach-vexpress/ct-ca9x4.c [new file with mode: 0644]
arch/arm/mach-vexpress/headsmp.S [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/ct-ca9x4.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/motherboard.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/smp.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-vexpress/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-vexpress/localtimer.c [new file with mode: 0644]
arch/arm/mach-vexpress/platsmp.c [new file with mode: 0644]
arch/arm/mach-vexpress/v2m.c [new file with mode: 0644]
arch/arm/mm/Kconfig
arch/arm/mm/abort-ev7.S
arch/arm/mm/alignment.c
arch/arm/mm/cache-l2x0.c
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/copypage-fa.c
arch/arm/mm/copypage-v6.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault-armv.c
arch/arm/mm/fault.c
arch/arm/mm/flush.c
arch/arm/mm/highmem.c
arch/arm/mm/init.c
arch/arm/mm/mm.h
arch/arm/mm/mmu.c
arch/arm/mm/nommu.c
arch/arm/mm/proc-sa1100.S
arch/arm/mm/tlb-v7.S
arch/arm/nwfpe/entry.S
arch/arm/nwfpe/fpmodule.c
arch/arm/oprofile/Makefile
arch/arm/oprofile/backtrace.c [deleted file]
arch/arm/oprofile/common.c
arch/arm/oprofile/op_arm_model.h [deleted file]
arch/arm/oprofile/op_counter.h [deleted file]
arch/arm/oprofile/op_model_arm11_core.c [deleted file]
arch/arm/oprofile/op_model_arm11_core.h [deleted file]
arch/arm/oprofile/op_model_mpcore.c [deleted file]
arch/arm/oprofile/op_model_mpcore.h [deleted file]
arch/arm/oprofile/op_model_v6.c [deleted file]
arch/arm/oprofile/op_model_v7.c [deleted file]
arch/arm/oprofile/op_model_v7.h [deleted file]
arch/arm/oprofile/op_model_xscale.c [deleted file]
arch/arm/plat-iop/Makefile
arch/arm/plat-iop/pmu.c [new file with mode: 0644]
arch/arm/plat-mxc/include/mach/board-mx31_3ds.h [new file with mode: 0644]
arch/arm/plat-mxc/include/mach/board-mx31pdk.h [deleted file]
arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
arch/arm/plat-mxc/include/mach/mx51.h
arch/arm/plat-mxc/include/mach/uncompress.h
arch/arm/plat-nomadik/Kconfig
arch/arm/plat-nomadik/Makefile
arch/arm/plat-nomadik/gpio.c [new file with mode: 0644]
arch/arm/plat-nomadik/include/plat/gpio.h [new file with mode: 0644]
arch/arm/plat-nomadik/timer.c
arch/arm/plat-omap/common.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/plat/irqs.h
arch/arm/plat-omap/include/plat/mcbsp.h
arch/arm/plat-omap/include/plat/nand.h
arch/arm/plat-omap/include/plat/omap44xx.h
arch/arm/plat-omap/include/plat/omap_hwmod.h
arch/arm/plat-omap/include/plat/usb.h
arch/arm/plat-pxa/Kconfig
arch/arm/plat-pxa/Makefile
arch/arm/plat-pxa/dma.c
arch/arm/plat-pxa/include/plat/mfp.h
arch/arm/plat-pxa/include/plat/ssp.h [new file with mode: 0644]
arch/arm/plat-pxa/mfp.c
arch/arm/plat-pxa/pmu.c [new file with mode: 0644]
arch/arm/plat-pxa/ssp.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/Kconfig
arch/arm/plat-s3c24xx/Makefile
arch/arm/plat-s3c24xx/common-smdk.c
arch/arm/plat-s3c24xx/cpu.c
arch/arm/plat-s3c24xx/devs.c
arch/arm/plat-s3c24xx/dma.c
arch/arm/plat-s3c24xx/gpio.c
arch/arm/plat-s3c24xx/gpiolib.c
arch/arm/plat-s3c24xx/include/plat/pll.h
arch/arm/plat-s3c24xx/include/plat/s3c2416.h [new file with mode: 0644]
arch/arm/plat-s3c24xx/include/plat/s3c2443.h
arch/arm/plat-s3c24xx/pm.c
arch/arm/plat-s3c24xx/s3c2410-clock.c
arch/arm/plat-s3c24xx/s3c2443-clock.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/setup-i2c.c
arch/arm/plat-s3c24xx/setup-ts.c [new file with mode: 0644]
arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
arch/arm/plat-s5p/Kconfig
arch/arm/plat-s5p/Makefile
arch/arm/plat-s5p/clock.c
arch/arm/plat-s5p/include/plat/irqs.h
arch/arm/plat-s5p/include/plat/pll.h
arch/arm/plat-s5p/include/plat/s5p-clock.h
arch/arm/plat-s5p/setup-i2c0.c [deleted file]
arch/arm/plat-s5pc1xx/Kconfig
arch/arm/plat-s5pc1xx/Makefile
arch/arm/plat-s5pc1xx/gpio-config.c [deleted file]
arch/arm/plat-s5pc1xx/gpiolib.c [deleted file]
arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h [deleted file]
arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h [deleted file]
arch/arm/plat-s5pc1xx/setup-fb-24bpp.c [deleted file]
arch/arm/plat-s5pc1xx/setup-i2c0.c [deleted file]
arch/arm/plat-s5pc1xx/setup-i2c1.c [deleted file]
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/clock.c
arch/arm/plat-samsung/dev-adc.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-fb.c
arch/arm/plat-samsung/dev-hwmon.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-rtc.c [new file with mode: 0644]
arch/arm/plat-samsung/dev-ts.c [new file with mode: 0644]
arch/arm/plat-samsung/gpio-config.c
arch/arm/plat-samsung/gpio.c
arch/arm/plat-samsung/include/plat/clock.h
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/devs.h
arch/arm/plat-samsung/include/plat/dma.h
arch/arm/plat-samsung/include/plat/fb.h
arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/arm/plat-samsung/include/plat/gpio-core.h
arch/arm/plat-samsung/include/plat/hwmon.h
arch/arm/plat-samsung/include/plat/pll6553x.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h [new file with mode: 0644]
arch/arm/plat-samsung/include/plat/ts.h [new file with mode: 0644]
arch/arm/plat-samsung/pm-gpio.c
arch/arm/plat-samsung/s3c-pl330.c [new file with mode: 0644]
arch/arm/plat-spear/Kconfig [new file with mode: 0644]
arch/arm/plat-spear/Makefile [new file with mode: 0644]
arch/arm/plat-spear/clock.c [new file with mode: 0644]
arch/arm/plat-spear/include/plat/clkdev.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/clock.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/debug-macro.S [new file with mode: 0644]
arch/arm/plat-spear/include/plat/gpio.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/io.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/memory.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/padmux.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/shirq.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/system.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/timex.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/uncompress.h [new file with mode: 0644]
arch/arm/plat-spear/include/plat/vmalloc.h [new file with mode: 0644]
arch/arm/plat-spear/padmux.c [new file with mode: 0644]
arch/arm/plat-spear/shirq.c [new file with mode: 0644]
arch/arm/plat-spear/time.c [new file with mode: 0644]
arch/arm/plat-versatile/Makefile [new file with mode: 0644]
arch/arm/plat-versatile/clock.c [new file with mode: 0644]
arch/arm/plat-versatile/include/plat/clock.h [new file with mode: 0644]
arch/arm/plat-versatile/include/plat/timer-sp.h [new file with mode: 0644]
arch/arm/plat-versatile/sched-clock.c [new file with mode: 0644]
arch/arm/plat-versatile/timer-sp.c [new file with mode: 0644]
arch/arm/tools/mach-types
arch/arm/vfp/vfpmodule.c
arch/avr32/include/asm/atomic.h
arch/avr32/kernel/ptrace.c
arch/avr32/kernel/time.c
arch/blackfin/kernel/time-ts.c
arch/blackfin/kernel/time.c
arch/cris/Kconfig
arch/cris/arch-v10/kernel/time.c
arch/cris/arch-v32/kernel/time.c
arch/cris/include/asm/atomic.h
arch/cris/kernel/time.c
arch/frv/include/asm/atomic.h
arch/frv/kernel/time.c
arch/h8300/include/asm/atomic.h
arch/h8300/kernel/time.c
arch/ia64/Kconfig
arch/ia64/hp/common/sba_iommu.c
arch/ia64/include/asm/atomic.h
arch/ia64/include/asm/bitops.h
arch/ia64/include/asm/mmzone.h
arch/ia64/kernel/acpi.c
arch/ia64/kernel/cpufreq/acpi-cpufreq.c
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/salinfo.c
arch/ia64/kernel/time.c
arch/ia64/kernel/topology.c
arch/ia64/kernel/unaligned.c
arch/ia64/kvm/kvm-ia64.c
arch/ia64/mm/fault.c
arch/ia64/sn/kernel/sn2/sn_hwperf.c
arch/m32r/include/asm/atomic.h
arch/m32r/kernel/time.c
arch/m68k/amiga/Makefile
arch/m68k/amiga/platform.c [new file with mode: 0644]
arch/m68k/bvme6000/rtc.c
arch/m68k/hp300/time.h
arch/m68k/include/asm/atomic_mm.h
arch/m68k/include/asm/atomic_no.h
arch/m68k/include/asm/bitops_mm.h
arch/m68k/include/asm/mcfuart.h
arch/m68k/include/asm/param.h
arch/m68k/include/asm/sigcontext.h
arch/m68k/kernel/time.c
arch/m68k/kernel/traps.c
arch/m68k/mac/config.c
arch/m68k/mm/fault.c
arch/m68k/mvme16x/rtc.c
arch/m68k/q40/config.c
arch/m68knommu/Makefile
arch/m68knommu/kernel/entry.S
arch/m68knommu/platform/68360/ints.c
arch/microblaze/configs/mmu_defconfig
arch/microblaze/configs/nommu_defconfig
arch/microblaze/include/asm/cache.h
arch/microblaze/include/asm/dma.h
arch/microblaze/include/asm/exceptions.h
arch/microblaze/include/asm/io.h
arch/microblaze/include/asm/page.h
arch/microblaze/include/asm/pci.h
arch/microblaze/include/asm/pgalloc.h
arch/microblaze/include/asm/pgtable.h
arch/microblaze/include/asm/uaccess.h
arch/microblaze/kernel/asm-offsets.c
arch/microblaze/kernel/cpu/cache.c
arch/microblaze/kernel/cpu/mb.c
arch/microblaze/kernel/dma.c
arch/microblaze/kernel/entry-nommu.S
arch/microblaze/kernel/exceptions.c
arch/microblaze/kernel/head.S
arch/microblaze/kernel/irq.c
arch/microblaze/kernel/microblaze_ksyms.c
arch/microblaze/kernel/misc.S
arch/microblaze/kernel/module.c
arch/microblaze/kernel/traps.c
arch/microblaze/kernel/vmlinux.lds.S
arch/microblaze/mm/consistent.c
arch/microblaze/mm/fault.c
arch/microblaze/mm/init.c
arch/microblaze/mm/pgtable.c
arch/microblaze/pci/pci-common.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/alchemy/devboards/db1200/setup.c
arch/mips/ar7/platform.c
arch/mips/bcm63xx/boards/board_bcm963xx.c
arch/mips/bcm63xx/cpu.c
arch/mips/bcm63xx/dev-uart.c
arch/mips/bcm63xx/gpio.c
arch/mips/cavium-octeon/setup.c
arch/mips/cavium-octeon/smp.c
arch/mips/configs/bcm63xx_defconfig
arch/mips/configs/bigsur_defconfig
arch/mips/include/asm/abi.h
arch/mips/include/asm/atomic.h
arch/mips/include/asm/cmpxchg.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/fpu_emulator.h
arch/mips/include/asm/i8253.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
arch/mips/include/asm/mach-loongson/loongson.h
arch/mips/include/asm/mach-sibyte/war.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/mmu.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/page.h
arch/mips/include/asm/pgtable-64.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/ptrace.h
arch/mips/include/asm/stackframe.h
arch/mips/include/asm/uasm.h
arch/mips/include/asm/vdso.h [new file with mode: 0644]
arch/mips/jazz/setup.c
arch/mips/kernel/Makefile
arch/mips/kernel/cpufreq/loongson2_clock.c
arch/mips/kernel/i8253.c
arch/mips/kernel/process.c
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/smtc.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/vdso.c [new file with mode: 0644]
arch/mips/lib/delay.c
arch/mips/lib/libgcc.h
arch/mips/loongson/common/machtype.c
arch/mips/loongson/common/mem.c
arch/mips/loongson/common/reset.c
arch/mips/loongson/common/setup.c
arch/mips/loongson/lemote-2f/irq.c
arch/mips/math-emu/cp1emu.c
arch/mips/mm/cache.c
arch/mips/mm/tlbex.c
arch/mips/mm/uasm.c
arch/mips/nxp/pnx8550/common/reset.c
arch/mips/oprofile/op_model_loongson2.c
arch/mips/pci/ops-loongson2.c
arch/mips/pci/pci-sb1250.c
arch/mips/sgi-ip22/ip22-berr.c
arch/mips/sgi-ip22/ip28-berr.c
arch/mips/sibyte/sb1250/setup.c
arch/mips/sibyte/swarm/setup.c
arch/mn10300/Kconfig
arch/mn10300/include/asm/atomic.h
arch/mn10300/kernel/rtc.c
arch/mn10300/kernel/time.c
arch/parisc/include/asm/atomic.h
arch/powerpc/configs/83xx/asp8347_defconfig
arch/powerpc/configs/83xx/kmeter1_defconfig
arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
arch/powerpc/configs/83xx/mpc832x_mds_defconfig
arch/powerpc/configs/83xx/mpc832x_rdb_defconfig
arch/powerpc/configs/83xx/mpc834x_itx_defconfig
arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig
arch/powerpc/configs/83xx/mpc834x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_mds_defconfig
arch/powerpc/configs/83xx/mpc836x_rdk_defconfig
arch/powerpc/configs/83xx/mpc837x_mds_defconfig
arch/powerpc/configs/83xx/mpc837x_rdb_defconfig
arch/powerpc/configs/83xx/sbc834x_defconfig
arch/powerpc/configs/85xx/ksi8560_defconfig
arch/powerpc/configs/85xx/mpc8540_ads_defconfig
arch/powerpc/configs/85xx/mpc8560_ads_defconfig
arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
arch/powerpc/configs/85xx/sbc8548_defconfig
arch/powerpc/configs/85xx/sbc8560_defconfig
arch/powerpc/configs/85xx/socrates_defconfig
arch/powerpc/configs/85xx/stx_gp3_defconfig
arch/powerpc/configs/85xx/tqm8540_defconfig
arch/powerpc/configs/85xx/tqm8541_defconfig
arch/powerpc/configs/85xx/tqm8548_defconfig
arch/powerpc/configs/85xx/tqm8555_defconfig
arch/powerpc/configs/85xx/tqm8560_defconfig
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
arch/powerpc/configs/86xx/gef_ppc9a_defconfig
arch/powerpc/configs/86xx/gef_sbc310_defconfig
arch/powerpc/configs/86xx/gef_sbc610_defconfig
arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig
arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
arch/powerpc/configs/86xx/sbc8641d_defconfig
arch/powerpc/configs/adder875_defconfig
arch/powerpc/configs/c2k_defconfig
arch/powerpc/configs/ep8248e_defconfig
arch/powerpc/configs/ep88xc_defconfig
arch/powerpc/configs/linkstation_defconfig
arch/powerpc/configs/mgcoge_defconfig
arch/powerpc/configs/mgsuvd_defconfig
arch/powerpc/configs/mpc7448_hpc2_defconfig
arch/powerpc/configs/mpc8272_ads_defconfig
arch/powerpc/configs/mpc83xx_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/configs/mpc866_ads_defconfig
arch/powerpc/configs/mpc86xx_defconfig
arch/powerpc/configs/mpc885_ads_defconfig
arch/powerpc/configs/pq2fads_defconfig
arch/powerpc/configs/prpmc2800_defconfig
arch/powerpc/configs/ps3_defconfig
arch/powerpc/configs/storcenter_defconfig
arch/powerpc/include/asm/hw_irq.h
arch/powerpc/include/asm/page.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/dma-swiotlb.c
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/perf_event.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/time.c
arch/powerpc/kvm/44x_tlb.c
arch/powerpc/kvm/book3s.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/86xx/Kconfig
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/sysdev/cpm1.c
arch/powerpc/sysdev/cpm2.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/hypfs/hypfs.h
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/hypfs_vm.c
arch/s390/hypfs/inode.c
arch/s390/include/asm/cputime.h
arch/s390/include/asm/lowcore.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/qdio.h
arch/s390/include/asm/setup.h
arch/s390/include/asm/system.h
arch/s390/include/asm/thread_info.h
arch/s390/include/asm/timex.h
arch/s390/include/asm/topology.h
arch/s390/include/asm/vdso.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/debug.c
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/head.S
arch/s390/kernel/head31.S
arch/s390/kernel/head64.S
arch/s390/kernel/nmi.c
arch/s390/kernel/processor.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/s390_ext.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/s390/kernel/swsusp_asm64.S
arch/s390/kernel/time.c
arch/s390/kernel/topology.c
arch/s390/kernel/traps.c
arch/s390/kernel/vdso.c
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso32/gettimeofday.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/s390/kernel/vdso64/gettimeofday.S
arch/s390/kernel/vtime.c
arch/s390/kvm/Kconfig
arch/s390/kvm/sie64a.S
arch/s390/mm/fault.c
arch/sh/Kconfig
arch/sh/Makefile
arch/sh/boards/board-urquell.c
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-highlander/setup.c
arch/sh/boards/mach-sdk7786/setup.c
arch/sh/boards/mach-se/7724/setup.c
arch/sh/boards/mach-x3proto/setup.c
arch/sh/boot/compressed/Makefile
arch/sh/boot/compressed/head_32.S
arch/sh/configs/ap325rxa_defconfig
arch/sh/configs/cayman_defconfig
arch/sh/configs/dreamcast_defconfig
arch/sh/configs/ecovec24-romimage_defconfig
arch/sh/configs/ecovec24_defconfig
arch/sh/configs/edosk7705_defconfig
arch/sh/configs/edosk7760_defconfig
arch/sh/configs/espt_defconfig
arch/sh/configs/hp6xx_defconfig
arch/sh/configs/kfr2r09-romimage_defconfig
arch/sh/configs/kfr2r09_defconfig
arch/sh/configs/landisk_defconfig
arch/sh/configs/lboxre2_defconfig
arch/sh/configs/magicpanelr2_defconfig
arch/sh/configs/microdev_defconfig
arch/sh/configs/migor_defconfig
arch/sh/configs/polaris_defconfig
arch/sh/configs/r7780mp_defconfig
arch/sh/configs/r7785rp_defconfig
arch/sh/configs/rsk7201_defconfig
arch/sh/configs/rsk7203_defconfig
arch/sh/configs/rts7751r2d1_defconfig
arch/sh/configs/rts7751r2dplus_defconfig
arch/sh/configs/sdk7780_defconfig
arch/sh/configs/sdk7786_defconfig
arch/sh/configs/se7206_defconfig
arch/sh/configs/se7343_defconfig
arch/sh/configs/se7619_defconfig
arch/sh/configs/se7705_defconfig
arch/sh/configs/se7712_defconfig
arch/sh/configs/se7721_defconfig
arch/sh/configs/se7722_defconfig
arch/sh/configs/se7724_defconfig
arch/sh/configs/se7750_defconfig
arch/sh/configs/se7751_defconfig
arch/sh/configs/se7780_defconfig
arch/sh/configs/sh03_defconfig
arch/sh/configs/sh7710voipgw_defconfig
arch/sh/configs/sh7724_generic_defconfig
arch/sh/configs/sh7763rdp_defconfig
arch/sh/configs/sh7770_generic_defconfig
arch/sh/configs/sh7785lcr_32bit_defconfig
arch/sh/configs/sh7785lcr_defconfig
arch/sh/configs/shmin_defconfig
arch/sh/configs/shx3_defconfig
arch/sh/configs/snapgear_defconfig
arch/sh/configs/systemh_defconfig
arch/sh/configs/titan_defconfig
arch/sh/configs/ul2_defconfig
arch/sh/configs/urquell_defconfig
arch/sh/drivers/pci/pci-sh7751.c
arch/sh/include/asm/atomic.h
arch/sh/include/asm/cache.h
arch/sh/include/asm/clkdev.h [new file with mode: 0644]
arch/sh/include/asm/clock.h
arch/sh/include/asm/dmaengine.h
arch/sh/include/asm/hw_breakpoint.h
arch/sh/include/asm/hwblk.h
arch/sh/include/asm/io_generic.h
arch/sh/include/asm/irq.h
arch/sh/include/asm/kexec.h
arch/sh/include/asm/machvec.h
arch/sh/include/asm/mmzone.h
arch/sh/include/asm/page.h
arch/sh/include/asm/processor.h
arch/sh/include/asm/processor_32.h
arch/sh/include/asm/setup.h
arch/sh/include/asm/siu.h
arch/sh/include/asm/smp-ops.h [new file with mode: 0644]
arch/sh/include/asm/smp.h
arch/sh/include/cpu-sh4/cpu/dma-register.h
arch/sh/include/cpu-sh4/cpu/mmu_context.h
arch/sh/include/mach-sdk7786/mach/fpga.h
arch/sh/kernel/Makefile
arch/sh/kernel/clkdev.c [new file with mode: 0644]
arch/sh/kernel/cpu/Makefile
arch/sh/kernel/cpu/clock-cpg.c
arch/sh/kernel/cpu/clock.c
arch/sh/kernel/cpu/hwblk.c
arch/sh/kernel/cpu/init.c
arch/sh/kernel/cpu/sh2/probe.c
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/probe.c
arch/sh/kernel/cpu/sh2a/setup-mxg.c
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/probe.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
arch/sh/kernel/cpu/sh4/probe.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/clock-sh7343.c
arch/sh/kernel/cpu/sh4a/clock-sh7366.c
arch/sh/kernel/cpu/sh4a/clock-sh7722.c
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/kernel/cpu/sh4a/clock-sh7757.c
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
arch/sh/kernel/cpu/sh4a/clock-sh7780.c
arch/sh/kernel/cpu/sh4a/clock-sh7785.c
arch/sh/kernel/cpu/sh4a/clock-sh7786.c
arch/sh/kernel/cpu/sh4a/clock-shx3.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7757.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sh/kernel/cpu/sh4a/smp-shx3.c
arch/sh/kernel/cpu/sh5/probe.c
arch/sh/kernel/cpu/sh5/setup-sh5.c
arch/sh/kernel/crash_dump.c
arch/sh/kernel/dwarf.c
arch/sh/kernel/head_32.S
arch/sh/kernel/hw_breakpoint.c
arch/sh/kernel/idle.c
arch/sh/kernel/irq.c
arch/sh/kernel/localtimer.c
arch/sh/kernel/machine_kexec.c
arch/sh/kernel/machvec.c
arch/sh/kernel/process.c
arch/sh/kernel/ptrace_32.c
arch/sh/kernel/setup.c
arch/sh/kernel/smp.c
arch/sh/kernel/topology.c
arch/sh/kernel/traps_64.c
arch/sh/mm/Makefile
arch/sh/mm/cache-shx3.c [new file with mode: 0644]
arch/sh/mm/cache.c
arch/sh/mm/fault_32.c
arch/sh/mm/init.c
arch/sh/mm/numa.c
arch/sh/mm/pmb.c
arch/sh/mm/tlb-debugfs.c [new file with mode: 0644]
arch/sh/mm/tlbflush_64.c
arch/sparc/Kconfig
arch/sparc/Kconfig.debug
arch/sparc/include/asm/atomic_32.h
arch/sparc/include/asm/atomic_64.h
arch/sparc/include/asm/bitops_64.h
arch/sparc/include/asm/cache.h
arch/sparc/include/asm/cpudata_64.h
arch/sparc/include/asm/irqflags_64.h
arch/sparc/include/asm/thread_info_64.h
arch/sparc/kernel/Makefile
arch/sparc/kernel/ftrace.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/kgdb_64.c
arch/sparc/kernel/kstack.h
arch/sparc/kernel/nmi.c
arch/sparc/kernel/pci_common.c
arch/sparc/kernel/pcr.c
arch/sparc/kernel/perf_event.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/stacktrace.c
arch/sparc/kernel/time_32.c
arch/sparc/kernel/time_64.c
arch/sparc/kernel/traps_64.c
arch/sparc/kernel/unaligned_64.c
arch/sparc/kernel/vmlinux.lds.S
arch/sparc/lib/mcount.S
arch/um/drivers/line.c
arch/um/os-Linux/helper.c
arch/x86/Kconfig
arch/x86/Kconfig.cpu
arch/x86/Kconfig.debug
arch/x86/Makefile
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/alternative-asm.h
arch/x86/include/asm/alternative.h
arch/x86/include/asm/amd_iommu_types.h
arch/x86/include/asm/apic.h
arch/x86/include/asm/arch_hweight.h [new file with mode: 0644]
arch/x86/include/asm/atomic.h
arch/x86/include/asm/atomic64_32.h
arch/x86/include/asm/atomic64_64.h
arch/x86/include/asm/bitops.h
arch/x86/include/asm/boot.h
arch/x86/include/asm/cacheflush.h
arch/x86/include/asm/cmpxchg_32.h
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/ds.h [deleted file]
arch/x86/include/asm/dwarf2.h
arch/x86/include/asm/e820.h
arch/x86/include/asm/hardirq.h
arch/x86/include/asm/hpet.h
arch/x86/include/asm/hw_breakpoint.h
arch/x86/include/asm/hyperv.h
arch/x86/include/asm/hypervisor.h
arch/x86/include/asm/i387.h
arch/x86/include/asm/i8253.h
arch/x86/include/asm/insn.h
arch/x86/include/asm/io.h
arch/x86/include/asm/io_apic.h
arch/x86/include/asm/k8.h
arch/x86/include/asm/kprobes.h
arch/x86/include/asm/lguest_hcall.h
arch/x86/include/asm/mpspec.h
arch/x86/include/asm/mshyperv.h [new file with mode: 0644]
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/percpu.h
arch/x86/include/asm/perf_event.h
arch/x86/include/asm/perf_event_p4.h [new file with mode: 0644]
arch/x86/include/asm/processor.h
arch/x86/include/asm/ptrace-abi.h
arch/x86/include/asm/ptrace.h
arch/x86/include/asm/thread_info.h
arch/x86/include/asm/traps.h
arch/x86/include/asm/uv/uv_bau.h
arch/x86/include/asm/uv/uv_hub.h
arch/x86/include/asm/uv/uv_mmrs.h
arch/x86/include/asm/vmware.h [deleted file]
arch/x86/include/asm/xsave.h
arch/x86/kernel/Makefile
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/alternative.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/apb_timer.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/addon_cpuid_features.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/cpufreq/Makefile
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/mperf.c [new file with mode: 0644]
arch/x86/kernel/cpu/cpufreq/mperf.h [new file with mode: 0644]
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.h
arch/x86/kernel/cpu/hypervisor.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/mce.c
arch/x86/kernel/cpu/mshyperv.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpu/perf_event_amd.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event_intel_lbr.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event_p4.c [new file with mode: 0644]
arch/x86/kernel/cpu/perf_event_p6.c
arch/x86/kernel/cpu/vmware.c
arch/x86/kernel/crash.c
arch/x86/kernel/ds.c [deleted file]
arch/x86/kernel/ds_selftest.c [deleted file]
arch/x86/kernel/ds_selftest.h [deleted file]
arch/x86/kernel/dumpstack.c
arch/x86/kernel/dumpstack.h
arch/x86/kernel/entry_32.S
arch/x86/kernel/hpet.c
arch/x86/kernel/hw_breakpoint.c
arch/x86/kernel/i387.c
arch/x86/kernel/i8253.c
arch/x86/kernel/irqinit.c
arch/x86/kernel/kprobes.c
arch/x86/kernel/microcode_core.c
arch/x86/kernel/microcode_intel.c
arch/x86/kernel/mpparse.c
arch/x86/kernel/mrst.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/quirks.c
arch/x86/kernel/sfi.c
arch/x86/kernel/step.c
arch/x86/kernel/tboot.c
arch/x86/kernel/tlb_uv.c
arch/x86/kernel/traps.c
arch/x86/kernel/uv_irq.c
arch/x86/kernel/x8664_ksyms_64.c
arch/x86/kernel/xsave.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
arch/x86/lib/Makefile
arch/x86/lib/atomic64_32.c
arch/x86/lib/atomic64_386_32.S [new file with mode: 0644]
arch/x86/lib/atomic64_cx8_32.S [new file with mode: 0644]
arch/x86/lib/rwsem_64.S
arch/x86/math-emu/fpu_aux.c
arch/x86/math-emu/fpu_entry.c
arch/x86/math-emu/fpu_system.h
arch/x86/mm/Makefile
arch/x86/mm/ioremap.c
arch/x86/mm/pat.c
arch/x86/mm/pat_internal.h [new file with mode: 0644]
arch/x86/mm/pat_rbtree.c [new file with mode: 0644]
arch/x86/mm/pgtable_32.c
arch/x86/mm/srat_64.c
arch/x86/oprofile/nmi_int.c
arch/x86/oprofile/op_model_amd.c
arch/x86/oprofile/op_model_p4.c
arch/x86/oprofile/op_model_ppro.c
arch/x86/oprofile/op_x86_model.h
arch/x86/pci/acpi.c
arch/x86/pci/i386.c
arch/x86/pci/mrst.c
arch/x86/xen/time.c
arch/xtensa/include/asm/atomic.h
arch/xtensa/kernel/time.c
block/blk-cgroup.c
block/blk-timeout.c
block/cfq-iosched.c
crypto/async_tx/async_raid6_recov.c
crypto/authenc.c
drivers/Makefile
drivers/acpi/acpi_pad.c
drivers/acpi/acpica/exprep.c
drivers/acpi/bus.c
drivers/acpi/hest.c
drivers/acpi/pci_irq.c
drivers/acpi/power_meter.c
drivers/acpi/sbshc.c
drivers/acpi/sleep.c
drivers/ata/libata-eh.c
drivers/ata/pata_pcmcia.c
drivers/base/iommu.c
drivers/base/platform.c
drivers/block/amiflop.c
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/block/hd.c
drivers/block/pktcdvd.c
drivers/char/agp/intel-agp.c
drivers/char/i8k.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/mxser.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/riscom8.c
drivers/char/serial167.c
drivers/char/stallion.c
drivers/char/sysrq.c
drivers/char/tpm/Kconfig
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm_tis.c
drivers/char/tty_io.c
drivers/clocksource/cs5535-clockevt.c
drivers/clocksource/sh_cmt.c
drivers/clocksource/sh_mtu2.c
drivers/clocksource/sh_tmu.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpuidle/governors/menu.c
drivers/dma/shdma.c
drivers/dma/shdma.h
drivers/dma/txx9dmac.c
drivers/edac/edac_mce_amd.c
drivers/firewire/core-cdev.c
drivers/firewire/core-iso.c
drivers/firewire/ohci.c
drivers/gpio/gpiolib.c
drivers/gpio/it8761e_gpio.c
drivers/gpio/pca953x.c
drivers/gpio/pl061.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_memory.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_debug.c
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_opregion.c
drivers/gpu/drm/i915/i915_reg.h
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_modes.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atombios.h
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300_cmdbuf.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/radeon_agp.c
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_family.h
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/radeon/radeon_state.c
drivers/gpu/drm/radeon/reg_srcs/r300
drivers/gpu/drm/radeon/reg_srcs/r420
drivers/gpu/drm/radeon/reg_srcs/rs600
drivers/gpu/drm/radeon/reg_srcs/rv515
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/ttm/ttm_bo.c
drivers/gpu/drm/ttm/ttm_lock.c
drivers/gpu/drm/via/via_video.c
drivers/gpu/vga/vga_switcheroo.c
drivers/hid/hid-cherry.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-ntrig.c
drivers/hid/hid-sony.c
drivers/hid/hid-wacom.c
drivers/hid/usbhid/hid-core.c
drivers/hwmon/applesmc.c
drivers/hwmon/asc7621.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/hp_accel.c
drivers/hwmon/it87.c
drivers/hwmon/sht15.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-octeon.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/i2c-core.c
drivers/ide/ide-cs.c
drivers/input/gameport/gameport.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/analog.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/corgikbd.c [deleted file]
drivers/input/keyboard/matrix_keypad.c
drivers/input/keyboard/spitzkbd.c [deleted file]
drivers/input/keyboard/tosakbd.c [deleted file]
drivers/input/misc/ati_remote.c
drivers/input/misc/pcspkr.c
drivers/input/mouse/bcm5974.c
drivers/input/mouse/elantech.c
drivers/input/mouse/elantech.h
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.h
drivers/input/serio/i8042.c
drivers/input/sparse-keymap.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/ad7877.c
drivers/input/touchscreen/corgi_ts.c [deleted file]
drivers/input/touchscreen/eeti_ts.c
drivers/input/touchscreen/s3c2410_ts.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/capi.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/proc.c
drivers/isdn/gigaset/ser-gigaset.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/lguest/lguest_device.c
drivers/lguest/x86/core.c
drivers/md/md.c
drivers/md/raid5.c
drivers/media/common/saa7146_fops.c
drivers/media/common/saa7146_video.c
drivers/media/dvb/frontends/stv090x.c
drivers/media/dvb/ttpci/budget.c
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/davinci/vpfe_capture.c
drivers/media/video/gspca/sn9c20x.c
drivers/media/video/gspca/spca508.c
drivers/media/video/gspca/spca561.c
drivers/media/video/gspca/stv06xx/stv06xx.c
drivers/media/video/hexium_gemini.c
drivers/media/video/hexium_orion.c
drivers/media/video/mx1_camera.c
drivers/media/video/mxb.c
drivers/media/video/omap24xxcam.c
drivers/media/video/pxa_camera.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm8350-core.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/vmware_balloon.c [new file with mode: 0644]
drivers/mmc/host/at91_mci.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h
drivers/mmc/host/pxamci.c
drivers/mtd/Makefile
drivers/mtd/internal.h [deleted file]
drivers/mtd/mtdbdi.c [deleted file]
drivers/mtd/mtdcore.c
drivers/mtd/mtdsuper.c
drivers/mtd/nand/orion_nand.c
drivers/net/8139too.c
drivers/net/Makefile
drivers/net/a2065.c
drivers/net/ariadne.c
drivers/net/arm/ep93xx_eth.c
drivers/net/bnx2.c
drivers/net/can/usb/ems_usb.c
drivers/net/cnic.c
drivers/net/cxgb3/ael1002.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/e100.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/netdev.c
drivers/net/fec.c
drivers/net/forcedeth.c
drivers/net/fsl_pq_mdio.c
drivers/net/gianfar.c
drivers/net/hydra.c
drivers/net/igb/igb_ethtool.c
drivers/net/igb/igb_main.c
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/ks8851.c
drivers/net/myri10ge/myri10ge.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/phy/Kconfig
drivers/net/phy/Makefile
drivers/net/phy/mdio-octeon.c
drivers/net/phy/micrel.c [new file with mode: 0644]
drivers/net/ppp_generic.c
drivers/net/qlcnic/qlcnic_hw.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/sb1250-mac.c
drivers/net/sfc/efx.c
drivers/net/sfc/falcon.c
drivers/net/sfc/falcon_boards.c
drivers/net/sfc/nic.h
drivers/net/sfc/siena.c
drivers/net/stmmac/stmmac_main.c
drivers/net/tg3.c
drivers/net/tun.c
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/cdc_ether.c
drivers/net/usb/dm9601.c
drivers/net/usb/ipheth.c [new file with mode: 0644]
drivers/net/usb/kaweth.c
drivers/net/usb/sierra_net.c [new file with mode: 0644]
drivers/net/veth.c
drivers/net/virtio_net.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wireless/ath/ar9170/usb.c
drivers/net/wireless/ath/ar9170/usb.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-calib.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/p54/p54pci.c
drivers/net/zorro8390.c
drivers/of/of_mdio.c
drivers/oprofile/cpu_buffer.c
drivers/oprofile/oprof.c
drivers/oprofile/oprof.h
drivers/oprofile/timer_int.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/intel-iommu.c
drivers/pci/pci.c
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/probe.c
drivers/pci/setup-bus.c
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pcmcia/db1xxx_ss.c
drivers/pcmcia/ds.c
drivers/pcmcia/pcmcia_ioctl.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pxa2xx_vpac270.c [new file with mode: 0644]
drivers/pcmcia/rsrc_nonstatic.c
drivers/platform/x86/Kconfig
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/eeepc-wmi.c
drivers/pnp/pnpacpi/rsparser.c
drivers/pnp/resource.c
drivers/regulator/max8925-regulator.c
drivers/regulator/mc13783-regulator.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-davinci.c [new file with mode: 0644]
drivers/s390/block/dasd.c
drivers/s390/block/dasd_3990_erp.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eckd.h
drivers/s390/block/dasd_int.h
drivers/s390/char/Kconfig
drivers/s390/char/fs3270.c
drivers/s390/char/keyboard.c
drivers/s390/char/vmcp.c
drivers/s390/char/zcore.c
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc_sch.c
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_setup.c
drivers/s390/cio/qdio_thinint.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/net/qeth_core_main.c
drivers/s390/scsi/zfcp_cfdc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/sbus/char/flash.c
drivers/scsi/advansys.c
drivers/scsi/be2iscsi/be_mgmt.c
drivers/scsi/bnx2i/bnx2i.h
drivers/scsi/bnx2i/bnx2i_init.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/dpt_i2o.c
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/libiscsi.c
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_error.c
drivers/scsi/sd.c
drivers/scsi/wd7000.c
drivers/scsi/zorro7xx.c
drivers/serial/8250_pnp.c
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/atmel_serial.c
drivers/serial/imx.c
drivers/serial/mcf.c
drivers/serial/mpc52xx_uart.c
drivers/serial/pmac_zilog.c
drivers/serial/serial_cs.c
drivers/serial/serial_ks8695.c
drivers/serial/sh-sci.c
drivers/sh/Kconfig [new file with mode: 0644]
drivers/sh/Makefile
drivers/sh/clk-cpg.c [new file with mode: 0644]
drivers/sh/clk.c [new file with mode: 0644]
drivers/sh/intc.c
drivers/spi/omap2_mcspi.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi.c
drivers/ssb/driver_pcicore.c
drivers/staging/dt3155/dt3155_drv.c
drivers/staging/hv/Hv.c
drivers/staging/hv/RndisFilter.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/iio/accel/lis3l02dq_core.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/adc/max1363_core.c
drivers/staging/iio/industrialio-core.c
drivers/staging/iio/light/tsl2563.c
drivers/staging/iio/ring_sw.c
drivers/staging/octeon/cvmx-helper-board.c
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rtl8192su/r8192U_core.c
drivers/staging/usbip/usbip_event.c
drivers/staging/vme/bridges/vme_tsi148.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/Kconfig
drivers/usb/core/driver.c
drivers/usb/core/generic.c
drivers/usb/core/inode.c
drivers/usb/core/usb.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-omap.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-da8xx.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.h
drivers/usb/misc/usbsevseg.c
drivers/usb/musb/Kconfig
drivers/usb/musb/Makefile
drivers/usb/musb/blackfin.c
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/musb/tusb6010_omap.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/qcaux.c
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/ti_usb_3410_5052.h
drivers/usb/wusbcore/devconnect.c
drivers/vhost/vhost.c
drivers/video/amifb.c
drivers/video/bfin-t350mcqb-fb.c
drivers/video/cirrusfb.c
drivers/video/efifb.c
drivers/video/fm2fb.c
drivers/video/sh_mobile_lcdcfb.c
drivers/virtio/virtio_balloon.c
drivers/w1/masters/omap_hdq.c
drivers/w1/slaves/w1_therm.c
drivers/watchdog/Kconfig
drivers/watchdog/booke_wdt.c
drivers/watchdog/ep93xx_wdt.c
drivers/watchdog/max63xx_wdt.c
drivers/watchdog/mpcore_wdt.c
drivers/watchdog/sb_wdog.c
drivers/watchdog/sbc_fitpc2_wdt.c
drivers/xen/manage.c
drivers/zorro/proc.c
drivers/zorro/zorro-driver.c
drivers/zorro/zorro-sysfs.c
drivers/zorro/zorro.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_super.c
fs/afs/internal.h
fs/afs/mntpt.c
fs/afs/super.c
fs/afs/volume.c
fs/autofs4/root.c
fs/binfmt_elf_fdpic.c
fs/binfmt_flat.c
fs/block_dev.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/ioctl.c
fs/btrfs/volumes.c
fs/cachefiles/internal.h
fs/cachefiles/namei.c
fs/cachefiles/security.c
fs/ceph/addr.c
fs/ceph/auth.c
fs/ceph/auth_none.h
fs/ceph/auth_x.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/messenger.c
fs/ceph/messenger.h
fs/ceph/osd_client.c
fs/ceph/osd_client.h
fs/ceph/osdmap.c
fs/ceph/osdmap.h
fs/ceph/rados.h
fs/ceph/snap.c
fs/ceph/super.c
fs/ceph/super.h
fs/cifs/asn1.c
fs/cifs/cifs_debug.c
fs/cifs/cifs_debug.h
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifs_fs_sb.h
fs/cifs/cifs_spnego.c
fs/cifs/cifs_unicode.c
fs/cifs/cifsacl.c
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/dns_resolve.c
fs/cifs/export.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/ioctl.c
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/cifs/transport.c
fs/cifs/xattr.c
fs/coda/inode.c
fs/compat.c
fs/compat_ioctl.c
fs/configfs/dir.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/main.c
fs/ecryptfs/mmap.c
fs/ecryptfs/super.c
fs/eventpoll.c
fs/exec.c
fs/exofs/exofs.h
fs/exofs/super.c
fs/ext2/symlink.c
fs/ext3/symlink.c
fs/ext4/extents.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/inode.c
fs/ioctl.c
fs/jfs/inode.c
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_inode.h
fs/jfs/namei.c
fs/jfs/resize.c
fs/jfs/super.c
fs/jfs/symlink.c
fs/logfs/dev_bdev.c
fs/logfs/dev_mtd.c
fs/logfs/file.c
fs/logfs/gc.c
fs/logfs/inode.c
fs/logfs/journal.c
fs/logfs/logfs.h
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/logfs/super.c
fs/namei.c
fs/namespace.c
fs/ncpfs/inode.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/fscache.c
fs/nfs/getroot.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/iostat.h
fs/nfs/namespace.c
fs/nfs/nfs3acl.c
fs/nfs/nfs3proc.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4namespace.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
fs/nfs/nfsroot.c
fs/nfs/pagelist.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/unlink.c
fs/nfs/write.c
fs/nfsd/export.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsd.h
fs/nfsd/nfssvc.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/nfsd/vfs.h
fs/nfsd/xdr4.h
fs/nilfs2/alloc.c
fs/nilfs2/btree.c
fs/nilfs2/ioctl.c
fs/nilfs2/super.c
fs/notify/inotify/Kconfig
fs/notify/inotify/inotify_fsnotify.c
fs/notify/inotify/inotify_user.c
fs/ocfs2/buffer_head_io.c
fs/ocfs2/dlm/dlmast.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/namei.c
fs/ocfs2/refcounttree.c
fs/proc/array.c
fs/proc/base.c
fs/proc/inode.c
fs/proc/kcore.c
fs/proc/kmsg.c
fs/proc/task_mmu.c
fs/proc/vmcore.c
fs/quota/Kconfig
fs/quota/dquot.c
fs/reiserfs/dir.c
fs/reiserfs/xattr.c
fs/smbfs/inode.c
fs/squashfs/block.c
fs/squashfs/super.c
fs/squashfs/zlib_wrapper.c
fs/super.c
fs/sync.c
fs/sysv/dir.c
fs/udf/balloc.c
fs/udf/file.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/udfdecl.h
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_sync.h
fs/xfs/quota/xfs_qm_syscalls.c
fs/xfs/xfs_ag.h
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_log.c
fs/xfs/xfs_mount.h
include/asm-generic/atomic.h
include/asm-generic/bitops/arch_hweight.h [new file with mode: 0644]
include/asm-generic/bitops/const_hweight.h [new file with mode: 0644]
include/asm-generic/bitops/hweight.h
include/asm-generic/dma-mapping-common.h
include/drm/drm_pciids.h
include/drm/ttm/ttm_bo_driver.h
include/linux/acpi.h
include/linux/amba/mmci.h
include/linux/backing-dev.h
include/linux/bitops.h
include/linux/cgroup.h
include/linux/clocksource.h
include/linux/coda_psdev.h
include/linux/cpufreq.h
include/linux/cpuset.h
include/linux/dcache.h
include/linux/debugobjects.h
include/linux/device.h
include/linux/elf.h
include/linux/firewire-cdev.h
include/linux/firewire-constants.h
include/linux/fs.h
include/linux/ftrace.h
include/linux/ftrace_event.h
include/linux/hrtimer.h
include/linux/hw_breakpoint.h
include/linux/i2c.h
include/linux/if_link.h
include/linux/init_task.h
include/linux/input/matrix_keypad.h
include/linux/interrupt.h
include/linux/iommu.h
include/linux/irq.h
include/linux/kernel.h
include/linux/ktime.h
include/linux/kvm_host.h
include/linux/lsm_audit.h
include/linux/mm.h
include/linux/mod_devicetable.h
include/linux/module.h
include/linux/ncp_fs_sb.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/nfsd/nfsfh.h
include/linux/perf_event.h
include/linux/platform_device.h
include/linux/poison.h
include/linux/ptrace.h
include/linux/rbtree.h
include/linux/rcupdate.h
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/regulator/consumer.h
include/linux/ring_buffer.h
include/linux/sched.h
include/linux/security.h
include/linux/serial_sci.h
include/linux/sh_clk.h [new file with mode: 0644]
include/linux/sh_dma.h [new file with mode: 0644]
include/linux/sh_intc.h
include/linux/smb_fs_sb.h
include/linux/srcu.h
include/linux/stop_machine.h
include/linux/sunrpc/auth.h
include/linux/sunrpc/auth_gss.h
include/linux/sunrpc/gss_api.h
include/linux/sunrpc/gss_krb5.h
include/linux/sunrpc/metrics.h
include/linux/sunrpc/sched.h
include/linux/sunrpc/xdr.h
include/linux/sunrpc/xprt.h
include/linux/tick.h
include/linux/time.h
include/linux/timer.h
include/linux/timex.h
include/linux/tracepoint.h
include/linux/types.h
include/linux/usb.h
include/linux/wait.h
include/linux/zorro.h
include/media/saa7146_vv.h
include/net/sctp/command.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/net/sctp/structs.h
include/net/sock.h
include/net/tcp.h
include/net/x25.h
include/pcmcia/ds.h
include/pcmcia/ss.h
include/trace/define_trace.h
include/trace/events/lock.h
include/trace/events/module.h
include/trace/events/napi.h
include/trace/events/sched.h
include/trace/events/signal.h
include/trace/ftrace.h
init/Kconfig
init/initramfs.c
ipc/mqueue.c
kernel/Makefile
kernel/acct.c
kernel/capability.c
kernel/cgroup.c
kernel/cgroup_freezer.c
kernel/compat.c
kernel/cpu.c
kernel/cpuset.c
kernel/cred-internals.h [deleted file]
kernel/cred.c
kernel/exit.c
kernel/fork.c
kernel/groups.c
kernel/hrtimer.c
kernel/hw_breakpoint.c
kernel/irq/handle.c
kernel/irq/manage.c
kernel/irq/proc.c
kernel/kexec.c
kernel/kprobes.c
kernel/lockdep.c
kernel/lockdep_internals.h
kernel/lockdep_proc.c
kernel/module.c
kernel/perf_event.c
kernel/posix-cpu-timers.c
kernel/power/user.c
kernel/profile.c
kernel/ptrace.c
kernel/rcupdate.c
kernel/rcutiny.c
kernel/rcutiny_plugin.h [new file with mode: 0644]
kernel/rcutorture.c
kernel/rcutree.c
kernel/rcutree.h
kernel/rcutree_plugin.h
kernel/rcutree_trace.c
kernel/sched.c
kernel/sched_debug.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_idletask.c
kernel/sched_rt.c
kernel/softirq.c
kernel/stop_machine.c
kernel/sys.c
kernel/sysctl.c
kernel/time.c
kernel/time/clocksource.c
kernel/time/ntp.c
kernel/time/tick-sched.c
kernel/time/timekeeping.c
kernel/time/timer_list.c
kernel/timer.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/ring_buffer_benchmark.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_entries.h
kernel/trace/trace_events_filter.c
kernel/trace/trace_functions_graph.c
kernel/trace/trace_hw_branches.c [deleted file]
kernel/trace/trace_irqsoff.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_ksym.c
kernel/trace/trace_output.c
kernel/trace/trace_sched_switch.c
kernel/trace/trace_sched_wakeup.c
kernel/trace/trace_selftest.c
kernel/user.c
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/atomic64.c
lib/atomic64_test.c [new file with mode: 0644]
lib/btree.c
lib/debugobjects.c
lib/decompress_unlzo.c
lib/dma-debug.c
lib/flex_array.c
lib/hweight.c
lib/rbtree.c
lib/rwsem.c
lib/vsprintf.c
mm/backing-dev.c
mm/hugetlb.c
mm/ksm.c
mm/memcontrol.c
mm/mlock.c
mm/mmap.c
mm/rmap.c
mm/slub.c
net/bluetooth/l2cap.c
net/bridge/br_multicast.c
net/can/raw.c
net/core/dev.c
net/core/rtnetlink.c
net/ieee802154/af_ieee802154.c
net/ipv4/arp.c
net/ipv4/fib_trie.c
net/ipv4/ip_output.c
net/ipv4/ipmr.c
net/ipv4/tcp.c
net/ipv4/udp.c
net/ipv6/af_inet6.c
net/ipv6/datagram.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/xfrm6_policy.c
net/llc/llc_sap.c
net/mac80211/agg-tx.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mlme.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/packet/af_packet.c
net/rds/rdma_transport.c
net/sctp/associola.c
net/sctp/endpointola.c
net/sctp/input.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/transport.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/Makefile
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/gss_krb5_keys.c [new file with mode: 0644]
net/sunrpc/auth_gss/gss_krb5_mech.c
net/sunrpc/auth_gss/gss_krb5_seal.c
net/sunrpc/auth_gss/gss_krb5_seqnum.c
net/sunrpc/auth_gss/gss_krb5_unseal.c
net/sunrpc/auth_gss/gss_krb5_wrap.c
net/sunrpc/auth_gss/gss_mech_switch.c
net/sunrpc/auth_gss/gss_spkm3_mech.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/clnt.c
net/sunrpc/sched.c
net/sunrpc/stats.c
net/sunrpc/svc_xprt.c
net/sunrpc/svcsock.c
net/sunrpc/xdr.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtsock.c
net/x25/af_x25.c
net/x25/x25_facilities.c
net/x25/x25_in.c
scripts/Makefile.lib
scripts/mod/file2alias.c
scripts/selinux/genheaders/genheaders.c
security/capability.c
security/commoncap.c
security/device_cgroup.c
security/inode.c
security/integrity/ima/Kconfig
security/integrity/ima/ima.h
security/integrity/ima/ima_audit.c
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_fs.c
security/integrity/ima/ima_iint.c
security/integrity/ima/ima_init.c
security/integrity/ima/ima_main.c
security/integrity/ima/ima_policy.c
security/integrity/ima/ima_queue.c
security/keys/gc.c
security/keys/internal.h
security/keys/key.c
security/keys/keyctl.c
security/keys/keyring.c
security/keys/permission.c
security/keys/proc.c
security/keys/process_keys.c
security/keys/request_key.c
security/keys/user_defined.c
security/lsm_audit.c
security/min_addr.c
security/security.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/initial_sid_to_string.h
security/selinux/include/netlabel.h
security/selinux/netlabel.c
security/selinux/netlink.c
security/selinux/nlmsgtab.c
security/selinux/selinuxfs.c
security/selinux/ss/avtab.h
security/selinux/ss/mls.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
security/smack/smack_lsm.c
security/tomoyo/Makefile
security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/domain.c
security/tomoyo/file.c
security/tomoyo/gc.c
security/tomoyo/path_group.c [new file with mode: 0644]
security/tomoyo/realpath.c
sound/arm/aaci.c
sound/core/pcm_native.c
sound/core/timer.c
sound/drivers/pcsp/pcsp.h
sound/drivers/pcsp/pcsp_input.c
sound/drivers/pcsp/pcsp_lib.c
sound/isa/sb/es968.c
sound/oss/dmasound/dmasound_paula.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/ice1712/maya44.c
sound/pci/maestro3.c
sound/pci/oxygen/xonar_cs43xx.c
sound/soc/codecs/wm2000.c
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-pcm-fiq.c
sound/soc/imx/imx-ssi.c
sound/soc/pxa/Kconfig
sound/soc/pxa/pxa-ssp.c
sound/soc/txx9/txx9aclc-ac97.c
sound/soc/txx9/txx9aclc-generic.c
sound/usb/usbmidi.c
tools/perf/Documentation/perf-annotate.txt
tools/perf/Documentation/perf-bench.txt
tools/perf/Documentation/perf-buildid-cache.txt
tools/perf/Documentation/perf-diff.txt
tools/perf/Documentation/perf-inject.txt [new file with mode: 0644]
tools/perf/Documentation/perf-kmem.txt
tools/perf/Documentation/perf-kvm.txt [new file with mode: 0644]
tools/perf/Documentation/perf-list.txt
tools/perf/Documentation/perf-probe.txt
tools/perf/Documentation/perf-record.txt
tools/perf/Documentation/perf-sched.txt
tools/perf/Documentation/perf-stat.txt
tools/perf/Documentation/perf-test.txt [new file with mode: 0644]
tools/perf/Documentation/perf-trace-perl.txt
tools/perf/Documentation/perf-trace-python.txt
tools/perf/Documentation/perf-trace.txt
tools/perf/Makefile
tools/perf/arch/powerpc/Makefile [new file with mode: 0644]
tools/perf/arch/powerpc/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/arch/x86/Makefile [new file with mode: 0644]
tools/perf/arch/x86/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/bench/mem-memcpy.c
tools/perf/bench/sched-messaging.c
tools/perf/bench/sched-pipe.c
tools/perf/builtin-annotate.c
tools/perf/builtin-bench.c
tools/perf/builtin-buildid-cache.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-diff.c
tools/perf/builtin-help.c
tools/perf/builtin-inject.c [new file with mode: 0644]
tools/perf/builtin-kmem.c
tools/perf/builtin-kvm.c [new file with mode: 0644]
tools/perf/builtin-lock.c
tools/perf/builtin-probe.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-stat.c
tools/perf/builtin-test.c [new file with mode: 0644]
tools/perf/builtin-timechart.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/builtin.h
tools/perf/command-list.txt
tools/perf/perf-archive.sh
tools/perf/perf.c
tools/perf/perf.h
tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace/Util.pm
tools/perf/scripts/perl/bin/check-perf-trace-record
tools/perf/scripts/perl/bin/failed-syscalls-record
tools/perf/scripts/perl/bin/failed-syscalls-report
tools/perf/scripts/perl/bin/rw-by-file-record
tools/perf/scripts/perl/bin/rw-by-file-report
tools/perf/scripts/perl/bin/rw-by-pid-record
tools/perf/scripts/perl/bin/rw-by-pid-report
tools/perf/scripts/perl/bin/rwtop-record [new file with mode: 0644]
tools/perf/scripts/perl/bin/rwtop-report [new file with mode: 0644]
tools/perf/scripts/perl/bin/wakeup-latency-record
tools/perf/scripts/perl/bin/wakeup-latency-report
tools/perf/scripts/perl/bin/workqueue-stats-record
tools/perf/scripts/perl/bin/workqueue-stats-report
tools/perf/scripts/perl/failed-syscalls.pl
tools/perf/scripts/perl/rw-by-pid.pl
tools/perf/scripts/perl/rwtop.pl [new file with mode: 0644]
tools/perf/scripts/perl/wakeup-latency.pl
tools/perf/scripts/perl/workqueue-stats.pl
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py
tools/perf/scripts/python/bin/failed-syscalls-by-pid-record
tools/perf/scripts/python/bin/failed-syscalls-by-pid-report
tools/perf/scripts/python/bin/sctop-record [new file with mode: 0644]
tools/perf/scripts/python/bin/sctop-report [new file with mode: 0644]
tools/perf/scripts/python/bin/syscall-counts-by-pid-record
tools/perf/scripts/python/bin/syscall-counts-by-pid-report
tools/perf/scripts/python/bin/syscall-counts-record
tools/perf/scripts/python/bin/syscall-counts-report
tools/perf/scripts/python/sctop.py [new file with mode: 0644]
tools/perf/util/PERF-VERSION-GEN
tools/perf/util/bitmap.c [new file with mode: 0644]
tools/perf/util/build-id.c
tools/perf/util/cache.h
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/color.c
tools/perf/util/color.h
tools/perf/util/debug.c
tools/perf/util/debug.h
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/header.c
tools/perf/util/header.h
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/hweight.c [new file with mode: 0644]
tools/perf/util/include/asm/bitops.h [deleted file]
tools/perf/util/include/asm/hweight.h [new file with mode: 0644]
tools/perf/util/include/dwarf-regs.h [new file with mode: 0644]
tools/perf/util/include/linux/bitmap.h
tools/perf/util/include/linux/bitops.h
tools/perf/util/include/linux/compiler.h
tools/perf/util/include/linux/kernel.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/newt.c [new file with mode: 0644]
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-options.c
tools/perf/util/parse-options.h
tools/perf/util/probe-event.c
tools/perf/util/probe-event.h
tools/perf/util/probe-finder.c
tools/perf/util/probe-finder.h
tools/perf/util/pstack.c [new file with mode: 0644]
tools/perf/util/pstack.h [new file with mode: 0644]
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/string.c
tools/perf/util/string.h [deleted file]
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/perf/util/trace-event-info.c
tools/perf/util/trace-event-parse.c
tools/perf/util/trace-event-read.c
tools/perf/util/trace-event.h
tools/perf/util/util.c
tools/perf/util/util.h
virt/kvm/ioapic.c
virt/kvm/ioapic.h
virt/kvm/iommu.c
virt/kvm/kvm_main.c

index ba99757..ff3e5be 100644 (file)
@@ -107,10 +107,6 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
        issue of SET FEATURES - XFER MODE, and prior to operation.
        </para>
        <para>
-       Called by ata_device_add() after ata_dev_identify() determines
-       a device is present.
-       </para>
-       <para>
        This entry may be specified as NULL in ata_port_operations.
        </para>
 
@@ -154,8 +150,8 @@ unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned in
 
        <sect2><title>Taskfile read/write</title>
        <programlisting>
-void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
-void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
        </programlisting>
 
        <para>
@@ -164,36 +160,35 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
        hardware registers / DMA buffers, to obtain the current set of
        taskfile register values.
        Most drivers for taskfile-based hardware (PIO or MMIO) use
-       ata_tf_load() and ata_tf_read() for these hooks.
+       ata_sff_tf_load() and ata_sff_tf_read() for these hooks.
        </para>
 
        </sect2>
 
        <sect2><title>PIO data read/write</title>
        <programlisting>
-void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
+void (*sff_data_xfer) (struct ata_device *, unsigned char *, unsigned int, int);
        </programlisting>
 
        <para>
 All bmdma-style drivers must implement this hook.  This is the low-level
 operation that actually copies the data bytes during a PIO data
 transfer.
-Typically the driver
-will choose one of ata_pio_data_xfer_noirq(), ata_pio_data_xfer(), or
-ata_mmio_data_xfer().
+Typically the driver will choose one of ata_sff_data_xfer_noirq(),
+ata_sff_data_xfer(), or ata_sff_data_xfer32().
        </para>
 
        </sect2>
 
        <sect2><title>ATA command execute</title>
        <programlisting>
-void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+void (*sff_exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
        </programlisting>
 
        <para>
        causes an ATA command, previously loaded with
        ->tf_load(), to be initiated in hardware.
-       Most drivers for taskfile-based hardware use ata_exec_command()
+       Most drivers for taskfile-based hardware use ata_sff_exec_command()
        for this hook.
        </para>
 
@@ -218,8 +213,8 @@ command.
 
        <sect2><title>Read specific ATA shadow registers</title>
        <programlisting>
-u8   (*check_status)(struct ata_port *ap);
-u8   (*check_altstatus)(struct ata_port *ap);
+u8   (*sff_check_status)(struct ata_port *ap);
+u8   (*sff_check_altstatus)(struct ata_port *ap);
        </programlisting>
 
        <para>
@@ -227,20 +222,14 @@ u8   (*check_altstatus)(struct ata_port *ap);
        hardware.  On some hardware, reading the Status register has
        the side effect of clearing the interrupt condition.
        Most drivers for taskfile-based hardware use
-       ata_check_status() for this hook.
-       </para>
-       <para>
-       Note that because this is called from ata_device_add(), at
-       least a dummy function that clears device interrupts must be
-       provided for all drivers, even if the controller doesn't
-       actually have a taskfile status register.
+       ata_sff_check_status() for this hook.
        </para>
 
        </sect2>
 
        <sect2><title>Select ATA device on bus</title>
        <programlisting>
-void (*dev_select)(struct ata_port *ap, unsigned int device);
+void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
        </programlisting>
 
        <para>
@@ -251,9 +240,7 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
        </para>
        <para>
        Most drivers for taskfile-based hardware use
-       ata_std_dev_select() for this hook.  Controllers which do not
-       support second drives on a port (such as SATA contollers) will
-       use ata_noop_dev_select().
+       ata_sff_dev_select() for this hook.
        </para>
 
        </sect2>
@@ -441,13 +428,13 @@ void (*irq_clear) (struct ata_port *);
        to struct ata_host_set.
        </para>
        <para>
-       Most legacy IDE drivers use ata_interrupt() for the
+       Most legacy IDE drivers use ata_sff_interrupt() for the
        irq_handler hook, which scans all ports in the host_set,
        determines which queued command was active (if any), and calls
-       ata_host_intr(ap,qc).
+       ata_sff_host_intr(ap,qc).
        </para>
        <para>
-       Most legacy IDE drivers use ata_bmdma_irq_clear() for the
+       Most legacy IDE drivers use ata_sff_irq_clear() for the
        irq_clear() hook, which simply clears the interrupt and error
        flags in the DMA status register.
        </para>
@@ -496,10 +483,6 @@ void (*host_stop) (struct ata_host_set *host_set);
        data from port at this time.
        </para>
        <para>
-       Many drivers use ata_port_stop() as this hook, which frees the
-       PRD table.
-       </para>
-       <para>
        ->host_stop() is called after all ->port_stop() calls
 have completed.  The hook must finalize hardware shutdown, release DMA
 and other resources, etc.
index 0c3dc4c..d858d92 100644 (file)
   </authorgroup>
 
   <copyright>
-   <year>2008</year>
+   <year>2008-2010</year>
    <holder>Paul Mundt</holder>
   </copyright>
   <copyright>
-   <year>2008</year>
+   <year>2008-2010</year>
    <holder>Renesas Technology Corp.</holder>
   </copyright>
+  <copyright>
+   <year>2010</year>
+   <holder>Renesas Electronics Corp.</holder>
+  </copyright>
 
   <legalnotice>
    <para>
@@ -77,7 +81,7 @@
   </chapter>
   <chapter id="clk">
     <title>Clock Framework Extensions</title>
-!Iarch/sh/include/asm/clock.h
+!Iinclude/linux/sh_clk.h
   </chapter>
   <chapter id="mach">
     <title>Machine Specific Interfaces</title>
index f5395af..40ada93 100644 (file)
@@ -234,7 +234,7 @@ process is as follows:
     Linus, usually the patches that have already been included in the
     -next kernel for a few weeks.  The preferred way to submit big changes
     is using git (the kernel's source management tool, more information
-    can be found at http://git.or.cz/) but plain patches are also just
+    can be found at http://git-scm.com/) but plain patches are also just
     fine.
   - After two weeks a -rc1 kernel is released it is now possible to push
     only patches that do not include new features that could affect the
index a6d32e6..a8536cb 100644 (file)
@@ -34,7 +34,7 @@ NMI handler.
                cpu = smp_processor_id();
                ++nmi_count(cpu);
 
-               if (!rcu_dereference(nmi_callback)(regs, cpu))
+               if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
                        default_do_nmi(regs);
 
                nmi_exit();
@@ -47,12 +47,13 @@ function pointer.  If this handler returns zero, do_nmi() invokes the
 default_do_nmi() function to handle a machine-specific NMI.  Finally,
 preemption is restored.
 
-Strictly speaking, rcu_dereference() is not needed, since this code runs
-only on i386, which does not need rcu_dereference() anyway.  However,
-it is a good documentation aid, particularly for anyone attempting to
-do something similar on Alpha.
+In theory, rcu_dereference_sched() is not needed, since this code runs
+only on i386, which in theory does not need rcu_dereference_sched()
+anyway.  However, in practice it is a good documentation aid, particularly
+for anyone attempting to do something similar on Alpha or on systems
+with aggressive optimizing compilers.
 
-Quick Quiz:  Why might the rcu_dereference() be necessary on Alpha,
+Quick Quiz:  Why might the rcu_dereference_sched() be necessary on Alpha,
             given that the code referenced by the pointer is read-only?
 
 
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
 
 Answer to Quick Quiz
 
-       Why might the rcu_dereference() be necessary on Alpha, given
+       Why might the rcu_dereference_sched() be necessary on Alpha, given
        that the code referenced by the pointer is read-only?
 
        Answer: The caller to set_nmi_callback() might well have
-               initialized some data that is to be used by the
-               new NMI handler.  In this case, the rcu_dereference()
-               would be needed, because otherwise a CPU that received
-               an NMI just after the new handler was set might see
-               the pointer to the new NMI handler, but the old
-               pre-initialized version of the handler's data.
-
-               More important, the rcu_dereference() makes it clear
-               to someone reading the code that the pointer is being
-               protected by RCU.
+               initialized some data that is to be used by the new NMI
+               handler.  In this case, the rcu_dereference_sched() would
+               be needed, because otherwise a CPU that received an NMI
+               just after the new handler was set might see the pointer
+               to the new NMI handler, but the old pre-initialized
+               version of the handler's data.
+
+               This same sad story can happen on other CPUs when using
+               a compiler with aggressive pointer-value speculation
+               optimizations.
+
+               More important, the rcu_dereference_sched() makes it
+               clear to someone reading the code that the pointer is
+               being protected by RCU-sched.
index cbc180f..790d1a8 100644 (file)
@@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome!
        The reason that it is permissible to use RCU list-traversal
        primitives when the update-side lock is held is that doing so
        can be quite helpful in reducing code bloat when common code is
-       shared between readers and updaters.
+       shared between readers and updaters.  Additional primitives
+       are provided for this case, as discussed in lockdep.txt.
 
 10.    Conversely, if you are in an RCU read-side critical section,
        and you don't hold the appropriate update-side lock, you -must-
@@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome!
        requiring SRCU's read-side deadlock immunity or low read-side
        realtime latency.
 
-       Note that, rcu_assign_pointer() and rcu_dereference() relate to
-       SRCU just as they do to other forms of RCU.
+       Note that, rcu_assign_pointer() relates to SRCU just as they do
+       to other forms of RCU.
 
 15.    The whole point of call_rcu(), synchronize_rcu(), and friends
        is to wait until all pre-existing readers have finished before
index fe24b58..d7a49b2 100644 (file)
@@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
        srcu_dereference(p, sp):
                Check for SRCU read-side critical section.
        rcu_dereference_check(p, c):
-               Use explicit check expression "c".
+               Use explicit check expression "c".  This is useful in
+               code that is invoked by both readers and updaters.
        rcu_dereference_raw(p)
                Don't check.  (Use sparingly, if at all.)
+       rcu_dereference_protected(p, c):
+               Use explicit check expression "c", and omit all barriers
+               and compiler constraints.  This is useful when the data
+               structure cannot change, for example, in code that is
+               invoked only by updaters.
+       rcu_access_pointer(p):
+               Return the value of the pointer and omit all barriers,
+               but retain the compiler constraints that prevent duplicating
+               or coalescsing.  This is useful when when testing the
+               value of the pointer itself, for example, against NULL.
 
 The rcu_dereference_check() check expression can be any boolean
 expression, but would normally include one of the rcu_read_lock_held()
@@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla
 RCU read-side critical sections, in case (2) the ->file_lock prevents
 any change from taking place, and finally, in case (3) the current task
 is the only task accessing the file_struct, again preventing any change
-from taking place.
+from taking place.  If the above statement was invoked only from updater
+code, it could instead be written as follows:
+
+       file = rcu_dereference_protected(fdt->fd[fd],
+                                        lockdep_is_held(&files->file_lock) ||
+                                        atomic_read(&files->count) == 1);
+
+This would verify cases #2 and #3 above, and furthermore lockdep would
+complain if this was used in an RCU read-side critical section unless one
+of these two cases held.  Because rcu_dereference_protected() omits all
+barriers and compiler constraints, it generates better code than do the
+other flavors of rcu_dereference().  On the other hand, it is illegal
+to use rcu_dereference_protected() if either the RCU-protected pointer
+or the RCU-protected data that it points to can change concurrently.
 
 There are currently only "universal" versions of the rcu_assign_pointer()
 and RCU list-/tree-traversal primitives, which do not (yet) check for
index 1423d25..44c6dcc 100644 (file)
@@ -3,35 +3,79 @@ Using RCU's CPU Stall Detector
 The CONFIG_RCU_CPU_STALL_DETECTOR kernel config parameter enables
 RCU's CPU stall detector, which detects conditions that unduly delay
 RCU grace periods.  The stall detector's idea of what constitutes
-"unduly delayed" is controlled by a pair of C preprocessor macros:
+"unduly delayed" is controlled by a set of C preprocessor macros:
 
 RCU_SECONDS_TILL_STALL_CHECK
 
        This macro defines the period of time that RCU will wait from
        the beginning of a grace period until it issues an RCU CPU
-       stall warning.  It is normally ten seconds.
+       stall warning.  This time period is normally ten seconds.
 
 RCU_SECONDS_TILL_STALL_RECHECK
 
        This macro defines the period of time that RCU will wait after
-       issuing a stall warning until it issues another stall warning.
-       It is normally set to thirty seconds.
+       issuing a stall warning until it issues another stall warning
+       for the same stall.  This time period is normally set to thirty
+       seconds.
 
 RCU_STALL_RAT_DELAY
 
-       The CPU stall detector tries to make the offending CPU rat on itself,
-       as this often gives better-quality stack traces.  However, if
-       the offending CPU does not detect its own stall in the number
-       of jiffies specified by RCU_STALL_RAT_DELAY, then other CPUs will
-       complain.  This is normally set to two jiffies.
+       The CPU stall detector tries to make the offending CPU print its
+       own warnings, as this often gives better-quality stack traces.
+       However, if the offending CPU does not detect its own stall in
+       the number of jiffies specified by RCU_STALL_RAT_DELAY, then
+       some other CPU will complain.  This delay is normally set to
+       two jiffies.
 
-The following problems can result in an RCU CPU stall warning:
+When a CPU detects that it is stalling, it will print a message similar
+to the following:
+
+INFO: rcu_sched_state detected stall on CPU 5 (t=2500 jiffies)
+
+This message indicates that CPU 5 detected that it was causing a stall,
+and that the stall was affecting RCU-sched.  This message will normally be
+followed by a stack dump of the offending CPU.  On TREE_RCU kernel builds,
+RCU and RCU-sched are implemented by the same underlying mechanism,
+while on TREE_PREEMPT_RCU kernel builds, RCU is instead implemented
+by rcu_preempt_state.
+
+On the other hand, if the offending CPU fails to print out a stall-warning
+message quickly enough, some other CPU will print a message similar to
+the following:
+
+INFO: rcu_bh_state detected stalls on CPUs/tasks: { 3 5 } (detected by 2, 2502 jiffies)
+
+This message indicates that CPU 2 detected that CPUs 3 and 5 were both
+causing stalls, and that the stall was affecting RCU-bh.  This message
+will normally be followed by stack dumps for each CPU.  Please note that
+TREE_PREEMPT_RCU builds can be stalled by tasks as well as by CPUs,
+and that the tasks will be indicated by PID, for example, "P3421".
+It is even possible for a rcu_preempt_state stall to be caused by both
+CPUs -and- tasks, in which case the offending CPUs and tasks will all
+be called out in the list.
+
+Finally, if the grace period ends just as the stall warning starts
+printing, there will be a spurious stall-warning message:
+
+INFO: rcu_bh_state detected stalls on CPUs/tasks: { } (detected by 4, 2502 jiffies)
+
+This is rare, but does happen from time to time in real life.
+
+So your kernel printed an RCU CPU stall warning.  The next question is
+"What caused it?"  The following problems can result in RCU CPU stall
+warnings:
 
 o      A CPU looping in an RCU read-side critical section.
        
-o      A CPU looping with interrupts disabled.
+o      A CPU looping with interrupts disabled.  This condition can
+       result in RCU-sched and RCU-bh stalls.
 
-o      A CPU looping with preemption disabled.
+o      A CPU looping with preemption disabled.  This condition can
+       result in RCU-sched stalls and, if ksoftirqd is in use, RCU-bh
+       stalls.
+
+o      A CPU looping with bottom halves disabled.  This condition can
+       result in RCU-sched and RCU-bh stalls.
 
 o      For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
        without invoking schedule().
@@ -39,20 +83,24 @@ o   For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
 o      A bug in the RCU implementation.
 
 o      A hardware failure.  This is quite unlikely, but has occurred
-       at least once in a former life.  A CPU failed in a running system,
+       at least once in real life.  A CPU failed in a running system,
        becoming unresponsive, but not causing an immediate crash.
        This resulted in a series of RCU CPU stall warnings, eventually
        leading the realization that the CPU had failed.
 
-The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning.
-SRCU does not do so directly, but its calls to synchronize_sched() will
-result in RCU-sched detecting any CPU stalls that might be occurring.
-
-To diagnose the cause of the stall, inspect the stack traces.  The offending
-function will usually be near the top of the stack.  If you have a series
-of stall warnings from a single extended stall, comparing the stack traces
-can often help determine where the stall is occurring, which will usually
-be in the function nearest the top of the stack that stays the same from
-trace to trace.
+The RCU, RCU-sched, and RCU-bh implementations have CPU stall
+warning.  SRCU does not have its own CPU stall warnings, but its
+calls to synchronize_sched() will result in RCU-sched detecting
+RCU-sched-related CPU stalls.  Please note that RCU only detects
+CPU stalls when there is a grace period in progress.  No grace period,
+no CPU stall warnings.
+
+To diagnose the cause of the stall, inspect the stack traces.
+The offending function will usually be near the top of the stack.
+If you have a series of stall warnings from a single extended stall,
+comparing the stack traces can often help determine where the stall
+is occurring, which will usually be in the function nearest the top of
+that portion of the stack which remains the same from trace to trace.
+If you can reliably trigger the stall, ftrace can be quite helpful.
 
 RCU bugs can often be debugged with the help of CONFIG_RCU_TRACE.
index 0e50bc2..5d90167 100644 (file)
@@ -182,16 +182,6 @@ Similarly, sched_expedited RCU provides the following:
        sched_expedited-torture: Reader Pipe:  12660320201 95875 0 0 0 0 0 0 0 0 0
        sched_expedited-torture: Reader Batch:  12660424885 0 0 0 0 0 0 0 0 0 0
        sched_expedited-torture: Free-Block Circulation:  1090795 1090795 1090794 1090793 1090792 1090791 1090790 1090789 1090788 1090787 0
-       state: -1 / 0:0 3:0 4:0
-
-As before, the first four lines are similar to those for RCU.
-The last line shows the task-migration state.  The first number is
--1 if synchronize_sched_expedited() is idle, -2 if in the process of
-posting wakeups to the migration kthreads, and N when waiting on CPU N.
-Each of the colon-separated fields following the "/" is a CPU:state pair.
-Valid states are "0" for idle, "1" for waiting for quiescent state,
-"2" for passed through quiescent state, and "3" when a race with a
-CPU-hotplug event forces use of the synchronize_sched() primitive.
 
 
 USAGE
index 8608fd8..efd8cc9 100644 (file)
@@ -256,23 +256,23 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
 The output of "cat rcu/rcu_pending" looks as follows:
 
 rcu_sched:
-  0 np=255892 qsp=53936 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
-  1 np=261224 qsp=54638 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
-  2 np=237496 qsp=49664 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
-  3 np=236249 qsp=48766 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
-  4 np=221310 qsp=46850 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
-  5 np=237332 qsp=48449 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
-  6 np=219995 qsp=46718 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
-  7 np=249893 qsp=49390 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
+  0 np=255892 qsp=53936 rpq=85 cbr=0 cng=14417 gpc=10033 gps=24320 nf=6445 nn=146741
+  1 np=261224 qsp=54638 rpq=33 cbr=0 cng=25723 gpc=16310 gps=2849 nf=5912 nn=155792
+  2 np=237496 qsp=49664 rpq=23 cbr=0 cng=2762 gpc=45478 gps=1762 nf=1201 nn=136629
+  3 np=236249 qsp=48766 rpq=98 cbr=0 cng=286 gpc=48049 gps=1218 nf=207 nn=137723
+  4 np=221310 qsp=46850 rpq=7 cbr=0 cng=26 gpc=43161 gps=4634 nf=3529 nn=123110
+  5 np=237332 qsp=48449 rpq=9 cbr=0 cng=54 gpc=47920 gps=3252 nf=201 nn=137456
+  6 np=219995 qsp=46718 rpq=12 cbr=0 cng=50 gpc=42098 gps=6093 nf=4202 nn=120834
+  7 np=249893 qsp=49390 rpq=42 cbr=0 cng=72 gpc=38400 gps=17102 nf=41 nn=144888
 rcu_bh:
-  0 np=146741 qsp=1419 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
-  1 np=155792 qsp=12597 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
-  2 np=136629 qsp=18680 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
-  3 np=137723 qsp=2843 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
-  4 np=123110 qsp=12433 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
-  5 np=137456 qsp=4210 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
-  6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
-  7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
+  0 np=146741 qsp=1419 rpq=6 cbr=0 cng=6 gpc=0 gps=0 nf=2 nn=145314
+  1 np=155792 qsp=12597 rpq=3 cbr=0 cng=0 gpc=4 gps=8 nf=3 nn=143180
+  2 np=136629 qsp=18680 rpq=1 cbr=0 cng=0 gpc=7 gps=6 nf=0 nn=117936
+  3 np=137723 qsp=2843 rpq=0 cbr=0 cng=0 gpc=10 gps=7 nf=0 nn=134863
+  4 np=123110 qsp=12433 rpq=0 cbr=0 cng=0 gpc=4 gps=2 nf=0 nn=110671
+  5 np=137456 qsp=4210 rpq=1 cbr=0 cng=0 gpc=6 gps=5 nf=0 nn=133235
+  6 np=120834 qsp=9902 rpq=2 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
+  7 np=144888 qsp=26336 rpq=0 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
 
 As always, this is once again split into "rcu_sched" and "rcu_bh"
 portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
@@ -284,6 +284,9 @@ o   "np" is the number of times that __rcu_pending() has been invoked
 o      "qsp" is the number of times that the RCU was waiting for a
        quiescent state from this CPU.
 
+o      "rpq" is the number of times that the CPU had passed through
+       a quiescent state, but not yet reported it to RCU.
+
 o      "cbr" is the number of times that this CPU had RCU callbacks
        that had passed through a grace period, and were thus ready
        to be invoked.
index 1dc00ee..cfaac34 100644 (file)
@@ -840,6 +840,12 @@ SRCU:      Initialization/cleanup
        init_srcu_struct
        cleanup_srcu_struct
 
+All:  lockdep-checked RCU-protected pointer access
+
+       rcu_dereference_check
+       rcu_dereference_protected
+       rcu_access_pointer
+
 See the comment headers in the source code (or the docbook generated
 from them) for more information.
 
index 82e418d..7f5fc3b 100644 (file)
@@ -20,6 +20,8 @@ Samsung-S3C24XX
        - S3C24XX ARM Linux Overview
 Sharp-LH
        - Linux on Sharp LH79524 and LH7A40X System On a Chip (SOC)
+SPEAr
+       - ST SPEAr platform Linux Overview
 VFP/
        - Release notes for Linux Kernel Vector Floating Point support code
 empeg/
diff --git a/Documentation/arm/SPEAr/overview.txt b/Documentation/arm/SPEAr/overview.txt
new file mode 100644 (file)
index 0000000..253a35c
--- /dev/null
@@ -0,0 +1,60 @@
+                       SPEAr ARM Linux Overview
+                       ==========================
+
+Introduction
+------------
+
+  SPEAr (Structured Processor Enhanced Architecture).
+  weblink : http://www.st.com/spear
+
+  The ST Microelectronics SPEAr range of ARM9/CortexA9 System-on-Chip CPUs are
+  supported by the 'spear' platform of ARM Linux. Currently SPEAr300,
+  SPEAr310, SPEAr320 and SPEAr600 SOCs are supported. Support for the SPEAr13XX
+  series is in progress.
+
+  Hierarchy in SPEAr is as follows:
+
+  SPEAr (Platform)
+       - SPEAr3XX (3XX SOC series, based on ARM9)
+               - SPEAr300 (SOC)
+                       - SPEAr300_EVB (Evaluation Board)
+               - SPEAr310 (SOC)
+                       - SPEAr310_EVB (Evaluation Board)
+               - SPEAr320 (SOC)
+                       - SPEAr320_EVB (Evaluation Board)
+       - SPEAr6XX (6XX SOC series, based on ARM9)
+               - SPEAr600 (SOC)
+                       - SPEAr600_EVB (Evaluation Board)
+       - SPEAr13XX (13XX SOC series, based on ARM CORTEXA9)
+               - SPEAr1300 (SOC)
+
+  Configuration
+  -------------
+
+  A generic configuration is provided for each machine, and can be used as the
+  default by
+       make spear600_defconfig
+       make spear300_defconfig
+       make spear310_defconfig
+       make spear320_defconfig
+
+  Layout
+  ------
+
+  The common files for multiple machine families (SPEAr3XX, SPEAr6XX and
+  SPEAr13XX) are located in the platform code contained in arch/arm/plat-spear
+  with headers in plat/.
+
+  Each machine series have a directory with name arch/arm/mach-spear followed by
+  series name. Like mach-spear3xx, mach-spear6xx and mach-spear13xx.
+
+  Common file for machines of spear3xx family is mach-spear3xx/spear3xx.c and for
+  spear6xx is mach-spear6xx/spear6xx.c. mach-spear* also contain soc/machine
+  specific files, like spear300.c, spear310.c, spear320.c and spear600.c.
+  mach-spear* also contains board specific files for each machine type.
+
+
+  Document Author
+  ---------------
+
+  Viresh Kumar, (c) 2010 ST Microelectronics
index fd588ff..a1ca592 100644 (file)
@@ -235,8 +235,7 @@ containing the following files describing that cgroup:
  - cgroup.procs: list of tgids in the cgroup.  This list is not
    guaranteed to be sorted or free of duplicate tgids, and userspace
    should sort/uniquify the list if this property is required.
-   Writing a tgid into this file moves all threads with that tgid into
-   this cgroup.
+   This is a read-only file, for now.
  - notify_on_release flag: run the release agent on exit?
  - release_agent: the path to use for release notifications (this file
    exists in the top cgroup only)
index df03169..a2db352 100644 (file)
@@ -408,9 +408,6 @@ This should be used inside the RCU read lock, as in the following example:
                ...
        }
 
-A function need not get RCU read lock to use __task_cred() if it is holding a
-spinlock at the time as this implicitly holds the RCU read lock.
-
 Should it be necessary to hold another task's credentials for a long period of
 time, and possibly to sleep whilst doing so, then the caller should get a
 reference on them using:
@@ -426,17 +423,16 @@ credentials, hiding the RCU magic from the caller:
        uid_t task_uid(task)            Task's real UID
        uid_t task_euid(task)           Task's effective UID
 
-If the caller is holding a spinlock or the RCU read lock at the time anyway,
-then:
+If the caller is holding the RCU read lock at the time anyway, then:
 
        __task_cred(task)->uid
        __task_cred(task)->euid
 
 should be used instead.  Similarly, if multiple aspects of a task's credentials
-need to be accessed, RCU read lock or a spinlock should be used, __task_cred()
-called, the result stored in a temporary pointer and then the credential
-aspects called from that before dropping the lock.  This prevents the
-potentially expensive RCU magic from being invoked multiple times.
+need to be accessed, RCU read lock should be used, __task_cred() called, the
+result stored in a temporary pointer and then the credential aspects called
+from that before dropping the lock.  This prevents the potentially expensive
+RCU magic from being invoked multiple times.
 
 Should some other single aspect of another task's credentials need to be
 accessed, then this can be used:
index ed511af..e7965f4 100644 (file)
@@ -520,29 +520,6 @@ Who:       Hans de Goede <hdegoede@redhat.com>
 
 ----------------------------
 
-What:  corgikbd, spitzkbd, tosakbd driver
-When:  2.6.35
-Files: drivers/input/keyboard/{corgi,spitz,tosa}kbd.c
-Why:   We now have a generic GPIO based matrix keyboard driver that
-       are fully capable of handling all the keys on these devices.
-       The original drivers manipulate the GPIO registers directly
-       and so are difficult to maintain.
-Who:   Eric Miao <eric.y.miao@gmail.com>
-
-----------------------------
-
-What:  corgi_ssp and corgi_ts driver
-When:  2.6.35
-Files: arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c
-Why:   The corgi touchscreen is now deprecated in favour of the generic
-       ads7846.c driver. The noise reduction technique used in corgi_ts.c,
-       that's to wait till vsync before ADC sampling, is also integrated into
-       ads7846 driver now. Provided that the original driver is not generic
-       and is difficult to maintain, it will be removed later.
-Who:   Eric Miao <eric.y.miao@gmail.com>
-
-----------------------------
-
 What:  capifs
 When:  February 2011
 Files: drivers/isdn/capi/capifs.*
@@ -564,6 +541,16 @@ Who:       Avi Kivity <avi@redhat.com>
 
 ----------------------------
 
+What:  xtime, wall_to_monotonic
+When:  2.6.36+
+Files: kernel/time/timekeeping.c include/linux/time.h
+Why:   Cleaning up timekeeping internal values. Please use
+       existing timekeeping accessor functions to access
+       the equivalent functionality.
+Who:   John Stultz <johnstul@us.ibm.com>
+
+----------------------------
+
 What:  KVM kernel-allocated memory slots
 When:  July 2010
 Why:   Since 2.6.25, kvm supports user-allocated memory slots, which are
@@ -589,3 +576,36 @@ Why:       Useful in 2003, implementation is a hack.
        Generally invoked by accident today.
        Seen as doing more harm than good.
 Who:   Len Brown <len.brown@intel.com>
+
+----------------------------
+
+What:  video4linux /dev/vtx teletext API support
+When:  2.6.35
+Files: drivers/media/video/saa5246a.c drivers/media/video/saa5249.c
+       include/linux/videotext.h
+Why:   The vtx device nodes have been superseded by vbi device nodes
+       for many years. No applications exist that use the vtx support.
+       Of the two i2c drivers that actually support this API the saa5249
+       has been impossible to use for a year now and no known hardware
+       that supports this device exists. The saa5246a is theoretically
+       supported by the old mxb boards, but it never actually worked.
+
+       In summary: there is no hardware that can use this API and there
+       are no applications actually implementing this API.
+
+       The vtx support still reserves minors 192-223 and we would really
+       like to reuse those for upcoming new functionality. In the unlikely
+       event that new hardware appears that wants to use the functionality
+       provided by the vtx API, then that functionality should be build
+       around the sliced VBI API instead.
+Who:   Hans Verkuil <hverkuil@xs4all.nl>
+
+----------------------------
+
+What:  IRQF_DISABLED
+When:  2.6.36
+Why:   The flag is a NOOP as we run interrupt handlers with interrupts disabled
+Who:   Thomas Gleixner <tglx@linutronix.de>
+
+----------------------------
+
index 6a53a84..0488491 100644 (file)
@@ -137,7 +137,7 @@ NS*| OPENATTR             | OPT        |              | Section 18.17  |
    | READ                 | REQ        |              | Section 18.22  |
    | READDIR              | REQ        |              | Section 18.23  |
    | READLINK             | OPT        |              | Section 18.24  |
-NS | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
+   | RECLAIM_COMPLETE     | REQ        |              | Section 18.51  |
    | RELEASE_LOCKOWNER    | MNI        |              | N/A            |
    | REMOVE               | REQ        |              | Section 18.25  |
    | RENAME               | REQ        |              | Section 18.26  |
index a4f30fa..fbce915 100644 (file)
@@ -316,7 +316,7 @@ address           perms offset  dev   inode      pathname
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [threadstack:001ff4b4]
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0
 a7eb2000-a7eb3000 ---p 00000000 00:00 0
 a7eb3000-a7ed5000 rw-p 00000000 00:00 0
 a7ed5000-a8008000 r-xp 00000000 03:00 4222       /lib/libc.so.6
@@ -352,7 +352,6 @@ is not associated with a file:
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
- [threadstack:xxxxxxxx]   = the stack of the thread, xxxxxxxx is the stack size
 
  or if empty, the mapping is anonymous.
 
@@ -566,6 +565,10 @@ The default_smp_affinity mask applies to all non-active IRQs, which are the
 IRQs which have not yet been allocated/activated, and hence which lack a
 /proc/irq/[0-9]* directory.
 
+The node file on an SMP system shows the node to which the device using the IRQ
+reports itself as being attached. This hardware locality information does not
+include information about any possible driver locality preference.
+
 prof_cpu_mask specifies which CPUs are to be profiled by the system wide
 profiler. Default value is ffffffff (all cpus).
 
index 3219ee0..5ebf5af 100644 (file)
@@ -74,6 +74,11 @@ structure at all.  You should use this to keep device-specific data.
        /* retrieve the value */
        void *i2c_get_clientdata(const struct i2c_client *client);
 
+Note that starting with kernel 2.6.34, you don't have to set the `data' field
+to NULL in remove() or if probe() failed anymore. The i2c-core does this
+automatically on these occasions. Those are also the only times the core will
+touch this field.
+
 
 Accessing the client
 ====================
index a10c3b6..56941ae 100644 (file)
@@ -333,14 +333,14 @@ byte 0:
 byte 1:
 
    bit   7   6   5   4   3   2   1   0
-        x15 x14 x13 x12 x11 x10 x9  x8
+         .   .   .   .   .  x10 x9  x8
 
 byte 2:
 
    bit   7   6   5   4   3   2   1   0
         x7  x6  x5  x4  x4  x2  x1  x0
 
-         x15..x0 = absolute x value (horizontal)
+         x10..x0 = absolute x value (horizontal)
 
 byte 3:
 
@@ -350,14 +350,14 @@ byte 3:
 byte 4:
 
    bit   7   6   5   4   3   2   1   0
-        y15 y14 y13 y12 y11 y10 y8  y8
+         .   .   .   .   .   .  y9  y8
 
 byte 5:
 
    bit   7   6   5   4   3   2   1   0
         y7  y6  y5  y4  y3  y2  y1  y0
 
-         y15..y0 = absolute y value (vertical)
+         y9..y0 = absolute y value (vertical)
 
 
 4.2.2 Two finger touch
index 8490480..c0fc1c7 100644 (file)
@@ -68,6 +68,22 @@ like:
    SYN_MT_REPORT
    SYN_REPORT
 
+Here is the sequence after lifting one of the fingers:
+
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   SYN_REPORT
+
+And here is the sequence after lifting the remaining finger:
+
+   SYN_MT_REPORT
+   SYN_REPORT
+
+If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
+ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
+last SYN_REPORT will be dropped by the input core, resulting in no
+zero-finger event reaching userland.
 
 Event Semantics
 ---------------
@@ -217,11 +233,6 @@ where examples can be found.
 difference between the contact position and the approaching tool position
 could be used to derive tilt.
 [2] The list can of course be extended.
-[3] The multi-touch X driver is currently in the prototyping stage. At the
-time of writing (April 2009), the MT protocol is not yet merged, and the
-prototype implements finger matching, basic mouse support and two-finger
-scrolling. The project aims at improving the quality of current multi-touch
-functionality available in the Synaptics X driver, and in addition
-implement more advanced gestures.
+[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
 [4] See the section on event computation.
 [5] See the section on finger tracking.
index f40a1f0..87c8990 100644 (file)
@@ -161,13 +161,15 @@ o  In order to put a system into any of the sleep states after a TXT
       has been restored, it will restore the TPM PCRs and then
       transfer control back to the kernel's S3 resume vector.
       In order to preserve system integrity across S3, the kernel
-      provides tboot with a set of memory ranges (kernel
-      code/data/bss, S3 resume code, and AP trampoline) that tboot
-      will calculate a MAC (message authentication code) over and then
-      seal with the TPM.  On resume and once the measured environment
-      has been re-established, tboot will re-calculate the MAC and
-      verify it against the sealed value.  Tboot's policy determines
-      what happens if the verification fails.
+      provides tboot with a set of memory ranges (RAM and RESERVED_KERN
+      in the e820 table, but not any memory that BIOS might alter over
+      the S3 transition) that tboot will calculate a MAC (message
+      authentication code) over and then seal with the TPM. On resume
+      and once the measured environment has been re-established, tboot
+      will re-calculate the MAC and verify it against the sealed value.
+      Tboot's policy determines what happens if the verification fails.
+      Note that the c/s 194 of tboot which has the new MAC code supports
+      this.
 
 That's pretty much it for TXT support.
 
index e4cbca5..b9b0d79 100644 (file)
@@ -99,6 +99,7 @@ parameter is applicable:
        SWSUSP  Software suspend (hibernation) is enabled.
        SUSPEND System suspend states are enabled.
        FTRACE  Function tracing enabled.
+       TPM     TPM drivers are enabled.
        TS      Appropriate touchscreen support is enabled.
        UMS     USB Mass Storage support is enabled.
        USB     USB support is enabled.
@@ -320,15 +321,12 @@ and is between 256 and 4096 characters. It is defined in the file
        amd_iommu=      [HW,X86-84]
                        Pass parameters to the AMD IOMMU driver in the system.
                        Possible values are:
-                       isolate - enable device isolation (each device, as far
-                                 as possible, will get its own protection
-                                 domain) [default]
-                       share - put every device behind one IOMMU into the
-                               same protection domain
                        fullflush - enable flushing of IO/TLB entries when
                                    they are unmapped. Otherwise they are
                                    flushed before they will be reused, which
                                    is a lot of faster
+                       off       - do not initialize any AMD IOMMU found in
+                                   the system
 
        amijoy.map=     [HW,JOY] Amiga joystick support
                        Map of devices attached to JOY0DAT and JOY1DAT
@@ -789,8 +787,12 @@ and is between 256 and 4096 characters. It is defined in the file
                        as early as possible in order to facilitate early
                        boot debugging.
 
-       ftrace_dump_on_oops
+       ftrace_dump_on_oops[=orig_cpu]
                        [FTRACE] will dump the trace buffers on oops.
+                       If no parameter is passed, ftrace will dump
+                       buffers of all CPUs, but if you pass orig_cpu, it will
+                       dump only the buffer of the CPU that triggered the
+                       oops.
 
        ftrace_filter=[function-list]
                        [FTRACE] Limit the functions traced by the function
@@ -1199,7 +1201,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
        libata.force=   [LIBATA] Force configurations.  The format is comma
                        separated list of "[ID:]VAL" where ID is
-                       PORT[:DEVICE].  PORT and DEVICE are decimal numbers
+                       PORT[.DEVICE].  PORT and DEVICE are decimal numbers
                        matching port, link or device.  Basically, it matches
                        the ATA ID string printed on console by libata.  If
                        the whole ID part is omitted, the last PORT and DEVICE
@@ -2615,6 +2617,15 @@ and is between 256 and 4096 characters. It is defined in the file
 
        tp720=          [HW,PS2]
 
+       tpm_suspend_pcr=[HW,TPM]
+                       Format: integer pcr id
+                       Specify that at suspend time, the tpm driver
+                       should extend the specified pcr with zeros,
+                       as a workaround for some chips which fail to
+                       flush the last written pcr on TPM_SaveState.
+                       This will guarantee that all the other pcrs
+                       are saved.
+
        trace_buf_size=nn[KMG]
                        [FTRACE] will set tracing buffer size.
 
index 2f9115c..61c291c 100644 (file)
@@ -165,8 +165,8 @@ the user entry_handler invocation is also skipped.
 
 1.4 How Does Jump Optimization Work?
 
-If you configured your kernel with CONFIG_OPTPROBES=y (currently
-this option is supported on x86/x86-64, non-preemptive kernel) and
+If your kernel is built with CONFIG_OPTPROBES=y (currently this flag
+is automatically set 'y' on x86/x86-64, non-preemptive kernel) and
 the "debug.kprobes_optimization" kernel parameter is set to 1 (see
 sysctl(8)), Kprobes tries to reduce probe-hit overhead by using a jump
 instruction instead of a breakpoint instruction at each probepoint.
@@ -271,8 +271,6 @@ tweak the kernel's execution path, you need to suppress optimization,
 using one of the following techniques:
 - Specify an empty function for the kprobe's post_handler or break_handler.
  or
-- Config CONFIG_OPTPROBES=n.
- or
 - Execute 'sysctl -w debug.kprobes_optimization=n'
 
 2. Architectures Supported
@@ -307,10 +305,6 @@ it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
 so you can use "objdump -d -l vmlinux" to see the source-to-object
 code mapping.
 
-If you want to reduce probing overhead, set "Kprobes jump optimization
-support" (CONFIG_OPTPROBES) to "y". You can find this option under the
-"Kprobes" line.
-
 4. API Reference
 
 The Kprobes API includes a "register" function and an "unregister"
index 0e58b45..e8c8f4f 100644 (file)
@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE:     return system time stamp generated in
 SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
 SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
 following control message:
-    struct scm_timestamping {
-           struct timespec systime;
-           struct timespec hwtimetrans;
-           struct timespec hwtimeraw;
-    };
+
+struct scm_timestamping {
+       struct timespec systime;
+       struct timespec hwtimetrans;
+       struct timespec hwtimeraw;
+};
 
 recvmsg() can be used to get this control message for regular incoming
 packets. For send time stamps the outgoing packet is looped back to
@@ -87,12 +88,13 @@ by the network device and will be empty without that support.
 SIOCSHWTSTAMP:
 
 Hardware time stamping must also be initialized for each device driver
-that is expected to do hardware time stamping. The parameter is:
+that is expected to do hardware time stamping. The parameter is defined in
+/include/linux/net_tstamp.h as:
 
 struct hwtstamp_config {
-    int flags;           /* no flags defined right now, must be zero */
-    int tx_type;         /* HWTSTAMP_TX_* */
-    int rx_filter;       /* HWTSTAMP_FILTER_* */
+       int flags;      /* no flags defined right now, must be zero */
+       int tx_type;    /* HWTSTAMP_TX_* */
+       int rx_filter;  /* HWTSTAMP_FILTER_* */
 };
 
 Desired behavior is passed into the kernel and to a specific device by
@@ -139,42 +141,56 @@ enum {
        /* time stamp any incoming packet */
        HWTSTAMP_FILTER_ALL,
 
-        /* return value: time stamp all packets requested plus some others */
-        HWTSTAMP_FILTER_SOME,
+       /* return value: time stamp all packets requested plus some others */
+       HWTSTAMP_FILTER_SOME,
 
        /* PTP v1, UDP, any kind of event packet */
        HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
 
-        ...
+       /* for the complete list of values, please check
+        * the include file /include/linux/net_tstamp.h
+        */
 };
 
 
 DEVICE IMPLEMENTATION
 
 A driver which supports hardware time stamping must support the
-SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
-in the skb with skb_hwtstamp_set().
+SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
+the actual values as described in the section on SIOCSHWTSTAMP.
+
+Time stamps for received packets must be stored in the skb. To get a pointer
+to the shared time stamp structure of the skb call skb_hwtstamps(). Then
+set the time stamps in the structure:
+
+struct skb_shared_hwtstamps {
+       /* hardware time stamp transformed into duration
+        * since arbitrary point in time
+        */
+       ktime_t hwtstamp;
+       ktime_t syststamp; /* hwtstamp transformed to system time base */
+};
 
 Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
-  returns non-zero. If yes, then the driver is expected
-  to do hardware time stamping.
+- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
+  If yes, then the driver is expected to do hardware time stamping.
 - If this is possible for the skb and requested, then declare
-  that the driver is doing the time stamping by calling
-  skb_hwtstamp_tx_in_progress(). A driver not supporting
-  hardware time stamping doesn't do that. A driver must never
-  touch sk_buff::tstamp! It is used to store how time stamping
-  for an outgoing packets is to be done.
+  that the driver is doing the time stamping by setting the field
+  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
+  to the associated skb for the next step and not free the skb. A driver
+  not supporting hardware time stamping doesn't do that. A driver must
+  never touch sk_buff::tstamp! It is used to store software generated
+  time stamps by the network subsystem.
 - As soon as the driver has sent the packet and/or obtained a
   hardware time stamp for it, it passes the time stamp back by
   calling skb_hwtstamp_tx() with the original skb, the raw
-  hardware time stamp and a handle to the device (necessary
-  to convert the hardware time stamp to system time). If obtaining
-  the hardware time stamp somehow fails, then the driver should
-  not fall back to software time stamping. The rationale is that
-  this would occur at a later time in the processing pipeline
-  than other software time stamping and therefore could lead
-  to unexpected deltas between time stamps.
-- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+  hardware time stamp. skb_hwtstamp_tx() clones the original skb and
+  adds the timestamps, therefore the original skb has to be freed now.
+  If obtaining the hardware time stamp somehow fails, then the driver
+  should not fall back to software time stamping. The rationale is that
+  this would occur at a later time in the processing pipeline than other
+  software time stamping and therefore could lead to unexpected deltas
+  between time stamps.
+- If the driver did not call set skb_tx(skb)->in_progress, then
   dev_hard_start_xmit() checks whether software time stamping
   is wanted as fallback and potentially generates the time stamp.
index aae8355..221f38b 100644 (file)
@@ -190,3 +190,61 @@ Example:
   for (node = rb_first(&mytree); node; node = rb_next(node))
        printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring);
 
+Support for Augmented rbtrees
+-----------------------------
+
+Augmented rbtree is an rbtree with "some" additional data stored in each node.
+This data can be used to augment some new functionality to rbtree.
+Augmented rbtree is an optional feature built on top of basic rbtree
+infrastructure. rbtree user who wants this feature will have an augment
+callback function in rb_root initialized.
+
+This callback function will be called from rbtree core routines whenever
+a node has a change in one or both of its children. It is the responsibility
+of the callback function to recalculate the additional data that is in the
+rb node using new children information. Note that if this new additional
+data affects the parent node's additional data, then callback function has
+to handle it and do the recursive updates.
+
+
+Interval tree is an example of augmented rb tree. Reference -
+"Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
+More details about interval trees:
+
+Classical rbtree has a single key and it cannot be directly used to store
+interval ranges like [lo:hi] and do a quick lookup for any overlap with a new
+lo:hi or to find whether there is an exact match for a new lo:hi.
+
+However, rbtree can be augmented to store such interval ranges in a structured
+way making it possible to do efficient lookup and exact match.
+
+This "extra information" stored in each node is the maximum hi
+(max_hi) value among all the nodes that are its descendents. This
+information can be maintained at each node just be looking at the node
+and its immediate children. And this will be used in O(log n) lookup
+for lowest match (lowest start address among all possible matches)
+with something like:
+
+find_lowest_match(lo, hi, node)
+{
+       lowest_match = NULL;
+       while (node) {
+               if (max_hi(node->left) > lo) {
+                       // Lowest overlap if any must be on left side
+                       node = node->left;
+               } else if (overlap(lo, hi, node)) {
+                       lowest_match = node;
+                       break;
+               } else if (lo > node->lo) {
+                       // Lowest overlap if any must be on right side
+                       node = node->right;
+               } else {
+                       break;
+               }
+       }
+       return lowest_match;
+}
+
+Finding exact match will be to first find lowest match and then to follow
+successor nodes looking for exact match, until the start of a node is beyond
+the hi value we are looking for.
index 6f33593..8239ebb 100644 (file)
@@ -211,7 +211,7 @@ provide fair CPU time to each such task group.  For example, it may be
 desirable to first provide fair CPU time to each user on the system and then to
 each task belonging to a user.
 
-CONFIG_GROUP_SCHED strives to achieve exactly that.  It lets tasks to be
+CONFIG_CGROUP_SCHED strives to achieve exactly that.  It lets tasks to be
 grouped and divides CPU time fairly among such groups.
 
 CONFIG_RT_GROUP_SCHED permits to group real-time (i.e., SCHED_FIFO and
@@ -220,38 +220,11 @@ SCHED_RR) tasks.
 CONFIG_FAIR_GROUP_SCHED permits to group CFS (i.e., SCHED_NORMAL and
 SCHED_BATCH) tasks.
 
-At present, there are two (mutually exclusive) mechanisms to group tasks for
-CPU bandwidth control purposes:
-
- - Based on user id (CONFIG_USER_SCHED)
-
-   With this option, tasks are grouped according to their user id.
-
- - Based on "cgroup" pseudo filesystem (CONFIG_CGROUP_SCHED)
-
-   This options needs CONFIG_CGROUPS to be defined, and lets the administrator
+   These options need CONFIG_CGROUPS to be defined, and let the administrator
    create arbitrary groups of tasks, using the "cgroup" pseudo filesystem.  See
    Documentation/cgroups/cgroups.txt for more information about this filesystem.
 
-Only one of these options to group tasks can be chosen and not both.
-
-When CONFIG_USER_SCHED is defined, a directory is created in sysfs for each new
-user and a "cpu_share" file is added in that directory.
-
-       # cd /sys/kernel/uids
-       # cat 512/cpu_share             # Display user 512's CPU share
-       1024
-       # echo 2048 > 512/cpu_share     # Modify user 512's CPU share
-       # cat 512/cpu_share             # Display user 512's CPU share
-       2048
-       #
-
-CPU bandwidth between two users is divided in the ratio of their CPU shares.
-For example: if you would like user "root" to get twice the bandwidth of user
-"guest," then set the cpu_share for both the users such that "root"'s cpu_share
-is twice "guest"'s cpu_share.
-
-When CONFIG_CGROUP_SCHED is defined, a "cpu.shares" file is created for each
+When CONFIG_FAIR_GROUP_SCHED is defined, a "cpu.shares" file is created for each
 group created using the pseudo filesystem.  See example steps below to create
 task groups and modify their CPU share using the "cgroups" pseudo filesystem.
 
@@ -273,24 +246,3 @@ task groups and modify their CPU share using the "cgroups" pseudo filesystem.
 
        # #Launch gmplayer (or your favourite movie player)
        # echo <movie_player_pid> > multimedia/tasks
-
-8. Implementation note: user namespaces
-
-User namespaces are intended to be hierarchical.  But they are currently
-only partially implemented.  Each of those has ramifications for CFS.
-
-First, since user namespaces are hierarchical, the /sys/kernel/uids
-presentation is inadequate.  Eventually we will likely want to use sysfs
-tagging to provide private views of /sys/kernel/uids within each user
-namespace.
-
-Second, the hierarchical nature is intended to support completely
-unprivileged use of user namespaces.  So if using user groups, then
-we want the users in a user namespace to be children of the user
-who created it.
-
-That is currently unimplemented.  So instead, every user in a new
-user namespace will receive 1024 shares just like any user in the
-initial user namespace.  Note that at the moment creation of a new
-user namespace requires each of CAP_SYS_ADMIN, CAP_SETUID, and
-CAP_SETGID.
index 86eabe6..605b0d4 100644 (file)
@@ -126,23 +126,12 @@ priority!
 2.3 Basis for grouping tasks
 ----------------------------
 
-There are two compile-time settings for allocating CPU bandwidth. These are
-configured using the "Basis for grouping tasks" multiple choice menu under
-General setup > Group CPU Scheduler:
-
-a. CONFIG_USER_SCHED (aka "Basis for grouping tasks" =  "user id")
-
-This lets you use the virtual files under
-"/sys/kernel/uids/<uid>/cpu_rt_runtime_us" to control he CPU time reserved for
-each user .
-
-The other option is:
-
-.o CONFIG_CGROUP_SCHED (aka "Basis for grouping tasks" = "Control groups")
+Enabling CONFIG_RT_GROUP_SCHED lets you explicitly allocate real
+CPU bandwidth to task groups.
 
 This uses the /cgroup virtual file system and
 "/cgroup/<cgroup>/cpu.rt_runtime_us" to control the CPU time reserved for each
-control group instead.
+control group.
 
 For more information on working with control groups, you should read
 Documentation/cgroups/cgroups.txt as well.
@@ -161,8 +150,7 @@ For now, this can be simplified to just the following (but see Future plans):
 ===============
 
 There is work in progress to make the scheduling period for each group
-("/sys/kernel/uids/<uid>/cpu_rt_period_us" or
-"/cgroup/<cgroup>/cpu.rt_period_us" respectively) configurable as well.
+("/cgroup/<cgroup>/cpu.rt_period_us") configurable as well.
 
 The constraint on the period is that a subgroup must have a smaller or
 equal period to its parent. But realistically its not very useful _yet_
index 10abd37..16feda9 100644 (file)
@@ -58,7 +58,7 @@ static void transfer(int fd)
        };
 
        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
-       if (ret == 1)
+       if (ret < 1)
                pabort("can't send spi message");
 
        for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
index 5effa5b..e213f45 100644 (file)
@@ -18,16 +18,15 @@ Rules on what kind of patches are accepted, and which ones are not, into the
  - It cannot contain any "trivial" fixes in it (spelling changes,
    whitespace cleanups, etc).
  - It must follow the Documentation/SubmittingPatches rules.
- - It or an equivalent fix must already exist in Linus' tree.  Quote the
-   respective commit ID in Linus' tree in your patch submission to -stable.
+ - It or an equivalent fix must already exist in Linus' tree (upstream).
 
 
 Procedure for submitting patches to the -stable tree:
 
  - Send the patch, after verifying that it follows the above rules, to
-   stable@kernel.org.
- - To have the patch automatically included in the stable tree, add the
  the tag
+   stable@kernel.org.  You must note the upstream commit ID in the changelog
+   of your submission.
- To have the patch automatically included in the stable tree, add the tag
      Cc: stable@kernel.org
    in the sign-off area. Once the patch is merged it will be applied to
    the stable tree without anything else needing to be done by the author
index 02ac6ed..778ddf3 100644 (file)
@@ -90,7 +90,8 @@ In order to facilitate early boot debugging, use boot option:
 
        trace_event=[event-list]
 
-The format of this boot option is the same as described in section 2.1.
+event-list is a comma separated list of events. See section 2.1 for event
+format.
 
 3. Defining an event-enabled tracepoint
 =======================================
index 03485bf..557c1ed 100644 (file)
@@ -155,6 +155,9 @@ of ftrace. Here is a list of some of the key files:
        to be traced. Echoing names of functions into this file
        will limit the trace to only those functions.
 
+       This interface also allows for commands to be used. See the
+       "Filter commands" section for more details.
+
   set_ftrace_notrace:
 
        This has an effect opposite to that of
@@ -1337,12 +1340,14 @@ ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
 can either use the sysctl function or set it via the proc system
 interface.
 
-  sysctl kernel.ftrace_dump_on_oops=1
+  sysctl kernel.ftrace_dump_on_oops=n
 
 or
 
-  echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
+  echo n > /proc/sys/kernel/ftrace_dump_on_oops
 
+If n = 1, ftrace will dump buffers of all CPUs, if n = 2 ftrace will
+only dump the buffer of the CPU that triggered the oops.
 
 Here's an example of such a dump after a null pointer
 dereference in a kernel module:
@@ -1822,6 +1827,47 @@ this special filter via:
  echo > set_graph_function
 
 
+Filter commands
+---------------
+
+A few commands are supported by the set_ftrace_filter interface.
+Trace commands have the following format:
+
+<function>:<command>:<parameter>
+
+The following commands are supported:
+
+- mod
+  This command enables function filtering per module. The
+  parameter defines the module. For example, if only the write*
+  functions in the ext3 module are desired, run:
+
+   echo 'write*:mod:ext3' > set_ftrace_filter
+
+  This command interacts with the filter in the same way as
+  filtering based on function names. Thus, adding more functions
+  in a different module is accomplished by appending (>>) to the
+  filter file. Remove specific module functions by prepending
+  '!':
+
+   echo '!writeback*:mod:ext3' >> set_ftrace_filter
+
+- traceon/traceoff
+  These commands turn tracing on and off when the specified
+  functions are hit. The parameter determines how many times the
+  tracing system is turned on and off. If unspecified, there is
+  no limit. For example, to disable tracing when a schedule bug
+  is hit the first 5 times, run:
+
+   echo '__schedule_bug:traceoff:5' > set_ftrace_filter
+
+  These commands are cumulative whether or not they are appended
+  to set_ftrace_filter. To remove a command, prepend it by '!'
+  and drop the parameter:
+
+   echo '!__schedule_bug:traceoff' > set_ftrace_filter
+
+
 trace_pipe
 ----------
 
index a9100b2..ec94748 100644 (file)
@@ -40,7 +40,9 @@ Synopsis of kprobe_events
   $stack       : Fetch stack address.
   $retval      : Fetch return value.(*)
   +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
-  NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
+  NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
+  FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
+                 (u8/u16/u32/u64/s8/s16/s32/s64) are supported.
 
   (*) only for return probe.
   (**) this is useful for fetching a field of data structures.
index 8a32aec..de39882 100644 (file)
@@ -485,8 +485,8 @@ S:  Maintained
 F:     drivers/input/mouse/bcm5974.c
 
 APPLE SMC DRIVER
-M:     Nicolas Boichat <nicolas@boichat.ch>
-L:     mactel-linux-devel@lists.sourceforge.net
+M:     Henrik Rydberg <rydberg@euromail.se>
+L:     lm-sensors@lm-sensors.org
 S:     Maintained
 F:     drivers/hwmon/applesmc.c
 
@@ -586,6 +586,12 @@ F: drivers/mtd/nand/bcm_umi_bch.c
 F:     drivers/mtd/nand/bcm_umi_hamming.c
 F:     drivers/mtd/nand/nand_bcm_umi.h
 
+ARM/CAVIUM NETWORKS CNS3XXX MACHINE SUPPORT
+M:     Anton Vorontsov <avorontsov@mvista.com>
+S:     Maintained
+F:     arch/arm/mach-cns3xxx/
+T:     git git://git.infradead.org/users/cbou/linux-cns3xxx.git
+
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 M:     Hartley Sweeten <hsweeten@visionengravers.com>
 M:     Ryan Mallon <ryan@bluewatersys.com>
@@ -775,11 +781,10 @@ M:        Philipp Zabel <philipp.zabel@gmail.com>
 S:     Maintained
 
 ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support
-M:     Lennert Buytenhek <buytenh@marvell.com>
-M:     Nicolas Pitre <nico@marvell.com>
+M:     Lennert Buytenhek <kernel@wantstofly.org>
+M:     Nicolas Pitre <nico@fluxnic.net>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-T:     git git://git.marvell.com/orion
-S:     Maintained
+S:     Odd Fixes
 F:     arch/arm/mach-loki/
 F:     arch/arm/mach-kirkwood/
 F:     arch/arm/mach-mv78xx0/
@@ -814,6 +819,7 @@ ARM/QUALCOMM MSM MACHINE SUPPORT
 M:     David Brown <davidb@codeaurora.org>
 M:     Daniel Walker <dwalker@codeaurora.org>
 M:     Bryan Huntsman <bryanh@codeaurora.org>
+L:     linux-arm-msm@vger.kernel.org
 F:     arch/arm/mach-msm/
 F:     drivers/video/msm/
 F:     drivers/mmc/host/msm_sdcc.c
@@ -971,6 +977,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.mcuos.com
 S:     Maintained
 
+ARM/U300 MACHINE SUPPORT
+M:     Linus Walleij <linus.walleij@stericsson.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Supported
+F:     arch/arm/mach-u300/
+F:     drivers/i2c/busses/i2c-stu300.c
+F:     drivers/rtc/rtc-coh901331.c
+F:     drivers/watchdog/coh901327_wdt.c
+F:     drivers/dma/coh901318*
+
 ARM/U8500 ARM ARCHITECTURE
 M:     Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -984,6 +1000,20 @@ W:        http://www.arm.linux.org.uk/
 S:     Maintained
 F:     arch/arm/vfp/
 
+ARM/VOIPAC PXA270 SUPPORT
+M:     Marek Vasut <marek.vasut@gmail.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-pxa/vpac270.c
+F:     arch/arm/mach-pxa/include/mach-pxa/vpac270.h
+
+ARM/ZIPIT Z2 SUPPORT
+M:     Marek Vasut <marek.vasut@gmail.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-pxa/z2.c
+F:     arch/arm/mach-pxa/include/mach-pxa/z2.h
+
 ASC7621 HARDWARE MONITOR DRIVER
 M:     George Joseph <george.joseph@fairview5.com>
 L:     lm-sensors@lm-sensors.org
@@ -1964,7 +1994,7 @@ F:        lib/kobj*
 
 DRM DRIVERS
 M:     David Airlie <airlied@linux.ie>
-L:     dri-devel@lists.sourceforge.net
+L:     dri-devel@lists.freedesktop.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
 S:     Maintained
 F:     drivers/gpu/drm/
@@ -2957,6 +2987,17 @@ S:       Odd Fixes
 F:     Documentation/networking/README.ipw2200
 F:     drivers/net/wireless/ipw2x00/ipw2200.*
 
+INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT)
+M:     Joseph Cihula <joseph.cihula@intel.com>
+M:     Shane Wang <shane.wang@intel.com>
+L:     tboot-devel@lists.sourceforge.net
+W:     http://tboot.sourceforge.net
+T:     Mercurial http://www.bughost.org/repos.hg/tboot.hg
+S:     Supported
+F:     Documentation/intel_txt.txt
+F:     include/linux/tboot.h
+F:     arch/x86/kernel/tboot.c
+
 INTEL WIRELESS WIMAX CONNECTION 2400
 M:     Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 M:     linux-wimax@intel.com
@@ -3628,7 +3669,8 @@ F:        drivers/net/wireless/mwl8k.c
 
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
 M:     Nicolas Pitre <nico@fluxnic.net>
-S:     Maintained
+S:     Odd Fixes
+F: drivers/mmc/host/mvsdio.*
 
 MARVELL YUKON / SYSKONNECT DRIVER
 M:     Mirko Lindner <mlindner@syskonnect.de>
@@ -4169,6 +4211,7 @@ OPROFILE
 M:     Robert Richter <robert.richter@amd.com>
 L:     oprofile-list@lists.sf.net
 S:     Maintained
+F:     arch/*/include/asm/oprofile*.h
 F:     arch/*/oprofile/
 F:     drivers/oprofile/
 F:     include/linux/oprofile.h
@@ -4357,13 +4400,13 @@ M:      Paul Mackerras <paulus@samba.org>
 M:     Ingo Molnar <mingo@elte.hu>
 M:     Arnaldo Carvalho de Melo <acme@redhat.com>
 S:     Supported
-F:     kernel/perf_event.c
+F:     kernel/perf_event*.c
 F:     include/linux/perf_event.h
-F:     arch/*/kernel/perf_event.c
-F:     arch/*/kernel/*/perf_event.c
-F:     arch/*/kernel/*/*/perf_event.c
+F:     arch/*/kernel/perf_event*.c
+F:     arch/*/kernel/*/perf_event*.c
+F:     arch/*/kernel/*/*/perf_event*.c
 F:     arch/*/include/asm/perf_event.h
-F:     arch/*/lib/perf_event.c
+F:     arch/*/lib/perf_event*.c
 F:     arch/*/kernel/perf_callchain.c
 F:     tools/perf/
 
@@ -4486,17 +4529,17 @@ S:      Maintained
 F:     drivers/ata/sata_promise.*
 
 PS3 NETWORK SUPPORT
-M:     Geoff Levand <geoffrey.levand@am.sony.com>
+M:     Geoff Levand <geoff@infradead.org>
 L:     netdev@vger.kernel.org
 L:     cbe-oss-dev@ozlabs.org
-S:     Supported
+S:     Maintained
 F:     drivers/net/ps3_gelic_net.*
 
 PS3 PLATFORM SUPPORT
-M:     Geoff Levand <geoffrey.levand@am.sony.com>
+M:     Geoff Levand <geoff@infradead.org>
 L:     linuxppc-dev@ozlabs.org
 L:     cbe-oss-dev@ozlabs.org
-S:     Supported
+S:     Maintained
 F:     arch/powerpc/boot/ps3*
 F:     arch/powerpc/include/asm/lv1call.h
 F:     arch/powerpc/include/asm/ps3*.h
@@ -4795,12 +4838,11 @@ F:      drivers/s390/crypto/
 
 S390 ZFCP DRIVER
 M:     Christof Schmitt <christof.schmitt@de.ibm.com>
-M:     Martin Peschke <mp3@de.ibm.com>
+M:     Swen Schillig <swen@vnet.ibm.com>
 M:     linux390@de.ibm.com
 L:     linux-s390@vger.kernel.org
 W:     http://www.ibm.com/developerworks/linux/linux390/
 S:     Supported
-F:     Documentation/s390/zfcpdump.txt
 F:     drivers/s390/scsi/zfcp_*
 
 S390 IUCV NETWORK LAYER
@@ -5126,7 +5168,7 @@ F:        mm/sl?b.c
 
 SMC91x ETHERNET DRIVER
 M:     Nicolas Pitre <nico@fluxnic.net>
-S:     Maintained
+S:     Odd Fixes
 F:     drivers/net/smc91x.*
 
 SMSC47B397 HARDWARE MONITOR DRIVER
@@ -5257,6 +5299,46 @@ F:       drivers/serial/sunsu.c
 F:     drivers/serial/sunzilog.c
 F:     drivers/serial/sunzilog.h
 
+SPEAR PLATFORM SUPPORT
+M:     Viresh Kumar <viresh.kumar@st.com>
+W:     http://www.st.com/spear
+S:     Maintained
+F:     arch/arm/plat-spear/
+
+SPEAR3XX MACHINE SUPPORT
+M:     Viresh Kumar <viresh.kumar@st.com>
+W:     http://www.st.com/spear
+S:     Maintained
+F:     arch/arm/mach-spear3xx/
+
+SPEAR6XX MACHINE SUPPORT
+M:     Rajeev Kumar <rajeev-dlh.kumar@st.com>
+W:     http://www.st.com/spear
+S:     Maintained
+F:     arch/arm/mach-spear6xx/
+
+SPEAR CLOCK FRAMEWORK SUPPORT
+M:     Viresh Kumar <viresh.kumar@st.com>
+W:     http://www.st.com/spear
+S:     Maintained
+F:     arch/arm/mach-spear*/clock.c
+F:     arch/arm/mach-spear*/include/mach/clkdev.h
+F:     arch/arm/plat-spear/clock.c
+F:     arch/arm/plat-spear/include/plat/clock.h and clkdev.h
+
+SPEAR PAD MULTIPLEXING SUPPORT
+M:     Viresh Kumar <viresh.kumar@st.com>
+W:     http://www.st.com/spear
+S:     Maintained
+F:     arch/arm/plat-spear/include/plat/padmux.h
+F:     arch/arm/plat-spear/padmux.c
+F:     arch/arm/mach-spear*/spear*xx.c
+F:     arch/arm/mach-spear*/include/mach/generic.h
+F:     arch/arm/mach-spear3xx/spear3*0.c
+F:     arch/arm/mach-spear3xx/spear3*0_evb.c
+F:     arch/arm/mach-spear6xx/spear600.c
+F:     arch/arm/mach-spear6xx/spear600_evb.c
+
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 M:     Roger Wolff <R.E.Wolff@BitWizard.nl>
 S:     Supported
@@ -5497,7 +5579,7 @@ S:        Maintained
 F:     drivers/mmc/host/tmio_mmc.*
 
 TMPFS (SHMEM FILESYSTEM)
-M:     Hugh Dickins <hugh.dickins@tiscali.co.uk>
+M:     Hugh Dickins <hughd@google.com>
 L:     linux-mm@kvack.org
 S:     Maintained
 F:     include/linux/shmem_fs.h
index 67c1001..ebc8225 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 34
-EXTRAVERSION = -rc3
-NAME = Man-Eating Seals of Antiquity
+EXTRAVERSION =
+NAME = Sheep on Meth
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index e5eb133..acda512 100644 (file)
@@ -42,15 +42,10 @@ config KPROBES
          If in doubt, say "N".
 
 config OPTPROBES
-       bool "Kprobes jump optimization support (EXPERIMENTAL)"
-       default y
-       depends on KPROBES
+       def_bool y
+       depends on KPROBES && HAVE_OPTPROBES
        depends on !PREEMPT
-       depends on HAVE_OPTPROBES
        select KALLSYMS_ALL
-       help
-         This option will allow kprobes to optimize breakpoint to
-         a jump for reducing its overhead.
 
 config HAVE_EFFICIENT_UNALIGNED_ACCESS
        bool
@@ -142,6 +137,17 @@ config HAVE_HW_BREAKPOINT
        bool
        depends on PERF_EVENTS
 
+config HAVE_MIXED_BREAKPOINTS_REGS
+       bool
+       depends on HAVE_HW_BREAKPOINT
+       help
+         Depending on the arch implementation of hardware breakpoints,
+         some of them have separate registers for data and instruction
+         breakpoints addresses, others have mixed registers to store
+         them but define the access type in a control register.
+         Select this option if your arch implements breakpoints under the
+         latter fashion.
+
 config HAVE_USER_RETURN_NOTIFIER
        bool
 
index 75291fd..b719398 100644 (file)
@@ -55,6 +55,9 @@ config ARCH_USES_GETTIMEOFFSET
        bool
        default y
 
+config GENERIC_CMOS_UPDATE
+        def_bool y
+
 config ZONE_DMA
        bool
        default y
index 610dff4..e756d04 100644 (file)
@@ -17,8 +17,8 @@
 #define ATOMIC_INIT(i)         ( (atomic_t) { (i) } )
 #define ATOMIC64_INIT(i)       ( (atomic64_t) { (i) } )
 
-#define atomic_read(v)         ((v)->counter + 0)
-#define atomic64_read(v)       ((v)->counter + 0)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 #define atomic_set(v,i)                ((v)->counter = (i))
 #define atomic64_set(v,i)      ((v)->counter = (i))
index 15f3ae2..296da1d 100644 (file)
@@ -405,29 +405,31 @@ static inline int fls(int x)
 
 #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
 /* Whee.  EV67 can calculate it directly.  */
-static inline unsigned long hweight64(unsigned long w)
+static inline unsigned long __arch_hweight64(unsigned long w)
 {
        return __kernel_ctpop(w);
 }
 
-static inline unsigned int hweight32(unsigned int w)
+static inline unsigned int __arch_weight32(unsigned int w)
 {
-       return hweight64(w);
+       return __arch_hweight64(w);
 }
 
-static inline unsigned int hweight16(unsigned int w)
+static inline unsigned int __arch_hweight16(unsigned int w)
 {
-       return hweight64(w & 0xffff);
+       return __arch_hweight64(w & 0xffff);
 }
 
-static inline unsigned int hweight8(unsigned int w)
+static inline unsigned int __arch_hweight8(unsigned int w)
 {
-       return hweight64(w & 0xff);
+       return __arch_hweight64(w & 0xff);
 }
 #else
-#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/arch_hweight.h>
 #endif
 
+#include <asm-generic/bitops/const_hweight.h>
+
 #endif /* __KERNEL__ */
 
 #include <asm-generic/bitops/find.h>
index 5d08266..5465e93 100644 (file)
@@ -75,8 +75,6 @@ static struct {
        __u32 last_time;
        /* ticks/cycle * 2^48 */
        unsigned long scaled_ticks_per_cycle;
-       /* last time the CMOS clock got updated */
-       time_t last_rtc_update;
        /* partial unused tick */
        unsigned long partial_tick;
 } state;
@@ -91,6 +89,52 @@ static inline __u32 rpcc(void)
     return result;
 }
 
+int update_persistent_clock(struct timespec now)
+{
+       return set_rtc_mmss(now.tv_sec);
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+       unsigned int year, mon, day, hour, min, sec, epoch;
+
+       sec = CMOS_READ(RTC_SECONDS);
+       min = CMOS_READ(RTC_MINUTES);
+       hour = CMOS_READ(RTC_HOURS);
+       day = CMOS_READ(RTC_DAY_OF_MONTH);
+       mon = CMOS_READ(RTC_MONTH);
+       year = CMOS_READ(RTC_YEAR);
+
+       if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+               sec = bcd2bin(sec);
+               min = bcd2bin(min);
+               hour = bcd2bin(hour);
+               day = bcd2bin(day);
+               mon = bcd2bin(mon);
+               year = bcd2bin(year);
+       }
+
+       /* PC-like is standard; used for year >= 70 */
+       epoch = 1900;
+       if (year < 20)
+               epoch = 2000;
+       else if (year >= 20 && year < 48)
+               /* NT epoch */
+               epoch = 1980;
+       else if (year >= 48 && year < 70)
+               /* Digital UNIX epoch */
+               epoch = 1952;
+
+       printk(KERN_INFO "Using epoch = %d\n", epoch);
+
+       if ((year += epoch) < 1970)
+               year += 100;
+
+       ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+}
+
+
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
@@ -123,19 +167,6 @@ irqreturn_t timer_interrupt(int irq, void *dev)
        if (nticks)
                do_timer(nticks);
 
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        */
-       if (ntp_synced()
-           && xtime.tv_sec > state.last_rtc_update + 660
-           && xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2
-           && xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) {
-               int tmp = set_rtc_mmss(xtime.tv_sec);
-               state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0);
-       }
-
        write_sequnlock(&xtime_lock);
 
 #ifndef CONFIG_SMP
@@ -304,7 +335,7 @@ rpcc_after_update_in_progress(void)
 void __init
 time_init(void)
 {
-       unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch;
+       unsigned int cc1, cc2;
        unsigned long cycle_freq, tolerance;
        long diff;
 
@@ -348,43 +379,6 @@ time_init(void)
           bogomips yet, but this is close on a 500Mhz box.  */
        __delay(1000000);
 
-       sec = CMOS_READ(RTC_SECONDS);
-       min = CMOS_READ(RTC_MINUTES);
-       hour = CMOS_READ(RTC_HOURS);
-       day = CMOS_READ(RTC_DAY_OF_MONTH);
-       mon = CMOS_READ(RTC_MONTH);
-       year = CMOS_READ(RTC_YEAR);
-
-       if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               sec = bcd2bin(sec);
-               min = bcd2bin(min);
-               hour = bcd2bin(hour);
-               day = bcd2bin(day);
-               mon = bcd2bin(mon);
-               year = bcd2bin(year);
-       }
-
-       /* PC-like is standard; used for year >= 70 */
-       epoch = 1900;
-       if (year < 20)
-               epoch = 2000;
-       else if (year >= 20 && year < 48)
-               /* NT epoch */
-               epoch = 1980;
-       else if (year >= 48 && year < 70)
-               /* Digital UNIX epoch */
-               epoch = 1952;
-
-       printk(KERN_INFO "Using epoch = %d\n", epoch);
-
-       if ((year += epoch) < 1970)
-               year += 100;
-
-       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-       xtime.tv_nsec = 0;
-
-        wall_to_monotonic.tv_sec -= xtime.tv_sec;
-        wall_to_monotonic.tv_nsec = 0;
 
        if (HZ > (1<<16)) {
                extern void __you_loose (void);
@@ -394,7 +388,6 @@ time_init(void)
        state.last_time = cc1;
        state.scaled_ticks_per_cycle
                = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
-       state.last_rtc_update = 0;
        state.partial_tick = 0L;
 
        /* Startup the timer source. */
index c5408bf..2d70cec 100644 (file)
@@ -13,7 +13,7 @@ config ARM
        select RTC_LIB
        select SYS_SUPPORTS_APM_EMULATION
        select GENERIC_ATOMIC64 if (!CPU_32v6K)
-       select HAVE_OPROFILE
+       select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
        select HAVE_ARCH_KGDB
        select HAVE_KPROBES if (!XIP_KERNEL)
        select HAVE_KRETPROBES if (HAVE_KPROBES)
@@ -21,6 +21,7 @@ config ARM
        select HAVE_GENERIC_DMA_COHERENT
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZO
+       select HAVE_KERNEL_LZMA
        select HAVE_PERF_EVENTS
        select PERF_USE_VMALLOC
        help
@@ -42,6 +43,11 @@ config GENERIC_GPIO
 
 config GENERIC_TIME
        bool
+       default y
+
+config ARCH_USES_GETTIMEOFFSET
+       bool
+       default n
 
 config GENERIC_CLOCKEVENTS
        bool
@@ -175,28 +181,6 @@ config ARM_L1_CACHE_SHIFT_6
        help
          Setting ARM L1 cache line size to 64 Bytes.
 
-if OPROFILE
-
-config OPROFILE_ARMV6
-       def_bool y
-       depends on CPU_V6 && !SMP
-       select OPROFILE_ARM11_CORE
-
-config OPROFILE_MPCORE
-       def_bool y
-       depends on CPU_V6 && SMP
-       select OPROFILE_ARM11_CORE
-
-config OPROFILE_ARM11_CORE
-       bool
-
-config OPROFILE_ARMV7
-       def_bool y
-       depends on CPU_V7 && !SMP
-       bool
-
-endif
-
 config VECTORS_BASE
        hex
        default 0xffff0000 if MMU || CPU_HIGH_VECTOR
@@ -231,6 +215,7 @@ config ARCH_AAEC2000
        select CPU_ARM920T
        select ARM_AMBA
        select HAVE_CLK
+       select ARCH_USES_GETTIMEOFFSET
        help
          This enables support for systems based on the Agilent AAEC-2000
 
@@ -238,21 +223,23 @@ config ARCH_INTEGRATOR
        bool "ARM Ltd. Integrator family"
        select ARM_AMBA
        select ARCH_HAS_CPUFREQ
-       select HAVE_CLK
        select COMMON_CLKDEV
-       select ICST525
+       select ICST
+       select GENERIC_CLOCKEVENTS
+       select PLAT_VERSATILE
        help
          Support for ARM's Integrator platform.
 
 config ARCH_REALVIEW
        bool "ARM Ltd. RealView family"
        select ARM_AMBA
-       select HAVE_CLK
        select COMMON_CLKDEV
-       select ICST307
-       select GENERIC_TIME
+       select ICST
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
+       select PLAT_VERSATILE
+       select ARM_TIMER_SP804
+       select GPIO_PL061 if GPIOLIB
        help
          This enables support for ARM Ltd RealView boards.
 
@@ -260,20 +247,33 @@ config ARCH_VERSATILE
        bool "ARM Ltd. Versatile family"
        select ARM_AMBA
        select ARM_VIC
-       select HAVE_CLK
        select COMMON_CLKDEV
-       select ICST307
-       select GENERIC_TIME
+       select ICST
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
+       select PLAT_VERSATILE
+       select ARM_TIMER_SP804
        help
          This enables support for ARM Ltd Versatile board.
 
+config ARCH_VEXPRESS
+       bool "ARM Ltd. Versatile Express family"
+       select ARCH_WANT_OPTIONAL_GPIOLIB
+       select ARM_AMBA
+       select ARM_TIMER_SP804
+       select COMMON_CLKDEV
+       select GENERIC_CLOCKEVENTS
+       select HAVE_CLK
+       select ICST
+       select PLAT_VERSATILE
+       help
+         This enables support for the ARM Ltd Versatile Express boards.
+
 config ARCH_AT91
        bool "Atmel AT91"
-       select GENERIC_GPIO
        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.
@@ -284,7 +284,6 @@ config ARCH_BCMRING
        select CPU_V6
        select ARM_AMBA
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select ARCH_WANT_OPTIONAL_GPIOLIB
        help
@@ -293,14 +292,23 @@ config ARCH_BCMRING
 config ARCH_CLPS711X
        bool "Cirrus Logic CLPS711x/EP721x-based"
        select CPU_ARM720T
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for Cirrus Logic 711x/721x based boards.
 
+config ARCH_CNS3XXX
+       bool "Cavium Networks CNS3XXX family"
+       select CPU_V6
+       select GENERIC_CLOCKEVENTS
+       select ARM_GIC
+       help
+         Support for Cavium Networks CNS3XXX platform.
+
 config ARCH_GEMINI
        bool "Cortina Systems Gemini"
        select CPU_FA526
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for the Cortina Systems Gemini family SoCs
 
@@ -309,6 +317,7 @@ config ARCH_EBSA110
        select CPU_SA110
        select ISA
        select NO_IOPORT
+       select ARCH_USES_GETTIMEOFFSET
        help
          This is an evaluation board for the StrongARM processor available
          from Digital. It has limited hardware on-board, including an
@@ -320,11 +329,10 @@ config ARCH_EP93XX
        select CPU_ARM920T
        select ARM_AMBA
        select ARM_VIC
-       select GENERIC_GPIO
-       select HAVE_CLK
        select COMMON_CLKDEV
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_HAS_HOLES_MEMORYMODEL
+       select ARCH_USES_GETTIMEOFFSET
        help
          This enables support for the Cirrus EP93xx series of CPUs.
 
@@ -332,16 +340,15 @@ config ARCH_FOOTBRIDGE
        bool "FootBridge"
        select CPU_SA110
        select FOOTBRIDGE
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for systems based on the DC21285 companion chip
          ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
 config ARCH_MXC
        bool "Freescale MXC/iMX-based"
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select ARCH_REQUIRE_GPIOLIB
-       select HAVE_CLK
        select COMMON_CLKDEV
        help
          Support for Freescale MXC/iMX-based family of processors
@@ -349,12 +356,9 @@ config ARCH_MXC
 config ARCH_STMP3XXX
        bool "Freescale STMP3xxx"
        select CPU_ARM926T
-       select HAVE_CLK
        select COMMON_CLKDEV
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
-       select GENERIC_GPIO
        select USB_ARCH_HAS_EHCI
        help
          Support for systems based on the Freescale 3xxx CPUs.
@@ -364,7 +368,6 @@ config ARCH_NETX
        select CPU_ARM926T
        select ARM_VIC
        select GENERIC_CLOCKEVENTS
-       select GENERIC_TIME
        help
          This enables support for systems based on the Hilscher NetX Soc
 
@@ -372,6 +375,7 @@ config ARCH_H720X
        bool "Hynix HMS720x-based"
        select CPU_ARM720T
        select ISA_DMA_API
+       select ARCH_USES_GETTIMEOFFSET
        help
          This enables support for systems based on the Hynix HMS720x
 
@@ -392,7 +396,6 @@ config ARCH_IOP32X
        select CPU_XSCALE
        select PLAT_IOP
        select PCI
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
        help
          Support for Intel's 80219 and IOP32X (XScale) family of
@@ -404,7 +407,6 @@ config ARCH_IOP33X
        select CPU_XSCALE
        select PLAT_IOP
        select PCI
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
        help
          Support for Intel's IOP33X (XScale) family of processors.
@@ -414,6 +416,7 @@ config ARCH_IXP23XX
        depends on MMU
        select CPU_XSC3
        select PCI
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for Intel's IXP23xx (XScale) family of processors.
 
@@ -422,6 +425,7 @@ config ARCH_IXP2000
        depends on MMU
        select CPU_XSCALE
        select PCI
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for Intel's IXP2400/2800 (XScale) family of processors.
 
@@ -430,7 +434,6 @@ config ARCH_IXP4XX
        depends on MMU
        select CPU_XSCALE
        select GENERIC_GPIO
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select DMABOUNCE if PCI
        help
@@ -440,6 +443,7 @@ config ARCH_L7200
        bool "LinkUp-L7200"
        select CPU_ARM720T
        select FIQ
+       select ARCH_USES_GETTIMEOFFSET
        help
          Say Y here if you intend to run this kernel on a LinkUp Systems
          L7200 Software Development Board which uses an ARM720T processor.
@@ -453,9 +457,7 @@ config ARCH_L7200
 config ARCH_DOVE
        bool "Marvell Dove"
        select PCI
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select PLAT_ORION
        help
@@ -465,9 +467,7 @@ config ARCH_KIRKWOOD
        bool "Marvell Kirkwood"
        select CPU_FEROCEON
        select PCI
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select PLAT_ORION
        help
@@ -477,7 +477,6 @@ config ARCH_KIRKWOOD
 config ARCH_LOKI
        bool "Marvell Loki (88RC8480)"
        select CPU_FEROCEON
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select PLAT_ORION
        help
@@ -487,9 +486,7 @@ config ARCH_MV78XX0
        bool "Marvell MV78xx0"
        select CPU_FEROCEON
        select PCI
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select PLAT_ORION
        help
@@ -501,9 +498,7 @@ config ARCH_ORION5X
        depends on MMU
        select CPU_FEROCEON
        select PCI
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select PLAT_ORION
        help
@@ -514,11 +509,8 @@ config ARCH_ORION5X
 config ARCH_MMP
        bool "Marvell PXA168/910/MMP2"
        depends on MMU
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
-       select HAVE_CLK
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
        select PLAT_PXA
@@ -528,8 +520,8 @@ config ARCH_MMP
 config ARCH_KS8695
        bool "Micrel/Kendin KS8695"
        select CPU_ARM922T
-       select GENERIC_GPIO
-        select ARCH_REQUIRE_GPIOLIB
+       select ARCH_REQUIRE_GPIOLIB
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
          System-on-Chip devices.
@@ -538,7 +530,6 @@ config ARCH_NS9XXX
        bool "NetSilicon NS9xxx"
        select CPU_ARM926T
        select GENERIC_GPIO
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_CLK
        help
@@ -551,10 +542,7 @@ config ARCH_W90X900
        bool "Nuvoton W90X900 CPU"
        select CPU_ARM926T
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_GPIO
-       select HAVE_CLK
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        help
          Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -568,7 +556,6 @@ config ARCH_W90X900
 config ARCH_NUC93X
        bool "Nuvoton NUC93X CPU"
        select CPU_ARM926T
-       select HAVE_CLK
        select COMMON_CLKDEV
        help
          Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
@@ -577,8 +564,8 @@ config ARCH_NUC93X
 config ARCH_PNX4008
        bool "Philips Nexperia PNX4008 Mobile"
        select CPU_ARM926T
-       select HAVE_CLK
        select COMMON_CLKDEV
+       select ARCH_USES_GETTIMEOFFSET
        help
          This enables support for Philips PNX4008 mobile platform.
 
@@ -587,11 +574,8 @@ config ARCH_PXA
        depends on MMU
        select ARCH_MTD_XIP
        select ARCH_HAS_CPUFREQ
-       select GENERIC_GPIO
-       select HAVE_CLK
        select COMMON_CLKDEV
        select ARCH_REQUIRE_GPIOLIB
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
        select PLAT_PXA
@@ -600,14 +584,14 @@ config ARCH_PXA
 
 config ARCH_MSM
        bool "Qualcomm MSM"
-       select CPU_V6
-       select GENERIC_TIME
+       select HAVE_CLK
        select GENERIC_CLOCKEVENTS
        help
-         Support for Qualcomm MSM7K based systems.  This runs on the ARM11
-         apps processor of the MSM7K and depends on a shared memory
-         interface to the ARM9 modem processor which runs the baseband stack
-         and controls some vital subsystems (clock and power control, etc).
+         Support for Qualcomm MSM/QSD based systems.  This runs on the
+         apps processor of the MSM/QSD and depends on a shared memory
+         interface to the modem processor which runs the baseband
+         stack and controls some vital subsystems
+         (clock and power control, etc).
 
 config ARCH_SHMOBILE
        bool "Renesas SH-Mobile"
@@ -624,6 +608,7 @@ config ARCH_RPC
        select ISA_DMA_API
        select NO_IOPORT
        select ARCH_SPARSEMEM_ENABLE
+       select ARCH_USES_GETTIMEOFFSET
        help
          On the Acorn Risc-PC, Linux can support the internal IDE disk and
          CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -636,8 +621,6 @@ config ARCH_SA1100
        select ARCH_MTD_XIP
        select ARCH_HAS_CPUFREQ
        select CPU_FREQ
-       select GENERIC_GPIO
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_CLK
        select TICK_ONESHOT
@@ -646,23 +629,28 @@ config ARCH_SA1100
          Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
-       bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
+       bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
        select GENERIC_GPIO
        select ARCH_HAS_CPUFREQ
        select HAVE_CLK
+       select ARCH_USES_GETTIMEOFFSET
        help
          Samsung S3C2410X CPU based systems, such as the Simtec Electronics
          BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
          the Samsung SMDK2410 development board (and derivatives).
 
+         Note, the S3C2416 and the S3C2450 are so close that they even share
+         the same SoC ID code. This means that there is no seperate machine
+         directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
+
 config ARCH_S3C64XX
        bool "Samsung S3C64XX"
        select PLAT_SAMSUNG
        select CPU_V6
-       select GENERIC_GPIO
        select ARM_VIC
        select HAVE_CLK
        select NO_IOPORT
+       select ARCH_USES_GETTIMEOFFSET
        select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
        select SAMSUNG_CLKSRC
@@ -719,6 +707,7 @@ config ARCH_SHARK
        select ISA_DMA
        select ZONE_DMA
        select PCI
+       select ARCH_USES_GETTIMEOFFSET
        help
          Support for the StrongARM based Digital DNARD machine, also known
          as "Shark" (<http://www.shark-linux.de/shark.html>).
@@ -728,6 +717,7 @@ config ARCH_LH7A40X
        select CPU_ARM922T
        select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
        select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
+       select ARCH_USES_GETTIMEOFFSET
        help
          Say Y here for systems based on one of the Sharp LH7A40X
          System on a Chip processors.  These CPUs include an ARM922T
@@ -741,9 +731,7 @@ config ARCH_U300
        select HAVE_TCM
        select ARM_AMBA
        select ARM_VIC
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
-       select HAVE_CLK
        select COMMON_CLKDEV
        select GENERIC_GPIO
        help
@@ -753,9 +741,9 @@ config ARCH_U8500
        bool "ST-Ericsson U8500 Series"
        select CPU_V7
        select ARM_AMBA
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select COMMON_CLKDEV
+       select ARCH_REQUIRE_GPIOLIB
        help
          Support for ST-Ericsson's Ux500 architecture
 
@@ -764,23 +752,16 @@ config ARCH_NOMADIK
        select ARM_AMBA
        select ARM_VIC
        select CPU_ARM926T
-       select HAVE_CLK
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
        help
          Support for the Nomadik platform by ST-Ericsson
 
 config ARCH_DAVINCI
        bool "TI DaVinci"
-       select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
-       select GENERIC_GPIO
        select ARCH_REQUIRE_GPIOLIB
-       select HAVE_CLK
        select ZONE_DMA
        select HAVE_IDE
        select COMMON_CLKDEV
@@ -791,16 +772,24 @@ config ARCH_DAVINCI
 
 config ARCH_OMAP
        bool "TI OMAP"
-       select GENERIC_GPIO
        select HAVE_CLK
        select ARCH_REQUIRE_GPIOLIB
        select ARCH_HAS_CPUFREQ
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select ARCH_HAS_HOLES_MEMORYMODEL
        help
          Support for TI's OMAP platform (OMAP1 and OMAP2).
 
+config PLAT_SPEAR
+       bool "ST SPEAr"
+       select ARM_AMBA
+       select ARCH_REQUIRE_GPIOLIB
+       select COMMON_CLKDEV
+       select GENERIC_CLOCKEVENTS
+       select HAVE_CLK
+       help
+         Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
+
 endchoice
 
 #
@@ -816,6 +805,8 @@ source "arch/arm/mach-bcmring/Kconfig"
 
 source "arch/arm/mach-clps711x/Kconfig"
 
+source "arch/arm/mach-cns3xxx/Kconfig"
+
 source "arch/arm/mach-davinci/Kconfig"
 
 source "arch/arm/mach-dove/Kconfig"
@@ -886,11 +877,13 @@ source "arch/arm/plat-samsung/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
 source "arch/arm/plat-s5p/Kconfig"
 source "arch/arm/plat-s5pc1xx/Kconfig"
+source "arch/arm/plat-spear/Kconfig"
 
 if ARCH_S3C2410
 source "arch/arm/mach-s3c2400/Kconfig"
 source "arch/arm/mach-s3c2410/Kconfig"
 source "arch/arm/mach-s3c2412/Kconfig"
+source "arch/arm/mach-s3c2416/Kconfig"
 source "arch/arm/mach-s3c2440/Kconfig"
 source "arch/arm/mach-s3c2443/Kconfig"
 endif
@@ -919,6 +912,8 @@ source "arch/arm/mach-ux500/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
+source "arch/arm/mach-vexpress/Kconfig"
+
 source "arch/arm/mach-w90x900/Kconfig"
 
 # Definitions to make life easier
@@ -928,7 +923,6 @@ config ARCH_ACORN
 config PLAT_IOP
        bool
        select GENERIC_CLOCKEVENTS
-       select GENERIC_TIME
 
 config PLAT_ORION
        bool
@@ -936,6 +930,12 @@ config PLAT_ORION
 config PLAT_PXA
        bool
 
+config PLAT_VERSATILE
+       bool
+
+config ARM_TIMER_SP804
+       bool
+
 source arch/arm/mm/Kconfig
 
 config IWMMXT
@@ -1064,6 +1064,10 @@ config PCI
          your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
          VESA. If you have PCI, say Y, otherwise N.
 
+config PCI_DOMAINS
+       bool
+       depends on PCI
+
 config PCI_SYSCALL
        def_bool PCI
 
@@ -1092,10 +1096,11 @@ source "kernel/time/Kconfig"
 config SMP
        bool "Symmetric Multi-Processing (EXPERIMENTAL)"
        depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
-                MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
+                MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
+                ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
        depends on GENERIC_CLOCKEVENTS
        select USE_GENERIC_SMP_HELPERS
-       select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
+       select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
        help
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
@@ -1276,7 +1281,7 @@ config HIGHPTE
 
 config HW_PERF_EVENTS
        bool "Enable hardware performance counter support for perf events"
-       depends on PERF_EVENTS && CPU_HAS_PMU && (CPU_V6 || CPU_V7)
+       depends on PERF_EVENTS && CPU_HAS_PMU
        default y
        help
          Enable hardware performance counter support for perf events. If
index ed820e7..4b857fb 100644 (file)
@@ -110,6 +110,8 @@ CHECKFLAGS  += -D__arm__
 head-y         := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
 textofs-y      := 0x00008000
 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
+# We don't want the htc bootloader to corrupt kernel during resume
+textofs-$(CONFIG_PM_H1940)      := 0x00108000
 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
 ifeq ($(CONFIG_ARCH_SA1100),y)
 textofs-$(CONFIG_SA1111) := 0x00208000
@@ -121,6 +123,7 @@ machine-$(CONFIG_ARCH_AAEC2000)             := aaec2000
 machine-$(CONFIG_ARCH_AT91)            := at91
 machine-$(CONFIG_ARCH_BCMRING)         := bcmring
 machine-$(CONFIG_ARCH_CLPS711X)                := clps711x
+machine-$(CONFIG_ARCH_CNS3XXX)         := cns3xxx
 machine-$(CONFIG_ARCH_DAVINCI)         := davinci
 machine-$(CONFIG_ARCH_DOVE)            := dove
 machine-$(CONFIG_ARCH_EBSA110)         := ebsa110
@@ -160,7 +163,7 @@ machine-$(CONFIG_ARCH_PNX4008)              := pnx4008
 machine-$(CONFIG_ARCH_PXA)             := pxa
 machine-$(CONFIG_ARCH_REALVIEW)                := realview
 machine-$(CONFIG_ARCH_RPC)             := rpc
-machine-$(CONFIG_ARCH_S3C2410)         := s3c2410 s3c2400 s3c2412 s3c2440 s3c2443
+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
@@ -175,9 +178,14 @@ machine-$(CONFIG_ARCH_STMP37XX)            := stmp37xx
 machine-$(CONFIG_ARCH_U300)            := u300
 machine-$(CONFIG_ARCH_U8500)           := ux500
 machine-$(CONFIG_ARCH_VERSATILE)       := versatile
+machine-$(CONFIG_ARCH_VEXPRESS)                := vexpress
 machine-$(CONFIG_ARCH_W90X900)         := w90x900
 machine-$(CONFIG_ARCH_NUC93X)          := nuc93x
 machine-$(CONFIG_FOOTBRIDGE)           := footbridge
+machine-$(CONFIG_MACH_SPEAR300)                := spear3xx
+machine-$(CONFIG_MACH_SPEAR310)                := spear3xx
+machine-$(CONFIG_MACH_SPEAR320)                := spear3xx
+machine-$(CONFIG_MACH_SPEAR600)                := spear6xx
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -192,6 +200,8 @@ plat-$(CONFIG_PLAT_PXA)             := pxa
 plat-$(CONFIG_PLAT_S3C24XX)    := s3c24xx samsung
 plat-$(CONFIG_PLAT_S5PC1XX)    := s5pc1xx samsung
 plat-$(CONFIG_PLAT_S5P)                := s5p samsung
+plat-$(CONFIG_PLAT_SPEAR)      := spear
+plat-$(CONFIG_PLAT_VERSATILE)  := versatile
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
index 97c89e7..53faa90 100644 (file)
@@ -65,6 +65,7 @@ SEDFLAGS      = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
 
 suffix_$(CONFIG_KERNEL_GZIP) = gzip
 suffix_$(CONFIG_KERNEL_LZO)  = lzo
+suffix_$(CONFIG_KERNEL_LZMA) = lzma
 
 targets       := vmlinux vmlinux.lds \
                 piggy.$(suffix_y) piggy.$(suffix_y).o \
index 9c09707..4c72a97 100644 (file)
@@ -40,6 +40,10 @@ extern void error(char *);
 #include "../../../../lib/decompress_unlzo.c"
 #endif
 
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
 void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
 {
        decompress(input, len, NULL, NULL, output, NULL, error);
index 0f23009..c5191b1 100644 (file)
@@ -172,7 +172,7 @@ not_angel:
                adr     r0, LC0
  ARM(          ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
  THUMB(                ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip}   )
- THUMB(                ldr     sp, [r0, #28]                           )
+ THUMB(                ldr     sp, [r0, #32]                           )
                subs    r0, r0, r1              @ calculate the delta offset
 
                                                @ if delta is zero, we are
@@ -685,8 +685,8 @@ proc_types:
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv4_mmu_cache_flush
 
-               .word   0x56056930
-               .word   0xff0ffff0              @ PXA935
+               .word   0x56056900
+               .word   0xffffff00              @ PXA9xx
                W(b)    __armv4_mmu_cache_on
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv4_mmu_cache_flush
@@ -697,12 +697,6 @@ proc_types:
                W(b)    __armv4_mmu_cache_off
                W(b)    __armv5tej_mmu_cache_flush
 
-               .word   0x56056930
-               .word   0xff0ffff0              @ PXA935
-               W(b)    __armv4_mmu_cache_on
-               W(b)    __armv4_mmu_cache_off
-               W(b)    __armv4_mmu_cache_flush
-
                .word   0x56050000              @ Feroceon
                .word   0xff0f0000
                W(b)    __armv4_mmu_cache_on
diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S
new file mode 100644 (file)
index 0000000..d7e69cf
--- /dev/null
@@ -0,0 +1,6 @@
+       .section .piggydata,#alloc
+       .globl  input_data
+input_data:
+       .incbin "arch/arm/boot/compressed/piggy.lzma"
+       .globl  input_data_end
+input_data_end:
index 4efbb9d..0a34c81 100644 (file)
@@ -12,10 +12,10 @@ config ARM_VIC_NR
          The maximum number of VICs available in the system, for
          power management.
 
-config ICST525
+config ICST
        bool
 
-config ICST307
+config PL330
        bool
 
 config SA1111
@@ -40,3 +40,4 @@ config SHARP_SCOOP
 
 config COMMON_CLKDEV
        bool
+       select HAVE_CLK
index 76be7ff..e6e8664 100644 (file)
@@ -4,8 +4,8 @@
 
 obj-$(CONFIG_ARM_GIC)          += gic.o
 obj-$(CONFIG_ARM_VIC)          += vic.o
-obj-$(CONFIG_ICST525)          += icst525.o
-obj-$(CONFIG_ICST307)          += icst307.o
+obj-$(CONFIG_ICST)             += icst.o
+obj-$(CONFIG_PL330)            += pl330.o
 obj-$(CONFIG_SA1111)           += sa1111.o
 obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
 obj-$(CONFIG_DMABOUNCE)                += dmabounce.o
index dba4c1d..e2b2bb6 100644 (file)
@@ -53,12 +53,13 @@ static struct clk *clk_find(const char *dev_id, const char *con_id)
                                continue;
                        match += 1;
                }
-               if (match == 0)
-                       continue;
 
                if (match > best) {
                        clk = p->clk;
-                       best = match;
+                       if (match != 3)
+                               best = match;
+                       else
+                               break;
                }
        }
        return clk;
diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c
new file mode 100644 (file)
index 0000000..9a7f09c
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ *  linux/arch/arm/common/icst307.c
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 as
+ * published by the Free Software Foundation.
+ *
+ *  Support functions for calculating clocks/divisors for the ICST307
+ *  clock generators.  See http://www.icst.com/ for more information
+ *  on these devices.
+ *
+ *  This is an almost identical implementation to the ICST525 clock generator.
+ *  The s2div and idx2s files are different
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware/icst.h>
+
+/*
+ * Divisors for each OD setting.
+ */
+const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
+const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
+EXPORT_SYMBOL(icst307_s2div);
+EXPORT_SYMBOL(icst525_s2div);
+
+unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
+{
+       return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]);
+}
+
+EXPORT_SYMBOL(icst_hz);
+
+/*
+ * Ascending divisor S values.
+ */
+const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
+const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 };
+EXPORT_SYMBOL(icst307_idx2s);
+EXPORT_SYMBOL(icst525_idx2s);
+
+struct icst_vco
+icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
+{
+       struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
+       unsigned long f;
+       unsigned int i = 0, rd, best = (unsigned int)-1;
+
+       /*
+        * First, find the PLL output divisor such
+        * that the PLL output is within spec.
+        */
+       do {
+               f = freq * p->s2div[p->idx2s[i]];
+
+               if (f > p->vco_min && f <= p->vco_max)
+                       break;
+       } while (i < 8);
+
+       if (i >= 8)
+               return vco;
+
+       vco.s = p->idx2s[i];
+
+       /*
+        * Now find the closest divisor combination
+        * which gives a PLL output of 'f'.
+        */
+       for (rd = p->rd_min; rd <= p->rd_max; rd++) {
+               unsigned long fref_div, f_pll;
+               unsigned int vd;
+               int f_diff;
+
+               fref_div = (2 * p->ref) / rd;
+
+               vd = (f + fref_div / 2) / fref_div;
+               if (vd < p->vd_min || vd > p->vd_max)
+                       continue;
+
+               f_pll = fref_div * vd;
+               f_diff = f_pll - f;
+               if (f_diff < 0)
+                       f_diff = -f_diff;
+
+               if ((unsigned)f_diff < best) {
+                       vco.v = vd - 8;
+                       vco.r = rd - 2;
+                       if (f_diff == 0)
+                               break;
+                       best = f_diff;
+               }
+       }
+
+       return vco;
+}
+
+EXPORT_SYMBOL(icst_hz_to_vco);
diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c
deleted file mode 100644 (file)
index 6d094c1..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  linux/arch/arm/common/icst307.c
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 as
- * published by the Free Software Foundation.
- *
- *  Support functions for calculating clocks/divisors for the ICST307
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- *
- *  This is an almost identical implementation to the ICST525 clock generator.
- *  The s2div and idx2s files are different
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include <asm/hardware/icst307.h>
-
-/*
- * Divisors for each OD setting.
- */
-static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
-
-unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco)
-{
-       return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]);
-}
-
-EXPORT_SYMBOL(icst307_khz);
-
-/*
- * Ascending divisor S values.
- */
-static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
-
-struct icst307_vco
-icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq)
-{
-       struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-       unsigned long f;
-       unsigned int i = 0, rd, best = (unsigned int)-1;
-
-       /*
-        * First, find the PLL output divisor such
-        * that the PLL output is within spec.
-        */
-       do {
-               f = freq * s2div[idx2s[i]];
-
-               /*
-                * f must be between 6MHz and 200MHz (3.3 or 5V)
-                */
-               if (f > 6000 && f <= p->vco_max)
-                       break;
-       } while (i < ARRAY_SIZE(idx2s));
-
-       if (i >= ARRAY_SIZE(idx2s))
-               return vco;
-
-       vco.s = idx2s[i];
-
-       /*
-        * Now find the closest divisor combination
-        * which gives a PLL output of 'f'.
-        */
-       for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-               unsigned long fref_div, f_pll;
-               unsigned int vd;
-               int f_diff;
-
-               fref_div = (2 * p->ref) / rd;
-
-               vd = (f + fref_div / 2) / fref_div;
-               if (vd < p->vd_min || vd > p->vd_max)
-                       continue;
-
-               f_pll = fref_div * vd;
-               f_diff = f_pll - f;
-               if (f_diff < 0)
-                       f_diff = -f_diff;
-
-               if ((unsigned)f_diff < best) {
-                       vco.v = vd - 8;
-                       vco.r = rd - 2;
-                       if (f_diff == 0)
-                               break;
-                       best = f_diff;
-               }
-       }
-
-       return vco;
-}
-
-EXPORT_SYMBOL(icst307_khz_to_vco);
-
-struct icst307_vco
-icst307_ps_to_vco(const struct icst307_params *p, unsigned long period)
-{
-       struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-       unsigned long f, ps;
-       unsigned int i = 0, rd, best = (unsigned int)-1;
-
-       ps = 1000000000UL / p->vco_max;
-
-       /*
-        * First, find the PLL output divisor such
-        * that the PLL output is within spec.
-        */
-       do {
-               f = period / s2div[idx2s[i]];
-
-               /*
-                * f must be between 6MHz and 200MHz (3.3 or 5V)
-                */
-               if (f >= ps && f < 1000000000UL / 6000 + 1)
-                       break;
-       } while (i < ARRAY_SIZE(idx2s));
-
-       if (i >= ARRAY_SIZE(idx2s))
-               return vco;
-
-       vco.s = idx2s[i];
-
-       ps = 500000000UL / p->ref;
-
-       /*
-        * Now find the closest divisor combination
-        * which gives a PLL output of 'f'.
-        */
-       for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-               unsigned long f_in_div, f_pll;
-               unsigned int vd;
-               int f_diff;
-
-               f_in_div = ps * rd;
-
-               vd = (f_in_div + f / 2) / f;
-               if (vd < p->vd_min || vd > p->vd_max)
-                       continue;
-
-               f_pll = (f_in_div + vd / 2) / vd;
-               f_diff = f_pll - f;
-               if (f_diff < 0)
-                       f_diff = -f_diff;
-
-               if ((unsigned)f_diff < best) {
-                       vco.v = vd - 8;
-                       vco.r = rd - 2;
-                       if (f_diff == 0)
-                               break;
-                       best = f_diff;
-               }
-       }
-
-       return vco;
-}
-
-EXPORT_SYMBOL(icst307_ps_to_vco);
diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c
deleted file mode 100644 (file)
index 3d377c5..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *  linux/arch/arm/common/icst525.c
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 as
- * published by the Free Software Foundation.
- *
- *  Support functions for calculating clocks/divisors for the ICST525
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include <asm/hardware/icst525.h>
-
-/*
- * Divisors for each OD setting.
- */
-static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
-
-unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco)
-{
-       return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]);
-}
-
-EXPORT_SYMBOL(icst525_khz);
-
-/*
- * Ascending divisor S values.
- */
-static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
-
-struct icst525_vco
-icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq)
-{
-       struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-       unsigned long f;
-       unsigned int i = 0, rd, best = (unsigned int)-1;
-
-       /*
-        * First, find the PLL output divisor such
-        * that the PLL output is within spec.
-        */
-       do {
-               f = freq * s2div[idx2s[i]];
-
-               /*
-                * f must be between 10MHz and
-                *  320MHz (5V) or 200MHz (3V)
-                */
-               if (f > 10000 && f <= p->vco_max)
-                       break;
-       } while (i < ARRAY_SIZE(idx2s));
-
-       if (i >= ARRAY_SIZE(idx2s))
-               return vco;
-
-       vco.s = idx2s[i];
-
-       /*
-        * Now find the closest divisor combination
-        * which gives a PLL output of 'f'.
-        */
-       for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-               unsigned long fref_div, f_pll;
-               unsigned int vd;
-               int f_diff;
-
-               fref_div = (2 * p->ref) / rd;
-
-               vd = (f + fref_div / 2) / fref_div;
-               if (vd < p->vd_min || vd > p->vd_max)
-                       continue;
-
-               f_pll = fref_div * vd;
-               f_diff = f_pll - f;
-               if (f_diff < 0)
-                       f_diff = -f_diff;
-
-               if ((unsigned)f_diff < best) {
-                       vco.v = vd - 8;
-                       vco.r = rd - 2;
-                       if (f_diff == 0)
-                               break;
-                       best = f_diff;
-               }
-       }
-
-       return vco;
-}
-
-EXPORT_SYMBOL(icst525_khz_to_vco);
-
-struct icst525_vco
-icst525_ps_to_vco(const struct icst525_params *p, unsigned long period)
-{
-       struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
-       unsigned long f, ps;
-       unsigned int i = 0, rd, best = (unsigned int)-1;
-
-       ps = 1000000000UL / p->vco_max;
-
-       /*
-        * First, find the PLL output divisor such
-        * that the PLL output is within spec.
-        */
-       do {
-               f = period / s2div[idx2s[i]];
-
-               /*
-                * f must be between 10MHz and
-                *  320MHz (5V) or 200MHz (3V)
-                */
-               if (f >= ps && f < 100000)
-                       break;
-       } while (i < ARRAY_SIZE(idx2s));
-
-       if (i >= ARRAY_SIZE(idx2s))
-               return vco;
-
-       vco.s = idx2s[i];
-
-       ps = 500000000UL / p->ref;
-
-       /*
-        * Now find the closest divisor combination
-        * which gives a PLL output of 'f'.
-        */
-       for (rd = p->rd_min; rd <= p->rd_max; rd++) {
-               unsigned long f_in_div, f_pll;
-               unsigned int vd;
-               int f_diff;
-
-               f_in_div = ps * rd;
-
-               vd = (f_in_div + f / 2) / f;
-               if (vd < p->vd_min || vd > p->vd_max)
-                       continue;
-
-               f_pll = (f_in_div + vd / 2) / vd;
-               f_diff = f_pll - f;
-               if (f_diff < 0)
-                       f_diff = -f_diff;
-
-               if ((unsigned)f_diff < best) {
-                       vco.v = vd - 8;
-                       vco.r = rd - 2;
-                       if (f_diff == 0)
-                               break;
-                       best = f_diff;
-               }
-       }
-
-       return vco;
-}
-
-EXPORT_SYMBOL(icst525_ps_to_vco);
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
new file mode 100644 (file)
index 0000000..5ebbab6
--- /dev/null
@@ -0,0 +1,1966 @@
+/* linux/arch/arm/common/pl330.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware/pl330.h>
+
+/* Register and Bit field Definitions */
+#define DS             0x0
+#define DS_ST_STOP     0x0
+#define DS_ST_EXEC     0x1
+#define DS_ST_CMISS    0x2
+#define DS_ST_UPDTPC   0x3
+#define DS_ST_WFE      0x4
+#define DS_ST_ATBRR    0x5
+#define DS_ST_QBUSY    0x6
+#define DS_ST_WFP      0x7
+#define DS_ST_KILL     0x8
+#define DS_ST_CMPLT    0x9
+#define DS_ST_FLTCMP   0xe
+#define DS_ST_FAULT    0xf
+
+#define DPC            0x4
+#define INTEN          0x20
+#define ES             0x24
+#define INTSTATUS      0x28
+#define INTCLR         0x2c
+#define FSM            0x30
+#define FSC            0x34
+#define FTM            0x38
+
+#define _FTC           0x40
+#define FTC(n)         (_FTC + (n)*0x4)
+
+#define _CS            0x100
+#define CS(n)          (_CS + (n)*0x8)
+#define CS_CNS         (1 << 21)
+
+#define _CPC           0x104
+#define CPC(n)         (_CPC + (n)*0x8)
+
+#define _SA            0x400
+#define SA(n)          (_SA + (n)*0x20)
+
+#define _DA            0x404
+#define DA(n)          (_DA + (n)*0x20)
+
+#define _CC            0x408
+#define CC(n)          (_CC + (n)*0x20)
+
+#define CC_SRCINC      (1 << 0)
+#define CC_DSTINC      (1 << 14)
+#define CC_SRCPRI      (1 << 8)
+#define CC_DSTPRI      (1 << 22)
+#define CC_SRCNS       (1 << 9)
+#define CC_DSTNS       (1 << 23)
+#define CC_SRCIA       (1 << 10)
+#define CC_DSTIA       (1 << 24)
+#define CC_SRCBRSTLEN_SHFT     4
+#define CC_DSTBRSTLEN_SHFT     18
+#define CC_SRCBRSTSIZE_SHFT    1
+#define CC_DSTBRSTSIZE_SHFT    15
+#define CC_SRCCCTRL_SHFT       11
+#define CC_SRCCCTRL_MASK       0x7
+#define CC_DSTCCTRL_SHFT       25
+#define CC_DRCCCTRL_MASK       0x7
+#define CC_SWAP_SHFT   28
+
+#define _LC0           0x40c
+#define LC0(n)         (_LC0 + (n)*0x20)
+
+#define _LC1           0x410
+#define LC1(n)         (_LC1 + (n)*0x20)
+
+#define DBGSTATUS      0xd00
+#define DBG_BUSY       (1 << 0)
+
+#define DBGCMD         0xd04
+#define DBGINST0       0xd08
+#define DBGINST1       0xd0c
+
+#define CR0            0xe00
+#define CR1            0xe04
+#define CR2            0xe08
+#define CR3            0xe0c
+#define CR4            0xe10
+#define CRD            0xe14
+
+#define PERIPH_ID      0xfe0
+#define PCELL_ID       0xff0
+
+#define CR0_PERIPH_REQ_SET     (1 << 0)
+#define CR0_BOOT_EN_SET                (1 << 1)
+#define CR0_BOOT_MAN_NS                (1 << 2)
+#define CR0_NUM_CHANS_SHIFT    4
+#define CR0_NUM_CHANS_MASK     0x7
+#define CR0_NUM_PERIPH_SHIFT   12
+#define CR0_NUM_PERIPH_MASK    0x1f
+#define CR0_NUM_EVENTS_SHIFT   17
+#define CR0_NUM_EVENTS_MASK    0x1f
+
+#define CR1_ICACHE_LEN_SHIFT   0
+#define CR1_ICACHE_LEN_MASK    0x7
+#define CR1_NUM_ICACHELINES_SHIFT      4
+#define CR1_NUM_ICACHELINES_MASK       0xf
+
+#define CRD_DATA_WIDTH_SHIFT   0
+#define CRD_DATA_WIDTH_MASK    0x7
+#define CRD_WR_CAP_SHIFT       4
+#define CRD_WR_CAP_MASK                0x7
+#define CRD_WR_Q_DEP_SHIFT     8
+#define CRD_WR_Q_DEP_MASK      0xf
+#define CRD_RD_CAP_SHIFT       12
+#define CRD_RD_CAP_MASK                0x7
+#define CRD_RD_Q_DEP_SHIFT     16
+#define CRD_RD_Q_DEP_MASK      0xf
+#define CRD_DATA_BUFF_SHIFT    20
+#define CRD_DATA_BUFF_MASK     0x3ff
+
+#define        PART            0x330
+#define DESIGNER       0x41
+#define REVISION       0x0
+#define INTEG_CFG      0x0
+#define PERIPH_ID_VAL  ((PART << 0) | (DESIGNER << 12) \
+                         | (REVISION << 20) | (INTEG_CFG << 24))
+
+#define PCELL_ID_VAL   0xb105f00d
+
+#define PL330_STATE_STOPPED            (1 << 0)
+#define PL330_STATE_EXECUTING          (1 << 1)
+#define PL330_STATE_WFE                        (1 << 2)
+#define PL330_STATE_FAULTING           (1 << 3)
+#define PL330_STATE_COMPLETING         (1 << 4)
+#define PL330_STATE_WFP                        (1 << 5)
+#define PL330_STATE_KILLING            (1 << 6)
+#define PL330_STATE_FAULT_COMPLETING   (1 << 7)
+#define PL330_STATE_CACHEMISS          (1 << 8)
+#define PL330_STATE_UPDTPC             (1 << 9)
+#define PL330_STATE_ATBARRIER          (1 << 10)
+#define PL330_STATE_QUEUEBUSY          (1 << 11)
+#define PL330_STATE_INVALID            (1 << 15)
+
+#define PL330_STABLE_STATES (PL330_STATE_STOPPED | PL330_STATE_EXECUTING \
+                               | PL330_STATE_WFE | PL330_STATE_FAULTING)
+
+#define CMD_DMAADDH    0x54
+#define CMD_DMAEND     0x00
+#define CMD_DMAFLUSHP  0x35
+#define CMD_DMAGO      0xa0
+#define CMD_DMALD      0x04
+#define CMD_DMALDP     0x25
+#define CMD_DMALP      0x20
+#define CMD_DMALPEND   0x28
+#define CMD_DMAKILL    0x01
+#define CMD_DMAMOV     0xbc
+#define CMD_DMANOP     0x18
+#define CMD_DMARMB     0x12
+#define CMD_DMASEV     0x34
+#define CMD_DMAST      0x08
+#define CMD_DMASTP     0x29
+#define CMD_DMASTZ     0x0c
+#define CMD_DMAWFE     0x36
+#define CMD_DMAWFP     0x30
+#define CMD_DMAWMB     0x13
+
+#define SZ_DMAADDH     3
+#define SZ_DMAEND      1
+#define SZ_DMAFLUSHP   2
+#define SZ_DMALD       1
+#define SZ_DMALDP      2
+#define SZ_DMALP       2
+#define SZ_DMALPEND    2
+#define SZ_DMAKILL     1
+#define SZ_DMAMOV      6
+#define SZ_DMANOP      1
+#define SZ_DMARMB      1
+#define SZ_DMASEV      2
+#define SZ_DMAST       1
+#define SZ_DMASTP      2
+#define SZ_DMASTZ      1
+#define SZ_DMAWFE      2
+#define SZ_DMAWFP      2
+#define SZ_DMAWMB      1
+#define SZ_DMAGO       6
+
+#define BRST_LEN(ccr)  ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1)
+#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7))
+
+#define BYTE_TO_BURST(b, ccr)  ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr))
+#define BURST_TO_BYTE(c, ccr)  ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr))
+
+/*
+ * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req
+ * at 1byte/burst for P<->M and M<->M respectively.
+ * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req
+ * should be enough for P<->M and M<->M respectively.
+ */
+#define MCODE_BUFF_PER_REQ     256
+
+/*
+ * Mark a _pl330_req as free.
+ * We do it by writing DMAEND as the first instruction
+ * because no valid request is going to have DMAEND as
+ * its first instruction to execute.
+ */
+#define MARK_FREE(req) do { \
+                               _emit_END(0, (req)->mc_cpu); \
+                               (req)->mc_len = 0; \
+                       } while (0)
+
+/* If the _pl330_req is available to the client */
+#define IS_FREE(req)   (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND)
+
+/* Use this _only_ to wait on transient states */
+#define UNTIL(t, s)    while (!(_state(t) & (s))) cpu_relax();
+
+#ifdef PL330_DEBUG_MCGEN
+static unsigned cmd_line;
+#define PL330_DBGCMD_DUMP(off, x...)   do { \
+                                               printk("%x:", cmd_line); \
+                                               printk(x); \
+                                               cmd_line += off; \
+                                       } while (0)
+#define PL330_DBGMC_START(addr)                (cmd_line = addr)
+#else
+#define PL330_DBGCMD_DUMP(off, x...)   do {} while (0)
+#define PL330_DBGMC_START(addr)                do {} while (0)
+#endif
+
+struct _xfer_spec {
+       u32 ccr;
+       struct pl330_req *r;
+       struct pl330_xfer *x;
+};
+
+enum dmamov_dst {
+       SAR = 0,
+       CCR,
+       DAR,
+};
+
+enum pl330_dst {
+       SRC = 0,
+       DST,
+};
+
+enum pl330_cond {
+       SINGLE,
+       BURST,
+       ALWAYS,
+};
+
+struct _pl330_req {
+       u32 mc_bus;
+       void *mc_cpu;
+       /* Number of bytes taken to setup MC for the req */
+       u32 mc_len;
+       struct pl330_req *r;
+       /* Hook to attach to DMAC's list of reqs with due callback */
+       struct list_head rqd;
+};
+
+/* ToBeDone for tasklet */
+struct _pl330_tbd {
+       bool reset_dmac;
+       bool reset_mngr;
+       u8 reset_chan;
+};
+
+/* A DMAC Thread */
+struct pl330_thread {
+       u8 id;
+       int ev;
+       /* If the channel is not yet acquired by any client */
+       bool free;
+       /* Parent DMAC */
+       struct pl330_dmac *dmac;
+       /* Only two at a time */
+       struct _pl330_req req[2];
+       /* Index of the last submitted request */
+       unsigned lstenq;
+};
+
+enum pl330_dmac_state {
+       UNINIT,
+       INIT,
+       DYING,
+};
+
+/* A DMAC */
+struct pl330_dmac {
+       spinlock_t              lock;
+       /* Holds list of reqs with due callbacks */
+       struct list_head        req_done;
+       /* Pointer to platform specific stuff */
+       struct pl330_info       *pinfo;
+       /* Maximum possible events/irqs */
+       int                     events[32];
+       /* BUS address of MicroCode buffer */
+       u32                     mcode_bus;
+       /* CPU address of MicroCode buffer */
+       void                    *mcode_cpu;
+       /* List of all Channel threads */
+       struct pl330_thread     *channels;
+       /* Pointer to the MANAGER thread */
+       struct pl330_thread     *manager;
+       /* To handle bad news in interrupt */
+       struct tasklet_struct   tasks;
+       struct _pl330_tbd       dmac_tbd;
+       /* State of DMAC operation */
+       enum pl330_dmac_state   state;
+};
+
+static inline void _callback(struct pl330_req *r, enum pl330_op_err err)
+{
+       if (r && r->xfer_cb)
+               r->xfer_cb(r->token, err);
+}
+
+static inline bool _queue_empty(struct pl330_thread *thrd)
+{
+       return (IS_FREE(&thrd->req[0]) && IS_FREE(&thrd->req[1]))
+               ? true : false;
+}
+
+static inline bool _queue_full(struct pl330_thread *thrd)
+{
+       return (IS_FREE(&thrd->req[0]) || IS_FREE(&thrd->req[1]))
+               ? false : true;
+}
+
+static inline bool is_manager(struct pl330_thread *thrd)
+{
+       struct pl330_dmac *pl330 = thrd->dmac;
+
+       /* MANAGER is indexed at the end */
+       if (thrd->id == pl330->pinfo->pcfg.num_chan)
+               return true;
+       else
+               return false;
+}
+
+/* If manager of the thread is in Non-Secure mode */
+static inline bool _manager_ns(struct pl330_thread *thrd)
+{
+       struct pl330_dmac *pl330 = thrd->dmac;
+
+       return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false;
+}
+
+static inline u32 get_id(struct pl330_info *pi, u32 off)
+{
+       void __iomem *regs = pi->base;
+       u32 id = 0;
+
+       id |= (readb(regs + off + 0x0) << 0);
+       id |= (readb(regs + off + 0x4) << 8);
+       id |= (readb(regs + off + 0x8) << 16);
+       id |= (readb(regs + off + 0xc) << 24);
+
+       return id;
+}
+
+static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
+               enum pl330_dst da, u16 val)
+{
+       if (dry_run)
+               return SZ_DMAADDH;
+
+       buf[0] = CMD_DMAADDH;
+       buf[0] |= (da << 1);
+       *((u16 *)&buf[1]) = val;
+
+       PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n",
+               da == 1 ? "DA" : "SA", val);
+
+       return SZ_DMAADDH;
+}
+
+static inline u32 _emit_END(unsigned dry_run, u8 buf[])
+{
+       if (dry_run)
+               return SZ_DMAEND;
+
+       buf[0] = CMD_DMAEND;
+
+       PL330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n");
+
+       return SZ_DMAEND;
+}
+
+static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri)
+{
+       if (dry_run)
+               return SZ_DMAFLUSHP;
+
+       buf[0] = CMD_DMAFLUSHP;
+
+       peri &= 0x1f;
+       peri <<= 3;
+       buf[1] = peri;
+
+       PL330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3);
+
+       return SZ_DMAFLUSHP;
+}
+
+static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum pl330_cond cond)
+{
+       if (dry_run)
+               return SZ_DMALD;
+
+       buf[0] = CMD_DMALD;
+
+       if (cond == SINGLE)
+               buf[0] |= (0 << 1) | (1 << 0);
+       else if (cond == BURST)
+               buf[0] |= (1 << 1) | (1 << 0);
+
+       PL330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n",
+               cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
+
+       return SZ_DMALD;
+}
+
+static inline u32 _emit_LDP(unsigned dry_run, u8 buf[],
+               enum pl330_cond cond, u8 peri)
+{
+       if (dry_run)
+               return SZ_DMALDP;
+
+       buf[0] = CMD_DMALDP;
+
+       if (cond == BURST)
+               buf[0] |= (1 << 1);
+
+       peri &= 0x1f;
+       peri <<= 3;
+       buf[1] = peri;
+
+       PL330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n",
+               cond == SINGLE ? 'S' : 'B', peri >> 3);
+
+       return SZ_DMALDP;
+}
+
+static inline u32 _emit_LP(unsigned dry_run, u8 buf[],
+               unsigned loop, u8 cnt)
+{
+       if (dry_run)
+               return SZ_DMALP;
+
+       buf[0] = CMD_DMALP;
+
+       if (loop)
+               buf[0] |= (1 << 1);
+
+       cnt--; /* DMAC increments by 1 internally */
+       buf[1] = cnt;
+
+       PL330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt);
+
+       return SZ_DMALP;
+}
+
+struct _arg_LPEND {
+       enum pl330_cond cond;
+       bool forever;
+       unsigned loop;
+       u8 bjump;
+};
+
+static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[],
+               const struct _arg_LPEND *arg)
+{
+       enum pl330_cond cond = arg->cond;
+       bool forever = arg->forever;
+       unsigned loop = arg->loop;
+       u8 bjump = arg->bjump;
+
+       if (dry_run)
+               return SZ_DMALPEND;
+
+       buf[0] = CMD_DMALPEND;
+
+       if (loop)
+               buf[0] |= (1 << 2);
+
+       if (!forever)
+               buf[0] |= (1 << 4);
+
+       if (cond == SINGLE)
+               buf[0] |= (0 << 1) | (1 << 0);
+       else if (cond == BURST)
+               buf[0] |= (1 << 1) | (1 << 0);
+
+       buf[1] = bjump;
+
+       PL330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n",
+                       forever ? "FE" : "END",
+                       cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'),
+                       loop ? '1' : '0',
+                       bjump);
+
+       return SZ_DMALPEND;
+}
+
+static inline u32 _emit_KILL(unsigned dry_run, u8 buf[])
+{
+       if (dry_run)
+               return SZ_DMAKILL;
+
+       buf[0] = CMD_DMAKILL;
+
+       return SZ_DMAKILL;
+}
+
+static inline u32 _emit_MOV(unsigned dry_run, u8 buf[],
+               enum dmamov_dst dst, u32 val)
+{
+       if (dry_run)
+               return SZ_DMAMOV;
+
+       buf[0] = CMD_DMAMOV;
+       buf[1] = dst;
+       *((u32 *)&buf[2]) = val;
+
+       PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n",
+               dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val);
+
+       return SZ_DMAMOV;
+}
+
+static inline u32 _emit_NOP(unsigned dry_run, u8 buf[])
+{
+       if (dry_run)
+               return SZ_DMANOP;
+
+       buf[0] = CMD_DMANOP;
+
+       PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n");
+
+       return SZ_DMANOP;
+}
+
+static inline u32 _emit_RMB(unsigned dry_run, u8 buf[])
+{
+       if (dry_run)
+               return SZ_DMARMB;
+
+       buf[0] = CMD_DMARMB;
+
+       PL330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n");
+
+       return SZ_DMARMB;
+}
+
+static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev)
+{
+       if (dry_run)
+               return SZ_DMASEV;
+
+       buf[0] = CMD_DMASEV;
+
+       ev &= 0x1f;
+       ev <<= 3;
+       buf[1] = ev;
+
+       PL330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3);
+
+       return SZ_DMASEV;
+}
+
+static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum pl330_cond cond)
+{
+       if (dry_run)
+               return SZ_DMAST;
+
+       buf[0] = CMD_DMAST;
+
+       if (cond == SINGLE)
+               buf[0] |= (0 << 1) | (1 << 0);
+       else if (cond == BURST)
+               buf[0] |= (1 << 1) | (1 << 0);
+
+       PL330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n",
+               cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
+
+       return SZ_DMAST;
+}
+
+static inline u32 _emit_STP(unsigned dry_run, u8 buf[],
+               enum pl330_cond cond, u8 peri)
+{
+       if (dry_run)
+               return SZ_DMASTP;
+
+       buf[0] = CMD_DMASTP;
+
+       if (cond == BURST)
+               buf[0] |= (1 << 1);
+
+       peri &= 0x1f;
+       peri <<= 3;
+       buf[1] = peri;
+
+       PL330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n",
+               cond == SINGLE ? 'S' : 'B', peri >> 3);
+
+       return SZ_DMASTP;
+}
+
+static inline u32 _emit_STZ(unsigned dry_run, u8 buf[])
+{
+       if (dry_run)
+               return SZ_DMASTZ;
+
+       buf[0] = CMD_DMASTZ;
+
+       PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n");
+
+       return SZ_DMASTZ;
+}
+
+static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev,
+               unsigned invalidate)
+{
+       if (dry_run)
+               return SZ_DMAWFE;
+
+       buf[0] = CMD_DMAWFE;
+
+       ev &= 0x1f;
+       ev <<= 3;
+       buf[1] = ev;
+
+       if (invalidate)
+               buf[1] |= (1 << 1);
+
+       PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n",
+               ev >> 3, invalidate ? ", I" : "");
+
+       return SZ_DMAWFE;
+}
+
+static inline u32 _emit_WFP(unsigned dry_run, u8 buf[],
+               enum pl330_cond cond, u8 peri)
+{
+       if (dry_run)
+               return SZ_DMAWFP;
+
+       buf[0] = CMD_DMAWFP;
+
+       if (cond == SINGLE)
+               buf[0] |= (0 << 1) | (0 << 0);
+       else if (cond == BURST)
+               buf[0] |= (1 << 1) | (0 << 0);
+       else
+               buf[0] |= (0 << 1) | (1 << 0);
+
+       peri &= 0x1f;
+       peri <<= 3;
+       buf[1] = peri;
+
+       PL330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n",
+               cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3);
+
+       return SZ_DMAWFP;
+}
+
+static inline u32 _emit_WMB(unsigned dry_run, u8 buf[])
+{
+       if (dry_run)
+               return SZ_DMAWMB;
+
+       buf[0] = CMD_DMAWMB;
+
+       PL330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n");
+
+       return SZ_DMAWMB;
+}
+
+struct _arg_GO {
+       u8 chan;
+       u32 addr;
+       unsigned ns;
+};
+
+static inline u32 _emit_GO(unsigned dry_run, u8 buf[],
+               const struct _arg_GO *arg)
+{
+       u8 chan = arg->chan;
+       u32 addr = arg->addr;
+       unsigned ns = arg->ns;
+
+       if (dry_run)
+               return SZ_DMAGO;
+
+       buf[0] = CMD_DMAGO;
+       buf[0] |= (ns << 1);
+
+       buf[1] = chan & 0x7;
+
+       *((u32 *)&buf[2]) = addr;
+
+       return SZ_DMAGO;
+}
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+/* Returns Time-Out */
+static bool _until_dmac_idle(struct pl330_thread *thrd)
+{
+       void __iomem *regs = thrd->dmac->pinfo->base;
+       unsigned long loops = msecs_to_loops(5);
+
+       do {
+               /* Until Manager is Idle */
+               if (!(readl(regs + DBGSTATUS) & DBG_BUSY))
+                       break;
+
+               cpu_relax();
+       } while (--loops);
+
+       if (!loops)
+               return true;
+
+       return false;
+}
+
+static inline void _execute_DBGINSN(struct pl330_thread *thrd,
+               u8 insn[], bool as_manager)
+{
+       void __iomem *regs = thrd->dmac->pinfo->base;
+       u32 val;
+
+       val = (insn[0] << 16) | (insn[1] << 24);
+       if (!as_manager) {
+               val |= (1 << 0);
+               val |= (thrd->id << 8); /* Channel Number */
+       }
+       writel(val, regs + DBGINST0);
+
+       val = *((u32 *)&insn[2]);
+       writel(val, regs + DBGINST1);
+
+       /* If timed out due to halted state-machine */
+       if (_until_dmac_idle(thrd)) {
+               dev_err(thrd->dmac->pinfo->dev, "DMAC halted!\n");
+               return;
+       }
+
+       /* Get going */
+       writel(0, regs + DBGCMD);
+}
+
+static inline u32 _state(struct pl330_thread *thrd)
+{
+       void __iomem *regs = thrd->dmac->pinfo->base;
+       u32 val;
+
+       if (is_manager(thrd))
+               val = readl(regs + DS) & 0xf;
+       else
+               val = readl(regs + CS(thrd->id)) & 0xf;
+
+       switch (val) {
+       case DS_ST_STOP:
+               return PL330_STATE_STOPPED;
+       case DS_ST_EXEC:
+               return PL330_STATE_EXECUTING;
+       case DS_ST_CMISS:
+               return PL330_STATE_CACHEMISS;
+       case DS_ST_UPDTPC:
+               return PL330_STATE_UPDTPC;
+       case DS_ST_WFE:
+               return PL330_STATE_WFE;
+       case DS_ST_FAULT:
+               return PL330_STATE_FAULTING;
+       case DS_ST_ATBRR:
+               if (is_manager(thrd))
+                       return PL330_STATE_INVALID;
+               else
+                       return PL330_STATE_ATBARRIER;
+       case DS_ST_QBUSY:
+               if (is_manager(thrd))
+                       return PL330_STATE_INVALID;
+               else
+                       return PL330_STATE_QUEUEBUSY;
+       case DS_ST_WFP:
+               if (is_manager(thrd))
+                       return PL330_STATE_INVALID;
+               else
+                       return PL330_STATE_WFP;
+       case DS_ST_KILL:
+               if (is_manager(thrd))
+                       return PL330_STATE_INVALID;
+               else
+                       return PL330_STATE_KILLING;
+       case DS_ST_CMPLT:
+               if (is_manager(thrd))
+                       return PL330_STATE_INVALID;
+               else
+                       return PL330_STATE_COMPLETING;
+       case DS_ST_FLTCMP:
+               if (is_manager(thrd))
+                       return PL330_STATE_INVALID;
+               else
+                       return PL330_STATE_FAULT_COMPLETING;
+       default:
+               return PL330_STATE_INVALID;
+       }
+}
+
+/* If the request 'req' of thread 'thrd' is currently active */
+static inline bool _req_active(struct pl330_thread *thrd,
+               struct _pl330_req *req)
+{
+       void __iomem *regs = thrd->dmac->pinfo->base;
+       u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id));
+
+       if (IS_FREE(req))
+               return false;
+
+       return (pc >= buf && pc <= buf + req->mc_len) ? true : false;
+}
+
+/* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */
+static inline unsigned _thrd_active(struct pl330_thread *thrd)
+{
+       if (_req_active(thrd, &thrd->req[0]))
+               return 1; /* First req active */
+
+       if (_req_active(thrd, &thrd->req[1]))
+               return 2; /* Second req active */
+
+       return 0;
+}
+
+static void _stop(struct pl330_thread *thrd)
+{
+       void __iomem *regs = thrd->dmac->pinfo->base;
+       u8 insn[6] = {0, 0, 0, 0, 0, 0};
+
+       if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
+               UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
+
+       /* Return if nothing needs to be done */
+       if (_state(thrd) == PL330_STATE_COMPLETING
+                 || _state(thrd) == PL330_STATE_KILLING
+                 || _state(thrd) == PL330_STATE_STOPPED)
+               return;
+
+       _emit_KILL(0, insn);
+
+       /* Stop generating interrupts for SEV */
+       writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
+
+       _execute_DBGINSN(thrd, insn, is_manager(thrd));
+}
+
+/* Start doing req 'idx' of thread 'thrd' */
+static bool _trigger(struct pl330_thread *thrd)
+{
+       void __iomem *regs = thrd->dmac->pinfo->base;
+       struct _pl330_req *req;
+       struct pl330_req *r;
+       struct _arg_GO go;
+       unsigned ns;
+       u8 insn[6] = {0, 0, 0, 0, 0, 0};
+
+       /* Return if already ACTIVE */
+       if (_state(thrd) != PL330_STATE_STOPPED)
+               return true;
+
+       if (!IS_FREE(&thrd->req[1 - thrd->lstenq]))
+               req = &thrd->req[1 - thrd->lstenq];
+       else if (!IS_FREE(&thrd->req[thrd->lstenq]))
+               req = &thrd->req[thrd->lstenq];
+       else
+               req = NULL;
+
+       /* Return if no request */
+       if (!req || !req->r)
+               return true;
+
+       r = req->r;
+
+       if (r->cfg)
+               ns = r->cfg->nonsecure ? 1 : 0;
+       else if (readl(regs + CS(thrd->id)) & CS_CNS)
+               ns = 1;
+       else
+               ns = 0;
+
+       /* See 'Abort Sources' point-4 at Page 2-25 */
+       if (_manager_ns(thrd) && !ns)
+               dev_info(thrd->dmac->pinfo->dev, "%s:%d Recipe for ABORT!\n",
+                       __func__, __LINE__);
+
+       go.chan = thrd->id;
+       go.addr = req->mc_bus;
+       go.ns = ns;
+       _emit_GO(0, insn, &go);
+
+       /* Set to generate interrupts for SEV */
+       writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN);
+
+       /* Only manager can execute GO */
+       _execute_DBGINSN(thrd, insn, true);
+
+       return true;
+}
+
+static bool _start(struct pl330_thread *thrd)
+{
+       switch (_state(thrd)) {
+       case PL330_STATE_FAULT_COMPLETING:
+               UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
+
+               if (_state(thrd) == PL330_STATE_KILLING)
+                       UNTIL(thrd, PL330_STATE_STOPPED)
+
+       case PL330_STATE_FAULTING:
+               _stop(thrd);
+
+       case PL330_STATE_KILLING:
+       case PL330_STATE_COMPLETING:
+               UNTIL(thrd, PL330_STATE_STOPPED)
+
+       case PL330_STATE_STOPPED:
+               return _trigger(thrd);
+
+       case PL330_STATE_WFP:
+       case PL330_STATE_QUEUEBUSY:
+       case PL330_STATE_ATBARRIER:
+       case PL330_STATE_UPDTPC:
+       case PL330_STATE_CACHEMISS:
+       case PL330_STATE_EXECUTING:
+               return true;
+
+       case PL330_STATE_WFE: /* For RESUME, nothing yet */
+       default:
+               return false;
+       }
+}
+
+static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
+               const struct _xfer_spec *pxs, int cyc)
+{
+       int off = 0;
+
+       while (cyc--) {
+               off += _emit_LD(dry_run, &buf[off], ALWAYS);
+               off += _emit_RMB(dry_run, &buf[off]);
+               off += _emit_ST(dry_run, &buf[off], ALWAYS);
+               off += _emit_WMB(dry_run, &buf[off]);
+       }
+
+       return off;
+}
+
+static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
+               const struct _xfer_spec *pxs, int cyc)
+{
+       int off = 0;
+
+       while (cyc--) {
+               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+               off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+               off += _emit_ST(dry_run, &buf[off], ALWAYS);
+               off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
+       }
+
+       return off;
+}
+
+static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
+               const struct _xfer_spec *pxs, int cyc)
+{
+       int off = 0;
+
+       while (cyc--) {
+               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+               off += _emit_LD(dry_run, &buf[off], ALWAYS);
+               off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+               off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
+       }
+
+       return off;
+}
+
+static int _bursts(unsigned dry_run, u8 buf[],
+               const struct _xfer_spec *pxs, int cyc)
+{
+       int off = 0;
+
+       switch (pxs->r->rqtype) {
+       case MEMTODEV:
+               off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
+               break;
+       case DEVTOMEM:
+               off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
+               break;
+       case MEMTOMEM:
+               off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
+               break;
+       default:
+               off += 0x40000000; /* Scare off the Client */
+               break;
+       }
+
+       return off;
+}
+
+/* Returns bytes consumed and updates bursts */
+static inline int _loop(unsigned dry_run, u8 buf[],
+               unsigned long *bursts, const struct _xfer_spec *pxs)
+{
+       int cyc, cycmax, szlp, szlpend, szbrst, off;
+       unsigned lcnt0, lcnt1, ljmp0, ljmp1;
+       struct _arg_LPEND lpend;
+
+       /* Max iterations possibile in DMALP is 256 */
+       if (*bursts >= 256*256) {
+               lcnt1 = 256;
+               lcnt0 = 256;
+               cyc = *bursts / lcnt1 / lcnt0;
+       } else if (*bursts > 256) {
+               lcnt1 = 256;
+               lcnt0 = *bursts / lcnt1;
+               cyc = 1;
+       } else {
+               lcnt1 = *bursts;
+               lcnt0 = 0;
+               cyc = 1;
+       }
+
+       szlp = _emit_LP(1, buf, 0, 0);
+       szbrst = _bursts(1, buf, pxs, 1);
+
+       lpend.cond = ALWAYS;
+       lpend.forever = false;
+       lpend.loop = 0;
+       lpend.bjump = 0;
+       szlpend = _emit_LPEND(1, buf, &lpend);
+
+       if (lcnt0) {
+               szlp *= 2;
+               szlpend *= 2;
+       }
+
+       /*
+        * Max bursts that we can unroll due to limit on the
+        * size of backward jump that can be encoded in DMALPEND
+        * which is 8-bits and hence 255
+        */
+       cycmax = (255 - (szlp + szlpend)) / szbrst;
+
+       cyc = (cycmax < cyc) ? cycmax : cyc;
+
+       off = 0;
+
+       if (lcnt0) {
+               off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
+               ljmp0 = off;
+       }
+
+       off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
+       ljmp1 = off;
+
+       off += _bursts(dry_run, &buf[off], pxs, cyc);
+
+       lpend.cond = ALWAYS;
+       lpend.forever = false;
+       lpend.loop = 1;
+       lpend.bjump = off - ljmp1;
+       off += _emit_LPEND(dry_run, &buf[off], &lpend);
+
+       if (lcnt0) {
+               lpend.cond = ALWAYS;
+               lpend.forever = false;
+               lpend.loop = 0;
+               lpend.bjump = off - ljmp0;
+               off += _emit_LPEND(dry_run, &buf[off], &lpend);
+       }
+
+       *bursts = lcnt1 * cyc;
+       if (lcnt0)
+               *bursts *= lcnt0;
+
+       return off;
+}
+
+static inline int _setup_loops(unsigned dry_run, u8 buf[],
+               const struct _xfer_spec *pxs)
+{
+       struct pl330_xfer *x = pxs->x;
+       u32 ccr = pxs->ccr;
+       unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);
+       int off = 0;
+
+       while (bursts) {
+               c = bursts;
+               off += _loop(dry_run, &buf[off], &c, pxs);
+               bursts -= c;
+       }
+
+       return off;
+}
+
+static inline int _setup_xfer(unsigned dry_run, u8 buf[],
+               const struct _xfer_spec *pxs)
+{
+       struct pl330_xfer *x = pxs->x;
+       int off = 0;
+
+       /* DMAMOV SAR, x->src_addr */
+       off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr);
+       /* DMAMOV DAR, x->dst_addr */
+       off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
+
+       /* Setup Loop(s) */
+       off += _setup_loops(dry_run, &buf[off], pxs);
+
+       return off;
+}
+
+/*
+ * A req is a sequence of one or more xfer units.
+ * Returns the number of bytes taken to setup the MC for the req.
+ */
+static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
+               unsigned index, struct _xfer_spec *pxs)
+{
+       struct _pl330_req *req = &thrd->req[index];
+       struct pl330_xfer *x;
+       u8 *buf = req->mc_cpu;
+       int off = 0;
+
+       PL330_DBGMC_START(req->mc_bus);
+
+       /* DMAMOV CCR, ccr */
+       off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
+
+       x = pxs->r->x;
+       do {
+               /* Error if xfer length is not aligned at burst size */
+               if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
+                       return -EINVAL;
+
+               pxs->x = x;
+               off += _setup_xfer(dry_run, &buf[off], pxs);
+
+               x = x->next;
+       } while (x);
+
+       /* DMASEV peripheral/event */
+       off += _emit_SEV(dry_run, &buf[off], thrd->ev);
+       /* DMAEND */
+       off += _emit_END(dry_run, &buf[off]);
+
+       return off;
+}
+
+static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
+{
+       u32 ccr = 0;
+
+       if (rqc->src_inc)
+               ccr |= CC_SRCINC;
+
+       if (rqc->dst_inc)
+               ccr |= CC_DSTINC;
+
+       /* We set same protection levels for Src and DST for now */
+       if (rqc->privileged)
+               ccr |= CC_SRCPRI | CC_DSTPRI;
+       if (rqc->nonsecure)
+               ccr |= CC_SRCNS | CC_DSTNS;
+       if (rqc->insnaccess)
+               ccr |= CC_SRCIA | CC_DSTIA;
+
+       ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT);
+       ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT);
+
+       ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
+       ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
+
+       ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
+       ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
+
+       ccr |= (rqc->swap << CC_SWAP_SHFT);
+
+       return ccr;
+}
+
+static inline bool _is_valid(u32 ccr)
+{
+       enum pl330_dstcachectrl dcctl;
+       enum pl330_srccachectrl scctl;
+
+       dcctl = (ccr >> CC_DSTCCTRL_SHFT) & CC_DRCCCTRL_MASK;
+       scctl = (ccr >> CC_SRCCCTRL_SHFT) & CC_SRCCCTRL_MASK;
+
+       if (dcctl == DINVALID1 || dcctl == DINVALID2
+                       || scctl == SINVALID1 || scctl == SINVALID2)
+               return false;
+       else
+               return true;
+}
+
+/*
+ * Submit a list of xfers after which the client wants notification.
+ * Client is not notified after each xfer unit, just once after all
+ * xfer units are done or some error occurs.
+ */
+int pl330_submit_req(void *ch_id, struct pl330_req *r)
+{
+       struct pl330_thread *thrd = ch_id;
+       struct pl330_dmac *pl330;
+       struct pl330_info *pi;
+       struct _xfer_spec xs;
+       unsigned long flags;
+       void __iomem *regs;
+       unsigned idx;
+       u32 ccr;
+       int ret = 0;
+
+       /* No Req or Unacquired Channel or DMAC */
+       if (!r || !thrd || thrd->free)
+               return -EINVAL;
+
+       pl330 = thrd->dmac;
+       pi = pl330->pinfo;
+       regs = pi->base;
+
+       if (pl330->state == DYING
+               || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) {
+               dev_info(thrd->dmac->pinfo->dev, "%s:%d\n",
+                       __func__, __LINE__);
+               return -EAGAIN;
+       }
+
+       /* If request for non-existing peripheral */
+       if (r->rqtype != MEMTOMEM && r->peri >= pi->pcfg.num_peri) {
+               dev_info(thrd->dmac->pinfo->dev,
+                               "%s:%d Invalid peripheral(%u)!\n",
+                               __func__, __LINE__, r->peri);
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&pl330->lock, flags);
+
+       if (_queue_full(thrd)) {
+               ret = -EAGAIN;
+               goto xfer_exit;
+       }
+
+       /* Prefer Secure Channel */
+       if (!_manager_ns(thrd))
+               r->cfg->nonsecure = 0;
+       else
+               r->cfg->nonsecure = 1;
+
+       /* Use last settings, if not provided */
+       if (r->cfg)
+               ccr = _prepare_ccr(r->cfg);
+       else
+               ccr = readl(regs + CC(thrd->id));
+
+       /* If this req doesn't have valid xfer settings */
+       if (!_is_valid(ccr)) {
+               ret = -EINVAL;
+               dev_info(thrd->dmac->pinfo->dev, "%s:%d Invalid CCR(%x)!\n",
+                       __func__, __LINE__, ccr);
+               goto xfer_exit;
+       }
+
+       idx = IS_FREE(&thrd->req[0]) ? 0 : 1;
+
+       xs.ccr = ccr;
+       xs.r = r;
+
+       /* First dry run to check if req is acceptable */
+       ret = _setup_req(1, thrd, idx, &xs);
+       if (ret < 0)
+               goto xfer_exit;
+
+       if (ret > pi->mcbufsz / 2) {
+               dev_info(thrd->dmac->pinfo->dev,
+                       "%s:%d Trying increasing mcbufsz\n",
+                               __func__, __LINE__);
+               ret = -ENOMEM;
+               goto xfer_exit;
+       }
+
+       /* Hook the request */
+       thrd->lstenq = idx;
+       thrd->req[idx].mc_len = _setup_req(0, thrd, idx, &xs);
+       thrd->req[idx].r = r;
+
+       ret = 0;
+
+xfer_exit:
+       spin_unlock_irqrestore(&pl330->lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(pl330_submit_req);
+
+static void pl330_dotask(unsigned long data)
+{
+       struct pl330_dmac *pl330 = (struct pl330_dmac *) data;
+       struct pl330_info *pi = pl330->pinfo;
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&pl330->lock, flags);
+
+       /* The DMAC itself gone nuts */
+       if (pl330->dmac_tbd.reset_dmac) {
+               pl330->state = DYING;
+               /* Reset the manager too */
+               pl330->dmac_tbd.reset_mngr = true;
+               /* Clear the reset flag */
+               pl330->dmac_tbd.reset_dmac = false;
+       }
+
+       if (pl330->dmac_tbd.reset_mngr) {
+               _stop(pl330->manager);
+               /* Reset all channels */
+               pl330->dmac_tbd.reset_chan = (1 << pi->pcfg.num_chan) - 1;
+               /* Clear the reset flag */
+               pl330->dmac_tbd.reset_mngr = false;
+       }
+
+       for (i = 0; i < pi->pcfg.num_chan; i++) {
+
+               if (pl330->dmac_tbd.reset_chan & (1 << i)) {
+                       struct pl330_thread *thrd = &pl330->channels[i];
+                       void __iomem *regs = pi->base;
+                       enum pl330_op_err err;
+
+                       _stop(thrd);
+
+                       if (readl(regs + FSC) & (1 << thrd->id))
+                               err = PL330_ERR_FAIL;
+                       else
+                               err = PL330_ERR_ABORT;
+
+                       spin_unlock_irqrestore(&pl330->lock, flags);
+
+                       _callback(thrd->req[1 - thrd->lstenq].r, err);
+                       _callback(thrd->req[thrd->lstenq].r, err);
+
+                       spin_lock_irqsave(&pl330->lock, flags);
+
+                       thrd->req[0].r = NULL;
+                       thrd->req[1].r = NULL;
+                       MARK_FREE(&thrd->req[0]);
+                       MARK_FREE(&thrd->req[1]);
+
+                       /* Clear the reset flag */
+                       pl330->dmac_tbd.reset_chan &= ~(1 << i);
+               }
+       }
+
+       spin_unlock_irqrestore(&pl330->lock, flags);
+
+       return;
+}
+
+/* Returns 1 if state was updated, 0 otherwise */
+int pl330_update(const struct pl330_info *pi)
+{
+       struct _pl330_req *rqdone;
+       struct pl330_dmac *pl330;
+       unsigned long flags;
+       void __iomem *regs;
+       u32 val;
+       int id, ev, ret = 0;
+
+       if (!pi || !pi->pl330_data)
+               return 0;
+
+       regs = pi->base;
+       pl330 = pi->pl330_data;
+
+       spin_lock_irqsave(&pl330->lock, flags);
+
+       val = readl(regs + FSM) & 0x1;
+       if (val)
+               pl330->dmac_tbd.reset_mngr = true;
+       else
+               pl330->dmac_tbd.reset_mngr = false;
+
+       val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1);
+       pl330->dmac_tbd.reset_chan |= val;
+       if (val) {
+               int i = 0;
+               while (i < pi->pcfg.num_chan) {
+                       if (val & (1 << i)) {
+                               dev_info(pi->dev,
+                                       "Reset Channel-%d\t CS-%x FTC-%x\n",
+                                               i, readl(regs + CS(i)),
+                                               readl(regs + FTC(i)));
+                               _stop(&pl330->channels[i]);
+                       }
+                       i++;
+               }
+       }
+
+       /* Check which event happened i.e, thread notified */
+       val = readl(regs + ES);
+       if (pi->pcfg.num_events < 32
+                       && val & ~((1 << pi->pcfg.num_events) - 1)) {
+               pl330->dmac_tbd.reset_dmac = true;
+               dev_err(pi->dev, "%s:%d Unexpected!\n", __func__, __LINE__);
+               ret = 1;
+               goto updt_exit;
+       }
+
+       for (ev = 0; ev < pi->pcfg.num_events; ev++) {
+               if (val & (1 << ev)) { /* Event occured */
+                       struct pl330_thread *thrd;
+                       u32 inten = readl(regs + INTEN);
+                       int active;
+
+                       /* Clear the event */
+                       if (inten & (1 << ev))
+                               writel(1 << ev, regs + INTCLR);
+
+                       ret = 1;
+
+                       id = pl330->events[ev];
+
+                       thrd = &pl330->channels[id];
+
+                       active = _thrd_active(thrd);
+                       if (!active) /* Aborted */
+                               continue;
+
+                       active -= 1;
+
+                       rqdone = &thrd->req[active];
+                       MARK_FREE(rqdone);
+
+                       /* Get going again ASAP */
+                       _start(thrd);
+
+                       /* For now, just make a list of callbacks to be done */
+                       list_add_tail(&rqdone->rqd, &pl330->req_done);
+               }
+       }
+
+       /* Now that we are in no hurry, do the callbacks */
+       while (!list_empty(&pl330->req_done)) {
+               rqdone = container_of(pl330->req_done.next,
+                                       struct _pl330_req, rqd);
+
+               list_del_init(&rqdone->rqd);
+
+               spin_unlock_irqrestore(&pl330->lock, flags);
+               _callback(rqdone->r, PL330_ERR_NONE);
+               spin_lock_irqsave(&pl330->lock, flags);
+       }
+
+updt_exit:
+       spin_unlock_irqrestore(&pl330->lock, flags);
+
+       if (pl330->dmac_tbd.reset_dmac
+                       || pl330->dmac_tbd.reset_mngr
+                       || pl330->dmac_tbd.reset_chan) {
+               ret = 1;
+               tasklet_schedule(&pl330->tasks);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(pl330_update);
+
+int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
+{
+       struct pl330_thread *thrd = ch_id;
+       struct pl330_dmac *pl330;
+       unsigned long flags;
+       int ret = 0, active;
+
+       if (!thrd || thrd->free || thrd->dmac->state == DYING)
+               return -EINVAL;
+
+       pl330 = thrd->dmac;
+
+       spin_lock_irqsave(&pl330->lock, flags);
+
+       switch (op) {
+       case PL330_OP_FLUSH:
+               /* Make sure the channel is stopped */
+               _stop(thrd);
+
+               thrd->req[0].r = NULL;
+               thrd->req[1].r = NULL;
+               MARK_FREE(&thrd->req[0]);
+               MARK_FREE(&thrd->req[1]);
+               break;
+
+       case PL330_OP_ABORT:
+               active = _thrd_active(thrd);
+
+               /* Make sure the channel is stopped */
+               _stop(thrd);
+
+               /* ABORT is only for the active req */
+               if (!active)
+                       break;
+
+               active--;
+
+               thrd->req[active].r = NULL;
+               MARK_FREE(&thrd->req[active]);
+
+               /* Start the next */
+       case PL330_OP_START:
+               if (!_start(thrd))
+                       ret = -EIO;
+               break;
+
+       default:
+               ret = -EINVAL;
+       }
+
+       spin_unlock_irqrestore(&pl330->lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL(pl330_chan_ctrl);
+
+int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus)
+{
+       struct pl330_thread *thrd = ch_id;
+       struct pl330_dmac *pl330;
+       struct pl330_info *pi;
+       void __iomem *regs;
+       int active;
+       u32 val;
+
+       if (!pstatus || !thrd || thrd->free)
+               return -EINVAL;
+
+       pl330 = thrd->dmac;
+       pi = pl330->pinfo;
+       regs = pi->base;
+
+       /* The client should remove the DMAC and add again */
+       if (pl330->state == DYING)
+               pstatus->dmac_halted = true;
+       else
+               pstatus->dmac_halted = false;
+
+       val = readl(regs + FSC);
+       if (val & (1 << thrd->id))
+               pstatus->faulting = true;
+       else
+               pstatus->faulting = false;
+
+       active = _thrd_active(thrd);
+
+       if (!active) {
+               /* Indicate that the thread is not running */
+               pstatus->top_req = NULL;
+               pstatus->wait_req = NULL;
+       } else {
+               active--;
+               pstatus->top_req = thrd->req[active].r;
+               pstatus->wait_req = !IS_FREE(&thrd->req[1 - active])
+                                       ? thrd->req[1 - active].r : NULL;
+       }
+
+       pstatus->src_addr = readl(regs + SA(thrd->id));
+       pstatus->dst_addr = readl(regs + DA(thrd->id));
+
+       return 0;
+}
+EXPORT_SYMBOL(pl330_chan_status);
+
+/* Reserve an event */
+static inline int _alloc_event(struct pl330_thread *thrd)
+{
+       struct pl330_dmac *pl330 = thrd->dmac;
+       struct pl330_info *pi = pl330->pinfo;
+       int ev;
+
+       for (ev = 0; ev < pi->pcfg.num_events; ev++)
+               if (pl330->events[ev] == -1) {
+                       pl330->events[ev] = thrd->id;
+                       return ev;
+               }
+
+       return -1;
+}
+
+/* Upon success, returns IdentityToken for the
+ * allocated channel, NULL otherwise.
+ */
+void *pl330_request_channel(const struct pl330_info *pi)
+{
+       struct pl330_thread *thrd = NULL;
+       struct pl330_dmac *pl330;
+       unsigned long flags;
+       int chans, i;
+
+       if (!pi || !pi->pl330_data)
+               return NULL;
+
+       pl330 = pi->pl330_data;
+
+       if (pl330->state == DYING)
+               return NULL;
+
+       chans = pi->pcfg.num_chan;
+
+       spin_lock_irqsave(&pl330->lock, flags);
+
+       for (i = 0; i < chans; i++) {
+               thrd = &pl330->channels[i];
+               if (thrd->free) {
+                       thrd->ev = _alloc_event(thrd);
+                       if (thrd->ev >= 0) {
+                               thrd->free = false;
+                               thrd->lstenq = 1;
+                               thrd->req[0].r = NULL;
+                               MARK_FREE(&thrd->req[0]);
+                               thrd->req[1].r = NULL;
+                               MARK_FREE(&thrd->req[1]);
+                               break;
+                       }
+               }
+               thrd = NULL;
+       }
+
+       spin_unlock_irqrestore(&pl330->lock, flags);
+
+       return thrd;
+}
+EXPORT_SYMBOL(pl330_request_channel);
+
+/* Release an event */
+static inline void _free_event(struct pl330_thread *thrd, int ev)
+{
+       struct pl330_dmac *pl330 = thrd->dmac;
+       struct pl330_info *pi = pl330->pinfo;
+
+       /* If the event is valid and was held by the thread */
+       if (ev >= 0 && ev < pi->pcfg.num_events
+                       && pl330->events[ev] == thrd->id)
+               pl330->events[ev] = -1;
+}
+
+void pl330_release_channel(void *ch_id)
+{
+       struct pl330_thread *thrd = ch_id;
+       struct pl330_dmac *pl330;
+       unsigned long flags;
+
+       if (!thrd || thrd->free)
+               return;
+
+       _stop(thrd);
+
+       _callback(thrd->req[1 - thrd->lstenq].r, PL330_ERR_ABORT);
+       _callback(thrd->req[thrd->lstenq].r, PL330_ERR_ABORT);
+
+       pl330 = thrd->dmac;
+
+       spin_lock_irqsave(&pl330->lock, flags);
+       _free_event(thrd, thrd->ev);
+       thrd->free = true;
+       spin_unlock_irqrestore(&pl330->lock, flags);
+}
+EXPORT_SYMBOL(pl330_release_channel);
+
+/* Initialize the structure for PL330 configuration, that can be used
+ * by the client driver the make best use of the DMAC
+ */
+static void read_dmac_config(struct pl330_info *pi)
+{
+       void __iomem *regs = pi->base;
+       u32 val;
+
+       val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT;
+       val &= CRD_DATA_WIDTH_MASK;
+       pi->pcfg.data_bus_width = 8 * (1 << val);
+
+       val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT;
+       val &= CRD_DATA_BUFF_MASK;
+       pi->pcfg.data_buf_dep = val + 1;
+
+       val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT;
+       val &= CR0_NUM_CHANS_MASK;
+       val += 1;
+       pi->pcfg.num_chan = val;
+
+       val = readl(regs + CR0);
+       if (val & CR0_PERIPH_REQ_SET) {
+               val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK;
+               val += 1;
+               pi->pcfg.num_peri = val;
+               pi->pcfg.peri_ns = readl(regs + CR4);
+       } else {
+               pi->pcfg.num_peri = 0;
+       }
+
+       val = readl(regs + CR0);
+       if (val & CR0_BOOT_MAN_NS)
+               pi->pcfg.mode |= DMAC_MODE_NS;
+       else
+               pi->pcfg.mode &= ~DMAC_MODE_NS;
+
+       val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT;
+       val &= CR0_NUM_EVENTS_MASK;
+       val += 1;
+       pi->pcfg.num_events = val;
+
+       pi->pcfg.irq_ns = readl(regs + CR3);
+
+       pi->pcfg.periph_id = get_id(pi, PERIPH_ID);
+       pi->pcfg.pcell_id = get_id(pi, PCELL_ID);
+}
+
+static inline void _reset_thread(struct pl330_thread *thrd)
+{
+       struct pl330_dmac *pl330 = thrd->dmac;
+       struct pl330_info *pi = pl330->pinfo;
+
+       thrd->req[0].mc_cpu = pl330->mcode_cpu
+                               + (thrd->id * pi->mcbufsz);
+       thrd->req[0].mc_bus = pl330->mcode_bus
+                               + (thrd->id * pi->mcbufsz);
+       thrd->req[0].r = NULL;
+       MARK_FREE(&thrd->req[0]);
+
+       thrd->req[1].mc_cpu = thrd->req[0].mc_cpu
+                               + pi->mcbufsz / 2;
+       thrd->req[1].mc_bus = thrd->req[0].mc_bus
+                               + pi->mcbufsz / 2;
+       thrd->req[1].r = NULL;
+       MARK_FREE(&thrd->req[1]);
+}
+
+static int dmac_alloc_threads(struct pl330_dmac *pl330)
+{
+       struct pl330_info *pi = pl330->pinfo;
+       int chans = pi->pcfg.num_chan;
+       struct pl330_thread *thrd;
+       int i;
+
+       /* Allocate 1 Manager and 'chans' Channel threads */
+       pl330->channels = kzalloc((1 + chans) * sizeof(*thrd),
+                                       GFP_KERNEL);
+       if (!pl330->channels)
+               return -ENOMEM;
+
+       /* Init Channel threads */
+       for (i = 0; i < chans; i++) {
+               thrd = &pl330->channels[i];
+               thrd->id = i;
+               thrd->dmac = pl330;
+               _reset_thread(thrd);
+               thrd->free = true;
+       }
+
+       /* MANAGER is indexed at the end */
+       thrd = &pl330->channels[chans];
+       thrd->id = chans;
+       thrd->dmac = pl330;
+       thrd->free = false;
+       pl330->manager = thrd;
+
+       return 0;
+}
+
+static int dmac_alloc_resources(struct pl330_dmac *pl330)
+{
+       struct pl330_info *pi = pl330->pinfo;
+       int chans = pi->pcfg.num_chan;
+       int ret;
+
+       /*
+        * Alloc MicroCode buffer for 'chans' Channel threads.
+        * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN)
+        */
+       pl330->mcode_cpu = dma_alloc_coherent(pi->dev,
+                               chans * pi->mcbufsz,
+                               &pl330->mcode_bus, GFP_KERNEL);
+       if (!pl330->mcode_cpu) {
+               dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
+                       __func__, __LINE__);
+               return -ENOMEM;
+       }
+
+       ret = dmac_alloc_threads(pl330);
+       if (ret) {
+               dev_err(pi->dev, "%s:%d Can't to create channels for DMAC!\n",
+                       __func__, __LINE__);
+               dma_free_coherent(pi->dev,
+                               chans * pi->mcbufsz,
+                               pl330->mcode_cpu, pl330->mcode_bus);
+               return ret;
+       }
+
+       return 0;
+}
+
+int pl330_add(struct pl330_info *pi)
+{
+       struct pl330_dmac *pl330;
+       void __iomem *regs;
+       int i, ret;
+
+       if (!pi || !pi->dev)
+               return -EINVAL;
+
+       /* If already added */
+       if (pi->pl330_data)
+               return -EINVAL;
+
+       /*
+        * If the SoC can perform reset on the DMAC, then do it
+        * before reading its configuration.
+        */
+       if (pi->dmac_reset)
+               pi->dmac_reset(pi);
+
+       regs = pi->base;
+
+       /* Check if we can handle this DMAC */
+       if (get_id(pi, PERIPH_ID) != PERIPH_ID_VAL
+          || get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
+               dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
+                       readl(regs + PERIPH_ID), readl(regs + PCELL_ID));
+               return -EINVAL;
+       }
+
+       /* Read the configuration of the DMAC */
+       read_dmac_config(pi);
+
+       if (pi->pcfg.num_events == 0) {
+               dev_err(pi->dev, "%s:%d Can't work without events!\n",
+                       __func__, __LINE__);
+               return -EINVAL;
+       }
+
+       pl330 = kzalloc(sizeof(*pl330), GFP_KERNEL);
+       if (!pl330) {
+               dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
+                       __func__, __LINE__);
+               return -ENOMEM;
+       }
+
+       /* Assign the info structure and private data */
+       pl330->pinfo = pi;
+       pi->pl330_data = pl330;
+
+       spin_lock_init(&pl330->lock);
+
+       INIT_LIST_HEAD(&pl330->req_done);
+
+       /* Use default MC buffer size if not provided */
+       if (!pi->mcbufsz)
+               pi->mcbufsz = MCODE_BUFF_PER_REQ * 2;
+
+       /* Mark all events as free */
+       for (i = 0; i < pi->pcfg.num_events; i++)
+               pl330->events[i] = -1;
+
+       /* Allocate resources needed by the DMAC */
+       ret = dmac_alloc_resources(pl330);
+       if (ret) {
+               dev_err(pi->dev, "Unable to create channels for DMAC\n");
+               kfree(pl330);
+               return ret;
+       }
+
+       tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330);
+
+       pl330->state = INIT;
+
+       return 0;
+}
+EXPORT_SYMBOL(pl330_add);
+
+static int dmac_free_threads(struct pl330_dmac *pl330)
+{
+       struct pl330_info *pi = pl330->pinfo;
+       int chans = pi->pcfg.num_chan;
+       struct pl330_thread *thrd;
+       int i;
+
+       /* Release Channel threads */
+       for (i = 0; i < chans; i++) {
+               thrd = &pl330->channels[i];
+               pl330_release_channel((void *)thrd);
+       }
+
+       /* Free memory */
+       kfree(pl330->channels);
+
+       return 0;
+}
+
+static void dmac_free_resources(struct pl330_dmac *pl330)
+{
+       struct pl330_info *pi = pl330->pinfo;
+       int chans = pi->pcfg.num_chan;
+
+       dmac_free_threads(pl330);
+
+       dma_free_coherent(pi->dev, chans * pi->mcbufsz,
+                               pl330->mcode_cpu, pl330->mcode_bus);
+}
+
+void pl330_del(struct pl330_info *pi)
+{
+       struct pl330_dmac *pl330;
+
+       if (!pi || !pi->pl330_data)
+               return;
+
+       pl330 = pi->pl330_data;
+
+       pl330->state = UNINIT;
+
+       tasklet_kill(&pl330->tasks);
+
+       /* Free DMAC resources */
+       dmac_free_resources(pl330);
+
+       kfree(pl330);
+       pi->pl330_data = NULL;
+}
+EXPORT_SYMBOL(pl330_del);
index 1cf999a..ba65f6e 100644 (file)
@@ -266,13 +266,53 @@ static int vic_set_wake(unsigned int irq, unsigned int on)
 #endif /* CONFIG_PM */
 
 static struct irq_chip vic_chip = {
-       .name   = "VIC",
-       .ack    = vic_ack_irq,
-       .mask   = vic_mask_irq,
-       .unmask = vic_unmask_irq,
-       .set_wake = vic_set_wake,
+       .name           = "VIC",
+       .ack            = vic_ack_irq,
+       .mask           = vic_mask_irq,
+       .unmask         = vic_unmask_irq,
+       .set_wake       = vic_set_wake,
 };
 
+static void __init vic_disable(void __iomem *base)
+{
+       writel(0, base + VIC_INT_SELECT);
+       writel(0, base + VIC_INT_ENABLE);
+       writel(~0, base + VIC_INT_ENABLE_CLEAR);
+       writel(0, base + VIC_IRQ_STATUS);
+       writel(0, base + VIC_ITCR);
+       writel(~0, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void __init vic_clear_interrupts(void __iomem *base)
+{
+       unsigned int i;
+
+       writel(0, base + VIC_PL190_VECT_ADDR);
+       for (i = 0; i < 19; i++) {
+               unsigned int value;
+
+               value = readl(base + VIC_PL190_VECT_ADDR);
+               writel(value, base + VIC_PL190_VECT_ADDR);
+       }
+}
+
+static void __init vic_set_irq_sources(void __iomem *base,
+                               unsigned int irq_start, u32 vic_sources)
+{
+       unsigned int i;
+
+       for (i = 0; i < 32; i++) {
+               if (vic_sources & (1 << i)) {
+                       unsigned int irq = irq_start + i;
+
+                       set_irq_chip(irq, &vic_chip);
+                       set_irq_chip_data(irq, base);
+                       set_irq_handler(irq, handle_level_irq);
+                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+               }
+       }
+}
+
 /*
  * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
  * The original cell has 32 interrupts, while the modified one has 64,
@@ -287,13 +327,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
        int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
 
        /* Disable all interrupts initially. */
-
-       writel(0, base + VIC_INT_SELECT);
-       writel(0, base + VIC_INT_ENABLE);
-       writel(~0, base + VIC_INT_ENABLE_CLEAR);
-       writel(0, base + VIC_IRQ_STATUS);
-       writel(0, base + VIC_ITCR);
-       writel(~0, base + VIC_INT_SOFT_CLEAR);
+       vic_disable(base);
 
        /*
         * Make sure we clear all existing interrupts. The vector registers
@@ -302,13 +336,8 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
         * the second base address, which is 0x20 in the page
         */
        if (vic_2nd_block) {
-               writel(0, base + VIC_PL190_VECT_ADDR);
-               for (i = 0; i < 19; i++) {
-                       unsigned int value;
+               vic_clear_interrupts(base);
 
-                       value = readl(base + VIC_PL190_VECT_ADDR);
-                       writel(value, base + VIC_PL190_VECT_ADDR);
-               }
                /* ST has 16 vectors as well, but we don't enable them by now */
                for (i = 0; i < 16; i++) {
                        void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
@@ -318,16 +347,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
                writel(32, base + VIC_PL190_DEF_VECT_ADDR);
        }
 
-       for (i = 0; i < 32; i++) {
-               if (vic_sources & (1 << i)) {
-                       unsigned int irq = irq_start + i;
-
-                       set_irq_chip(irq, &vic_chip);
-                       set_irq_chip_data(irq, base);
-                       set_irq_handler(irq, handle_level_irq);
-                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-               }
-       }
+       vic_set_irq_sources(base, irq_start, vic_sources);
 }
 
 /**
@@ -365,37 +385,14 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
        }
 
        /* Disable all interrupts initially. */
+       vic_disable(base);
 
-       writel(0, base + VIC_INT_SELECT);
-       writel(0, base + VIC_INT_ENABLE);
-       writel(~0, base + VIC_INT_ENABLE_CLEAR);
-       writel(0, base + VIC_IRQ_STATUS);
-       writel(0, base + VIC_ITCR);
-       writel(~0, base + VIC_INT_SOFT_CLEAR);
-
-       /*
-        * Make sure we clear all existing interrupts
-        */
-       writel(0, base + VIC_PL190_VECT_ADDR);
-       for (i = 0; i < 19; i++) {
-               unsigned int value;
-
-               value = readl(base + VIC_PL190_VECT_ADDR);
-               writel(value, base + VIC_PL190_VECT_ADDR);
-       }
+       /* Make sure we clear all existing interrupts */
+       vic_clear_interrupts(base);
 
        vic_init2(base);
 
-       for (i = 0; i < 32; i++) {
-               if (vic_sources & (1 << i)) {
-                       unsigned int irq = irq_start + i;
-
-                       set_irq_chip(irq, &vic_chip);
-                       set_irq_chip_data(irq, base);
-                       set_irq_handler(irq, handle_level_irq);
-                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-               }
-       }
+       vic_set_irq_sources(base, irq_start, vic_sources);
 
        vic_pm_register(base, irq_start, resume_sources);
 }
index 1e12167..6ac6693 100644 (file)
@@ -1,13 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc3
-# Fri Jul 17 12:07:28 2009
+# Linux kernel version: 2.6.34-rc2
+# Mon Mar 29 12:01:41 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_MMU=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,6 +18,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,6 +33,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -43,21 +50,22 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -75,19 +83,21 @@ CONFIG_FUTEX=y
 # CONFIG_EVENTFD is not set
 CONFIG_SHMEM=y
 # CONFIG_AIO is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_COUNTERS=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y
@@ -115,24 +125,53 @@ CONFIG_LBDAF=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
 # System Type
 #
+CONFIG_MMU=y
 # CONFIG_ARCH_AAEC2000 is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
+CONFIG_ARCH_BCMRING=y
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -149,6 +188,7 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_ARCH_IXP2000 is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
 # CONFIG_ARCH_KIRKWOOD is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
@@ -157,19 +197,26 @@ CONFIG_DEFAULT_IOSCHED="noop"
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-CONFIG_ARCH_BCMRING=y
 # CONFIG_ARCH_FPGA11107 is not set
 CONFIG_ARCH_BCM11107=y
 
@@ -185,7 +232,7 @@ CONFIG_CPU_V6=y
 CONFIG_CPU_32v6K=y
 CONFIG_CPU_32v6=y
 CONFIG_CPU_ABRT_EV6=y
-CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_PABRT_V6=y
 CONFIG_CPU_CACHE_V6=y
 CONFIG_CPU_CACHE_VIPT=y
 CONFIG_CPU_COPY_V6=y
@@ -201,6 +248,8 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
 # CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_COMMON_CLKDEV=y
 
@@ -222,6 +271,8 @@ CONFIG_VMSPLIT_3G=y
 # CONFIG_VMSPLIT_2G is not set
 # CONFIG_VMSPLIT_1G is not set
 CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
@@ -229,6 +280,7 @@ CONFIG_AEABI=y
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
+CONFIG_HW_PERF_EVENTS=y
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -240,8 +292,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ALIGNMENT_TRAP=y
 CONFIG_UACCESS_WITH_MEMCPY=y
@@ -335,9 +386,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
@@ -433,6 +484,10 @@ CONFIG_MTD_NAND_BCM_UMI_HWCS=y
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
@@ -444,6 +499,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -452,6 +508,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_MD is not set
 # CONFIG_NETDEVICES is not set
 # CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
 
 #
 # Input device support
@@ -459,6 +516,7 @@ CONFIG_HAVE_IDE=y
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -508,6 +566,7 @@ CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -519,13 +578,17 @@ CONFIG_LEGACY_PTY_COUNT=64
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -541,6 +604,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -566,14 +630,17 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -589,9 +656,12 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
@@ -647,6 +717,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -657,7 +728,6 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -675,11 +745,12 @@ CONFIG_MSDOS_PARTITION=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 CONFIG_HEADERS_CHECK=y
 # CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -693,6 +764,7 @@ CONFIG_TRACING_SUPPORT=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_ARM_UNWIND is not set
 # CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
 
 #
 # Security options
@@ -700,7 +772,11 @@ CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff --git a/arch/arm/configs/cns3420vb_defconfig b/arch/arm/configs/cns3420vb_defconfig
new file mode 100644 (file)
index 0000000..d5c0881
--- /dev/null
@@ -0,0 +1,831 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc6
+# Sun May  2 21:58:08 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_NS is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=m
+# CONFIG_CFQ_GROUP_IOSCHED is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+CONFIG_ARCH_CNS3XXX=y
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# CNS3XXX platform type
+#
+CONFIG_MACH_CNS3420VB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_ARM_GIC=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,38400 mem=128M root=/dev/mmcblk0p1 ro rootwait"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=20000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+# CONFIG_ATA_SFF is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+CONFIG_FSCACHE=y
+# CONFIG_FSCACHE_STATS is not set
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+# CONFIG_CACHEFILES is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_GENERIC_ATOMIC64=y
index 95d2bec..21f2bff 100644 (file)
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc8
-# Sat Feb 13 21:48:53 2010
+# Linux kernel version: 2.6.34-rc2
+# Thu Apr  8 14:49:08 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -19,6 +20,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_ARCH_HAS_CPUFREQ=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_ARCH_MTD_XIP=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -60,11 +62,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -97,10 +94,14 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
@@ -184,6 +185,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -193,7 +195,6 @@ CONFIG_MMU=y
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -210,21 +211,26 @@ CONFIG_MMU=y
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 CONFIG_ARCH_PXA=y
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
 # CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_U8500 is not set
 
 #
 # Intel PXA2xx/PXA3xx Implementations
@@ -253,6 +259,7 @@ CONFIG_ARCH_PXA=y
 # CONFIG_MACH_EM_X270 is not set
 # CONFIG_MACH_EXEDA is not set
 # CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_CAPC7117 is not set
 # CONFIG_ARCH_GUMSTIX is not set
 CONFIG_MACH_INTELMOTE2=y
 # CONFIG_MACH_STARGATE2 is not set
@@ -275,7 +282,11 @@ CONFIG_MACH_INTELMOTE2=y
 # CONFIG_PXA_EZX is not set
 # CONFIG_MACH_MP900C is not set
 # CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_MACH_RAUMFELD_RC is not set
+# CONFIG_MACH_RAUMFELD_CONNECTOR is not set
+# CONFIG_MACH_RAUMFELD_SPEAKER is not set
 # CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_ICONTROL is not set
 # CONFIG_ARCH_PXA_ESERIES is not set
 CONFIG_PXA27x=y
 CONFIG_PXA_SSP=y
@@ -302,6 +313,7 @@ CONFIG_ARM_THUMB=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_IWMMXT=y
 CONFIG_XSCALE_PMU=y
+CONFIG_CPU_HAS_PMU=y
 CONFIG_COMMON_CLKDEV=y
 
 #
@@ -352,7 +364,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
+CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS2,115200 mem=32M"
 # CONFIG_XIP_KERNEL is not set
 CONFIG_KEXEC=y
 CONFIG_ATAGS_PROC=y
@@ -360,24 +372,8 @@ CONFIG_ATAGS_PROC=y
 #
 # CPU Power Management
 #
-CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_TABLE=y
-CONFIG_CPU_FREQ_DEBUG=y
-CONFIG_CPU_FREQ_STAT=y
-# CONFIG_CPU_FREQ_STAT_DETAILS is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
-# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-CONFIG_CPU_FREQ_GOV_POWERSAVE=m
-CONFIG_CPU_FREQ_GOV_USERSPACE=m
-CONFIG_CPU_FREQ_GOV_ONDEMAND=m
-CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -409,6 +405,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_APM_EMULATION=y
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -416,7 +413,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -506,6 +502,7 @@ CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_LED=m
@@ -622,6 +619,7 @@ CONFIG_IP6_NF_RAW=m
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
 # CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
@@ -646,32 +644,7 @@ CONFIG_NET_CLS_ROUTE=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-CONFIG_BT_HIDP=y
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIBTUSB=m
-CONFIG_BT_HCIBTSDIO=m
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART_BCSP is not set
-# CONFIG_BT_HCIUART_LL is not set
-CONFIG_BT_HCIBCM203X=m
-CONFIG_BT_HCIBPA10X=m
-CONFIG_BT_HCIBFUSB=m
-CONFIG_BT_HCIVHCI=m
-CONFIG_BT_MRVL=m
-CONFIG_BT_MRVL_SDIO=m
-# CONFIG_BT_ATH3K is not set
+# CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
 # CONFIG_WIRELESS is not set
@@ -687,7 +660,8 @@ CONFIG_FIB_RULES=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_DEVTMPFS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
@@ -703,9 +677,9 @@ CONFIG_MTD=y
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_AR7_PARTS=y
 
 #
 # User Modules And Translation Layers
@@ -812,6 +786,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -965,6 +940,7 @@ CONFIG_SERIAL_PXA=y
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -993,6 +969,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1006,15 +983,9 @@ CONFIG_I2C_PXA=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1046,10 +1017,12 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
@@ -1093,10 +1066,12 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
@@ -1105,22 +1080,25 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TC6393XB is not set
 CONFIG_PMIC_DA903X=y
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_DEBUG=y
+# CONFIG_REGULATOR_DUMMY is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
 CONFIG_REGULATOR_USERSPACE_CONSUMER=y
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
 # CONFIG_REGULATOR_MAX8660 is not set
 CONFIG_REGULATOR_DA903X=y
 # CONFIG_REGULATOR_LP3971 is not set
@@ -1218,6 +1196,7 @@ CONFIG_VIDEO_IR_I2C=y
 # CONFIG_VIDEO_SAA7191 is not set
 # CONFIG_VIDEO_TVP514X is not set
 # CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_TVP7002 is not set
 # CONFIG_VIDEO_VPX3220 is not set
 
 #
@@ -1264,15 +1243,7 @@ CONFIG_SOC_CAMERA_MT9M111=y
 CONFIG_VIDEO_PXA27x=y
 # CONFIG_VIDEO_SH_MOBILE_CEU is not set
 # CONFIG_V4L_USB_DRIVERS is not set
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_I2C_SI4713 is not set
-# CONFIG_RADIO_SI4713 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_RADIO_SI470X is not set
-# CONFIG_USB_MR800 is not set
-CONFIG_RADIO_TEA5764=y
-CONFIG_RADIO_TEA5764_XTAL=y
-# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_RADIO_ADAPTERS is not set
 # CONFIG_DAB is not set
 
 #
@@ -1398,8 +1369,6 @@ CONFIG_HID=y
 #
 # Special HID drivers
 #
-CONFIG_HID_APPLE=m
-# CONFIG_HID_WACOM is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1477,7 +1446,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1489,7 +1457,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1529,6 +1496,7 @@ CONFIG_USB_ETH=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1555,8 +1523,6 @@ CONFIG_SDIO_UART=m
 #
 CONFIG_MMC_PXA=y
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -1574,11 +1540,11 @@ CONFIG_LEDS_LP3944=y
 # CONFIG_LEDS_REGULATOR is not set
 # CONFIG_LEDS_BD2802 is not set
 # CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_BACKLIGHT=y
@@ -1656,7 +1622,7 @@ CONFIG_RTC_INTF_DEV=y
 # on-CPU RTC drivers
 #
 # CONFIG_RTC_DRV_SA1100 is not set
-# CONFIG_RTC_DRV_PXA is not set
+CONFIG_RTC_DRV_PXA=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -1681,19 +1647,10 @@ CONFIG_EXT3_FS_XATTR=y
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
+# CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
 # CONFIG_NILFS2_FS is not set
@@ -1716,9 +1673,7 @@ CONFIG_CUSE=m
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
+# CONFIG_ISO9660_FS is not set
 # CONFIG_UDF_FS is not set
 
 #
@@ -1750,12 +1705,14 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-# CONFIG_JFFS2_SUMMARY is not set
-# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_LZO=y
@@ -1765,6 +1722,7 @@ CONFIG_JFFS2_RUBIN=y
 CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_JFFS2_CMODE_SIZE is not set
 # CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
 # CONFIG_SQUASHFS_EMBEDDED is not set
@@ -1802,6 +1760,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 CONFIG_CIFS_STATS=y
 # CONFIG_CIFS_STATS2 is not set
@@ -1895,6 +1854,7 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
 CONFIG_LOCKDEP=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_LOCKDEP is not set
@@ -1918,6 +1878,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -2061,9 +2022,9 @@ CONFIG_CRC32=y
 CONFIG_CRC7=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
@@ -2075,3 +2036,4 @@ CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
index 03f76cf..4b55dcb 100644 (file)
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Tue Jan  5 13:55:22 2010
+# Linux kernel version: 2.6.34-rc5
+# Wed Apr 28 11:23:19 2010
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,6 +19,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,6 +34,12 @@ CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -52,7 +60,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -85,10 +92,14 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
 
 #
 # Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -104,6 +115,7 @@ CONFIG_HAVE_CLK=y
 #
 # GCOV-based kernel profiling
 #
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -170,6 +182,7 @@ CONFIG_MMU=y
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
@@ -179,7 +192,6 @@ CONFIG_MMU=y
 # CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -196,21 +208,26 @@ CONFIG_ARCH_MMP=y
 # CONFIG_ARCH_KS8695 is not set
 # CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
 # CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_U8500 is not set
 # CONFIG_MACH_TAVOREVB is not set
 
 #
@@ -218,8 +235,10 @@ CONFIG_ARCH_MMP=y
 #
 # CONFIG_MACH_ASPENITE is not set
 # CONFIG_MACH_ZYLONITE2 is not set
+# CONFIG_MACH_AVENGERS_LITE is not set
 # CONFIG_MACH_TTC_DKB is not set
 CONFIG_MACH_FLINT=y
+CONFIG_MACH_MARVELL_JASPER=y
 CONFIG_CPU_MMP2=y
 CONFIG_PLAT_PXA=y
 
@@ -246,7 +265,10 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_TAUROS2=y
 CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
 # CONFIG_ARM_ERRATA_411920 is not set
 CONFIG_COMMON_CLKDEV=y
 
@@ -298,7 +320,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M user_debug=255"
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=128M user_debug=255"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -338,7 +360,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -532,6 +553,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -640,6 +662,7 @@ CONFIG_SERIAL_PXA=y
 CONFIG_SERIAL_PXA_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -667,6 +690,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_PXA=y
 # CONFIG_I2C_PXA_SLAVE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -679,15 +703,9 @@ CONFIG_I2C_PXA=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -702,13 +720,16 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -737,10 +758,12 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
@@ -749,24 +772,27 @@ CONFIG_MFD_CORE=y
 # CONFIG_MFD_TC6393XB is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+CONFIG_MFD_MAX8925=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-CONFIG_MFD_88PM8607=y
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
 # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_REGULATOR_MAX1586 is not set
-CONFIG_REGULATOR_MAX8660=y
+CONFIG_REGULATOR_MAX8649=y
+# CONFIG_REGULATOR_MAX8660 is not set
+CONFIG_REGULATOR_MAX8925=y
 # CONFIG_REGULATOR_LP3971 is not set
 # CONFIG_REGULATOR_TPS65023 is not set
 # CONFIG_REGULATOR_TPS6507X is not set
-CONFIG_REGULATOR_88PM8607=y
 # CONFIG_MEDIA_SUPPORT is not set
 
 #
@@ -781,6 +807,7 @@ CONFIG_LCD_CLASS_DEVICE=y
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_BACKLIGHT_MAX8925=y
 
 #
 # Display device support
@@ -821,6 +848,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_DS1374 is not set
 # CONFIG_RTC_DRV_DS1672 is not set
 # CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_MAX8925=y
 # CONFIG_RTC_DRV_RS5C372 is not set
 # CONFIG_RTC_DRV_ISL1208 is not set
 # CONFIG_RTC_DRV_X1205 is not set
@@ -872,7 +900,6 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
@@ -883,7 +910,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
-CONFIG_DNOTIFY=y
+# CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
@@ -940,6 +967,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -967,6 +995,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -990,7 +1019,7 @@ CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
@@ -1032,6 +1061,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1052,6 +1082,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1059,9 +1090,7 @@ CONFIG_ARM_UNWIND=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_STACK_USAGE is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_EARLY_PRINTK is not set
-# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_LL is not set
 # CONFIG_OC_ETM is not set
 
 #
index 216ad00..9405e32 100644 (file)
@@ -1058,7 +1058,6 @@ CONFIG_JFFS2_CMODE_PRIORITY=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
index f5c6e11..881faea 100644 (file)
@@ -661,7 +661,7 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
index ea9a501..5e55b55 100644 (file)
@@ -680,7 +680,7 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
index 45135ff..473f9e1 100644 (file)
@@ -59,8 +59,6 @@ CONFIG_FAIR_GROUP_SCHED=y
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -480,7 +478,6 @@ CONFIG_BT_HIDP=m
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=y
 # CONFIG_CFG80211_REG_DEBUG is not set
diff --git a/arch/arm/configs/spear300_defconfig b/arch/arm/configs/spear300_defconfig
new file mode 100644 (file)
index 0000000..35e64d1
--- /dev/null
@@ -0,0 +1,773 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:36:23 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+CONFIG_MACH_SPEAR300=y
+# CONFIG_MACH_SPEAR310 is not set
+# CONFIG_MACH_SPEAR320 is not set
+CONFIG_BOARD_SPEAR300_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear310_defconfig b/arch/arm/configs/spear310_defconfig
new file mode 100644 (file)
index 0000000..cbbfd29
--- /dev/null
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:37:01 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+# CONFIG_MACH_SPEAR300 is not set
+CONFIG_MACH_SPEAR310=y
+# CONFIG_MACH_SPEAR320 is not set
+# CONFIG_BOARD_SPEAR300_EVB is not set
+CONFIG_BOARD_SPEAR310_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear320_defconfig b/arch/arm/configs/spear320_defconfig
new file mode 100644 (file)
index 0000000..2ae3c11
--- /dev/null
@@ -0,0 +1,775 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:37:12 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR3XX=y
+# CONFIG_ARCH_SPEAR6XX is not set
+# CONFIG_MACH_SPEAR300 is not set
+# CONFIG_MACH_SPEAR310 is not set
+CONFIG_MACH_SPEAR320=y
+# CONFIG_BOARD_SPEAR300_EVB is not set
+CONFIG_BOARD_SPEAR320_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/spear600_defconfig b/arch/arm/configs/spear600_defconfig
new file mode 100644 (file)
index 0000000..c85a029
--- /dev/null
@@ -0,0 +1,760 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32
+# Tue Mar 23 14:37:26 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_PLAT_SPEAR=y
+# CONFIG_ARCH_SPEAR3XX is not set
+CONFIG_ARCH_SPEAR6XX=y
+# CONFIG_MACH_SPEAR300 is not set
+# CONFIG_MACH_SPEAR310 is not set
+# CONFIG_MACH_SPEAR320 is not set
+# CONFIG_BOARD_SPEAR300_EVB is not set
+CONFIG_MACH_SPEAR600=y
+CONFIG_BOARD_SPEAR600_EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_PL061=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig
new file mode 100644 (file)
index 0000000..06a8293
--- /dev/null
@@ -0,0 +1,1456 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc1
+# Wed Mar 17 16:38:03 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_RCU is not set
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+CONFIG_HAVE_AT91_USART3=y
+CONFIG_HAVE_AT91_USART4=y
+CONFIG_HAVE_AT91_USART5=y
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9G10 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+CONFIG_ARCH_AT91SAM9G20=y
+# CONFIG_ARCH_AT91SAM9G45 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT572D940HF is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9G20 Board Type
+#
+# CONFIG_MACH_AT91SAM9G20EK is not set
+# CONFIG_MACH_AT91SAM9G20EK_2MMC is not set
+# CONFIG_MACH_CPU9G20 is not set
+CONFIG_MACH_PORTUXG20=y
+CONFIG_MACH_STAMP9G20=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_SLOW_CLOCK=y
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=999999
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
+# CONFIG_MTD_DATAFLASH_OTP is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
+CONFIG_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+CONFIG_W1_MASTER_GPIO=y
+
+#
+# 1-wire Slaves
+#
+CONFIG_W1_SLAVE_THERM=y
+# CONFIG_W1_SLAVE_SMEM is not set
+CONFIG_W1_SLAVE_DS2431=y
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_AT91SAM9X_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=m
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_AT91 is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_RTC_DRV_AT91SAM9_RTT=0
+CONFIG_RTC_DRV_AT91SAM9_GPBR=0
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
index 00f46d9..6e8f05c 100644 (file)
 
 #define USER(x...)                             \
 9999:  x;                                      \
-       .section __ex_table,"a";                \
+       .pushsection __ex_table,"a";            \
        .align  3;                              \
        .long   9999b,9001f;                    \
-       .previous
+       .popsection
 
 /*
  * SMP data memory barrier
        .error  "Unsupported inc macro argument"
        .endif
 
-       .section __ex_table,"a"
+       .pushsection __ex_table,"a"
        .align  3
        .long   9999b, \abort
-       .previous
+       .popsection
        .endm
 
        .macro  usracc, instr, reg, ptr, inc, cond, rept, abort
        .error  "Unsupported inc macro argument"
        .endif
 
-       .section __ex_table,"a"
+       .pushsection __ex_table,"a"
        .align  3
        .long   9999b, \abort
-       .previous
+       .popsection
        .endr
        .endm
 
index e8ddec2..a0162fa 100644 (file)
@@ -24,7 +24,7 @@
  * strex/ldrex monitor on some implementations. The reason we can use it for
  * atomic_set() is the clrex or dummy strex done on every exception return.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 #define atomic_set(v,i)        (((v)->counter) = (i))
 
 #if __LINUX_ARM_ARCH__ >= 6
index 0d08d41..4656a24 100644 (file)
@@ -371,6 +371,10 @@ static inline void __flush_icache_all(void)
 #ifdef CONFIG_ARM_ERRATA_411920
        extern void v6_icache_inval_all(void);
        v6_icache_inval_all();
+#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7
+       asm("mcr        p15, 0, %0, c7, c1, 0   @ invalidate I-cache inner shareable\n"
+           :
+           : "r" (0));
 #else
        asm("mcr        p15, 0, %0, c7, c5, 0   @ invalidate I-cache\n"
            :
index bff0564..51662fe 100644 (file)
@@ -9,6 +9,8 @@
 #include <asm/ptrace.h>
 #include <asm/user.h>
 
+struct task_struct;
+
 typedef unsigned long elf_greg_t;
 typedef unsigned long elf_freg_t[3];
 
index bfcc159..540a044 100644 (file)
        "2:     strt    %0, [%2]\n"                             \
        "       mov     %0, #0\n"                               \
        "3:\n"                                                  \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 4f, 2b, 4f\n"                       \
-       "       .previous\n"                                    \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .popsection\n"                                  \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "4:     mov     %0, %4\n"                               \
        "       b       3b\n"                                   \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "=&r" (ret), "=&r" (oldval)                           \
        : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)              \
        : "cc", "memory")
@@ -102,14 +102,14 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
        "       it      eq      @ explicit IT needed for the 2b label\n"
        "2:     streqt  %2, [%3]\n"
        "3:\n"
-       "       .section __ex_table,\"a\"\n"
+       "       .pushsection __ex_table,\"a\"\n"
        "       .align  3\n"
        "       .long   1b, 4f, 2b, 4f\n"
-       "       .previous\n"
-       "       .section .fixup,\"ax\"\n"
+       "       .popsection\n"
+       "       .pushsection .fixup,\"ax\"\n"
        "4:     mov     %0, %4\n"
        "       b       3b\n"
-       "       .previous"
+       "       .popsection"
        : "=&r" (val)
        : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
        : "cc", "memory");
index 04be3bd..c0f4e7b 100644 (file)
@@ -1,21 +1,30 @@
 #ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
 #define __ASM_ARM_HARDWARE_ARM_TIMER_H
 
-#define TIMER_LOAD     0x00
-#define TIMER_VALUE    0x04
-#define TIMER_CTRL     0x08
-#define TIMER_CTRL_ONESHOT     (1 << 0)
-#define TIMER_CTRL_32BIT       (1 << 1)
-#define TIMER_CTRL_DIV1                (0 << 2)
-#define TIMER_CTRL_DIV16       (1 << 2)
-#define TIMER_CTRL_DIV256      (2 << 2)
-#define TIMER_CTRL_IE          (1 << 5)        /* Interrupt Enable (versatile only) */
-#define TIMER_CTRL_PERIODIC    (1 << 6)
-#define TIMER_CTRL_ENABLE      (1 << 7)
+/*
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms.  Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD     0x00                    /* ACVR rw */
+#define TIMER_VALUE    0x04                    /* ACVR ro */
+#define TIMER_CTRL     0x08                    /* ACVR rw */
+#define TIMER_CTRL_ONESHOT     (1 << 0)        /*  CVR */
+#define TIMER_CTRL_32BIT       (1 << 1)        /*  CVR */
+#define TIMER_CTRL_DIV1                (0 << 2)        /* ACVR */
+#define TIMER_CTRL_DIV16       (1 << 2)        /* ACVR */
+#define TIMER_CTRL_DIV256      (2 << 2)        /* ACVR */
+#define TIMER_CTRL_IE          (1 << 5)        /*   VR */
+#define TIMER_CTRL_PERIODIC    (1 << 6)        /* ACVR */
+#define TIMER_CTRL_ENABLE      (1 << 7)        /* ACVR */
 
-#define TIMER_INTCLR   0x0c
-#define TIMER_RIS      0x10
-#define TIMER_MIS      0x14
-#define TIMER_BGLOAD   0x18
+#define TIMER_INTCLR   0x0c                    /* ACVR wo */
+#define TIMER_RIS      0x10                    /*  CVR ro */
+#define TIMER_MIS      0x14                    /*  CVR ro */
+#define TIMER_BGLOAD   0x18                    /*  CVR rw */
 
 #endif
index cdb9022..6bcba48 100644 (file)
@@ -21,6 +21,9 @@
 #define __ASM_ARM_HARDWARE_L2X0_H
 
 #define L2X0_CACHE_ID                  0x000
+#define   L2X0_CACHE_ID_PART_MASK      (0xf << 6)
+#define   L2X0_CACHE_ID_PART_L210      (1 << 6)
+#define   L2X0_CACHE_ID_PART_L310      (3 << 6)
 #define L2X0_CACHE_TYPE                        0x004
 #define L2X0_CTRL                      0x100
 #define L2X0_AUX_CTRL                  0x104
diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h
new file mode 100644 (file)
index 0000000..10382a3
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  arch/arm/include/asm/hardware/icst.h
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 as
+ * published by the Free Software Foundation.
+ *
+ *  Support functions for calculating clocks/divisors for the ICST
+ *  clock generators.  See http://www.icst.com/ for more information
+ *  on these devices.
+ */
+#ifndef ASMARM_HARDWARE_ICST_H
+#define ASMARM_HARDWARE_ICST_H
+
+struct icst_params {
+       unsigned long   ref;
+       unsigned long   vco_max;        /* inclusive */
+       unsigned long   vco_min;        /* exclusive */
+       unsigned short  vd_min;         /* inclusive */
+       unsigned short  vd_max;         /* inclusive */
+       unsigned char   rd_min;         /* inclusive */
+       unsigned char   rd_max;         /* inclusive */
+       const unsigned char *s2div;     /* chip specific s2div array */
+       const unsigned char *idx2s;     /* chip specific idx2s array */
+};
+
+struct icst_vco {
+       unsigned short  v;
+       unsigned char   r;
+       unsigned char   s;
+};
+
+unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco);
+struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq);
+
+/*
+ * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V).
+ * This frequency is pre-output divider.
+ */
+#define ICST307_VCO_MIN        6000000
+#define ICST307_VCO_MAX        200000000
+
+extern const unsigned char icst307_s2div[];
+extern const unsigned char icst307_idx2s[];
+
+/*
+ * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V).
+ * This frequency is pre-output divider.
+ */
+#define ICST525_VCO_MIN                10000000
+#define ICST525_VCO_MAX_3V     200000000
+#define ICST525_VCO_MAX_5V     320000000
+
+extern const unsigned char icst525_s2div[];
+extern const unsigned char icst525_idx2s[];
+
+#endif
diff --git a/arch/arm/include/asm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h
deleted file mode 100644 (file)
index 554f128..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  arch/arm/include/asm/hardware/icst307.h
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 as
- * published by the Free Software Foundation.
- *
- *  Support functions for calculating clocks/divisors for the ICS307
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- *
- *  This file is similar to the icst525.h file
- */
-#ifndef ASMARM_HARDWARE_ICST307_H
-#define ASMARM_HARDWARE_ICST307_H
-
-struct icst307_params {
-       unsigned long   ref;
-       unsigned long   vco_max;        /* inclusive */
-       unsigned short  vd_min;         /* inclusive */
-       unsigned short  vd_max;         /* inclusive */
-       unsigned char   rd_min;         /* inclusive */
-       unsigned char   rd_max;         /* inclusive */
-};
-
-struct icst307_vco {
-       unsigned short  v;
-       unsigned char   r;
-       unsigned char   s;
-};
-
-unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco);
-struct icst307_vco icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq);
-struct icst307_vco icst307_ps_to_vco(const struct icst307_params *p, unsigned long period);
-
-#endif
diff --git a/arch/arm/include/asm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h
deleted file mode 100644 (file)
index 58f0dc4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  arch/arm/include/asm/hardware/icst525.h
- *
- *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 as
- * published by the Free Software Foundation.
- *
- *  Support functions for calculating clocks/divisors for the ICST525
- *  clock generators.  See http://www.icst.com/ for more information
- *  on these devices.
- */
-#ifndef ASMARM_HARDWARE_ICST525_H
-#define ASMARM_HARDWARE_ICST525_H
-
-struct icst525_params {
-       unsigned long   ref;
-       unsigned long   vco_max;        /* inclusive */
-       unsigned short  vd_min;         /* inclusive */
-       unsigned short  vd_max;         /* inclusive */
-       unsigned char   rd_min;         /* inclusive */
-       unsigned char   rd_max;         /* inclusive */
-};
-
-struct icst525_vco {
-       unsigned short  v;
-       unsigned char   r;
-       unsigned char   s;
-};
-
-unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco);
-struct icst525_vco icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq);
-struct icst525_vco icst525_ps_to_vco(const struct icst525_params *p, unsigned long period);
-
-#endif
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
new file mode 100644 (file)
index 0000000..575fa81
--- /dev/null
@@ -0,0 +1,217 @@
+/* linux/include/asm/hardware/pl330.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PL330_CORE_H
+#define __PL330_CORE_H
+
+#define PL330_MAX_CHAN         8
+#define PL330_MAX_IRQS         32
+#define PL330_MAX_PERI         32
+
+enum pl330_srccachectrl {
+       SCCTRL0 = 0, /* Noncacheable and nonbufferable */
+       SCCTRL1, /* Bufferable only */
+       SCCTRL2, /* Cacheable, but do not allocate */
+       SCCTRL3, /* Cacheable and bufferable, but do not allocate */
+       SINVALID1,
+       SINVALID2,
+       SCCTRL6, /* Cacheable write-through, allocate on reads only */
+       SCCTRL7, /* Cacheable write-back, allocate on reads only */
+};
+
+enum pl330_dstcachectrl {
+       DCCTRL0 = 0, /* Noncacheable and nonbufferable */
+       DCCTRL1, /* Bufferable only */
+       DCCTRL2, /* Cacheable, but do not allocate */
+       DCCTRL3, /* Cacheable and bufferable, but do not allocate */
+       DINVALID1 = 8,
+       DINVALID2,
+       DCCTRL6, /* Cacheable write-through, allocate on writes only */
+       DCCTRL7, /* Cacheable write-back, allocate on writes only */
+};
+
+/* Populated by the PL330 core driver for DMA API driver's info */
+struct pl330_config {
+       u32     periph_id;
+       u32     pcell_id;
+#define DMAC_MODE_NS   (1 << 0)
+       unsigned int    mode;
+       unsigned int    data_bus_width:10; /* In number of bits */
+       unsigned int    data_buf_dep:10;
+       unsigned int    num_chan:4;
+       unsigned int    num_peri:6;
+       u32             peri_ns;
+       unsigned int    num_events:6;
+       u32             irq_ns;
+};
+
+/* Handle to the DMAC provided to the PL330 core */
+struct pl330_info {
+       /* Owning device */
+       struct device *dev;
+       /* Size of MicroCode buffers for each channel. */
+       unsigned mcbufsz;
+       /* ioremap'ed address of PL330 registers. */
+       void __iomem    *base;
+       /* Client can freely use it. */
+       void    *client_data;
+       /* PL330 core data, Client must not touch it. */
+       void    *pl330_data;
+       /* Populated by the PL330 core driver during pl330_add */
+       struct pl330_config     pcfg;
+       /*
+        * If the DMAC has some reset mechanism, then the
+        * client may want to provide pointer to the method.
+        */
+       void (*dmac_reset)(struct pl330_info *pi);
+};
+
+enum pl330_byteswap {
+       SWAP_NO = 0,
+       SWAP_2,
+       SWAP_4,
+       SWAP_8,
+       SWAP_16,
+};
+
+/**
+ * Request Configuration.
+ * The PL330 core does not modify this and uses the last
+ * working configuration if the request doesn't provide any.
+ *
+ * The Client may want to provide this info only for the
+ * first request and a request with new settings.
+ */
+struct pl330_reqcfg {
+       /* Address Incrementing */
+       unsigned dst_inc:1;
+       unsigned src_inc:1;
+
+       /*
+        * For now, the SRC & DST protection levels
+        * and burst size/length are assumed same.
+        */
+       bool nonsecure;
+       bool privileged;
+       bool insnaccess;
+       unsigned brst_len:5;
+       unsigned brst_size:3; /* in power of 2 */
+
+       enum pl330_dstcachectrl dcctl;
+       enum pl330_srccachectrl scctl;
+       enum pl330_byteswap swap;
+};
+
+/*
+ * One cycle of DMAC operation.
+ * There may be more than one xfer in a request.
+ */
+struct pl330_xfer {
+       u32 src_addr;
+       u32 dst_addr;
+       /* Size to xfer */
+       u32 bytes;
+       /*
+        * Pointer to next xfer in the list.
+        * The last xfer in the req must point to NULL.
+        */
+       struct pl330_xfer *next;
+};
+
+/* The xfer callbacks are made with one of these arguments. */
+enum pl330_op_err {
+       /* The all xfers in the request were success. */
+       PL330_ERR_NONE,
+       /* If req aborted due to global error. */
+       PL330_ERR_ABORT,
+       /* If req failed due to problem with Channel. */
+       PL330_ERR_FAIL,
+};
+
+enum pl330_reqtype {
+       MEMTOMEM,
+       MEMTODEV,
+       DEVTOMEM,
+       DEVTODEV,
+};
+
+/* A request defining Scatter-Gather List ending with NULL xfer. */
+struct pl330_req {
+       enum pl330_reqtype rqtype;
+       /* Index of peripheral for the xfer. */
+       unsigned peri:5;
+       /* Unique token for this xfer, set by the client. */
+       void *token;
+       /* Callback to be called after xfer. */
+       void (*xfer_cb)(void *token, enum pl330_op_err err);
+       /* If NULL, req will be done at last set parameters. */
+       struct pl330_reqcfg *cfg;
+       /* Pointer to first xfer in the request. */
+       struct pl330_xfer *x;
+};
+
+/*
+ * To know the status of the channel and DMAC, the client
+ * provides a pointer to this structure. The PL330 core
+ * fills it with current information.
+ */
+struct pl330_chanstatus {
+       /*
+        * If the DMAC engine halted due to some error,
+        * the client should remove-add DMAC.
+        */
+       bool dmac_halted;
+       /*
+        * If channel is halted due to some error,
+        * the client should ABORT/FLUSH and START the channel.
+        */
+       bool faulting;
+       /* Location of last load */
+       u32 src_addr;
+       /* Location of last store */
+       u32 dst_addr;
+       /*
+        * Pointer to the currently active req, NULL if channel is
+        * inactive, even though the requests may be present.
+        */
+       struct pl330_req *top_req;
+       /* Pointer to req waiting second in the queue if any. */
+       struct pl330_req *wait_req;
+};
+
+enum pl330_chan_op {
+       /* Start the channel */
+       PL330_OP_START,
+       /* Abort the active xfer */
+       PL330_OP_ABORT,
+       /* Stop xfer and flush queue */
+       PL330_OP_FLUSH,
+};
+
+extern int pl330_add(struct pl330_info *);
+extern void pl330_del(struct pl330_info *pi);
+extern int pl330_update(const struct pl330_info *pi);
+extern void pl330_release_channel(void *ch_id);
+extern void *pl330_request_channel(const struct pl330_info *pi);
+extern int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus);
+extern int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op);
+extern int pl330_submit_req(void *ch_id, struct pl330_req *r);
+
+#endif /* __PL330_CORE_H */
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
new file mode 100644 (file)
index 0000000..a101f10
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/include/asm/hardware/sp810.h
+ *
+ * ARM PrimeXsys System Controller SP810 header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARM_SP810_H
+#define __ASM_ARM_SP810_H
+
+#include <linux/io.h>
+
+/* sysctl registers offset */
+#define SCCTRL                 0x000
+#define SCSYSSTAT              0x004
+#define SCIMCTRL               0x008
+#define SCIMSTAT               0x00C
+#define SCXTALCTRL             0x010
+#define SCPLLCTRL              0x014
+#define SCPLLFCTRL             0x018
+#define SCPERCTRL0             0x01C
+#define SCPERCTRL1             0x020
+#define SCPEREN                        0x024
+#define SCPERDIS               0x028
+#define SCPERCLKEN             0x02C
+#define SCPERSTAT              0x030
+#define SCSYSID0               0xEE0
+#define SCSYSID1               0xEE4
+#define SCSYSID2               0xEE8
+#define SCSYSID3               0xEEC
+#define SCITCR                 0xF00
+#define SCITIR0                        0xF04
+#define SCITIR1                        0xF08
+#define SCITOR                 0xF0C
+#define SCCNTCTRL              0xF10
+#define SCCNTDATA              0xF14
+#define SCCNTSTEP              0xF18
+#define SCPERIPHID0            0xFE0
+#define SCPERIPHID1            0xFE4
+#define SCPERIPHID2            0xFE8
+#define SCPERIPHID3            0xFEC
+#define SCPCELLID0             0xFF0
+#define SCPCELLID1             0xFF4
+#define SCPCELLID2             0xFF8
+#define SCPCELLID3             0xFFC
+
+static inline void sysctl_soft_reset(void __iomem *base)
+{
+       /* writing any value to SCSYSSTAT reg will reset system */
+       writel(0, base + SCSYSSTAT);
+}
+
+#endif /* __ASM_ARM_SP810_H */
index 7f36d00..feb988a 100644 (file)
 
 #define kmap_prot              PAGE_KERNEL
 
-#define flush_cache_kmaps()    flush_cache_all()
+#define flush_cache_kmaps() \
+       do { \
+               if (cache_is_vivt()) \
+                       flush_cache_all(); \
+       } while (0)
 
 extern pte_t *pkmap_page_table;
 
@@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void kunmap_high(struct page *page);
 
+extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
+extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
 extern void *kmap(struct page *page);
 extern void kunmap(struct page *page);
 extern void *kmap_atomic(struct page *page, enum km_type type);
 extern void kunmap_atomic(void *kvaddr, enum km_type type);
 extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 extern struct page *kmap_atomic_to_page(const void *ptr);
+#endif
 
 #endif
index a91d8a1..7f0b6d1 100644 (file)
@@ -53,6 +53,9 @@
 #define TIOCGPTN       _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK     _IOW('T',0x31, int)  /* Lock/unlock Pty */
 
+#define TIOCGRS485      0x542E
+#define TIOCSRS485      0x542F
+
 #define FIONCLEX       0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX                0x5451
 #define FIOASYNC       0x5452
index c019949..c4b2ea3 100644 (file)
@@ -18,6 +18,7 @@ enum km_type {
        KM_IRQ1,
        KM_SOFTIRQ0,
        KM_SOFTIRQ1,
+       KM_L1_CACHE,
        KM_L2_CACHE,
        KM_TYPE_NR
 };
index a38bdc7..52f0da1 100644 (file)
@@ -8,10 +8,16 @@
  * published by the Free Software Foundation.
  */
 
+#ifndef __ASM_MACH_PCI_H
+#define __ASM_MACH_PCI_H
+
 struct pci_sys_data;
 struct pci_bus;
 
 struct hw_pci {
+#ifdef CONFIG_PCI_DOMAINS
+       int             domain;
+#endif
        struct list_head buses;
        int             nr_controllers;
        int             (*setup)(int nr, struct pci_sys_data *);
@@ -26,6 +32,9 @@ struct hw_pci {
  * Per-controller structure
  */
 struct pci_sys_data {
+#ifdef CONFIG_PCI_DOMAINS
+       int             domain;
+#endif
        struct list_head node;
        int             busnr;          /* primary bus number                   */
        u64             mem_offset;     /* bus->cpu memory mapping offset       */
@@ -70,3 +79,5 @@ extern int pci_v3_setup(int nr, struct pci_sys_data *);
 extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *);
 extern void pci_v3_preinit(void);
 extern void pci_v3_postinit(void);
+
+#endif /* __ASM_MACH_PCI_H */
index 8bffc3f..35d408f 100644 (file)
@@ -38,7 +38,7 @@ struct sys_timer {
        void                    (*init)(void);
        void                    (*suspend)(void);
        void                    (*resume)(void);
-#ifndef CONFIG_GENERIC_TIME
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
        unsigned long           (*offset)(void);
 #endif
 };
index 4798011..92e2a83 100644 (file)
@@ -4,8 +4,23 @@
 #ifdef __KERNEL__
 #include <asm-generic/pci-dma-compat.h>
 
+#include <asm/mach/pci.h> /* for pci_sys_data */
 #include <mach/hardware.h> /* for PCIBIOS_MIN_* */
 
+#ifdef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+       struct pci_sys_data *root = bus->sysdata;
+
+       return root->domain;
+}
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+       return pci_domain_nr(bus);
+}
+#endif /* CONFIG_PCI_DOMAINS */
+
 #ifdef CONFIG_PCI_HOST_ITE8152
 /* ITE bridge requires setting latency timer to avoid early bus access
    termination by PIC bus mater devices
index 49e3049..48837e6 100644 (file)
@@ -28,4 +28,21 @@ set_perf_event_pending(void)
  * same indexes here for consistency. */
 #define PERF_EVENT_INDEX_OFFSET 1
 
+/* ARM perf PMU IDs for use by internal perf clients. */
+enum arm_perf_pmu_ids {
+       ARM_PERF_PMU_ID_XSCALE1 = 0,
+       ARM_PERF_PMU_ID_XSCALE2,
+       ARM_PERF_PMU_ID_V6,
+       ARM_PERF_PMU_ID_V6MP,
+       ARM_PERF_PMU_ID_CA8,
+       ARM_PERF_PMU_ID_CA9,
+       ARM_NUM_PMU_IDS,
+};
+
+extern enum arm_perf_pmu_ids
+armpmu_get_pmu_id(void);
+
+extern int
+armpmu_get_max_events(void);
+
 #endif /* __ARM_PERF_EVENT_H__ */
index 1139768..ab68cf1 100644 (file)
@@ -314,7 +314,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
 #define pgprot_writecombine(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
-#if __LINUX_ARM_ARCH__ >= 7
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 #define pgprot_dmacoherent(prot) \
        __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
 #else
index 2829b9f..8ccea01 100644 (file)
 #ifndef __ARM_PMU_H__
 #define __ARM_PMU_H__
 
-#ifdef CONFIG_CPU_HAS_PMU
-
-struct pmu_irqs {
-       const int   *irqs;
-       int         num_irqs;
+enum arm_pmu_type {
+       ARM_PMU_DEVICE_CPU      = 0,
+       ARM_NUM_PMU_DEVICES,
 };
 
+#ifdef CONFIG_CPU_HAS_PMU
+
 /**
  * reserve_pmu() - reserve the hardware performance counters
  *
  * Reserve the hardware performance counters in the system for exclusive use.
- * The 'struct pmu_irqs' for the system is returned on success, ERR_PTR()
+ * The platform_device for the system is returned on success, ERR_PTR()
  * encoded error on failure.
  */
-extern const struct pmu_irqs *
-reserve_pmu(void);
+extern struct platform_device *
+reserve_pmu(enum arm_pmu_type device);
 
 /**
  * release_pmu() - Relinquish control of the performance counters
  *
  * Release the performance counters and allow someone else to use them.
  * Callers must have disabled the counters and released IRQs before calling
- * this. The 'struct pmu_irqs' returned from reserve_pmu() must be passed as
+ * this. The platform_device returned from reserve_pmu() must be passed as
  * a cookie.
  */
 extern int
-release_pmu(const struct pmu_irqs *irqs);
+release_pmu(struct platform_device *pdev);
 
 /**
  * init_pmu() - Initialise the PMU.
@@ -48,24 +48,26 @@ release_pmu(const struct pmu_irqs *irqs);
  * the actual hardware initialisation.
  */
 extern int
-init_pmu(void);
+init_pmu(enum arm_pmu_type device);
 
 #else /* CONFIG_CPU_HAS_PMU */
 
-static inline const struct pmu_irqs *
-reserve_pmu(void)
+#include <linux/err.h>
+
+static inline struct platform_device *
+reserve_pmu(enum arm_pmu_type device)
 {
        return ERR_PTR(-ENODEV);
 }
 
 static inline int
-release_pmu(const struct pmu_irqs *irqs)
+release_pmu(struct platform_device *pdev)
 {
        return -ENODEV;
 }
 
 static inline int
-init_pmu(void)
+init_pmu(enum arm_pmu_type device)
 {
        return -ENODEV;
 }
index ca0a37d..bcda59f 100644 (file)
@@ -4,24 +4,8 @@
 #include <asm/memory.h>
 #include <asm/types.h>
 
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-       unsigned long   sg_magic;
-#endif
-       unsigned long   page_link;
-       unsigned int    offset;         /* buffer offset                 */
-       dma_addr_t      dma_address;    /* dma address                   */
-       unsigned int    length;         /* length                        */
-};
+#include <asm-generic/scatterlist.h>
 
-/*
- * These macros should be used after a pci_map_sg call has been done
- * to get bus addresses of each of the SG entries and their lengths.
- * You should only work with the number of sg entries pci_map_sg
- * returns, or alternatively stop on the first sg_dma_len(sg) which
- * is 0.
- */
-#define sg_dma_address(sg)      ((sg)->dma_address)
-#define sg_dma_len(sg)          ((sg)->length)
+#undef ARCH_HAS_SG_CHAIN
 
 #endif /* _ASMARM_SCATTERLIST_H */
index e0d763b..3d05190 100644 (file)
@@ -82,7 +82,7 @@ struct secondary_data {
 extern struct secondary_data secondary_data;
 
 extern int __cpu_disable(void);
-extern int mach_cpu_disable(unsigned int cpu);
+extern int platform_cpu_disable(unsigned int cpu);
 
 extern void __cpu_die(unsigned int cpu);
 extern void cpu_die(void);
index 7be0978..634f357 100644 (file)
@@ -1,6 +1,23 @@
 #ifndef __ASMARM_SMP_TWD_H
 #define __ASMARM_SMP_TWD_H
 
+#define TWD_TIMER_LOAD                 0x00
+#define TWD_TIMER_COUNTER              0x04
+#define TWD_TIMER_CONTROL              0x08
+#define TWD_TIMER_INTSTAT              0x0C
+
+#define TWD_WDOG_LOAD                  0x20
+#define TWD_WDOG_COUNTER               0x24
+#define TWD_WDOG_CONTROL               0x28
+#define TWD_WDOG_INTSTAT               0x2C
+#define TWD_WDOG_RESETSTAT             0x30
+#define TWD_WDOG_DISABLE               0x34
+
+#define TWD_TIMER_CONTROL_ENABLE       (1 << 0)
+#define TWD_TIMER_CONTROL_ONESHOT      (0 << 1)
+#define TWD_TIMER_CONTROL_PERIODIC     (1 << 1)
+#define TWD_TIMER_CONTROL_IT_ENABLE    (1 << 2)
+
 struct clock_event_device;
 
 extern void __iomem *twd_base;
index 4ace45e..5f4f480 100644 (file)
@@ -141,7 +141,7 @@ extern unsigned int user_debug;
 
 #ifdef CONFIG_ARCH_HAS_BARRIERS
 #include <mach/barriers.h>
-#elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
 #define mb()           do { dsb(); outer_sync(); } while (0)
 #define rmb()          dmb()
 #define wmb()          mb()
index e085e2c..bd863d8 100644 (file)
@@ -46,6 +46,9 @@
 #define TLB_V7_UIS_FULL (1 << 20)
 #define TLB_V7_UIS_ASID (1 << 21)
 
+/* Inner Shareable BTB operation (ARMv7 MP extensions) */
+#define TLB_V7_IS_BTB  (1 << 22)
+
 #define TLB_L2CLEAN_FR (1 << 29)               /* Feroceon */
 #define TLB_DCLEAN     (1 << 30)
 #define TLB_WB         (1 << 31)
 #endif
 
 #ifdef CONFIG_SMP
-#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
                         TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
 #else
 #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
@@ -339,6 +342,12 @@ static inline void local_flush_tlb_all(void)
                dsb();
                isb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -376,6 +385,12 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
                asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
                dsb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void
@@ -416,6 +431,12 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
                asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
                dsb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -454,6 +475,12 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
                dsb();
                isb();
        }
+       if (tlb_flag(TLB_V7_IS_BTB)) {
+               /* flush the branch target cache */
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+               dsb();
+               isb();
+       }
 }
 
 /*
index 1d6bd40..33e4a48 100644 (file)
@@ -229,16 +229,16 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     ldrbt   %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       mov     %1, #0\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err), "=&r" (x)                                 \
        : "r" (addr), "i" (-EFAULT)                             \
        : "cc")
@@ -265,16 +265,16 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     ldrt    %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       mov     %1, #0\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err), "=&r" (x)                                 \
        : "r" (addr), "i" (-EFAULT)                             \
        : "cc")
@@ -310,15 +310,15 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     strbt   %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err)                                            \
        : "r" (x), "r" (__pu_addr), "i" (-EFAULT)               \
        : "cc")
@@ -343,15 +343,15 @@ do {                                                                      \
        __asm__ __volatile__(                                   \
        "1:     strt    %1,[%2]\n"                              \
        "2:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "3:     mov     %0, %3\n"                               \
        "       b       2b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 3b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err)                                            \
        : "r" (x), "r" (__pu_addr), "i" (-EFAULT)               \
        : "cc")
@@ -371,16 +371,16 @@ do {                                                                      \
  THUMB(        "1:     strt    " __reg_oper1 ", [%1]\n"        )       \
  THUMB(        "2:     strt    " __reg_oper0 ", [%1, #4]\n"    )       \
        "3:\n"                                                  \
-       "       .section .fixup,\"ax\"\n"                       \
+       "       .pushsection .fixup,\"ax\"\n"                   \
        "       .align  2\n"                                    \
        "4:     mov     %0, %3\n"                               \
        "       b       3b\n"                                   \
-       "       .previous\n"                                    \
-       "       .section __ex_table,\"a\"\n"                    \
+       "       .popsection\n"                                  \
+       "       .pushsection __ex_table,\"a\"\n"                \
        "       .align  3\n"                                    \
        "       .long   1b, 4b\n"                               \
        "       .long   2b, 4b\n"                               \
-       "       .previous"                                      \
+       "       .popsection"                                    \
        : "+r" (err), "+r" (__pu_addr)                          \
        : "r" (x), "i" (-EFAULT)                                \
        : "cc")
index bf65e9f..47f023a 100644 (file)
@@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
 #endif /* CONFIG_IWMMXT */
 
 #ifdef CONFIG_VFP
-#if __LINUX_ARM_ARCH__ < 6
-/* For ARM pre-v6, we use fstmiax and fldmiax.  This adds one extra
- * word after the registers, and a word of padding at the end for
- * alignment.  */
 #define VFP_MAGIC              0x56465001
-#define VFP_STORAGE_SIZE       152
-#else
-#define VFP_MAGIC              0x56465002
-#define VFP_STORAGE_SIZE       144
-#endif
 
 struct vfp_sigframe
 {
        unsigned long           magic;
        unsigned long           size;
-       union vfp_state         storage;
-};
+       struct user_vfp         ufp;
+       struct user_vfp_exc     ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ *  8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ *  4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE       sizeof(struct vfp_sigframe)
+
 #endif /* CONFIG_VFP */
 
 /*
@@ -91,7 +90,7 @@ struct aux_sigframe {
 #ifdef CONFIG_IWMMXT
        struct iwmmxt_sigframe  iwmmxt;
 #endif
-#if 0 && defined CONFIG_VFP /* Not yet saved.  */
+#ifdef CONFIG_VFP
        struct vfp_sigframe     vfp;
 #endif
        /* Something that isn't a valid magic number for any coprocessor.  */
index df95e05..05ac4b0 100644 (file)
@@ -83,11 +83,21 @@ struct user{
 
 /*
  * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
- * are ignored by the ptrace system call.
+ * are ignored by the ptrace system call and the signal handler.
  */
 struct user_vfp {
        unsigned long long fpregs[32];
        unsigned long fpscr;
 };
 
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+       unsigned long   fpexc;
+       unsigned long   fpinst;
+       unsigned long   fpinst2;
+};
+
 #endif /* _ARM_USER_H */
index bd397e0..c6273a3 100644 (file)
@@ -527,6 +527,9 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
                if (!sys)
                        panic("PCI: unable to allocate sys data!");
 
+#ifdef CONFIG_PCI_DOMAINS
+               sys->domain  = hw->domain;
+#endif
                sys->hw      = hw;
                sys->busnr   = busnr;
                sys->swizzle = hw->swizzle;
index 7d5b9fb..2c4a185 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/scatterlist.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
 
 #include <asm/dma.h>
 
@@ -264,3 +266,37 @@ int get_dma_residue(unsigned int chan)
        return ret;
 }
 EXPORT_SYMBOL(get_dma_residue);
+
+#ifdef CONFIG_PROC_FS
+static int proc_dma_show(struct seq_file *m, void *v)
+{
+       int i;
+
+       for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+               dma_t *dma = dma_channel(i);
+               if (dma && dma->lock)
+                       seq_printf(m, "%2d: %s\n", i, dma->device_id);
+       }
+       return 0;
+}
+
+static int proc_dma_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, proc_dma_show, NULL);
+}
+
+static const struct file_operations proc_dma_operations = {
+       .open           = proc_dma_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_dma_init(void)
+{
+       proc_create("dma", 0, NULL, &proc_dma_operations);
+       return 0;
+}
+
+__initcall(proc_dma_init);
+#endif
index 6c5cf36..7ee48e7 100644 (file)
@@ -523,16 +523,16 @@ ENDPROC(__und_usr)
 /*
  * The out of line fixup for the ldrt above.
  */
-       .section .fixup, "ax"
+       .pushsection .fixup, "ax"
 4:     mov     pc, r9
-       .previous
-       .section __ex_table,"a"
+       .popsection
+       .pushsection __ex_table,"a"
        .long   1b, 4b
 #if __LINUX_ARM_ARCH__ >= 7
        .long   2b, 4b
        .long   3b, 4b
 #endif
-       .previous
+       .popsection
 
 /*
  * Check whether the instruction is a co-processor instruction.
@@ -676,10 +676,10 @@ do_fpe:
  *  lr  = unrecognised FP instruction return address
  */
 
-       .data
+       .pushsection .data
 ENTRY(fp_enter)
        .word   no_fp
-       .previous
+       .popsection
 
 ENTRY(no_fp)
        mov     pc, lr
index c638427..0298286 100644 (file)
@@ -62,15 +62,15 @@ int ftrace_modify_code(unsigned long pc, unsigned char *old_code,
                "    movne  %0, #2    \n"
                "3:\n"
 
-               ".section .fixup, \"ax\"\n"
+               ".pushsection .fixup, \"ax\"\n"
                "4:  mov  %0, #1  \n"
                "    b    3b      \n"
-               ".previous\n"
+               ".popsection\n"
 
-               ".section __ex_table, \"a\"\n"
+               ".pushsection __ex_table, \"a\"\n"
                "    .long 1b, 4b \n"
                "    .long 2b, 4b \n"
-               ".previous\n"
+               ".popsection\n"
 
                : "=r"(err), "=r"(replaced)
                : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced)
index 9e70f20..c457686 100644 (file)
@@ -16,7 +16,9 @@
 
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/perf_event.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
 
@@ -26,7 +28,7 @@
 #include <asm/pmu.h>
 #include <asm/stacktrace.h>
 
-static const struct pmu_irqs *pmu_irqs;
+static struct platform_device *pmu_device;
 
 /*
  * Hardware lock to serialize accesses to PMU registers. Needed for the
@@ -67,8 +69,18 @@ struct cpu_hw_events {
 };
 DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
 
+/* PMU names. */
+static const char *arm_pmu_names[] = {
+       [ARM_PERF_PMU_ID_XSCALE1] = "xscale1",
+       [ARM_PERF_PMU_ID_XSCALE2] = "xscale2",
+       [ARM_PERF_PMU_ID_V6]      = "v6",
+       [ARM_PERF_PMU_ID_V6MP]    = "v6mpcore",
+       [ARM_PERF_PMU_ID_CA8]     = "ARMv7 Cortex-A8",
+       [ARM_PERF_PMU_ID_CA9]     = "ARMv7 Cortex-A9",
+};
+
 struct arm_pmu {
-       char            *name;
+       enum arm_perf_pmu_ids id;
        irqreturn_t     (*handle_irq)(int irq_num, void *dev);
        void            (*enable)(struct hw_perf_event *evt, int idx);
        void            (*disable)(struct hw_perf_event *evt, int idx);
@@ -87,6 +99,30 @@ struct arm_pmu {
 /* Set at runtime when we know what CPU type we are. */
 static const struct arm_pmu *armpmu;
 
+enum arm_perf_pmu_ids
+armpmu_get_pmu_id(void)
+{
+       int id = -ENODEV;
+
+       if (armpmu != NULL)
+               id = armpmu->id;
+
+       return id;
+}
+EXPORT_SYMBOL_GPL(armpmu_get_pmu_id);
+
+int
+armpmu_get_max_events(void)
+{
+       int max_events = 0;
+
+       if (armpmu != NULL)
+               max_events = armpmu->num_events;
+
+       return max_events;
+}
+EXPORT_SYMBOL_GPL(armpmu_get_max_events);
+
 #define HW_OP_UNSUPPORTED              0xFFFF
 
 #define C(_x) \
@@ -314,38 +350,44 @@ validate_group(struct perf_event *event)
 static int
 armpmu_reserve_hardware(void)
 {
-       int i;
-       int err;
+       int i, err = -ENODEV, irq;
 
-       pmu_irqs = reserve_pmu();
-       if (IS_ERR(pmu_irqs)) {
+       pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU);
+       if (IS_ERR(pmu_device)) {
                pr_warning("unable to reserve pmu\n");
-               return PTR_ERR(pmu_irqs);
+               return PTR_ERR(pmu_device);
        }
 
-       init_pmu();
+       init_pmu(ARM_PMU_DEVICE_CPU);
 
-       if (pmu_irqs->num_irqs < 1) {
+       if (pmu_device->num_resources < 1) {
                pr_err("no irqs for PMUs defined\n");
                return -ENODEV;
        }
 
-       for (i = 0; i < pmu_irqs->num_irqs; ++i) {
-               err = request_irq(pmu_irqs->irqs[i], armpmu->handle_irq,
+       for (i = 0; i < pmu_device->num_resources; ++i) {
+               irq = platform_get_irq(pmu_device, i);
+               if (irq < 0)
+                       continue;
+
+               err = request_irq(irq, armpmu->handle_irq,
                                  IRQF_DISABLED | IRQF_NOBALANCING,
                                  "armpmu", NULL);
                if (err) {
-                       pr_warning("unable to request IRQ%d for ARM "
-                                  "perf counters\n", pmu_irqs->irqs[i]);
+                       pr_warning("unable to request IRQ%d for ARM perf "
+                               "counters\n", irq);
                        break;
                }
        }
 
        if (err) {
-               for (i = i - 1; i >= 0; --i)
-                       free_irq(pmu_irqs->irqs[i], NULL);
-               release_pmu(pmu_irqs);
-               pmu_irqs = NULL;
+               for (i = i - 1; i >= 0; --i) {
+                       irq = platform_get_irq(pmu_device, i);
+                       if (irq >= 0)
+                               free_irq(irq, NULL);
+               }
+               release_pmu(pmu_device);
+               pmu_device = NULL;
        }
 
        return err;
@@ -354,14 +396,17 @@ armpmu_reserve_hardware(void)
 static void
 armpmu_release_hardware(void)
 {
-       int i;
+       int i, irq;
 
-       for (i = pmu_irqs->num_irqs - 1; i >= 0; --i)
-               free_irq(pmu_irqs->irqs[i], NULL);
+       for (i = pmu_device->num_resources - 1; i >= 0; --i) {
+               irq = platform_get_irq(pmu_device, i);
+               if (irq >= 0)
+                       free_irq(irq, NULL);
+       }
        armpmu->stop();
 
-       release_pmu(pmu_irqs);
-       pmu_irqs = NULL;
+       release_pmu(pmu_device);
+       pmu_device = NULL;
 }
 
 static atomic_t active_events = ATOMIC_INIT(0);
@@ -1144,7 +1189,7 @@ armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
 }
 
 static const struct arm_pmu armv6pmu = {
-       .name                   = "v6",
+       .id                     = ARM_PERF_PMU_ID_V6,
        .handle_irq             = armv6pmu_handle_irq,
        .enable                 = armv6pmu_enable_event,
        .disable                = armv6pmu_disable_event,
@@ -1167,7 +1212,7 @@ static const struct arm_pmu armv6pmu = {
  * reset the period and enable the interrupt reporting.
  */
 static const struct arm_pmu armv6mpcore_pmu = {
-       .name                   = "v6mpcore",
+       .id                     = ARM_PERF_PMU_ID_V6MP,
        .handle_irq             = armv6pmu_handle_irq,
        .enable                 = armv6pmu_enable_event,
        .disable                = armv6mpcore_pmu_disable_event,
@@ -1197,10 +1242,6 @@ static const struct arm_pmu armv6mpcore_pmu = {
  *  counter and all 4 performance counters together can be reset separately.
  */
 
-#define ARMV7_PMU_CORTEX_A8_NAME               "ARMv7 Cortex-A8"
-
-#define ARMV7_PMU_CORTEX_A9_NAME               "ARMv7 Cortex-A9"
-
 /* Common ARMv7 event types */
 enum armv7_perf_types {
        ARMV7_PERFCTR_PMNC_SW_INCR              = 0x00,
@@ -2079,6 +2120,803 @@ static u32 __init armv7_reset_read_pmnc(void)
        return nb_cnt + 1;
 }
 
+/*
+ * ARMv5 [xscale] Performance counter handling code.
+ *
+ * Based on xscale OProfile code.
+ *
+ * There are two variants of the xscale PMU that we support:
+ *     - xscale1pmu: 2 event counters and a cycle counter
+ *     - xscale2pmu: 4 event counters and a cycle counter
+ * The two variants share event definitions, but have different
+ * PMU structures.
+ */
+
+enum xscale_perf_types {
+       XSCALE_PERFCTR_ICACHE_MISS              = 0x00,
+       XSCALE_PERFCTR_ICACHE_NO_DELIVER        = 0x01,
+       XSCALE_PERFCTR_DATA_STALL               = 0x02,
+       XSCALE_PERFCTR_ITLB_MISS                = 0x03,
+       XSCALE_PERFCTR_DTLB_MISS                = 0x04,
+       XSCALE_PERFCTR_BRANCH                   = 0x05,
+       XSCALE_PERFCTR_BRANCH_MISS              = 0x06,
+       XSCALE_PERFCTR_INSTRUCTION              = 0x07,
+       XSCALE_PERFCTR_DCACHE_FULL_STALL        = 0x08,
+       XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
+       XSCALE_PERFCTR_DCACHE_ACCESS            = 0x0A,
+       XSCALE_PERFCTR_DCACHE_MISS              = 0x0B,
+       XSCALE_PERFCTR_DCACHE_WRITE_BACK        = 0x0C,
+       XSCALE_PERFCTR_PC_CHANGED               = 0x0D,
+       XSCALE_PERFCTR_BCU_REQUEST              = 0x10,
+       XSCALE_PERFCTR_BCU_FULL                 = 0x11,
+       XSCALE_PERFCTR_BCU_DRAIN                = 0x12,
+       XSCALE_PERFCTR_BCU_ECC_NO_ELOG          = 0x14,
+       XSCALE_PERFCTR_BCU_1_BIT_ERR            = 0x15,
+       XSCALE_PERFCTR_RMW                      = 0x16,
+       /* XSCALE_PERFCTR_CCNT is not hardware defined */
+       XSCALE_PERFCTR_CCNT                     = 0xFE,
+       XSCALE_PERFCTR_UNUSED                   = 0xFF,
+};
+
+enum xscale_counters {
+       XSCALE_CYCLE_COUNTER    = 1,
+       XSCALE_COUNTER0,
+       XSCALE_COUNTER1,
+       XSCALE_COUNTER2,
+       XSCALE_COUNTER3,
+};
+
+static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = XSCALE_PERFCTR_CCNT,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = XSCALE_PERFCTR_INSTRUCTION,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = XSCALE_PERFCTR_BRANCH_MISS,
+       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                          [PERF_COUNT_HW_CACHE_OP_MAX]
+                                          [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = XSCALE_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_DCACHE_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = XSCALE_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_DCACHE_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_ICACHE_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_ICACHE_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_DTLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_DTLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = XSCALE_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+#define        XSCALE_PMU_ENABLE       0x001
+#define XSCALE_PMN_RESET       0x002
+#define        XSCALE_CCNT_RESET       0x004
+#define        XSCALE_PMU_RESET        (CCNT_RESET | PMN_RESET)
+#define XSCALE_PMU_CNT64       0x008
+
+static inline int
+xscalepmu_event_map(int config)
+{
+       int mapping = xscale_perf_map[config];
+       if (HW_OP_UNSUPPORTED == mapping)
+               mapping = -EOPNOTSUPP;
+       return mapping;
+}
+
+static u64
+xscalepmu_raw_event(u64 config)
+{
+       return config & 0xff;
+}
+
+#define XSCALE1_OVERFLOWED_MASK        0x700
+#define XSCALE1_CCOUNT_OVERFLOW        0x400
+#define XSCALE1_COUNT0_OVERFLOW        0x100
+#define XSCALE1_COUNT1_OVERFLOW        0x200
+#define XSCALE1_CCOUNT_INT_EN  0x040
+#define XSCALE1_COUNT0_INT_EN  0x010
+#define XSCALE1_COUNT1_INT_EN  0x020
+#define XSCALE1_COUNT0_EVT_SHFT        12
+#define XSCALE1_COUNT0_EVT_MASK        (0xff << XSCALE1_COUNT0_EVT_SHFT)
+#define XSCALE1_COUNT1_EVT_SHFT        20
+#define XSCALE1_COUNT1_EVT_MASK        (0xff << XSCALE1_COUNT1_EVT_SHFT)
+
+static inline u32
+xscale1pmu_read_pmnc(void)
+{
+       u32 val;
+       asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
+       return val;
+}
+
+static inline void
+xscale1pmu_write_pmnc(u32 val)
+{
+       /* upper 4bits and 7, 11 are write-as-0 */
+       val &= 0xffff77f;
+       asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
+}
+
+static inline int
+xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
+                                       enum xscale_counters counter)
+{
+       int ret = 0;
+
+       switch (counter) {
+       case XSCALE_CYCLE_COUNTER:
+               ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
+               break;
+       case XSCALE_COUNTER0:
+               ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
+               break;
+       case XSCALE_COUNTER1:
+               ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
+               break;
+       default:
+               WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+       }
+
+       return ret;
+}
+
+static irqreturn_t
+xscale1pmu_handle_irq(int irq_num, void *dev)
+{
+       unsigned long pmnc;
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc;
+       struct pt_regs *regs;
+       int idx;
+
+       /*
+        * NOTE: there's an A stepping erratum that states if an overflow
+        *       bit already exists and another occurs, the previous
+        *       Overflow bit gets cleared. There's no workaround.
+        *       Fixed in B stepping or later.
+        */
+       pmnc = xscale1pmu_read_pmnc();
+
+       /*
+        * Write the value back to clear the overflow flags. Overflow
+        * flags remain in pmnc for use below. We also disable the PMU
+        * while we process the interrupt.
+        */
+       xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+       if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
+               return IRQ_NONE;
+
+       regs = get_irq_regs();
+
+       perf_sample_data_init(&data, 0);
+
+       cpuc = &__get_cpu_var(cpu_hw_events);
+       for (idx = 0; idx <= armpmu->num_events; ++idx) {
+               struct perf_event *event = cpuc->events[idx];
+               struct hw_perf_event *hwc;
+
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+
+               if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
+                       continue;
+
+               hwc = &event->hw;
+               armpmu_event_update(event, hwc, idx);
+               data.period = event->hw.last_period;
+               if (!armpmu_event_set_period(event, hwc, idx))
+                       continue;
+
+               if (perf_event_overflow(event, 0, &data, regs))
+                       armpmu->disable(hwc, idx);
+       }
+
+       perf_event_do_pending();
+
+       /*
+        * Re-enable the PMU.
+        */
+       pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+       xscale1pmu_write_pmnc(pmnc);
+
+       return IRQ_HANDLED;
+}
+
+static void
+xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+       unsigned long val, mask, evt, flags;
+
+       switch (idx) {
+       case XSCALE_CYCLE_COUNTER:
+               mask = 0;
+               evt = XSCALE1_CCOUNT_INT_EN;
+               break;
+       case XSCALE_COUNTER0:
+               mask = XSCALE1_COUNT0_EVT_MASK;
+               evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
+                       XSCALE1_COUNT0_INT_EN;
+               break;
+       case XSCALE_COUNTER1:
+               mask = XSCALE1_COUNT1_EVT_MASK;
+               evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
+                       XSCALE1_COUNT1_INT_EN;
+               break;
+       default:
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = xscale1pmu_read_pmnc();
+       val &= ~mask;
+       val |= evt;
+       xscale1pmu_write_pmnc(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+       unsigned long val, mask, evt, flags;
+
+       switch (idx) {
+       case XSCALE_CYCLE_COUNTER:
+               mask = XSCALE1_CCOUNT_INT_EN;
+               evt = 0;
+               break;
+       case XSCALE_COUNTER0:
+               mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
+               evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER1:
+               mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
+               evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
+               break;
+       default:
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = xscale1pmu_read_pmnc();
+       val &= ~mask;
+       val |= evt;
+       xscale1pmu_write_pmnc(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
+                       struct hw_perf_event *event)
+{
+       if (XSCALE_PERFCTR_CCNT == event->config_base) {
+               if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
+                       return -EAGAIN;
+
+               return XSCALE_CYCLE_COUNTER;
+       } else {
+               if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) {
+                       return XSCALE_COUNTER1;
+               }
+
+               if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) {
+                       return XSCALE_COUNTER0;
+               }
+
+               return -EAGAIN;
+       }
+}
+
+static void
+xscale1pmu_start(void)
+{
+       unsigned long flags, val;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = xscale1pmu_read_pmnc();
+       val |= XSCALE_PMU_ENABLE;
+       xscale1pmu_write_pmnc(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_stop(void)
+{
+       unsigned long flags, val;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = xscale1pmu_read_pmnc();
+       val &= ~XSCALE_PMU_ENABLE;
+       xscale1pmu_write_pmnc(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale1pmu_read_counter(int counter)
+{
+       u32 val = 0;
+
+       switch (counter) {
+       case XSCALE_CYCLE_COUNTER:
+               asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
+               break;
+       case XSCALE_COUNTER0:
+               asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
+               break;
+       case XSCALE_COUNTER1:
+               asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
+               break;
+       }
+
+       return val;
+}
+
+static inline void
+xscale1pmu_write_counter(int counter, u32 val)
+{
+       switch (counter) {
+       case XSCALE_CYCLE_COUNTER:
+               asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
+               break;
+       case XSCALE_COUNTER0:
+               asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
+               break;
+       case XSCALE_COUNTER1:
+               asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
+               break;
+       }
+}
+
+static const struct arm_pmu xscale1pmu = {
+       .id             = ARM_PERF_PMU_ID_XSCALE1,
+       .handle_irq     = xscale1pmu_handle_irq,
+       .enable         = xscale1pmu_enable_event,
+       .disable        = xscale1pmu_disable_event,
+       .event_map      = xscalepmu_event_map,
+       .raw_event      = xscalepmu_raw_event,
+       .read_counter   = xscale1pmu_read_counter,
+       .write_counter  = xscale1pmu_write_counter,
+       .get_event_idx  = xscale1pmu_get_event_idx,
+       .start          = xscale1pmu_start,
+       .stop           = xscale1pmu_stop,
+       .num_events     = 3,
+       .max_period     = (1LLU << 32) - 1,
+};
+
+#define XSCALE2_OVERFLOWED_MASK        0x01f
+#define XSCALE2_CCOUNT_OVERFLOW        0x001
+#define XSCALE2_COUNT0_OVERFLOW        0x002
+#define XSCALE2_COUNT1_OVERFLOW        0x004
+#define XSCALE2_COUNT2_OVERFLOW        0x008
+#define XSCALE2_COUNT3_OVERFLOW        0x010
+#define XSCALE2_CCOUNT_INT_EN  0x001
+#define XSCALE2_COUNT0_INT_EN  0x002
+#define XSCALE2_COUNT1_INT_EN  0x004
+#define XSCALE2_COUNT2_INT_EN  0x008
+#define XSCALE2_COUNT3_INT_EN  0x010
+#define XSCALE2_COUNT0_EVT_SHFT        0
+#define XSCALE2_COUNT0_EVT_MASK        (0xff << XSCALE2_COUNT0_EVT_SHFT)
+#define XSCALE2_COUNT1_EVT_SHFT        8
+#define XSCALE2_COUNT1_EVT_MASK        (0xff << XSCALE2_COUNT1_EVT_SHFT)
+#define XSCALE2_COUNT2_EVT_SHFT        16
+#define XSCALE2_COUNT2_EVT_MASK        (0xff << XSCALE2_COUNT2_EVT_SHFT)
+#define XSCALE2_COUNT3_EVT_SHFT        24
+#define XSCALE2_COUNT3_EVT_MASK        (0xff << XSCALE2_COUNT3_EVT_SHFT)
+
+static inline u32
+xscale2pmu_read_pmnc(void)
+{
+       u32 val;
+       asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
+       /* bits 1-2 and 4-23 are read-unpredictable */
+       return val & 0xff000009;
+}
+
+static inline void
+xscale2pmu_write_pmnc(u32 val)
+{
+       /* bits 4-23 are write-as-0, 24-31 are write ignored */
+       val &= 0xf;
+       asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_overflow_flags(void)
+{
+       u32 val;
+       asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
+       return val;
+}
+
+static inline void
+xscale2pmu_write_overflow_flags(u32 val)
+{
+       asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_event_select(void)
+{
+       u32 val;
+       asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
+       return val;
+}
+
+static inline void
+xscale2pmu_write_event_select(u32 val)
+{
+       asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
+}
+
+static inline u32
+xscale2pmu_read_int_enable(void)
+{
+       u32 val;
+       asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
+       return val;
+}
+
+static void
+xscale2pmu_write_int_enable(u32 val)
+{
+       asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
+}
+
+static inline int
+xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
+                                       enum xscale_counters counter)
+{
+       int ret = 0;
+
+       switch (counter) {
+       case XSCALE_CYCLE_COUNTER:
+               ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
+               break;
+       case XSCALE_COUNTER0:
+               ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
+               break;
+       case XSCALE_COUNTER1:
+               ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
+               break;
+       case XSCALE_COUNTER2:
+               ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
+               break;
+       case XSCALE_COUNTER3:
+               ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
+               break;
+       default:
+               WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+       }
+
+       return ret;
+}
+
+static irqreturn_t
+xscale2pmu_handle_irq(int irq_num, void *dev)
+{
+       unsigned long pmnc, of_flags;
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc;
+       struct pt_regs *regs;
+       int idx;
+
+       /* Disable the PMU. */
+       pmnc = xscale2pmu_read_pmnc();
+       xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+       /* Check the overflow flag register. */
+       of_flags = xscale2pmu_read_overflow_flags();
+       if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
+               return IRQ_NONE;
+
+       /* Clear the overflow bits. */
+       xscale2pmu_write_overflow_flags(of_flags);
+
+       regs = get_irq_regs();
+
+       perf_sample_data_init(&data, 0);
+
+       cpuc = &__get_cpu_var(cpu_hw_events);
+       for (idx = 0; idx <= armpmu->num_events; ++idx) {
+               struct perf_event *event = cpuc->events[idx];
+               struct hw_perf_event *hwc;
+
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+
+               if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
+                       continue;
+
+               hwc = &event->hw;
+               armpmu_event_update(event, hwc, idx);
+               data.period = event->hw.last_period;
+               if (!armpmu_event_set_period(event, hwc, idx))
+                       continue;
+
+               if (perf_event_overflow(event, 0, &data, regs))
+                       armpmu->disable(hwc, idx);
+       }
+
+       perf_event_do_pending();
+
+       /*
+        * Re-enable the PMU.
+        */
+       pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+       xscale2pmu_write_pmnc(pmnc);
+
+       return IRQ_HANDLED;
+}
+
+static void
+xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+       unsigned long flags, ien, evtsel;
+
+       ien = xscale2pmu_read_int_enable();
+       evtsel = xscale2pmu_read_event_select();
+
+       switch (idx) {
+       case XSCALE_CYCLE_COUNTER:
+               ien |= XSCALE2_CCOUNT_INT_EN;
+               break;
+       case XSCALE_COUNTER0:
+               ien |= XSCALE2_COUNT0_INT_EN;
+               evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+               evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER1:
+               ien |= XSCALE2_COUNT1_INT_EN;
+               evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+               evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER2:
+               ien |= XSCALE2_COUNT2_INT_EN;
+               evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+               evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER3:
+               ien |= XSCALE2_COUNT3_INT_EN;
+               evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+               evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
+               break;
+       default:
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       xscale2pmu_write_event_select(evtsel);
+       xscale2pmu_write_int_enable(ien);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+       unsigned long flags, ien, evtsel;
+
+       ien = xscale2pmu_read_int_enable();
+       evtsel = xscale2pmu_read_event_select();
+
+       switch (idx) {
+       case XSCALE_CYCLE_COUNTER:
+               ien &= ~XSCALE2_CCOUNT_INT_EN;
+               break;
+       case XSCALE_COUNTER0:
+               ien &= ~XSCALE2_COUNT0_INT_EN;
+               evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+               evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER1:
+               ien &= ~XSCALE2_COUNT1_INT_EN;
+               evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+               evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER2:
+               ien &= ~XSCALE2_COUNT2_INT_EN;
+               evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+               evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
+               break;
+       case XSCALE_COUNTER3:
+               ien &= ~XSCALE2_COUNT3_INT_EN;
+               evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+               evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
+               break;
+       default:
+               WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+               return;
+       }
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       xscale2pmu_write_event_select(evtsel);
+       xscale2pmu_write_int_enable(ien);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
+                       struct hw_perf_event *event)
+{
+       int idx = xscale1pmu_get_event_idx(cpuc, event);
+       if (idx >= 0)
+               goto out;
+
+       if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
+               idx = XSCALE_COUNTER3;
+       else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
+               idx = XSCALE_COUNTER2;
+out:
+       return idx;
+}
+
+static void
+xscale2pmu_start(void)
+{
+       unsigned long flags, val;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
+       val |= XSCALE_PMU_ENABLE;
+       xscale2pmu_write_pmnc(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_stop(void)
+{
+       unsigned long flags, val;
+
+       spin_lock_irqsave(&pmu_lock, flags);
+       val = xscale2pmu_read_pmnc();
+       val &= ~XSCALE_PMU_ENABLE;
+       xscale2pmu_write_pmnc(val);
+       spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale2pmu_read_counter(int counter)
+{
+       u32 val = 0;
+
+       switch (counter) {
+       case XSCALE_CYCLE_COUNTER:
+               asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
+               break;
+       case XSCALE_COUNTER0:
+               asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
+               break;
+       case XSCALE_COUNTER1:
+               asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
+               break;
+       case XSCALE_COUNTER2:
+               asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
+               break;
+       case XSCALE_COUNTER3:
+               asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
+               break;
+       }
+
+       return val;
+}
+
+static inline void
+xscale2pmu_write_counter(int counter, u32 val)
+{
+       switch (counter) {
+       case XSCALE_CYCLE_COUNTER:
+               asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
+               break;
+       case XSCALE_COUNTER0:
+               asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
+               break;
+       case XSCALE_COUNTER1:
+               asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
+               break;
+       case XSCALE_COUNTER2:
+               asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
+               break;
+       case XSCALE_COUNTER3:
+               asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
+               break;
+       }
+}
+
+static const struct arm_pmu xscale2pmu = {
+       .id             = ARM_PERF_PMU_ID_XSCALE2,
+       .handle_irq     = xscale2pmu_handle_irq,
+       .enable         = xscale2pmu_enable_event,
+       .disable        = xscale2pmu_disable_event,
+       .event_map      = xscalepmu_event_map,
+       .raw_event      = xscalepmu_raw_event,
+       .read_counter   = xscale2pmu_read_counter,
+       .write_counter  = xscale2pmu_write_counter,
+       .get_event_idx  = xscale2pmu_get_event_idx,
+       .start          = xscale2pmu_start,
+       .stop           = xscale2pmu_stop,
+       .num_events     = 5,
+       .max_period     = (1LLU << 32) - 1,
+};
+
 static int __init
 init_hw_perf_events(void)
 {
@@ -2086,7 +2924,7 @@ init_hw_perf_events(void)
        unsigned long implementor = (cpuid & 0xFF000000) >> 24;
        unsigned long part_number = (cpuid & 0xFFF0);
 
-       /* We only support ARM CPUs implemented by ARM at the moment. */
+       /* ARM Ltd CPUs. */
        if (0x41 == implementor) {
                switch (part_number) {
                case 0xB360:    /* ARM1136 */
@@ -2105,7 +2943,7 @@ init_hw_perf_events(void)
                        perf_max_events = armv6mpcore_pmu.num_events;
                        break;
                case 0xC080:    /* Cortex-A8 */
-                       armv7pmu.name = ARMV7_PMU_CORTEX_A8_NAME;
+                       armv7pmu.id = ARM_PERF_PMU_ID_CA8;
                        memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map,
                                sizeof(armv7_a8_perf_cache_map));
                        armv7pmu.event_map = armv7_a8_pmu_event_map;
@@ -2117,7 +2955,7 @@ init_hw_perf_events(void)
                        perf_max_events = armv7pmu.num_events;
                        break;
                case 0xC090:    /* Cortex-A9 */
-                       armv7pmu.name = ARMV7_PMU_CORTEX_A9_NAME;
+                       armv7pmu.id = ARM_PERF_PMU_ID_CA9;
                        memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map,
                                sizeof(armv7_a9_perf_cache_map));
                        armv7pmu.event_map = armv7_a9_pmu_event_map;
@@ -2128,15 +2966,33 @@ init_hw_perf_events(void)
                        armv7pmu.num_events = armv7_reset_read_pmnc();
                        perf_max_events = armv7pmu.num_events;
                        break;
-               default:
-                       pr_info("no hardware support available\n");
-                       perf_max_events = -1;
+               }
+       /* Intel CPUs [xscale]. */
+       } else if (0x69 == implementor) {
+               part_number = (cpuid >> 13) & 0x7;
+               switch (part_number) {
+               case 1:
+                       armpmu = &xscale1pmu;
+                       memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
+                                       sizeof(xscale_perf_cache_map));
+                       perf_max_events = xscale1pmu.num_events;
+                       break;
+               case 2:
+                       armpmu = &xscale2pmu;
+                       memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
+                                       sizeof(xscale_perf_cache_map));
+                       perf_max_events = xscale2pmu.num_events;
+                       break;
                }
        }
 
-       if (armpmu)
+       if (armpmu) {
                pr_info("enabled with %s PMU driver, %d counters available\n",
-                       armpmu->name, armpmu->num_events);
+                               arm_pmu_names[armpmu->id], armpmu->num_events);
+       } else {
+               pr_info("no hardware support available\n");
+               perf_max_events = -1;
+       }
 
        return 0;
 }
index a124312..b8af96e 100644 (file)
@@ -2,6 +2,7 @@
  *  linux/arch/arm/kernel/pmu.c
  *
  *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *  Copyright (C) 2010 ARM Ltd, Will Deacon
  *
  * 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
  *
  */
 
+#define pr_fmt(fmt) "PMU: " fmt
+
 #include <linux/cpumask.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 
 #include <asm/pmu.h>
 
-/*
- * Define the IRQs for the system. We could use something like a platform
- * device but that seems fairly heavyweight for this. Also, the performance
- * counters can't be removed or hotplugged.
- *
- * Ordering is important: init_pmu() will use the ordering to set the affinity
- * to the corresponding core. e.g. the first interrupt will go to cpu 0, the
- * second goes to cpu 1 etc.
- */
-static const int irqs[] = {
-#if defined(CONFIG_ARCH_OMAP2)
-       3,
-#elif defined(CONFIG_ARCH_BCMRING)
-       IRQ_PMUIRQ,
-#elif defined(CONFIG_MACH_REALVIEW_EB)
-       IRQ_EB11MP_PMU_CPU0,
-       IRQ_EB11MP_PMU_CPU1,
-       IRQ_EB11MP_PMU_CPU2,
-       IRQ_EB11MP_PMU_CPU3,
-#elif defined(CONFIG_ARCH_OMAP3)
-       INT_34XX_BENCH_MPU_EMUL,
-#elif defined(CONFIG_ARCH_IOP32X)
-       IRQ_IOP32X_CORE_PMU,
-#elif defined(CONFIG_ARCH_IOP33X)
-       IRQ_IOP33X_CORE_PMU,
-#elif defined(CONFIG_ARCH_PXA)
-       IRQ_PMU,
-#endif
-};
+static volatile long pmu_lock;
+
+static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES];
+
+static int __devinit pmu_device_probe(struct platform_device *pdev)
+{
+
+       if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) {
+               pr_warning("received registration request for unknown "
+                               "device %d\n", pdev->id);
+               return -EINVAL;
+       }
+
+       if (pmu_devices[pdev->id])
+               pr_warning("registering new PMU device type %d overwrites "
+                               "previous registration!\n", pdev->id);
+       else
+               pr_info("registered new PMU device of type %d\n",
+                               pdev->id);
 
-static const struct pmu_irqs pmu_irqs = {
-       .irqs       = irqs,
-       .num_irqs   = ARRAY_SIZE(irqs),
+       pmu_devices[pdev->id] = pdev;
+       return 0;
+}
+
+static struct platform_driver pmu_driver = {
+       .driver         = {
+               .name   = "arm-pmu",
+       },
+       .probe          = pmu_device_probe,
 };
 
-static volatile long pmu_lock;
+static int __init register_pmu_driver(void)
+{
+       return platform_driver_register(&pmu_driver);
+}
+device_initcall(register_pmu_driver);
 
-const struct pmu_irqs *
-reserve_pmu(void)
+struct platform_device *
+reserve_pmu(enum arm_pmu_type device)
 {
-       return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) :
-               &pmu_irqs;
+       struct platform_device *pdev;
+
+       if (test_and_set_bit_lock(device, &pmu_lock)) {
+               pdev = ERR_PTR(-EBUSY);
+       } else if (pmu_devices[device] == NULL) {
+               clear_bit_unlock(device, &pmu_lock);
+               pdev = ERR_PTR(-ENODEV);
+       } else {
+               pdev = pmu_devices[device];
+       }
+
+       return pdev;
 }
 EXPORT_SYMBOL_GPL(reserve_pmu);
 
 int
-release_pmu(const struct pmu_irqs *irqs)
+release_pmu(struct platform_device *pdev)
 {
-       if (WARN_ON(irqs != &pmu_irqs))
+       if (WARN_ON(pdev != pmu_devices[pdev->id]))
                return -EINVAL;
-       clear_bit_unlock(0, &pmu_lock);
+       clear_bit_unlock(pdev->id, &pmu_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(release_pmu);
@@ -87,17 +101,42 @@ set_irq_affinity(int irq,
 #endif
 }
 
-int
-init_pmu(void)
+static int
+init_cpu_pmu(void)
 {
        int i, err = 0;
+       struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU];
+
+       if (!pdev) {
+               err = -ENODEV;
+               goto out;
+       }
 
-       for (i = 0; i < pmu_irqs.num_irqs; ++i) {
-               err = set_irq_affinity(pmu_irqs.irqs[i], i);
+       for (i = 0; i < pdev->num_resources; ++i) {
+               err = set_irq_affinity(platform_get_irq(pdev, i), i);
                if (err)
                        break;
        }
 
+out:
+       return err;
+}
+
+int
+init_pmu(enum arm_pmu_type device)
+{
+       int err = 0;
+
+       switch (device) {
+       case ARM_PMU_DEVICE_CPU:
+               err = init_cpu_pmu();
+               break;
+       default:
+               pr_warning("attempt to initialise unknown device %d\n",
+                               device);
+               err = -EINVAL;
+       }
+
        return err;
 }
 EXPORT_SYMBOL_GPL(init_pmu);
index 0e12e0a..acf5e6f 100644 (file)
@@ -355,7 +355,7 @@ EXPORT_SYMBOL(dump_fpu);
  * the thread function, and r3 points to the exit function.
  */
 extern void kernel_thread_helper(void);
-asm(   ".section .text\n"
+asm(   ".pushsection .text\n"
 "      .align\n"
 "      .type   kernel_thread_helper, #function\n"
 "kernel_thread_helper:\n"
@@ -363,11 +363,11 @@ asm(      ".section .text\n"
 "      mov     lr, r3\n"
 "      mov     pc, r2\n"
 "      .size   kernel_thread_helper, . - kernel_thread_helper\n"
-"      .previous");
+"      .popsection");
 
 #ifdef CONFIG_ARM_UNWIND
 extern void kernel_thread_exit(long code);
-asm(   ".section .text\n"
+asm(   ".pushsection .text\n"
 "      .align\n"
 "      .type   kernel_thread_exit, #function\n"
 "kernel_thread_exit:\n"
@@ -377,7 +377,7 @@ asm(        ".section .text\n"
 "      nop\n"
 "      .fnend\n"
 "      .size   kernel_thread_exit, . - kernel_thread_exit\n"
-"      .previous");
+"      .popsection");
 #else
 #define kernel_thread_exit     do_exit
 #endif
index e7714f3..907d5a6 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
+#include <asm/vfp.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
 
 #endif
 
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *h = &thread->vfpstate.hard;
+       const unsigned long magic = VFP_MAGIC;
+       const unsigned long size = VFP_STORAGE_SIZE;
+       int err = 0;
+
+       vfp_sync_hwstate(thread);
+       __put_user_error(magic, &frame->magic, err);
+       __put_user_error(size, &frame->size, err);
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+                             sizeof(h->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+       /*
+        * Copy the exception registers.
+        */
+       __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+       __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+       __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+       return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *h = &thread->vfpstate.hard;
+       unsigned long magic;
+       unsigned long size;
+       unsigned long fpexc;
+       int err = 0;
+
+       __get_user_error(magic, &frame->magic, err);
+       __get_user_error(size, &frame->size, err);
+
+       if (err)
+               return -EFAULT;
+       if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+               return -EINVAL;
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+                               sizeof(h->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+       /*
+        * Sanitise and restore the exception registers.
+        */
+       __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+       /* Ensure the VFP is enabled. */
+       fpexc |= FPEXC_EN;
+       /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+       fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+       h->fpexc = fpexc;
+
+       __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+       __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+       if (!err)
+               vfp_flush_hwstate(thread);
+
+       return err ? -EFAULT : 0;
+}
+
+#endif
+
 /*
  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  */
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
                err |= restore_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//     if (err == 0)
-//             err |= vfp_restore_state(&sf->aux.vfp);
+       if (err == 0)
+               err |= restore_vfp_context(&aux->vfp);
 #endif
 
        return err;
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
                err |= preserve_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//     if (err == 0)
-//             err |= vfp_save_state(&sf->aux.vfp);
+       if (err == 0)
+               err |= preserve_vfp_context(&aux->vfp);
 #endif
        __put_user_error(0, &aux->end_magic, err);
 
index 577543f..b8c3d0f 100644 (file)
@@ -86,6 +86,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
                        return PTR_ERR(idle);
                }
                ci->idle = idle;
+       } else {
+               /*
+                * Since this idle thread is being re-used, call
+                * init_idle() to reinitialize the thread structure.
+                */
+               init_idle(idle, cpu);
        }
 
        /*
@@ -162,7 +168,7 @@ int __cpu_disable(void)
        struct task_struct *p;
        int ret;
 
-       ret = mach_cpu_disable(cpu);
+       ret = platform_cpu_disable(cpu);
        if (ret)
                return ret;
 
index ea02a7b..7c5f0c0 100644 (file)
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
 
-#define TWD_TIMER_LOAD                         0x00
-#define TWD_TIMER_COUNTER              0x04
-#define TWD_TIMER_CONTROL              0x08
-#define TWD_TIMER_INTSTAT              0x0C
-
-#define TWD_WDOG_LOAD                  0x20
-#define TWD_WDOG_COUNTER               0x24
-#define TWD_WDOG_CONTROL               0x28
-#define TWD_WDOG_INTSTAT               0x2C
-#define TWD_WDOG_RESETSTAT             0x30
-#define TWD_WDOG_DISABLE               0x34
-
-#define TWD_TIMER_CONTROL_ENABLE       (1 << 0)
-#define TWD_TIMER_CONTROL_ONESHOT      (0 << 1)
-#define TWD_TIMER_CONTROL_PERIODIC     (1 << 1)
-#define TWD_TIMER_CONTROL_IT_ENABLE    (1 << 2)
-
 /* set up by the platform code */
 void __iomem *twd_base;
 
index 2875380..38c261f 100644 (file)
@@ -72,12 +72,15 @@ unsigned long profile_pc(struct pt_regs *regs)
 EXPORT_SYMBOL(profile_pc);
 #endif
 
-#ifndef CONFIG_GENERIC_TIME
-static unsigned long dummy_gettimeoffset(void)
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+u32 arch_gettimeoffset(void)
 {
+       if (system_timer->offset != NULL)
+               return system_timer->offset() * 1000;
+
        return 0;
 }
-#endif
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
 
 #ifdef CONFIG_LEDS_TIMER
 static inline void do_leds(void)
@@ -93,63 +96,6 @@ static inline void do_leds(void)
 #define        do_leds()
 #endif
 
-#ifndef CONFIG_GENERIC_TIME
-void do_gettimeofday(struct timeval *tv)
-{
-       unsigned long flags;
-       unsigned long seq;
-       unsigned long usec, sec;
-
-       do {
-               seq = read_seqbegin_irqsave(&xtime_lock, flags);
-               usec = system_timer->offset();
-               sec = xtime.tv_sec;
-               usec += xtime.tv_nsec / 1000;
-       } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-       /* usec may have gone up a lot: be safe */
-       while (usec >= 1000000) {
-               usec -= 1000000;
-               sec++;
-       }
-
-       tv->tv_sec = sec;
-       tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
-       time_t wtm_sec, sec = tv->tv_sec;
-       long wtm_nsec, nsec = tv->tv_nsec;
-
-       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-               return -EINVAL;
-
-       write_seqlock_irq(&xtime_lock);
-       /*
-        * This is revolting. We need to set "xtime" correctly. However, the
-        * value in this location is the value at the most recent update of
-        * wall time.  Discover what correction gettimeofday() would have
-        * done, and then undo it!
-        */
-       nsec -= system_timer->offset() * NSEC_PER_USEC;
-
-       wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-       wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-       set_normalized_timespec(&xtime, sec, nsec);
-       set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-       ntp_clear();
-       write_sequnlock_irq(&xtime_lock);
-       clock_was_set();
-       return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-#endif /* !CONFIG_GENERIC_TIME */
 
 #ifndef CONFIG_GENERIC_CLOCKEVENTS
 /*
@@ -214,10 +160,6 @@ device_initcall(timer_init_sysfs);
 
 void __init time_init(void)
 {
-#ifndef CONFIG_GENERIC_TIME
-       if (system_timer->offset == NULL)
-               system_timer->offset = dummy_gettimeoffset;
-#endif
        system_timer->init();
 }
 
index aaf7220..a673297 100644 (file)
@@ -110,13 +110,13 @@ no_frame: ldmfd   sp!, {r4 - r8, pc}
 ENDPROC(__backtrace)
 ENDPROC(c_backtrace)
                
-               .section __ex_table,"a"
+               .pushsection __ex_table,"a"
                .align  3
                .long   1001b, 1006b
                .long   1002b, 1006b
                .long   1003b, 1006b
                .long   1004b, 1006b
-               .previous
+               .popsection
 
 #define instr r4
 #define reg   r5
index 1279abd..14a0d98 100644 (file)
@@ -45,9 +45,10 @@ USER(                strnebt r2, [r0])
                mov     r0, #0
                ldmfd   sp!, {r1, pc}
 ENDPROC(__clear_user)
+ENDPROC(__clear_user_std)
 
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  0
 9001:          ldmfd   sp!, {r0, pc}
-               .previous
+               .popsection
 
index e4fe124..66a477a 100644 (file)
@@ -90,7 +90,7 @@ ENTRY(__copy_from_user)
 
 ENDPROC(__copy_from_user)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align 0
        copy_abort_preamble
        ldmfd   sp!, {r1, r2}
@@ -100,5 +100,5 @@ ENDPROC(__copy_from_user)
        bl      __memzero
        ldr     r0, [sp], #4
        copy_abort_end
-       .previous
+       .popsection
 
index 1a71e15..d066df6 100644 (file)
@@ -93,13 +93,14 @@ WEAK(__copy_to_user)
 #include "copy_template.S"
 
 ENDPROC(__copy_to_user)
+ENDPROC(__copy_to_user_std)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align 0
        copy_abort_preamble
        ldmfd   sp!, {r1, r2, r3}
        sub     r0, r0, r1
        rsb     r0, r0, r2
        copy_abort_end
-       .previous
+       .popsection
 
index fd0e9dc..59ff6fd 100644 (file)
@@ -68,7 +68,7 @@
  * so properly, we would have to add in whatever registers were loaded before
  * the fault, which, with the current asm above is not predictable.
  */
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  4
 9001:          mov     r4, #-EFAULT
                ldr     r5, [fp, #4]            @ *err_ptr
@@ -80,4 +80,4 @@
                strneb  r0, [r1], #1
                bne     9002b
                load_regs
-               .previous
+               .popsection
index a1814d9..b1631a7 100644 (file)
@@ -64,9 +64,9 @@ __get_user_bad:
        mov     pc, lr
 ENDPROC(__get_user_bad)
 
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
        .long   1b, __get_user_bad
        .long   2b, __get_user_bad
        .long   3b, __get_user_bad
        .long   4b, __get_user_bad
-.previous
+.popsection
index 02fedbf..5a01a23 100644 (file)
@@ -81,11 +81,11 @@ __put_user_bad:
        mov     pc, lr
 ENDPROC(__put_user_bad)
 
-.section __ex_table, "a"
+.pushsection __ex_table, "a"
        .long   1b, __put_user_bad
        .long   2b, __put_user_bad
        .long   3b, __put_user_bad
        .long   4b, __put_user_bad
        .long   5b, __put_user_bad
        .long   6b, __put_user_bad
-.previous
+.popsection
index 1c9814f..f202d7b 100644 (file)
@@ -33,11 +33,11 @@ ENTRY(__strncpy_from_user)
        mov     pc, lr
 ENDPROC(__strncpy_from_user)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align  0
 9001:  mov     r3, #0
        strb    r3, [r0, #0]    @ null terminate
        mov     r0, #-EFAULT
        mov     pc, lr
-       .previous
+       .popsection
 
index 7855b29..0ecbb45 100644 (file)
@@ -33,8 +33,8 @@ ENTRY(__strnlen_user)
        mov     pc, lr
 ENDPROC(__strnlen_user)
 
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align  0
 9001:  mov     r0, #0
        mov     pc, lr
-       .previous
+       .popsection
index ffdd274..fee9f6f 100644 (file)
@@ -279,10 +279,10 @@ USER(             strgtbt r3, [r0], #1)                   @ May fault
                b       .Lc2u_finished
 ENDPROC(__copy_to_user)
 
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  0
 9001:          ldmfd   sp!, {r0, r4 - r7, pc}
-               .previous
+               .popsection
 
 /* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
  * Purpose  : copy a block from user memory to kernel memory
@@ -545,7 +545,7 @@ USER(               ldrgtbt r3, [r1], #1)                   @ May fault
                b       .Lcfu_finished
 ENDPROC(__copy_from_user)
 
-               .section .fixup,"ax"
+               .pushsection .fixup,"ax"
                .align  0
                /*
                 * We took an exception.  r0 contains a pointer to
@@ -559,5 +559,5 @@ ENDPROC(__copy_from_user)
                blne    __memzero
                mov     r0, r4
                ldmfd   sp!, {r4 - r7, pc}
-               .previous
+               .popsection
 
index 2db43a5..841eaf8 100644 (file)
@@ -23,14 +23,12 @@ choice
 config ARCH_AT91RM9200
        bool "AT91RM9200"
        select CPU_ARM920T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_USART3
 
 config ARCH_AT91SAM9260
        bool "AT91SAM9260 or AT91SAM9XE"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_USART3
        select HAVE_AT91_USART4
@@ -39,28 +37,24 @@ config ARCH_AT91SAM9260
 config ARCH_AT91SAM9261
        bool "AT91SAM9261"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9G10
        bool "AT91SAM9G10"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9263
        bool "AT91SAM9263"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
 
 config ARCH_AT91SAM9RL
        bool "AT91SAM9RL"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
@@ -68,7 +62,6 @@ config ARCH_AT91SAM9RL
 config ARCH_AT91SAM9G20
        bool "AT91SAM9G20"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_USART3
        select HAVE_AT91_USART4
@@ -77,7 +70,6 @@ config ARCH_AT91SAM9G20
 config ARCH_AT91SAM9G45
        bool "AT91SAM9G45"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_AT91_USART3
        select HAVE_FB_ATMEL
@@ -85,18 +77,17 @@ config ARCH_AT91SAM9G45
 config ARCH_AT91CAP9
        bool "AT91CAP9"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select HAVE_FB_ATMEL
 
 config ARCH_AT572D940HF
        bool "AT572D940HF"
        select CPU_ARM926T
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
 
 config ARCH_AT91X40
        bool "AT91x40"
+       select ARCH_USES_GETTIMEOFFSET
 
 endchoice
 
@@ -360,6 +351,19 @@ config MACH_CPU9G20
          Select this if you are using a Eukrea Electromatique's
          CPU9G20 Board <http://www.eukrea.com/>
 
+config MACH_PORTUXG20
+       bool "taskit PortuxG20"
+       help
+         Select this if you are using taskit's PortuxG20.
+         <http://www.taskit.de/en/>
+
+config MACH_STAMP9G20
+       bool "taskit Stamp9G20 CPU module"
+       help
+         Select this if you are using taskit's Stamp9G20 CPU module on its
+         evaluation board.
+         <http://www.taskit.de/en/>
+
 endif
 
 # ----------------------------------------------------------
index 027dd57..c1f821e 100644 (file)
@@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261)        += at91sam9261.o at91sam926x_time.o at91sam9261_d
 obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)  += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
- obj-$(CONFIG_ARCH_AT91SAM9G45)        += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)    += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)     += at91x40.o at91x40_time.o
@@ -63,6 +63,8 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK)       += board-sam9rlek.o
 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
 
 # AT91SAM9G45 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
new file mode 100644 (file)
index 0000000..8795827
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ *  Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
+ *                     taskit GmbH
+ *
+ * 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/mm.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init portuxg20_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, CTS, RTS) */
+       at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */
+       at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* USART4 on ttyS5. (Rx, Tx only) */
+       at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+       /* USART5 on ttyS6. (Rx, Tx only) */
+       at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init stamp9g20_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);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init init_irq(void)
+{
+       at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * NAND flash
+ */
+static struct atmel_nand_data __initdata nand_data = {
+       .ale            = 21,
+       .cle            = 22,
+       .rdy_pin        = AT91_PIN_PC13,
+       .enable_pin     = AT91_PIN_PC14,
+       .bus_width_16   = 0,
+};
+
+static struct sam9_smc_config __initdata 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 | AT91_SMC_DBW_8,
+       .tdf_cycles             = 3,
+};
+
+static void __init add_device_nand(void)
+{
+       /* configure chip-select 3 (NAND) */
+       sam9_smc_configure(3, &nand_smc_config);
+
+       at91_add_device_nand(&nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata mmc_data = {
+       .slot[0] = {
+               .bus_width      = 4,
+       },
+};
+#else
+static struct at91_mmc_data __initdata mmc_data = {
+       .slot_b         = 0,
+       .wire4          = 1,
+};
+#endif
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+       .ports          = 2,
+};
+
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata portuxg20_udc_data = {
+       .vbus_pin       = AT91_PIN_PC7,
+       .pullup_pin     = 0,            /* pull-up driven by UDC */
+};
+
+static struct at91_udc_data __initdata stamp9g20_udc_data = {
+       .vbus_pin       = AT91_PIN_PA22,
+       .pullup_pin     = 0,            /* pull-up driven by UDC */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+       .phy_irq_pin    = AT91_PIN_PA28,
+       .is_rmii        = 1,
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led portuxg20_leds[] = {
+       {
+               .name                   = "LED2",
+               .gpio                   = AT91_PIN_PC5,
+               .default_trigger        = "none",
+       }, {
+               .name                   = "LED3",
+               .gpio                   = AT91_PIN_PC4,
+               .default_trigger        = "none",
+       }, {
+               .name                   = "LED4",
+               .gpio                   = AT91_PIN_PC10,
+               .default_trigger        = "heartbeat",
+       }
+};
+
+static struct gpio_led stamp9g20_leds[] = {
+       {
+               .name                   = "D8",
+               .gpio                   = AT91_PIN_PB18,
+               .active_low             = 1,
+               .default_trigger        = "none",
+       }, {
+               .name                   = "D9",
+               .gpio                   = AT91_PIN_PB19,
+               .active_low             = 1,
+               .default_trigger        = "none",
+       }, {
+               .name                   = "D10",
+               .gpio                   = AT91_PIN_PB20,
+               .active_low             = 1,
+               .default_trigger        = "heartbeat",
+       }
+};
+
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info portuxg20_spi_devices[] = {
+       {
+               .modalias       = "spidev",
+               .chip_select    = 0,
+               .max_speed_hz   = 1 * 1000 * 1000,
+               .bus_num        = 0,
+       }, {
+               .modalias       = "spidev",
+               .chip_select    = 0,
+               .max_speed_hz   = 1 * 1000 * 1000,
+               .bus_num        = 1,
+       },
+};
+
+
+/*
+ * Dallas 1-Wire
+ */
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+       .pin            = AT91_PIN_PA29,
+       .is_open_drain  = 1,
+};
+
+static struct platform_device w1_device = {
+       .name                   = "w1-gpio",
+       .id                     = -1,
+       .dev.platform_data      = &w1_gpio_pdata,
+};
+
+void add_w1(void)
+{
+       at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
+       at91_set_multi_drive(w1_gpio_pdata.pin, 1);
+       platform_device_register(&w1_device);
+}
+
+
+static void __init generic_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* NAND */
+       add_device_nand();
+       /* MMC */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+       at91_add_device_mci(0, &mmc_data);
+#else
+       at91_add_device_mmc(0, &mmc_data);
+#endif
+       /* USB Host */
+       at91_add_device_usbh(&usbh_data);
+       /* Ethernet */
+       at91_add_device_eth(&macb_data);
+       /* I2C */
+       at91_add_device_i2c(NULL, 0);
+       /* W1 */
+       add_w1();
+}
+
+static void __init portuxg20_board_init(void)
+{
+       generic_board_init();
+       /* SPI */
+       at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
+       /* USB Device */
+       at91_add_device_udc(&portuxg20_udc_data);
+       /* LEDs */
+       at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
+}
+
+static void __init stamp9g20_board_init(void)
+{
+       generic_board_init();
+       /* USB Device */
+       at91_add_device_udc(&stamp9g20_udc_data);
+       /* LEDs */
+       at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds));
+}
+
+MACHINE_START(PORTUXG20, "taskit PortuxG20")
+       /* Maintainer: taskit GmbH */
+       .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         = portuxg20_map_io,
+       .init_irq       = init_irq,
+       .init_machine   = portuxg20_board_init,
+MACHINE_END
+
+MACHINE_START(STAMP9G20, "taskit Stamp9G20")
+       /* Maintainer: taskit GmbH */
+       .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         = stamp9g20_map_io,
+       .init_irq       = init_irq,
+       .init_machine   = stamp9g20_board_init,
+MACHINE_END
index ceaec6c..df2ed84 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/usb/atmel_usba_udc.h>
 #include <linux/atmel-mci.h>
 #include <sound/atmel-ac97c.h>
+#include <linux/serial.h>
 
  /* USB Device */
 struct at91_udc_data {
@@ -143,9 +144,10 @@ extern struct platform_device *atmel_default_console_device;
 extern void __init __deprecated at91_init_serial(struct at91_uart_config *config);
 
 struct atmel_uart_data {
-       short           use_dma_tx;     /* use transmit DMA? */
-       short           use_dma_rx;     /* use receive DMA? */
-       void __iomem    *regs;          /* virtual base address, if any */
+       short                   use_dma_tx;     /* use transmit DMA? */
+       short                   use_dma_rx;     /* use receive DMA? */
+       void __iomem            *regs;          /* virt. base address, if any */
+       struct serial_rs485     rs485;          /* rs485 settings */
 };
 extern void __init at91_add_device_serial(void);
 
index 5a06501..833659d 100644 (file)
@@ -21,7 +21,7 @@
 #define ARCH_ID_AT91SAM9260    0x019803a0
 #define ARCH_ID_AT91SAM9261    0x019703a0
 #define ARCH_ID_AT91SAM9263    0x019607a0
-#define ARCH_ID_AT91SAM9G10    0x819903a0
+#define ARCH_ID_AT91SAM9G10    0x019903a0
 #define ARCH_ID_AT91SAM9G20    0x019905a0
 #define ARCH_ID_AT91SAM9RL64   0x019b03a0
 #define ARCH_ID_AT91SAM9G45    0x819b05a0
@@ -108,7 +108,7 @@ static inline unsigned long at91cap9_rev_identify(void)
 #endif
 
 #ifdef CONFIG_ARCH_AT91SAM9G10
-#define cpu_is_at91sam9g10()   (at91_cpu_identify() == ARCH_ID_AT91SAM9G10)
+#define cpu_is_at91sam9g10()   ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10)
 #else
 #define cpu_is_at91sam9g10()   (0)
 #endif
index 5268af3..c80e090 100644 (file)
 #include <mach/hardware.h>
 #include <mach/at91_st.h>
 #include <mach/at91_dbgu.h>
+#include <mach/at91_pmc.h>
 
 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);
-
+       at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#else
        /*
         * 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.
         */
        cpu_do_idle();
+#endif
 }
 
 void (*at91_arch_reset)(void);
index 987fab3..9c5b48e 100644 (file)
@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
        orr     r3, r3, #(1 << 29)              /* bit 29 always set */
        str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
-       wait_pllalock
-
        /* Save PLLB setting and disable it */
        ldr     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
        str     r3, .saved_pllbr
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
        mov     r3, #AT91_PMC_PLLCOUNT
        str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
-       wait_pllblock
-
        /* Turn off the main oscillator */
        ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
        bic     r3, r3, #AT91_PMC_MOSCEN
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
        ldr     r3, .saved_pllbr
        str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
+       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       bne     1f
+       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       beq     2f
+1:
        wait_pllblock
+2:
 
        /* Restore PLLA setting */
        ldr     r3, .saved_pllar
        str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
+       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       bne     3f
+       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       beq     4f
+3:
        wait_pllalock
+4:
 
 #ifdef SLOWDOWN_MASTER_CLOCK
        /*
index 53dd2a9..2f13919 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
+#include <asm/pmu.h>
 
 #include <asm/mach/arch.h>
 #include <mach/dma.h>
@@ -85,8 +86,23 @@ static struct platform_device nand_device = {
        .num_resources  = ARRAY_SIZE(nand_resource),
 };
 
+static struct resource pmu_resource = {
+       .start  = IRQ_PMUIRQ,
+       .end    = IRQ_PMUIRQ,
+       .flags  = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+       .name           = "arm-pmu",
+       .id             = ARM_PMU_DEVICE_CPU,
+       .resource       = &pmu_resource,
+       .num_resources  = 1,
+};
+
+
 static struct platform_device *devices[] __initdata = {
        &nand_device,
+       &pmu_device,
 };
 
 /****************************************************************************
index 2ccf670..29c0a91 100644 (file)
@@ -2221,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring);
 int dma_unmap(DMA_MemMap_t *memMap,    /* Stores state information about the map */
              int dirtied       /* non-zero if any of the pages were modified */
     ) {
+
+       int rc = 0;
        int regionIdx;
        int segmentIdx;
        DMA_Region_t *region;
        DMA_Segment_t *segment;
 
+       down(&memMap->lock);
+
        for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
                region = &memMap->region[regionIdx];
 
@@ -2239,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap,       /* Stores state information about the map */
                                        printk(KERN_ERR
                                               "%s: vmalloc'd pages are not yet supported\n",
                                               __func__);
-                                       return -EINVAL;
+                                       rc = -EINVAL;
+                                       goto out;
                                }
 
                        case DMA_MEM_TYPE_KMALLOC:
@@ -2276,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap,       /* Stores state information about the map */
                                        printk(KERN_ERR
                                               "%s: Unsupported memory type: %d\n",
                                               __func__, region->memType);
-                                       return -EINVAL;
+                                       rc = -EINVAL;
+                                       goto out;
                                }
                        }
 
@@ -2314,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap,      /* Stores state information about the map */
        memMap->numRegionsUsed = 0;
        memMap->inUse = 0;
 
+out:
        up(&memMap->lock);
 
-       return 0;
+       return rc;
 }
 
 EXPORT_SYMBOL(dma_unmap);
index a7b4591..9865921 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
new file mode 100644 (file)
index 0000000..9ebfcc4
--- /dev/null
@@ -0,0 +1,12 @@
+menu "CNS3XXX platform type"
+       depends on ARCH_CNS3XXX
+
+config MACH_CNS3420VB
+       bool "Support for CNS3420 Validation Board"
+       help
+         Include support for the Cavium Networks CNS3420 MPCore Platform
+         Baseboard.
+         This is a platform with an on-board ARM11 MPCore and has support
+         for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc.
+
+endmenu
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile
new file mode 100644 (file)
index 0000000..427507a
--- /dev/null
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARCH_CNS3XXX)             += core.o pm.o
+obj-$(CONFIG_MACH_CNS3420VB)           += cns3420vb.o
diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot
new file mode 100644 (file)
index 0000000..7770128
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00C00000
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
new file mode 100644 (file)
index 0000000..2e30c82
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Cavium Networks CNS3420 Validation Board
+ *
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *               Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ *               Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file 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/compiler.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+#include <mach/irqs.h>
+#include "core.h"
+
+/*
+ * NOR Flash
+ */
+static struct mtd_partition cns3420_nor_partitions[] = {
+       {
+               .name           = "uboot",
+               .size           = 0x00040000,
+               .offset         = 0,
+               .mask_flags     = MTD_WRITEABLE,
+       }, {
+               .name           = "kernel",
+               .size           = 0x004C0000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "filesystem",
+               .size           = 0x7000000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "filesystem2",
+               .size           = 0x0AE0000,
+               .offset         = MTDPART_OFS_APPEND,
+       }, {
+               .name           = "ubootenv",
+               .size           = MTDPART_SIZ_FULL,
+               .offset         = MTDPART_OFS_APPEND,
+       },
+};
+
+static struct physmap_flash_data cns3420_nor_pdata = {
+       .width = 2,
+       .parts = cns3420_nor_partitions,
+       .nr_parts = ARRAY_SIZE(cns3420_nor_partitions),
+};
+
+static struct resource cns3420_nor_res = {
+       .start = CNS3XXX_FLASH_BASE,
+       .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
+       .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct platform_device cns3420_nor_pdev = {
+       .name = "physmap-flash",
+       .id = 0,
+       .resource = &cns3420_nor_res,
+       .num_resources = 1,
+       .dev = {
+               .platform_data = &cns3420_nor_pdata,
+       },
+};
+
+/*
+ * UART
+ */
+static void __init cns3420_early_serial_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+       static struct uart_port cns3420_serial_port = {
+               .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
+               .mapbase        = CNS3XXX_UART0_BASE,
+               .irq            = IRQ_CNS3XXX_UART0,
+               .iotype         = UPIO_MEM,
+               .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+               .regshift       = 2,
+               .uartclk        = 24000000,
+               .line           = 0,
+               .type           = PORT_16550A,
+               .fifosize       = 16,
+       };
+
+       early_serial_setup(&cns3420_serial_port);
+#endif
+}
+
+/*
+ * Initialization
+ */
+static struct platform_device *cns3420_pdevs[] __initdata = {
+       &cns3420_nor_pdev,
+};
+
+static void __init cns3420_init(void)
+{
+       platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs));
+
+       pm_power_off = cns3xxx_power_off;
+}
+
+static struct map_desc cns3420_io_desc[] __initdata = {
+       {
+               .virtual        = CNS3XXX_UART0_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_UART0_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void __init cns3420_map_io(void)
+{
+       cns3xxx_map_io();
+       iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
+
+       cns3420_early_serial_setup();
+}
+
+MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
+       .phys_io        = CNS3XXX_UART0_BASE,
+       .io_pg_offst    = (CNS3XXX_UART0_BASE_VIRT >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = cns3420_map_io,
+       .init_irq       = cns3xxx_init_irq,
+       .timer          = &cns3xxx_timer,
+       .init_machine   = cns3420_init,
+MACHINE_END
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
new file mode 100644 (file)
index 0000000..9ca4d58
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright 1999 - 2003 ARM Limited
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/gic.h>
+#include <mach/cns3xxx.h>
+#include "core.h"
+
+static struct map_desc cns3xxx_io_desc[] __initdata = {
+       {
+               .virtual        = CNS3XXX_TC11MP_TWD_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_TIMER1_2_3_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_TIMER1_2_3_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_GPIOA_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_GPIOA_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_GPIOB_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_GPIOB_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_MISC_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_MISC_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = CNS3XXX_PM_BASE_VIRT,
+               .pfn            = __phys_to_pfn(CNS3XXX_PM_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+void __init cns3xxx_map_io(void)
+{
+       iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
+}
+
+/* used by entry-macro.S */
+void __iomem *gic_cpu_base_addr;
+
+void __init cns3xxx_init_irq(void)
+{
+       gic_cpu_base_addr = __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT);
+       gic_dist_init(0, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT), 29);
+       gic_cpu_init(0, gic_cpu_base_addr);
+}
+
+void cns3xxx_power_off(void)
+{
+       u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT);
+       u32 clkctrl;
+
+       printk(KERN_INFO "powering system down...\n");
+
+       clkctrl = readl(pm_base + PM_SYS_CLK_CTRL_OFFSET);
+       clkctrl &= 0xfffff1ff;
+       clkctrl |= (0x5 << 9);          /* Hibernate */
+       writel(clkctrl, pm_base + PM_SYS_CLK_CTRL_OFFSET);
+
+}
+
+/*
+ * Timer
+ */
+static void __iomem *cns3xxx_tmr1;
+
+static void cns3xxx_timer_set_mode(enum clock_event_mode mode,
+                                  struct clock_event_device *clk)
+{
+       unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+       int pclk = cns3xxx_cpu_clock() / 8;
+       int reload;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               reload = pclk * 20 / (3 * HZ) * 0x25000;
+               writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+               ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               /* period set, and timer enabled in 'next_event' hook */
+               ctrl |= (1 << 2) | (1 << 9);
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       default:
+               ctrl = 0;
+       }
+
+       writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+}
+
+static int cns3xxx_timer_set_next_event(unsigned long evt,
+                                       struct clock_event_device *unused)
+{
+       unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+       writel(evt, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+       writel(ctrl | (1 << 0), cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+       return 0;
+}
+
+static struct clock_event_device cns3xxx_tmr1_clockevent = {
+       .name           = "cns3xxx timer1",
+       .shift          = 8,
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_mode       = cns3xxx_timer_set_mode,
+       .set_next_event = cns3xxx_timer_set_next_event,
+       .rating         = 350,
+       .cpumask        = cpu_all_mask,
+};
+
+static void __init cns3xxx_clockevents_init(unsigned int timer_irq)
+{
+       cns3xxx_tmr1_clockevent.irq = timer_irq;
+       cns3xxx_tmr1_clockevent.mult =
+               div_sc((cns3xxx_cpu_clock() >> 3) * 1000000, NSEC_PER_SEC,
+                      cns3xxx_tmr1_clockevent.shift);
+       cns3xxx_tmr1_clockevent.max_delta_ns =
+               clockevent_delta2ns(0xffffffff, &cns3xxx_tmr1_clockevent);
+       cns3xxx_tmr1_clockevent.min_delta_ns =
+               clockevent_delta2ns(0xf, &cns3xxx_tmr1_clockevent);
+
+       clockevents_register_device(&cns3xxx_tmr1_clockevent);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = &cns3xxx_tmr1_clockevent;
+       u32 __iomem *stat = cns3xxx_tmr1 + TIMER1_2_INTERRUPT_STATUS_OFFSET;
+       u32 val;
+
+       /* Clear the interrupt */
+       val = readl(stat);
+       writel(val & ~(1 << 2), stat);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction cns3xxx_timer_irq = {
+       .name           = "timer",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = cns3xxx_timer_interrupt,
+};
+
+/*
+ * Set up the clock source and clock events devices
+ */
+static void __init __cns3xxx_timer_init(unsigned int timer_irq)
+{
+       u32 val;
+       u32 irq_mask;
+
+       /*
+        * Initialise to a known state (all timers off)
+        */
+
+       /* disable timer1 and timer2 */
+       writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+       /* stop free running timer3 */
+       writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
+
+       /* timer1 */
+       writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
+       writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+
+       writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
+       writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
+
+       /* mask irq, non-mask timer1 overflow */
+       irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+       irq_mask &= ~(1 << 2);
+       irq_mask |= 0x03;
+       writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+       /* down counter */
+       val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+       val |= (1 << 9);
+       writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+       /* timer2 */
+       writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
+       writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
+
+       /* mask irq */
+       irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+       irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
+       writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+       /* down counter */
+       val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+       val |= (1 << 10);
+       writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+       /* Make irqs happen for the system timer */
+       setup_irq(timer_irq, &cns3xxx_timer_irq);
+
+       cns3xxx_clockevents_init(timer_irq);
+}
+
+static void __init cns3xxx_timer_init(void)
+{
+       cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT);
+
+       __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
+}
+
+struct sys_timer cns3xxx_timer = {
+       .init = cns3xxx_timer_init,
+};
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
new file mode 100644 (file)
index 0000000..6b33ec1
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __CNS3XXX_CORE_H
+#define __CNS3XXX_CORE_H
+
+extern void __iomem *gic_cpu_base_addr;
+extern struct sys_timer cns3xxx_timer;
+
+void __init cns3xxx_map_io(void);
+void __init cns3xxx_init_irq(void);
+void cns3xxx_power_off(void);
+void cns3xxx_pwr_power_up(unsigned int block);
+void cns3xxx_pwr_power_down(unsigned int block);
+
+#endif /* __CNS3XXX_CORE_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
new file mode 100644 (file)
index 0000000..8a2f5a2
--- /dev/null
@@ -0,0 +1,635 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_BOARD_CNS3XXXH
+#define __MACH_BOARD_CNS3XXXH
+
+/*
+ * Memory map
+ */
+#define CNS3XXX_FLASH_BASE                     0x10000000      /* Flash/SRAM Memory Bank 0 */
+#define CNS3XXX_FLASH_SIZE                     SZ_256M
+
+#define CNS3XXX_DDR2SDRAM_BASE                 0x20000000      /* DDR2 SDRAM Memory */
+
+#define CNS3XXX_SPI_FLASH_BASE                 0x60000000      /* SPI Serial Flash Memory */
+
+#define CNS3XXX_SWITCH_BASE                    0x70000000      /* Switch and HNAT Control */
+#define CNS3XXX_SWITCH_BASE_VIRT               0xFFF00000
+
+#define CNS3XXX_PPE_BASE                       0x70001000      /* HANT */
+#define CNS3XXX_PPE_BASE_VIRT                  0xFFF50000
+
+#define CNS3XXX_EMBEDDED_SRAM_BASE             0x70002000      /* HANT Embedded SRAM */
+#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT                0xFFF60000
+
+#define CNS3XXX_SSP_BASE                       0x71000000      /* Synchronous Serial Port - SPI/PCM/I2C */
+#define CNS3XXX_SSP_BASE_VIRT                  0xFFF01000
+
+#define CNS3XXX_DMC_BASE                       0x72000000      /* DMC Control (DDR2 SDRAM) */
+#define CNS3XXX_DMC_BASE_VIRT                  0xFFF02000
+
+#define CNS3XXX_SMC_BASE                       0x73000000      /* SMC Control */
+#define CNS3XXX_SMC_BASE_VIRT                  0xFFF03000
+
+#define SMC_MEMC_STATUS_OFFSET                 0x000
+#define SMC_MEMIF_CFG_OFFSET                   0x004
+#define SMC_MEMC_CFG_SET_OFFSET                        0x008
+#define SMC_MEMC_CFG_CLR_OFFSET                        0x00C
+#define SMC_DIRECT_CMD_OFFSET                  0x010
+#define SMC_SET_CYCLES_OFFSET                  0x014
+#define SMC_SET_OPMODE_OFFSET                  0x018
+#define SMC_REFRESH_PERIOD_0_OFFSET            0x020
+#define SMC_REFRESH_PERIOD_1_OFFSET            0x024
+#define SMC_SRAM_CYCLES0_0_OFFSET              0x100
+#define SMC_NAND_CYCLES0_0_OFFSET              0x100
+#define SMC_OPMODE0_0_OFFSET                   0x104
+#define SMC_SRAM_CYCLES0_1_OFFSET              0x120
+#define SMC_NAND_CYCLES0_1_OFFSET              0x120
+#define SMC_OPMODE0_1_OFFSET                   0x124
+#define SMC_USER_STATUS_OFFSET                 0x200
+#define SMC_USER_CONFIG_OFFSET                 0x204
+#define SMC_ECC_STATUS_OFFSET                  0x300
+#define SMC_ECC_MEMCFG_OFFSET                  0x304
+#define SMC_ECC_MEMCOMMAND1_OFFSET             0x308
+#define SMC_ECC_MEMCOMMAND2_OFFSET             0x30C
+#define SMC_ECC_ADDR0_OFFSET                   0x310
+#define SMC_ECC_ADDR1_OFFSET                   0x314
+#define SMC_ECC_VALUE0_OFFSET                  0x318
+#define SMC_ECC_VALUE1_OFFSET                  0x31C
+#define SMC_ECC_VALUE2_OFFSET                  0x320
+#define SMC_ECC_VALUE3_OFFSET                  0x324
+#define SMC_PERIPH_ID_0_OFFSET                 0xFE0
+#define SMC_PERIPH_ID_1_OFFSET                 0xFE4
+#define SMC_PERIPH_ID_2_OFFSET                 0xFE8
+#define SMC_PERIPH_ID_3_OFFSET                 0xFEC
+#define SMC_PCELL_ID_0_OFFSET                  0xFF0
+#define SMC_PCELL_ID_1_OFFSET                  0xFF4
+#define SMC_PCELL_ID_2_OFFSET                  0xFF8
+#define SMC_PCELL_ID_3_OFFSET                  0xFFC
+
+#define CNS3XXX_GPIOA_BASE                     0x74000000      /* GPIO port A */
+#define CNS3XXX_GPIOA_BASE_VIRT                        0xFFF04000
+
+#define CNS3XXX_GPIOB_BASE                     0x74800000      /* GPIO port B */
+#define CNS3XXX_GPIOB_BASE_VIRT                        0xFFF05000
+
+#define CNS3XXX_RTC_BASE                       0x75000000      /* Real Time Clock */
+#define CNS3XXX_RTC_BASE_VIRT                  0xFFF06000
+
+#define RTC_SEC_OFFSET                         0x00
+#define RTC_MIN_OFFSET                         0x04
+#define RTC_HOUR_OFFSET                                0x08
+#define RTC_DAY_OFFSET                         0x0C
+#define RTC_SEC_ALM_OFFSET                     0x10
+#define RTC_MIN_ALM_OFFSET                     0x14
+#define RTC_HOUR_ALM_OFFSET                    0x18
+#define RTC_REC_OFFSET                         0x1C
+#define RTC_CTRL_OFFSET                                0x20
+#define RTC_INTR_STS_OFFSET                    0x34
+
+#define CNS3XXX_MISC_BASE                      0x76000000      /* Misc Control */
+#define CNS3XXX_MISC_BASE_VIRT                 0xFFF07000      /* Misc Control */
+
+#define CNS3XXX_PM_BASE                                0x77000000      /* Power Management Control */
+#define CNS3XXX_PM_BASE_VIRT                   0xFFF08000
+
+#define PM_CLK_GATE_OFFSET                     0x00
+#define PM_SOFT_RST_OFFSET                     0x04
+#define PM_HS_CFG_OFFSET                       0x08
+#define PM_CACTIVE_STA_OFFSET                  0x0C
+#define PM_PWR_STA_OFFSET                      0x10
+#define PM_SYS_CLK_CTRL_OFFSET                 0x14
+#define PM_PLL_LCD_I2S_CTRL_OFFSET             0x18
+#define PM_PLL_HM_PD_OFFSET                    0x1C
+
+#define CNS3XXX_UART0_BASE                     0x78000000      /* UART 0 */
+#define CNS3XXX_UART0_BASE_VIRT                        0xFFF09000
+
+#define CNS3XXX_UART1_BASE                     0x78400000      /* UART 1 */
+#define CNS3XXX_UART1_BASE_VIRT                        0xFFF0A000
+
+#define CNS3XXX_UART2_BASE                     0x78800000      /* UART 2 */
+#define CNS3XXX_UART2_BASE_VIRT                        0xFFF0B000
+
+#define CNS3XXX_DMAC_BASE                      0x79000000      /* Generic DMA Control */
+#define CNS3XXX_DMAC_BASE_VIRT                 0xFFF0D000
+
+#define CNS3XXX_CORESIGHT_BASE                 0x7A000000      /* CoreSight */
+#define CNS3XXX_CORESIGHT_BASE_VIRT            0xFFF0E000
+
+#define CNS3XXX_CRYPTO_BASE                    0x7B000000      /* Crypto */
+#define CNS3XXX_CRYPTO_BASE_VIRT               0xFFF0F000
+
+#define CNS3XXX_I2S_BASE                       0x7C000000      /* I2S */
+#define CNS3XXX_I2S_BASE_VIRT                  0xFFF10000
+
+#define CNS3XXX_TIMER1_2_3_BASE                        0x7C800000      /* Timer */
+#define CNS3XXX_TIMER1_2_3_BASE_VIRT           0xFFF10800
+
+#define TIMER1_COUNTER_OFFSET                  0x00
+#define TIMER1_AUTO_RELOAD_OFFSET              0x04
+#define TIMER1_MATCH_V1_OFFSET                 0x08
+#define TIMER1_MATCH_V2_OFFSET                 0x0C
+
+#define TIMER2_COUNTER_OFFSET                  0x10
+#define TIMER2_AUTO_RELOAD_OFFSET              0x14
+#define TIMER2_MATCH_V1_OFFSET                 0x18
+#define TIMER2_MATCH_V2_OFFSET                 0x1C
+
+#define TIMER1_2_CONTROL_OFFSET                        0x30
+#define TIMER1_2_INTERRUPT_STATUS_OFFSET       0x34
+#define TIMER1_2_INTERRUPT_MASK_OFFSET         0x38
+
+#define TIMER_FREERUN_OFFSET                   0x40
+#define TIMER_FREERUN_CONTROL_OFFSET           0x44
+
+#define CNS3XXX_HCIE_BASE                      0x7D000000      /* HCIE Control */
+#define CNS3XXX_HCIE_BASE_VIRT                 0xFFF30000
+
+#define CNS3XXX_RAID_BASE                      0x7E000000      /* RAID Control */
+#define CNS3XXX_RAID_BASE_VIRT                 0xFFF12000
+
+#define CNS3XXX_AXI_IXC_BASE                   0x7F000000      /* AXI IXC */
+#define CNS3XXX_AXI_IXC_BASE_VIRT              0xFFF13000
+
+#define CNS3XXX_CLCD_BASE                      0x80000000      /* LCD Control */
+#define CNS3XXX_CLCD_BASE_VIRT                 0xFFF14000
+
+#define CNS3XXX_USBOTG_BASE                    0x81000000      /* USB OTG Control */
+#define CNS3XXX_USBOTG_BASE_VIRT               0xFFF15000
+
+#define CNS3XXX_USB_BASE                       0x82000000      /* USB Host Control */
+#define CNS3XXX_USB_BASE_VIRT                  0xFFF16000
+
+#define CNS3XXX_SATA2_BASE                     0x83000000      /* SATA */
+#define CNS3XXX_SATA2_SIZE                     SZ_16M
+#define CNS3XXX_SATA2_BASE_VIRT                        0xFFF17000
+
+#define CNS3XXX_CAMERA_BASE                    0x84000000      /* Camera Interface */
+#define CNS3XXX_CAMERA_BASE_VIRT               0xFFF18000
+
+#define CNS3XXX_SDIO_BASE                      0x85000000      /* SDIO */
+#define CNS3XXX_SDIO_BASE_VIRT                 0xFFF19000
+
+#define CNS3XXX_I2S_TDM_BASE                   0x86000000      /* I2S TDM */
+#define CNS3XXX_I2S_TDM_BASE_VIRT              0xFFF1A000
+
+#define CNS3XXX_2DG_BASE                       0x87000000      /* 2D Graphic Control */
+#define CNS3XXX_2DG_BASE_VIRT                  0xFFF1B000
+
+#define CNS3XXX_USB_OHCI_BASE                  0x88000000      /* USB OHCI */
+#define CNS3XXX_USB_OHCI_BASE_VIRT             0xFFF1C000
+
+#define CNS3XXX_L2C_BASE                       0x92000000      /* L2 Cache Control */
+#define CNS3XXX_L2C_BASE_VIRT                  0xFFF27000
+
+#define CNS3XXX_PCIE0_MEM_BASE                 0xA0000000      /* PCIe Port 0 IO/Memory Space */
+#define CNS3XXX_PCIE0_MEM_BASE_VIRT            0xE0000000
+
+#define CNS3XXX_PCIE0_HOST_BASE                        0xAB000000      /* PCIe Port 0 RC Base */
+#define CNS3XXX_PCIE0_HOST_BASE_VIRT           0xE1000000
+
+#define CNS3XXX_PCIE0_IO_BASE                  0xAC000000      /* PCIe Port 0 */
+#define CNS3XXX_PCIE0_IO_BASE_VIRT             0xE2000000
+
+#define CNS3XXX_PCIE0_CFG0_BASE                        0xAD000000      /* PCIe Port 0 CFG Type 0 */
+#define CNS3XXX_PCIE0_CFG0_BASE_VIRT           0xE3000000
+
+#define CNS3XXX_PCIE0_CFG1_BASE                        0xAE000000      /* PCIe Port 0 CFG Type 1 */
+#define CNS3XXX_PCIE0_CFG1_BASE_VIRT           0xE4000000
+
+#define CNS3XXX_PCIE0_MSG_BASE                 0xAF000000      /* PCIe Port 0 Message Space */
+#define CNS3XXX_PCIE0_MSG_BASE_VIRT            0xE5000000
+
+#define CNS3XXX_PCIE1_MEM_BASE                 0xB0000000      /* PCIe Port 1 IO/Memory Space */
+#define CNS3XXX_PCIE1_MEM_BASE_VIRT            0xE8000000
+
+#define CNS3XXX_PCIE1_HOST_BASE                        0xBB000000      /* PCIe Port 1 RC Base */
+#define CNS3XXX_PCIE1_HOST_BASE_VIRT           0xE9000000
+
+#define CNS3XXX_PCIE1_IO_BASE                  0xBC000000      /* PCIe Port 1 */
+#define CNS3XXX_PCIE1_IO_BASE_VIRT             0xEA000000
+
+#define CNS3XXX_PCIE1_CFG0_BASE                        0xBD000000      /* PCIe Port 1 CFG Type 0 */
+#define CNS3XXX_PCIE1_CFG0_BASE_VIRT           0xEB000000
+
+#define CNS3XXX_PCIE1_CFG1_BASE                        0xBE000000      /* PCIe Port 1 CFG Type 1 */
+#define CNS3XXX_PCIE1_CFG1_BASE_VIRT           0xEC000000
+
+#define CNS3XXX_PCIE1_MSG_BASE                 0xBF000000      /* PCIe Port 1 Message Space */
+#define CNS3XXX_PCIE1_MSG_BASE_VIRT            0xED000000
+
+/*
+ * Testchip peripheral and fpga gic regions
+ */
+#define CNS3XXX_TC11MP_SCU_BASE                        0x90000000      /* IRQ, Test chip */
+#define CNS3XXX_TC11MP_SCU_BASE_VIRT           0xFF000000
+
+#define CNS3XXX_TC11MP_GIC_CPU_BASE            0x90000100      /* Test chip interrupt controller CPU interface */
+#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT       0xFF000100
+
+#define CNS3XXX_TC11MP_TWD_BASE                        0x90000600
+#define CNS3XXX_TC11MP_TWD_BASE_VIRT           0xFF000600
+
+#define CNS3XXX_TC11MP_GIC_DIST_BASE           0x90001000      /* Test chip interrupt controller distributor */
+#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT      0xFF001000
+
+#define CNS3XXX_TC11MP_L220_BASE               0x92002000      /* L220 registers */
+#define CNS3XXX_TC11MP_L220_BASE_VIRT          0xFF002000
+
+/*
+ * Misc block
+ */
+#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs))
+#define MISC_MEM_MAP_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_MISC_BASE_VIRT + (offset))))
+
+#define MISC_MEMORY_REMAP_REG                  MISC_MEM_MAP_VALUE(0x00)
+#define MISC_CHIP_CONFIG_REG                   MISC_MEM_MAP_VALUE(0x04)
+#define MISC_DEBUG_PROBE_DATA_REG              MISC_MEM_MAP_VALUE(0x08)
+#define MISC_DEBUG_PROBE_SELECTION_REG         MISC_MEM_MAP_VALUE(0x0C)
+#define MISC_IO_PIN_FUNC_SELECTION_REG         MISC_MEM_MAP_VALUE(0x10)
+#define MISC_GPIOA_PIN_ENABLE_REG              MISC_MEM_MAP_VALUE(0x14)
+#define MISC_GPIOB_PIN_ENABLE_REG              MISC_MEM_MAP_VALUE(0x18)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A      MISC_MEM_MAP_VALUE(0x1C)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B      MISC_MEM_MAP_VALUE(0x20)
+#define MISC_GPIOA_15_0_PULL_CTRL_REG          MISC_MEM_MAP_VALUE(0x24)
+#define MISC_GPIOA_16_31_PULL_CTRL_REG         MISC_MEM_MAP_VALUE(0x28)
+#define MISC_GPIOB_15_0_PULL_CTRL_REG          MISC_MEM_MAP_VALUE(0x2C)
+#define MISC_GPIOB_16_31_PULL_CTRL_REG         MISC_MEM_MAP_VALUE(0x30)
+#define MISC_IO_PULL_CTRL_REG                  MISC_MEM_MAP_VALUE(0x34)
+#define MISC_E_FUSE_31_0_REG                   MISC_MEM_MAP_VALUE(0x40)
+#define MISC_E_FUSE_63_32_REG                  MISC_MEM_MAP_VALUE(0x44)
+#define MISC_E_FUSE_95_64_REG                  MISC_MEM_MAP_VALUE(0x48)
+#define MISC_E_FUSE_127_96_REG                 MISC_MEM_MAP_VALUE(0x4C)
+#define MISC_SOFTWARE_TEST_1_REG               MISC_MEM_MAP_VALUE(0x50)
+#define MISC_SOFTWARE_TEST_2_REG               MISC_MEM_MAP_VALUE(0x54)
+
+#define MISC_SATA_POWER_MODE                   MISC_MEM_MAP_VALUE(0x310)
+
+#define MISC_USB_CFG_REG                       MISC_MEM_MAP_VALUE(0x800)
+#define MISC_USB_STS_REG                       MISC_MEM_MAP_VALUE(0x804)
+#define MISC_USBPHY00_CFG_REG                  MISC_MEM_MAP_VALUE(0x808)
+#define MISC_USBPHY01_CFG_REG                  MISC_MEM_MAP_VALUE(0x80c)
+#define MISC_USBPHY10_CFG_REG                  MISC_MEM_MAP_VALUE(0x810)
+#define MISC_USBPHY11_CFG_REG                  MISC_MEM_MAP_VALUE(0x814)
+
+#define MISC_PCIEPHY_CMCTL(x)                  MISC_MEM_MAP(0x900 + (x) * 0x004)
+#define MISC_PCIEPHY_CTL(x)                    MISC_MEM_MAP(0x940 + (x) * 0x100)
+#define MISC_PCIE_AXIS_AWMISC(x)               MISC_MEM_MAP(0x944 + (x) * 0x100)
+#define MISC_PCIE_AXIS_ARMISC(x)               MISC_MEM_MAP(0x948 + (x) * 0x100)
+#define MISC_PCIE_AXIS_RMISC(x)                        MISC_MEM_MAP(0x94C + (x) * 0x100)
+#define MISC_PCIE_AXIS_BMISC(x)                        MISC_MEM_MAP(0x950 + (x) * 0x100)
+#define MISC_PCIE_AXIM_RMISC(x)                        MISC_MEM_MAP(0x954 + (x) * 0x100)
+#define MISC_PCIE_AXIM_BMISC(x)                        MISC_MEM_MAP(0x958 + (x) * 0x100)
+#define MISC_PCIE_CTRL(x)                      MISC_MEM_MAP(0x95C + (x) * 0x100)
+#define MISC_PCIE_PM_DEBUG(x)                  MISC_MEM_MAP(0x960 + (x) * 0x100)
+#define MISC_PCIE_RFC_DEBUG(x)                 MISC_MEM_MAP(0x964 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGL(x)               MISC_MEM_MAP(0x968 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGH(x)               MISC_MEM_MAP(0x96C + (x) * 0x100)
+#define MISC_PCIE_DIAG_DEBUGH(x)               MISC_MEM_MAP(0x970 + (x) * 0x100)
+#define MISC_PCIE_W1CLR(x)                     MISC_MEM_MAP(0x974 + (x) * 0x100)
+#define MISC_PCIE_INT_MASK(x)                  MISC_MEM_MAP(0x978 + (x) * 0x100)
+#define MISC_PCIE_INT_STATUS(x)                        MISC_MEM_MAP(0x97C + (x) * 0x100)
+
+/*
+ * Power management and clock control
+ */
+#define PMU_REG_VALUE(offset) (*((volatile unsigned int *)(CNS3XXX_PM_BASE_VIRT + (offset))))
+
+#define PM_CLK_GATE_REG                                        PMU_REG_VALUE(0x000)
+#define PM_SOFT_RST_REG                                        PMU_REG_VALUE(0x004)
+#define PM_HS_CFG_REG                                  PMU_REG_VALUE(0x008)
+#define PM_CACTIVE_STA_REG                             PMU_REG_VALUE(0x00C)
+#define PM_PWR_STA_REG                                 PMU_REG_VALUE(0x010)
+#define PM_CLK_CTRL_REG                                        PMU_REG_VALUE(0x014)
+#define PM_PLL_LCD_I2S_CTRL_REG                                PMU_REG_VALUE(0x018)
+#define PM_PLL_HM_PD_CTRL_REG                          PMU_REG_VALUE(0x01C)
+#define PM_REGULAT_CTRL_REG                            PMU_REG_VALUE(0x020)
+#define PM_WDT_CTRL_REG                                        PMU_REG_VALUE(0x024)
+#define PM_WU_CTRL0_REG                                        PMU_REG_VALUE(0x028)
+#define PM_WU_CTRL1_REG                                        PMU_REG_VALUE(0x02C)
+#define PM_CSR_REG                                     PMU_REG_VALUE(0x030)
+
+/* PM_CLK_GATE_REG */
+#define PM_CLK_GATE_REG_OFFSET_SDIO                    (25)
+#define PM_CLK_GATE_REG_OFFSET_GPU                     (24)
+#define PM_CLK_GATE_REG_OFFSET_CIM                     (23)
+#define PM_CLK_GATE_REG_OFFSET_LCDC                    (22)
+#define PM_CLK_GATE_REG_OFFSET_I2S                     (21)
+#define PM_CLK_GATE_REG_OFFSET_RAID                    (20)
+#define PM_CLK_GATE_REG_OFFSET_SATA                    (19)
+#define PM_CLK_GATE_REG_OFFSET_PCIE(x)                 (17 + (x))
+#define PM_CLK_GATE_REG_OFFSET_USB_HOST                        (16)
+#define PM_CLK_GATE_REG_OFFSET_USB_OTG                 (15)
+#define PM_CLK_GATE_REG_OFFSET_TIMER                   (14)
+#define PM_CLK_GATE_REG_OFFSET_CRYPTO                  (13)
+#define PM_CLK_GATE_REG_OFFSET_HCIE                    (12)
+#define PM_CLK_GATE_REG_OFFSET_SWITCH                  (11)
+#define PM_CLK_GATE_REG_OFFSET_GPIO                    (10)
+#define PM_CLK_GATE_REG_OFFSET_UART3                   (9)
+#define PM_CLK_GATE_REG_OFFSET_UART2                   (8)
+#define PM_CLK_GATE_REG_OFFSET_UART1                   (7)
+#define PM_CLK_GATE_REG_OFFSET_RTC                     (5)
+#define PM_CLK_GATE_REG_OFFSET_GDMA                    (4)
+#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C             (3)
+#define PM_CLK_GATE_REG_OFFSET_SMC_NFI                 (1)
+#define PM_CLK_GATE_REG_MASK                           (0x03FFFFBA)
+
+/* PM_SOFT_RST_REG */
+#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG            (31)
+#define PM_SOFT_RST_REG_OFFST_CPU1                     (29)
+#define PM_SOFT_RST_REG_OFFST_CPU0                     (28)
+#define PM_SOFT_RST_REG_OFFST_SDIO                     (25)
+#define PM_SOFT_RST_REG_OFFST_GPU                      (24)
+#define PM_SOFT_RST_REG_OFFST_CIM                      (23)
+#define PM_SOFT_RST_REG_OFFST_LCDC                     (22)
+#define PM_SOFT_RST_REG_OFFST_I2S                      (21)
+#define PM_SOFT_RST_REG_OFFST_RAID                     (20)
+#define PM_SOFT_RST_REG_OFFST_SATA                     (19)
+#define PM_SOFT_RST_REG_OFFST_PCIE(x)                  (17 + (x))
+#define PM_SOFT_RST_REG_OFFST_USB_HOST                 (16)
+#define PM_SOFT_RST_REG_OFFST_USB_OTG                  (15)
+#define PM_SOFT_RST_REG_OFFST_TIMER                    (14)
+#define PM_SOFT_RST_REG_OFFST_CRYPTO                   (13)
+#define PM_SOFT_RST_REG_OFFST_HCIE                     (12)
+#define PM_SOFT_RST_REG_OFFST_SWITCH                   (11)
+#define PM_SOFT_RST_REG_OFFST_GPIO                     (10)
+#define PM_SOFT_RST_REG_OFFST_UART3                    (9)
+#define PM_SOFT_RST_REG_OFFST_UART2                    (8)
+#define PM_SOFT_RST_REG_OFFST_UART1                    (7)
+#define PM_SOFT_RST_REG_OFFST_RTC                      (5)
+#define PM_SOFT_RST_REG_OFFST_GDMA                     (4)
+#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C              (3)
+#define PM_SOFT_RST_REG_OFFST_DMC                      (2)
+#define PM_SOFT_RST_REG_OFFST_SMC_NFI                  (1)
+#define PM_SOFT_RST_REG_OFFST_GLOBAL                   (0)
+#define PM_SOFT_RST_REG_MASK                           (0xF3FFFFBF)
+
+/* PMHS_CFG_REG */
+#define PM_HS_CFG_REG_OFFSET_SDIO                      (25)
+#define PM_HS_CFG_REG_OFFSET_GPU                       (24)
+#define PM_HS_CFG_REG_OFFSET_CIM                       (23)
+#define PM_HS_CFG_REG_OFFSET_LCDC                      (22)
+#define PM_HS_CFG_REG_OFFSET_I2S                       (21)
+#define PM_HS_CFG_REG_OFFSET_RAID                      (20)
+#define PM_HS_CFG_REG_OFFSET_SATA                      (19)
+#define PM_HS_CFG_REG_OFFSET_PCIE1                     (18)
+#define PM_HS_CFG_REG_OFFSET_PCIE0                     (17)
+#define PM_HS_CFG_REG_OFFSET_USB_HOST                  (16)
+#define PM_HS_CFG_REG_OFFSET_USB_OTG                   (15)
+#define PM_HS_CFG_REG_OFFSET_TIMER                     (14)
+#define PM_HS_CFG_REG_OFFSET_CRYPTO                    (13)
+#define PM_HS_CFG_REG_OFFSET_HCIE                      (12)
+#define PM_HS_CFG_REG_OFFSET_SWITCH                    (11)
+#define PM_HS_CFG_REG_OFFSET_GPIO                      (10)
+#define PM_HS_CFG_REG_OFFSET_UART3                     (9)
+#define PM_HS_CFG_REG_OFFSET_UART2                     (8)
+#define PM_HS_CFG_REG_OFFSET_UART1                     (7)
+#define PM_HS_CFG_REG_OFFSET_RTC                       (5)
+#define PM_HS_CFG_REG_OFFSET_GDMA                      (4)
+#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S               (3)
+#define PM_HS_CFG_REG_OFFSET_DMC                       (2)
+#define PM_HS_CFG_REG_OFFSET_SMC_NFI                   (1)
+#define PM_HS_CFG_REG_MASK                             (0x03FFFFBE)
+#define PM_HS_CFG_REG_MASK_SUPPORT                     (0x01100806)
+
+/* PM_CACTIVE_STA_REG */
+#define PM_CACTIVE_STA_REG_OFFSET_SDIO                 (25)
+#define PM_CACTIVE_STA_REG_OFFSET_GPU                  (24)
+#define PM_CACTIVE_STA_REG_OFFSET_CIM                  (23)
+#define PM_CACTIVE_STA_REG_OFFSET_LCDC                 (22)
+#define PM_CACTIVE_STA_REG_OFFSET_I2S                  (21)
+#define PM_CACTIVE_STA_REG_OFFSET_RAID                 (20)
+#define PM_CACTIVE_STA_REG_OFFSET_SATA                 (19)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE1                        (18)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE0                        (17)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST             (16)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG              (15)
+#define PM_CACTIVE_STA_REG_OFFSET_TIMER                        (14)
+#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO               (13)
+#define PM_CACTIVE_STA_REG_OFFSET_HCIE                 (12)
+#define PM_CACTIVE_STA_REG_OFFSET_SWITCH               (11)
+#define PM_CACTIVE_STA_REG_OFFSET_GPIO                 (10)
+#define PM_CACTIVE_STA_REG_OFFSET_UART3                        (9)
+#define PM_CACTIVE_STA_REG_OFFSET_UART2                        (8)
+#define PM_CACTIVE_STA_REG_OFFSET_UART1                        (7)
+#define PM_CACTIVE_STA_REG_OFFSET_RTC                  (5)
+#define PM_CACTIVE_STA_REG_OFFSET_GDMA                 (4)
+#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S          (3)
+#define PM_CACTIVE_STA_REG_OFFSET_DMC                  (2)
+#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI              (1)
+#define PM_CACTIVE_STA_REG_MASK                                (0x03FFFFBE)
+
+/* PM_PWR_STA_REG */
+#define PM_PWR_STA_REG_REG_OFFSET_SDIO                 (25)
+#define PM_PWR_STA_REG_REG_OFFSET_GPU                  (24)
+#define PM_PWR_STA_REG_REG_OFFSET_CIM                  (23)
+#define PM_PWR_STA_REG_REG_OFFSET_LCDC                 (22)
+#define PM_PWR_STA_REG_REG_OFFSET_I2S                  (21)
+#define PM_PWR_STA_REG_REG_OFFSET_RAID                 (20)
+#define PM_PWR_STA_REG_REG_OFFSET_SATA                 (19)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE1                        (18)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE0                        (17)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST             (16)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG              (15)
+#define PM_PWR_STA_REG_REG_OFFSET_TIMER                        (14)
+#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO               (13)
+#define PM_PWR_STA_REG_REG_OFFSET_HCIE                 (12)
+#define PM_PWR_STA_REG_REG_OFFSET_SWITCH               (11)
+#define PM_PWR_STA_REG_REG_OFFSET_GPIO                 (10)
+#define PM_PWR_STA_REG_REG_OFFSET_UART3                        (9)
+#define PM_PWR_STA_REG_REG_OFFSET_UART2                        (8)
+#define PM_PWR_STA_REG_REG_OFFSET_UART1                        (7)
+#define PM_PWR_STA_REG_REG_OFFSET_RTC                  (5)
+#define PM_PWR_STA_REG_REG_OFFSET_GDMA                 (4)
+#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S          (3)
+#define PM_PWR_STA_REG_REG_OFFSET_DMC                  (2)
+#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI              (1)
+#define PM_PWR_STA_REG_REG_MASK                                (0x03FFFFBE)
+
+/* PM_CLK_CTRL_REG */
+#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK                        (31)
+#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN             (30)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN            (29)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN            (28)
+#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE          (27)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV              (24)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL              (22)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV              (20)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL              (16)
+#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV                 (14)
+#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL          (12)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE            (9)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL            (7)
+#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE           (6)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV             (4)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL             (0)
+
+#define PM_CPU_CLK_DIV(DIV) { \
+       PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+       PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+}
+
+#define PM_PLL_CPU_SEL(CPU) { \
+       PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+       PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+}
+
+/* PM_PLL_LCD_I2S_CTRL_REG */
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV    (22)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL           (17)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P       (11)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M       (3)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S       (0)
+
+/* PM_PLL_HM_PD_CTRL_REG */
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1         (11)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0         (10)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD         (6)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S           (5)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD           (4)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB           (3)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII         (2)
+#define PM_PLL_HM_PD_CTRL_REG_MASK                     (0x00000C7C)
+
+/* PM_WDT_CTRL_REG */
+#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY          (0)
+
+/* PM_CSR_REG - Clock Scaling Register*/
+#define PM_CSR_REG_OFFSET_CSR_EN                       (30)
+#define PM_CSR_REG_OFFSET_CSR_NUM                      (0)
+
+#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1<<PM_CLK_GATE_REG_OFFSET_##BLOCK)
+
+/* Software reset*/
+#define CNS3XXX_PWR_SOFTWARE_RST(BLOCK) (0x1<<PM_SOFT_RST_REG_OFFST_##BLOCK)
+
+/*
+ * CNS3XXX support several power saving mode as following,
+ * DFS, IDLE, HALT, DOZE, SLEEP, Hibernate
+ */
+#define CNS3XXX_PWR_CPU_MODE_DFS                       (0)
+#define CNS3XXX_PWR_CPU_MODE_IDLE                      (1)
+#define CNS3XXX_PWR_CPU_MODE_HALT                      (2)
+#define CNS3XXX_PWR_CPU_MODE_DOZE                      (3)
+#define CNS3XXX_PWR_CPU_MODE_SLEEP                     (4)
+#define CNS3XXX_PWR_CPU_MODE_HIBERNATE                 (5)
+
+#define CNS3XXX_PWR_PLL(BLOCK) (0x1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_##BLOCK)
+#define CNS3XXX_PWR_PLL_ALL    PM_PLL_HM_PD_CTRL_REG_MASK
+
+/* Change CPU frequency and divider */
+#define CNS3XXX_PWR_PLL_CPU_300MHZ                     (0)
+#define CNS3XXX_PWR_PLL_CPU_333MHZ                     (1)
+#define CNS3XXX_PWR_PLL_CPU_366MHZ                     (2)
+#define CNS3XXX_PWR_PLL_CPU_400MHZ                     (3)
+#define CNS3XXX_PWR_PLL_CPU_433MHZ                     (4)
+#define CNS3XXX_PWR_PLL_CPU_466MHZ                     (5)
+#define CNS3XXX_PWR_PLL_CPU_500MHZ                     (6)
+#define CNS3XXX_PWR_PLL_CPU_533MHZ                     (7)
+#define CNS3XXX_PWR_PLL_CPU_566MHZ                     (8)
+#define CNS3XXX_PWR_PLL_CPU_600MHZ                     (9)
+#define CNS3XXX_PWR_PLL_CPU_633MHZ                     (10)
+#define CNS3XXX_PWR_PLL_CPU_666MHZ                     (11)
+#define CNS3XXX_PWR_PLL_CPU_700MHZ                     (12)
+
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY1                    (0)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY2                    (1)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY4                    (2)
+
+/* Change DDR2 frequency */
+#define CNS3XXX_PWR_PLL_DDR2_200MHZ                    (0)
+#define CNS3XXX_PWR_PLL_DDR2_266MHZ                    (1)
+#define CNS3XXX_PWR_PLL_DDR2_333MHZ                    (2)
+#define CNS3XXX_PWR_PLL_DDR2_400MHZ                    (3)
+
+void cns3xxx_pwr_soft_rst(unsigned int block);
+void cns3xxx_pwr_clk_en(unsigned int block);
+int cns3xxx_cpu_clock(void);
+
+/*
+ * ARM11 MPCore interrupt sources (primary GIC)
+ */
+#define IRQ_CNS3XXX_PMU                        (IRQ_TC11MP_GIC_START + 0)
+#define IRQ_CNS3XXX_SDIO               (IRQ_TC11MP_GIC_START + 1)
+#define IRQ_CNS3XXX_L2CC               (IRQ_TC11MP_GIC_START + 2)
+#define IRQ_CNS3XXX_RTC                        (IRQ_TC11MP_GIC_START + 3)
+#define IRQ_CNS3XXX_I2S                        (IRQ_TC11MP_GIC_START + 4)
+#define IRQ_CNS3XXX_PCM                        (IRQ_TC11MP_GIC_START + 5)
+#define IRQ_CNS3XXX_SPI                        (IRQ_TC11MP_GIC_START + 6)
+#define IRQ_CNS3XXX_I2C                        (IRQ_TC11MP_GIC_START + 7)
+#define IRQ_CNS3XXX_CIM                        (IRQ_TC11MP_GIC_START + 8)
+#define IRQ_CNS3XXX_GPU                        (IRQ_TC11MP_GIC_START + 9)
+#define IRQ_CNS3XXX_LCD                        (IRQ_TC11MP_GIC_START + 10)
+#define IRQ_CNS3XXX_GPIOA              (IRQ_TC11MP_GIC_START + 11)
+#define IRQ_CNS3XXX_GPIOB              (IRQ_TC11MP_GIC_START + 12)
+#define IRQ_CNS3XXX_UART0              (IRQ_TC11MP_GIC_START + 13)
+#define IRQ_CNS3XXX_UART1              (IRQ_TC11MP_GIC_START + 14)
+#define IRQ_CNS3XXX_UART2              (IRQ_TC11MP_GIC_START + 15)
+#define IRQ_CNS3XXX_ARM11              (IRQ_TC11MP_GIC_START + 16)
+
+#define IRQ_CNS3XXX_SW_STATUS          (IRQ_TC11MP_GIC_START + 17)
+#define IRQ_CNS3XXX_SW_R0TXC           (IRQ_TC11MP_GIC_START + 18)
+#define IRQ_CNS3XXX_SW_R0RXC           (IRQ_TC11MP_GIC_START + 19)
+#define IRQ_CNS3XXX_SW_R0QE            (IRQ_TC11MP_GIC_START + 20)
+#define IRQ_CNS3XXX_SW_R0QF            (IRQ_TC11MP_GIC_START + 21)
+#define IRQ_CNS3XXX_SW_R1TXC           (IRQ_TC11MP_GIC_START + 22)
+#define IRQ_CNS3XXX_SW_R1RXC           (IRQ_TC11MP_GIC_START + 23)
+#define IRQ_CNS3XXX_SW_R1QE            (IRQ_TC11MP_GIC_START + 24)
+#define IRQ_CNS3XXX_SW_R1QF            (IRQ_TC11MP_GIC_START + 25)
+#define IRQ_CNS3XXX_SW_PPE             (IRQ_TC11MP_GIC_START + 26)
+
+#define IRQ_CNS3XXX_CRYPTO             (IRQ_TC11MP_GIC_START + 27)
+#define IRQ_CNS3XXX_HCIE               (IRQ_TC11MP_GIC_START + 28)
+#define IRQ_CNS3XXX_PCIE0_DEVICE       (IRQ_TC11MP_GIC_START + 29)
+#define IRQ_CNS3XXX_PCIE1_DEVICE       (IRQ_TC11MP_GIC_START + 30)
+#define IRQ_CNS3XXX_USB_OTG            (IRQ_TC11MP_GIC_START + 31)
+#define IRQ_CNS3XXX_USB_EHCI           (IRQ_TC11MP_GIC_START + 32)
+#define IRQ_CNS3XXX_SATA               (IRQ_TC11MP_GIC_START + 33)
+#define IRQ_CNS3XXX_RAID               (IRQ_TC11MP_GIC_START + 34)
+#define IRQ_CNS3XXX_SMC                        (IRQ_TC11MP_GIC_START + 35)
+
+#define IRQ_CNS3XXX_DMAC_ABORT         (IRQ_TC11MP_GIC_START + 36)
+#define IRQ_CNS3XXX_DMAC0              (IRQ_TC11MP_GIC_START + 37)
+#define IRQ_CNS3XXX_DMAC1              (IRQ_TC11MP_GIC_START + 38)
+#define IRQ_CNS3XXX_DMAC2              (IRQ_TC11MP_GIC_START + 39)
+#define IRQ_CNS3XXX_DMAC3              (IRQ_TC11MP_GIC_START + 40)
+#define IRQ_CNS3XXX_DMAC4              (IRQ_TC11MP_GIC_START + 41)
+#define IRQ_CNS3XXX_DMAC5              (IRQ_TC11MP_GIC_START + 42)
+#define IRQ_CNS3XXX_DMAC6              (IRQ_TC11MP_GIC_START + 43)
+#define IRQ_CNS3XXX_DMAC7              (IRQ_TC11MP_GIC_START + 44)
+#define IRQ_CNS3XXX_DMAC8              (IRQ_TC11MP_GIC_START + 45)
+#define IRQ_CNS3XXX_DMAC9              (IRQ_TC11MP_GIC_START + 46)
+#define IRQ_CNS3XXX_DMAC10             (IRQ_TC11MP_GIC_START + 47)
+#define IRQ_CNS3XXX_DMAC11             (IRQ_TC11MP_GIC_START + 48)
+#define IRQ_CNS3XXX_DMAC12             (IRQ_TC11MP_GIC_START + 49)
+#define IRQ_CNS3XXX_DMAC13             (IRQ_TC11MP_GIC_START + 50)
+#define IRQ_CNS3XXX_DMAC14             (IRQ_TC11MP_GIC_START + 51)
+#define IRQ_CNS3XXX_DMAC15             (IRQ_TC11MP_GIC_START + 52)
+#define IRQ_CNS3XXX_DMAC16             (IRQ_TC11MP_GIC_START + 53)
+#define IRQ_CNS3XXX_DMAC17             (IRQ_TC11MP_GIC_START + 54)
+
+#define IRQ_CNS3XXX_PCIE0_RC           (IRQ_TC11MP_GIC_START + 55)
+#define IRQ_CNS3XXX_PCIE1_RC           (IRQ_TC11MP_GIC_START + 56)
+#define IRQ_CNS3XXX_TIMER0             (IRQ_TC11MP_GIC_START + 57)
+#define IRQ_CNS3XXX_TIMER1             (IRQ_TC11MP_GIC_START + 58)
+#define IRQ_CNS3XXX_USB_OHCI           (IRQ_TC11MP_GIC_START + 59)
+#define IRQ_CNS3XXX_TIMER2             (IRQ_TC11MP_GIC_START + 60)
+#define IRQ_CNS3XXX_EXTERNAL_PIN0      (IRQ_TC11MP_GIC_START + 61)
+#define IRQ_CNS3XXX_EXTERNAL_PIN1      (IRQ_TC11MP_GIC_START + 62)
+#define IRQ_CNS3XXX_EXTERNAL_PIN2      (IRQ_TC11MP_GIC_START + 63)
+
+#define NR_IRQS_CNS3XXX                        (IRQ_TC11MP_GIC_START + 64)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_CNS3XXX)
+#undef NR_IRQS
+#define NR_IRQS                                NR_IRQS_CNS3XXX
+#endif
+
+#endif /* __MACH_BOARD_CNS3XXX_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..d16ce7e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright 1994-1999 Russell King
+ * Copyright 2008 Cavium Networks
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This file 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
+               mrc     p15, 0, \rx, c1, c0
+               tst     \rx, #1                 @ MMU enabled?
+               moveq   \rx,      #0x10000000
+               movne   \rx,      #0xf0000000   @ virtual base
+               orr     \rx, \rx, #0x00009000
+               .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..5e1c554
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Low-level IRQ helper macros for Cavium Networks platforms
+ *
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <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:
+                *
+                * Interrupts 0-15 are IPI
+                * 16-28 are reserved
+                * 29-31 are local.  We allow 30 to be used for the watchdog.
+                * 32-1020 are global
+                * 1021-1022 are reserved
+                * 1023 is "spurious" (no interrupt)
+                *
+                * For now, we ignore all local interrupts so only return an interrupt if it's
+                * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
+                *
+                * 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 (30-1020 inclusive).
+                */
+
+               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+               ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+
+               ldr     \tmp, =1021
+
+               bic     \irqnr, \irqstat, #0x1c00
+
+               cmp     \irqnr, #29
+               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, #29
+               moveq   \tmp, #1
+               streq   \irqstat, [\base, #GIC_CPU_EOI]
+               cmp     \tmp, #0
+               .endm
diff --git a/arch/arm/mach-cns3xxx/include/mach/hardware.h b/arch/arm/mach-cns3xxx/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..57e0983
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * This file contains the hardware definitions of the Cavium Networks boards.
+ *
+ * Copyright 2003 ARM Limited.
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* macro to get at IO space when running virtually */
+#define PCIBIOS_MIN_IO         0x00000000
+#define PCIBIOS_MIN_MEM                0x00000000
+#define pcibios_assign_all_busses()    1
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/io.h b/arch/arm/mach-cns3xxx/include/mach/io.h
new file mode 100644 (file)
index 0000000..33b6fc1
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2008 Cavium Networks
+ * Copyright 2003 ARM Limited
+ *
+ * This file 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 __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)                        __typesafe_io(a)
+#define __mem_pci(a)           (a)
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/irqs.h b/arch/arm/mach-cns3xxx/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..2ab96f8
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_LOCALTIMER         29
+#define IRQ_LOCALWDOG          30
+#define IRQ_TC11MP_GIC_START   32
+
+#include <mach/cns3xxx.h>
+
+#ifndef NR_IRQS
+#error "NR_IRQS not defined by the board-specific files"
+#endif
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h
new file mode 100644 (file)
index 0000000..3b6b769
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET            UL(0x00000000)
+
+#define __phys_to_bus(x)       ((x) + PHYS_OFFSET)
+#define __bus_to_phys(x)       ((x) - PHYS_OFFSET)
+
+#define __virt_to_bus(v)       __phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b)       __phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p)                __phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b)                __phys_to_pfn(__bus_to_phys(b))
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h
new file mode 100644 (file)
index 0000000..58bb03a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+       /*
+        * This should do all the clock switching
+        * and wait for interrupt tricks
+        */
+       cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/timex.h b/arch/arm/mach-cns3xxx/include/mach/timex.h
new file mode 100644 (file)
index 0000000..1fd0421
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Cavium Networks architecture timex specifications
+ *
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#define CLOCK_TICK_RATE                (50000000 / 16)
diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..de8ead9
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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 <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+
+#define AMBA_UART_DR(base)     (*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base)   (*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base)     (*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base)     (*(volatile unsigned char *)((base) + 0x18))
+
+/*
+ * Return the UART base address
+ */
+static inline unsigned long get_uart_base(void)
+{
+       if (machine_is_cns3420vb())
+               return CNS3XXX_UART0_BASE;
+       else
+               return 0;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+       unsigned long base = get_uart_base();
+
+       while (AMBA_UART_FR(base) & (1 << 5))
+               barrier();
+
+       AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+       unsigned long base = get_uart_base();
+
+       while (AMBA_UART_FR(base) & (1 << 3))
+               barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-cns3xxx/include/mach/vmalloc.h b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..4d381ec
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2000 Russell King.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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.
+ */
+
+#define VMALLOC_END            0xd8000000
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c
new file mode 100644 (file)
index 0000000..725e1a4
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file 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/delay.h>
+#include <mach/system.h>
+#include <mach/cns3xxx.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block)
+{
+       PM_CLK_GATE_REG |= (block & PM_CLK_GATE_REG_MASK);
+}
+
+void cns3xxx_pwr_power_up(unsigned int block)
+{
+       PM_PLL_HM_PD_CTRL_REG &= ~(block & CNS3XXX_PWR_PLL_ALL);
+
+       /* Wait for 300us for the PLL output clock locked. */
+       udelay(300);
+};
+
+void cns3xxx_pwr_power_down(unsigned int block)
+{
+       /* write '1' to power down */
+       PM_PLL_HM_PD_CTRL_REG |= (block & CNS3XXX_PWR_PLL_ALL);
+};
+
+static void cns3xxx_pwr_soft_rst_force(unsigned int block)
+{
+       /*
+        * bit 0, 28, 29 => program low to reset,
+        * the other else program low and then high
+        */
+       if (block & 0x30000001) {
+               PM_SOFT_RST_REG &= ~(block & PM_SOFT_RST_REG_MASK);
+       } else {
+               PM_SOFT_RST_REG &= ~(block & PM_SOFT_RST_REG_MASK);
+               PM_SOFT_RST_REG |= (block & PM_SOFT_RST_REG_MASK);
+       }
+}
+
+void cns3xxx_pwr_soft_rst(unsigned int block)
+{
+       static unsigned int soft_reset;
+
+       if (soft_reset & block) {
+               /* SPI/I2C/GPIO use the same block, reset once. */
+               return;
+       } else {
+               soft_reset |= block;
+       }
+       cns3xxx_pwr_soft_rst_force(block);
+}
+
+void arch_reset(char mode, const char *cmd)
+{
+       /*
+        * To reset, we hit the on-board reset register
+        * in the system FPGA.
+        */
+       cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(GLOBAL));
+}
+
+/*
+ * cns3xxx_cpu_clock - return CPU/L2 clock
+ *  aclk: cpu clock/2
+ *  hclk: cpu clock/4
+ *  pclk: cpu clock/8
+ */
+int cns3xxx_cpu_clock(void)
+{
+       int cpu;
+       int cpu_sel;
+       int div_sel;
+
+       cpu_sel = (PM_CLK_CTRL_REG >> PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL) & 0xf;
+       div_sel = (PM_CLK_CTRL_REG >> PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV) & 0x3;
+
+       cpu = (300 + ((cpu_sel / 3) * 100) + ((cpu_sel % 3) * 33)) >> div_sel;
+
+       return cpu;
+}
index 0ebe185..0316e20 100644 (file)
@@ -7,6 +7,7 @@ config CP_INTC
        bool
 
 config ARCH_DAVINCI_DMx
+       select CPU_ARM926T
        bool
 
 menu "TI DaVinci Implementations"
@@ -41,6 +42,7 @@ config ARCH_DAVINCI_DA850
        select ARCH_HAS_CPUFREQ
 
 config ARCH_DAVINCI_DA8XX
+       select CPU_ARM926T
        bool
 
 config ARCH_DAVINCI_DM365
index dc19870..212d970 100644 (file)
@@ -33,9 +33,6 @@
 #define DA830_EVM_PHY_MASK             0x0
 #define DA830_EVM_MDIO_FREQUENCY       2200000 /* PHY bus frequency */
 
-#define DA830_EMIF25_ASYNC_DATA_CE3_BASE       0x62000000
-#define DA830_EMIF25_CONTROL_BASE              0x68000000
-
 /*
  * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
  */
@@ -157,7 +154,7 @@ static __init void da830_evm_usb_init(void)
                                   __func__, ret);
        }
 
-       ret = da8xx_pinmux_setup(da830_evm_usb11_pins);
+       ret = davinci_cfg_reg_list(da830_evm_usb11_pins);
        if (ret) {
                pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
                           __func__, ret);
@@ -229,15 +226,22 @@ static const short da830_evm_mmc_sd_pins[] = {
 };
 
 #define DA830_MMCSD_WP_PIN             GPIO_TO_PIN(2, 1)
+#define DA830_MMCSD_CD_PIN             GPIO_TO_PIN(2, 2)
 
 static int da830_evm_mmc_get_ro(int index)
 {
        return gpio_get_value(DA830_MMCSD_WP_PIN);
 }
 
+static int da830_evm_mmc_get_cd(int index)
+{
+       return !gpio_get_value(DA830_MMCSD_CD_PIN);
+}
+
 static struct davinci_mmc_config da830_evm_mmc_config = {
        .get_ro                 = da830_evm_mmc_get_ro,
-       .wires                  = 4,
+       .get_cd                 = da830_evm_mmc_get_cd,
+       .wires                  = 8,
        .max_freq               = 50000000,
        .caps                   = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
        .version                = MMC_CTLR_VERSION_2,
@@ -247,7 +251,7 @@ static inline void da830_evm_init_mmc(void)
 {
        int ret;
 
-       ret = da8xx_pinmux_setup(da830_evm_mmc_sd_pins);
+       ret = davinci_cfg_reg_list(da830_evm_mmc_sd_pins);
        if (ret) {
                pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n",
                                ret);
@@ -262,6 +266,14 @@ static inline void da830_evm_init_mmc(void)
        }
        gpio_direction_input(DA830_MMCSD_WP_PIN);
 
+       ret = gpio_request(DA830_MMCSD_CD_PIN, "MMC CD\n");
+       if (ret) {
+               pr_warning("da830_evm_init: can not open GPIO %d\n",
+                          DA830_MMCSD_CD_PIN);
+               return;
+       }
+       gpio_direction_input(DA830_MMCSD_CD_PIN);
+
        ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
        if (ret) {
                pr_warning("da830_evm_init: mmc/sd registration failed: %d\n",
@@ -360,13 +372,13 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = {
 
 static struct resource da830_evm_nand_resources[] = {
        [0] = {         /* First memory resource is NAND I/O window */
-               .start  = DA830_EMIF25_ASYNC_DATA_CE3_BASE,
-               .end    = DA830_EMIF25_ASYNC_DATA_CE3_BASE + PAGE_SIZE - 1,
+               .start  = DA8XX_AEMIF_CS3_BASE,
+               .end    = DA8XX_AEMIF_CS3_BASE + PAGE_SIZE - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {         /* Second memory resource is AEMIF control registers */
-               .start  = DA830_EMIF25_CONTROL_BASE,
-               .end    = DA830_EMIF25_CONTROL_BASE + SZ_32K - 1,
+               .start  = DA8XX_AEMIF_CTL_BASE,
+               .end    = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
                .flags  = IORESOURCE_MEM,
        },
 };
@@ -392,7 +404,7 @@ static inline void da830_evm_init_nand(int mux_mode)
                return;
        }
 
-       ret = da8xx_pinmux_setup(da830_evm_emif25_pins);
+       ret = davinci_cfg_reg_list(da830_evm_emif25_pins);
        if (ret)
                pr_warning("da830_evm_init: emif25 mux setup failed: %d\n",
                                ret);
@@ -412,7 +424,7 @@ static inline void da830_evm_init_lcdc(int mux_mode)
 {
        int ret;
 
-       ret = da8xx_pinmux_setup(da830_lcdcntl_pins);
+       ret = davinci_cfg_reg_list(da830_lcdcntl_pins);
        if (ret)
                pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n",
                                ret);
@@ -492,7 +504,7 @@ static __init void da830_evm_init(void)
                pr_warning("da830_evm_init: edma registration failed: %d\n",
                                ret);
 
-       ret = da8xx_pinmux_setup(da830_i2c0_pins);
+       ret = davinci_cfg_reg_list(da830_i2c0_pins);
        if (ret)
                pr_warning("da830_evm_init: i2c0 mux setup failed: %d\n",
                                ret);
@@ -508,7 +520,7 @@ static __init void da830_evm_init(void)
        soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY;
        soc_info->emac_pdata->rmii_en = 1;
 
-       ret = da8xx_pinmux_setup(da830_cpgmac_pins);
+       ret = davinci_cfg_reg_list(da830_cpgmac_pins);
        if (ret)
                pr_warning("da830_evm_init: cpgmac mux setup failed: %d\n",
                                ret);
@@ -527,7 +539,7 @@ static __init void da830_evm_init(void)
        i2c_register_board_info(1, da830_evm_i2c_devices,
                        ARRAY_SIZE(da830_evm_i2c_devices));
 
-       ret = da8xx_pinmux_setup(da830_evm_mcasp1_pins);
+       ret = davinci_cfg_reg_list(da830_evm_mcasp1_pins);
        if (ret)
                pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n",
                                ret);
@@ -549,14 +561,6 @@ static int __init da830_evm_console_init(void)
 console_initcall(da830_evm_console_init);
 #endif
 
-static __init void da830_evm_irq_init(void)
-{
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA830_N_CP_INTC_IRQ,
-                       soc_info->intc_irq_prios);
-}
-
 static void __init da830_evm_map_io(void)
 {
        da830_init();
@@ -567,7 +571,7 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM")
        .io_pg_offst    = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params    = (DA8XX_DDR_BASE + 0x100),
        .map_io         = da830_evm_map_io,
-       .init_irq       = da830_evm_irq_init,
+       .init_irq       = cp_intc_init,
        .timer          = &davinci_timer,
        .init_machine   = da830_evm_init,
 MACHINE_END
index 411284d..abd0493 100644 (file)
@@ -206,12 +206,12 @@ static __init void da850_evm_setup_nor_nand(void)
        int ret = 0;
 
        if (ui_card_detected & !HAS_MMC) {
-               ret = da8xx_pinmux_setup(da850_nand_pins);
+               ret = davinci_cfg_reg_list(da850_nand_pins);
                if (ret)
                        pr_warning("da850_evm_init: nand mux setup failed: "
                                        "%d\n", ret);
 
-               ret = da8xx_pinmux_setup(da850_nor_pins);
+               ret = davinci_cfg_reg_list(da850_nor_pins);
                if (ret)
                        pr_warning("da850_evm_init: nor mux setup failed: %d\n",
                                ret);
@@ -568,12 +568,12 @@ static int __init da850_evm_config_emac(void)
 
        if (rmii_en) {
                val |= BIT(8);
-               ret = da8xx_pinmux_setup(da850_rmii_pins);
+               ret = davinci_cfg_reg_list(da850_rmii_pins);
                pr_info("EMAC: RMII PHY configured, MII PHY will not be"
                                                        " functional\n");
        } else {
                val &= ~BIT(8);
-               ret = da8xx_pinmux_setup(da850_cpgmac_pins);
+               ret = davinci_cfg_reg_list(da850_cpgmac_pins);
                pr_info("EMAC: MII PHY configured, RMII PHY will not be"
                                                        " functional\n");
        }
@@ -626,7 +626,7 @@ static __init void da850_evm_init(void)
                pr_warning("da850_evm_init: edma registration failed: %d\n",
                                ret);
 
-       ret = da8xx_pinmux_setup(da850_i2c0_pins);
+       ret = davinci_cfg_reg_list(da850_i2c0_pins);
        if (ret)
                pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
                                ret);
@@ -643,7 +643,7 @@ static __init void da850_evm_init(void)
                                ret);
 
        if (HAS_MMC) {
-               ret = da8xx_pinmux_setup(da850_mmcsd0_pins);
+               ret = davinci_cfg_reg_list(da850_mmcsd0_pins);
                if (ret)
                        pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
                                        " %d\n", ret);
@@ -679,20 +679,20 @@ static __init void da850_evm_init(void)
        __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);
        __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30);
 
-       ret = da8xx_pinmux_setup(da850_mcasp_pins);
+       ret = davinci_cfg_reg_list(da850_mcasp_pins);
        if (ret)
                pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
                                ret);
 
        da8xx_register_mcasp(0, &da850_evm_snd_data);
 
-       ret = da8xx_pinmux_setup(da850_lcdcntl_pins);
+       ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
        if (ret)
                pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
                                ret);
 
        /* Handle board specific muxing for LCD here */
-       ret = da8xx_pinmux_setup(da850_evm_lcdc_pins);
+       ret = davinci_cfg_reg_list(da850_evm_lcdc_pins);
        if (ret)
                pr_warning("da850_evm_init: evm specific lcd mux setup "
                                "failed: %d\n", ret);
@@ -736,14 +736,6 @@ static int __init da850_evm_console_init(void)
 console_initcall(da850_evm_console_init);
 #endif
 
-static __init void da850_evm_irq_init(void)
-{
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA850_N_CP_INTC_IRQ,
-                       soc_info->intc_irq_prios);
-}
-
 static void __init da850_evm_map_io(void)
 {
        da850_init();
@@ -754,7 +746,7 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138 EVM")
        .io_pg_offst    = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params    = (DA8XX_DDR_BASE + 0x100),
        .map_io         = da850_evm_map_io,
-       .init_irq       = da850_evm_irq_init,
+       .init_irq       = cp_intc_init,
        .timer          = &davinci_timer,
        .init_machine   = da850_evm_init,
 MACHINE_END
index aa48e3f..a319101 100644 (file)
@@ -33,9 +33,6 @@
 #include <mach/mmc.h>
 #include <mach/usb.h>
 
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE                0x01e10000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE       0x02000000
-
 /* NOTE:  this is geared for the standard config, with a socketed
  * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors.  If you
  * swap chips, maybe with a different block size, partitioning may
@@ -86,12 +83,12 @@ static struct davinci_nand_pdata davinci_nand_data = {
 
 static struct resource davinci_nand_resources[] = {
        {
-               .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+               .start          = DM355_ASYNC_EMIF_DATA_CE0_BASE,
+               .end            = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
                .flags          = IORESOURCE_MEM,
        }, {
-               .start          = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .start          = DM355_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
                .flags          = IORESOURCE_MEM,
        },
 };
@@ -353,17 +350,12 @@ static __init void dm355_evm_init(void)
        dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data);
 }
 
-static __init void dm355_evm_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
        .phys_io      = IO_PHYS,
        .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (0x80000100),
        .map_io       = dm355_evm_map_io,
-       .init_irq     = dm355_evm_irq_init,
+       .init_irq     = davinci_irq_init,
        .timer        = &davinci_timer,
        .init_machine = dm355_evm_init,
 MACHINE_END
index 21f32eb..f1d8132 100644 (file)
@@ -30,9 +30,6 @@
 #include <mach/mmc.h>
 #include <mach/usb.h>
 
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE                0x01e10000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE       0x02000000
-
 /* NOTE:  this is geared for the standard config, with a socketed
  * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors.  If you
  * swap chips, maybe with a different block size, partitioning may
@@ -82,12 +79,12 @@ static struct davinci_nand_pdata davinci_nand_data = {
 
 static struct resource davinci_nand_resources[] = {
        {
-               .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+               .start          = DM355_ASYNC_EMIF_DATA_CE0_BASE,
+               .end            = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
                .flags          = IORESOURCE_MEM,
        }, {
-               .start          = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .start          = DM355_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
                .flags          = IORESOURCE_MEM,
        },
 };
@@ -272,17 +269,12 @@ static __init void dm355_leopard_init(void)
                        ARRAY_SIZE(dm355_leopard_spi_info));
 }
 
-static __init void dm355_leopard_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
        .phys_io      = IO_PHYS,
        .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (0x80000100),
        .map_io       = dm355_leopard_map_io,
-       .init_irq     = dm355_leopard_irq_init,
+       .init_irq     = davinci_irq_init,
        .timer        = &davinci_timer,
        .init_machine = dm355_leopard_init,
 MACHINE_END
index df4ab21..98814e6 100644 (file)
@@ -54,11 +54,6 @@ static inline int have_tvp7002(void)
        return 0;
 }
 
-
-#define DM365_ASYNC_EMIF_CONTROL_BASE  0x01d10000
-#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
-#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
-
 #define DM365_EVM_PHY_MASK             (0x2)
 #define DM365_EVM_MDIO_FREQUENCY       (2200000) /* PHY bus frequency */
 
@@ -613,17 +608,12 @@ static __init void dm365_evm_init(void)
                        ARRAY_SIZE(dm365_evm_spi_info));
 }
 
-static __init void dm365_evm_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
        .phys_io        = IO_PHYS,
        .io_pg_offst    = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params    = (0x80000100),
        .map_io         = dm365_evm_map_io,
-       .init_irq       = dm365_evm_irq_init,
+       .init_irq       = davinci_irq_init,
        .timer          = &davinci_timer,
        .init_machine   = dm365_evm_init,
 MACHINE_END
index 976e11b..34c8b41 100644 (file)
 #define DM644X_EVM_PHY_MASK            (0x2)
 #define DM644X_EVM_MDIO_FREQUENCY      (2200000) /* PHY bus frequency */
 
-#define DAVINCI_CFC_ATA_BASE             0x01C66000
-
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE   0x01e00000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE  0x02000000
-#define DAVINCI_ASYNC_EMIF_DATA_CE1_BASE  0x04000000
-#define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE  0x06000000
-#define DAVINCI_ASYNC_EMIF_DATA_CE3_BASE  0x08000000
-
 #define LXT971_PHY_ID  (0x001378e2)
 #define LXT971_PHY_MASK        (0xfffffff0)
 
@@ -92,8 +84,8 @@ static struct physmap_flash_data davinci_evm_norflash_data = {
 /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
  * limits addresses to 16M, so using addresses past 16M will wrap */
 static struct resource davinci_evm_norflash_resource = {
-       .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-       .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+       .start          = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+       .end            = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
        .flags          = IORESOURCE_MEM,
 };
 
@@ -111,7 +103,7 @@ static struct platform_device davinci_evm_norflash_device = {
  * It may used instead of the (default) NOR chip to boot, using TI's
  * tools to install the secondary boot loader (UBL) and U-Boot.
  */
-struct mtd_partition davinci_evm_nandflash_partition[] = {
+static struct mtd_partition davinci_evm_nandflash_partition[] = {
        /* Bootloader layout depends on whose u-boot is installed, but we
         * can hide all the details.
         *  - block 0 for u-boot environment ... in mainline u-boot
@@ -154,12 +146,12 @@ static struct davinci_nand_pdata davinci_evm_nandflash_data = {
 
 static struct resource davinci_evm_nandflash_resource[] = {
        {
-               .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+               .start          = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+               .end            = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
                .flags          = IORESOURCE_MEM,
        }, {
-               .start          = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .start          = DM644X_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
                .flags          = IORESOURCE_MEM,
        },
 };
@@ -258,32 +250,6 @@ static struct platform_device rtc_dev = {
        .id             = -1,
 };
 
-static struct resource ide_resources[] = {
-       {
-               .start          = DAVINCI_CFC_ATA_BASE,
-               .end            = DAVINCI_CFC_ATA_BASE + 0x7ff,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = IRQ_IDE,
-               .end            = IRQ_IDE,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static u64 ide_dma_mask = DMA_BIT_MASK(32);
-
-static struct platform_device ide_dev = {
-       .name           = "palm_bk3710",
-       .id             = -1,
-       .resource       = ide_resources,
-       .num_resources  = ARRAY_SIZE(ide_resources),
-       .dev = {
-               .dma_mask               = &ide_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
 static struct snd_platform_data dm644x_evm_snd_data;
 
 /*----------------------------------------------------------------------*/
@@ -704,10 +670,7 @@ static __init void davinci_evm_init(void)
                        pr_warning("WARNING: both IDE and Flash are "
                                "enabled, but they share AEMIF pins.\n"
                                "\tDisable IDE for NAND/NOR support.\n");
-               davinci_cfg_reg(DM644X_HPIEN_DISABLE);
-               davinci_cfg_reg(DM644X_ATAEN);
-               davinci_cfg_reg(DM644X_HDIREN);
-               platform_device_register(&ide_dev);
+               davinci_init_ide();
        } else if (HAS_NAND || HAS_NOR) {
                davinci_cfg_reg(DM644X_HPIEN_DISABLE);
                davinci_cfg_reg(DM644X_ATAEN_DISABLE);
@@ -741,18 +704,13 @@ static __init void davinci_evm_init(void)
 
 }
 
-static __init void davinci_evm_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
        /* Maintainer: MontaVista Software <source@mvista.com> */
        .phys_io      = IO_PHYS,
        .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (DAVINCI_DDR_BASE + 0x100),
        .map_io       = davinci_evm_map_io,
-       .init_irq     = davinci_evm_irq_init,
+       .init_irq     = davinci_irq_init,
        .timer        = &davinci_timer,
        .init_machine = davinci_evm_init,
 MACHINE_END
index 5ba3cb2..6d88893 100644 (file)
@@ -80,17 +80,14 @@ static struct davinci_nand_pdata davinci_nand_data = {
        .options                = 0,
 };
 
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE                0x20008000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE       0x42000000
-
 static struct resource davinci_nand_resources[] = {
        {
-               .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+               .start          = DM646X_ASYNC_EMIF_CS2_SPACE_BASE,
+               .end            = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1,
                .flags          = IORESOURCE_MEM,
        }, {
-               .start          = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .start          = DM646X_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
                .flags          = IORESOURCE_MEM,
        },
 };
@@ -736,17 +733,12 @@ static __init void evm_init(void)
        platform_device_register(&davinci_nand_device);
 
        if (HAS_ATA)
-               dm646x_init_ide();
+               davinci_init_ide();
 
        soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK;
        soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY;
 }
 
-static __init void davinci_dm646x_evm_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 #define DM646X_EVM_REF_FREQ            27000000
 #define DM6467T_EVM_REF_FREQ           33000000
 
@@ -763,7 +755,7 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
        .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (0x80000100),
        .map_io       = davinci_map_io,
-       .init_irq     = davinci_dm646x_evm_irq_init,
+       .init_irq     = davinci_irq_init,
        .timer        = &davinci_timer,
        .init_machine = evm_init,
 MACHINE_END
@@ -773,7 +765,7 @@ MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
        .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (0x80000100),
        .map_io       = davinci_map_io,
-       .init_irq     = davinci_dm646x_evm_irq_init,
+       .init_irq     = davinci_irq_init,
        .timer        = &davinci_timer,
        .init_machine = evm_init,
 MACHINE_END
index bd9ca07..4c30e92 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/mach/arch.h>
 
 #include <mach/dm644x.h>
+#include <mach/common.h>
 #include <mach/i2c.h>
 #include <mach/serial.h>
 #include <mach/mux.h>
 #define NEUROS_OSD2_PHY_MASK           0x2
 #define NEUROS_OSD2_MDIO_FREQUENCY     2200000 /* PHY bus frequency */
 
-#define DAVINCI_CFC_ATA_BASE            0x01C66000
-
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE         0x01e00000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
-
 #define LXT971_PHY_ID                  0x001378e2
 #define LXT971_PHY_MASK                        0xfffffff0
 
@@ -60,7 +56,7 @@
 
 #define NAND_BLOCK_SIZE                SZ_128K
 
-struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
+static struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
        {
                /* UBL (a few copies) plus U-Boot */
                .name           = "bootloader",
@@ -98,12 +94,12 @@ static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
 
 static struct resource davinci_ntosd2_nandflash_resource[] = {
        {
-               .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+               .start          = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+               .end            = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
                .flags          = IORESOURCE_MEM,
        }, {
-               .start          = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .start          = DM644X_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
                .flags          = IORESOURCE_MEM,
        },
 };
@@ -130,32 +126,6 @@ static struct platform_device davinci_fb_device = {
        .num_resources = 0,
 };
 
-static struct resource ide_resources[] = {
-       {
-               .start          = DAVINCI_CFC_ATA_BASE,
-               .end            = DAVINCI_CFC_ATA_BASE + 0x7ff,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = IRQ_IDE,
-               .end            = IRQ_IDE,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static u64 ide_dma_mask = DMA_BIT_MASK(32);
-
-static struct platform_device ide_dev = {
-       .name           = "palm_bk3710",
-       .id             = -1,
-       .resource       = ide_resources,
-       .num_resources  = ARRAY_SIZE(ide_resources),
-       .dev = {
-               .dma_mask               = &ide_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
 static struct snd_platform_data dm644x_ntosd2_snd_data;
 
 static struct gpio_led ntosd2_leds[] = {
@@ -259,10 +229,7 @@ static __init void davinci_ntosd2_init(void)
                        pr_warning("WARNING: both IDE and Flash are "
                                "enabled, but they share AEMIF pins.\n"
                                "\tDisable IDE for NAND/NOR support.\n");
-               davinci_cfg_reg(DM644X_HPIEN_DISABLE);
-               davinci_cfg_reg(DM644X_ATAEN);
-               davinci_cfg_reg(DM644X_HDIREN);
-               platform_device_register(&ide_dev);
+               davinci_init_ide();
        } else if (HAS_NAND) {
                davinci_cfg_reg(DM644X_HPIEN_DISABLE);
                davinci_cfg_reg(DM644X_ATAEN_DISABLE);
@@ -306,18 +273,13 @@ static __init void davinci_ntosd2_init(void)
        davinci_setup_mmc(0, &davinci_ntosd2_mmc_config);
 }
 
-static __init void davinci_ntosd2_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
        /* Maintainer: Neuros Technologies <neuros@groups.google.com> */
        .phys_io        = IO_PHYS,
        .io_pg_offst    = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params    = (DAVINCI_DDR_BASE + 0x100),
        .map_io          = davinci_ntosd2_map_io,
-       .init_irq       = davinci_ntosd2_irq_init,
+       .init_irq       = davinci_irq_init,
        .timer          = &davinci_timer,
        .init_machine = davinci_ntosd2_init,
 MACHINE_END
index 08d373b..23e664a 100644 (file)
 #define SFFSDR_PHY_MASK                (0x2)
 #define SFFSDR_MDIO_FREQUENCY  (2200000) /* PHY bus frequency */
 
-#define DAVINCI_ASYNC_EMIF_CONTROL_BASE   0x01e00000
-#define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE  0x02000000
-
-struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
+static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
        /* U-Boot Environment: Block 0
         * UBL:                Block 1
         * U-Boot:             Blocks 6-7 (256 kb)
@@ -76,12 +73,12 @@ static struct flash_platform_data davinci_sffsdr_nandflash_data = {
 
 static struct resource davinci_sffsdr_nandflash_resource[] = {
        {
-               .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+               .start          = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+               .end            = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
                .flags          = IORESOURCE_MEM,
        }, {
-               .start          = DAVINCI_ASYNC_EMIF_CONTROL_BASE,
-               .end            = DAVINCI_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+               .start          = DM644X_ASYNC_EMIF_CONTROL_BASE,
+               .end            = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
                .flags          = IORESOURCE_MEM,
        },
 };
@@ -155,18 +152,13 @@ static __init void davinci_sffsdr_init(void)
        davinci_cfg_reg(DM644X_VLYNQWD);
 }
 
-static __init void davinci_sffsdr_irq_init(void)
-{
-       davinci_irq_init();
-}
-
 MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
        /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */
        .phys_io      = IO_PHYS,
        .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (DAVINCI_DDR_BASE + 0x100),
        .map_io       = davinci_sffsdr_map_io,
-       .init_irq     = davinci_sffsdr_irq_init,
+       .init_irq     = davinci_irq_init,
        .timer        = &davinci_timer,
        .init_machine = davinci_sffsdr_init,
 MACHINE_END
index aec3756..ba8b12b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 
 #include <mach/clock.h>
+#include <mach/cdce949.h>
 
 #include "clock.h"
 
index bf6218e..054c303 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <mach/hardware.h>
 
+#include <mach/clock.h>
 #include <mach/psc.h>
 #include <mach/cputype.h>
 #include "clock.h"
@@ -42,7 +43,8 @@ static void __clk_enable(struct clk *clk)
        if (clk->parent)
                __clk_enable(clk->parent);
        if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
-               davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 1);
+               davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc,
+                               PSC_STATE_ENABLE);
 }
 
 static void __clk_disable(struct clk *clk)
@@ -51,7 +53,9 @@ static void __clk_disable(struct clk *clk)
                return;
        if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
            (clk->flags & CLK_PSC))
-               davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, 0);
+               davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc,
+                               (clk->flags & PSC_SWRSTDISABLE) ?
+                               PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE);
        if (clk->parent)
                __clk_disable(clk->parent);
 }
@@ -233,7 +237,10 @@ static int __init clk_disable_unused(void)
                        continue;
 
                pr_info("Clocks: disable unused %s\n", ck->name);
-               davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, 0);
+
+               davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc,
+                               (ck->flags & PSC_SWRSTDISABLE) ?
+                               PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE);
        }
        spin_unlock_irq(&clockfw_lock);
 
@@ -272,7 +279,7 @@ static unsigned long clk_sysclk_recalc(struct clk *clk)
 
        v = __raw_readl(pll->base + clk->div_reg);
        if (v & PLLDIV_EN) {
-               plldiv = (v & PLLDIV_RATIO_MASK) + 1;
+               plldiv = (v & pll->div_ratio_mask) + 1;
                if (plldiv)
                        rate /= plldiv;
        }
@@ -295,7 +302,6 @@ static unsigned long clk_pllclk_recalc(struct clk *clk)
        struct pll_data *pll = clk->pll_data;
        unsigned long rate = clk->rate;
 
-       pll->base = IO_ADDRESS(pll->phys_base);
        ctrl = __raw_readl(pll->base + PLLCTL);
        rate = pll->input_rate = clk->parent->rate;
 
@@ -312,7 +318,7 @@ static unsigned long clk_pllclk_recalc(struct clk *clk)
        if (pll->flags & PLL_HAS_PREDIV) {
                prediv = __raw_readl(pll->base + PREDIV);
                if (prediv & PLLDIV_EN)
-                       prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
+                       prediv = (prediv & pll->div_ratio_mask) + 1;
                else
                        prediv = 1;
        }
@@ -324,7 +330,7 @@ static unsigned long clk_pllclk_recalc(struct clk *clk)
        if (pll->flags & PLL_HAS_POSTDIV) {
                postdiv = __raw_readl(pll->base + POSTDIV);
                if (postdiv & PLLDIV_EN)
-                       postdiv = (postdiv & PLLDIV_RATIO_MASK) + 1;
+                       postdiv = (postdiv & pll->div_ratio_mask) + 1;
                else
                        postdiv = 1;
        }
@@ -451,6 +457,18 @@ int __init davinci_clk_init(struct clk_lookup *clocks)
                                clk->recalc = clk_leafclk_recalc;
                }
 
+               if (clk->pll_data) {
+                       struct pll_data *pll = clk->pll_data;
+
+                       if (!pll->div_ratio_mask)
+                               pll->div_ratio_mask = PLLDIV_RATIO_MASK;
+
+                       if (pll->phys_base && !pll->base) {
+                               pll->base = ioremap(pll->phys_base, SZ_4K);
+                               WARN_ON(!pll->base);
+                       }
+               }
+
                if (clk->recalc)
                        clk->rate = clk->recalc(clk);
 
index aa0a611..01e3648 100644 (file)
@@ -76,6 +76,7 @@ struct pll_data {
        u32 num;
        u32 flags;
        u32 input_rate;
+       u32 div_ratio_mask;
 };
 #define PLL_HAS_PREDIV          0x01
 #define PLL_HAS_POSTDIV         0x02
@@ -101,10 +102,11 @@ struct clk {
 
 /* Clock flags: SoC-specific flags start at BIT(16) */
 #define ALWAYS_ENABLED         BIT(1)
-#define CLK_PSC                 BIT(2)
-#define PSC_DSP                 BIT(3) /* PSC uses DSP domain, not ARM */
+#define CLK_PSC                        BIT(2)
+#define PSC_DSP                        BIT(3) /* PSC uses DSP domain, not ARM */
 #define CLK_PLL                        BIT(4) /* PLL-derived clock */
-#define PRE_PLL                 BIT(5) /* source is before PLL mult/div */
+#define PRE_PLL                        BIT(5) /* source is before PLL mult/div */
+#define PSC_SWRSTDISABLE       BIT(6) /* Disable state is SwRstDisable */
 
 #define CLK(dev, con, ck)      \
        {                       \
@@ -118,6 +120,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
                                unsigned int mult, unsigned int postdiv);
 
 extern struct platform_device davinci_wdt_device;
+extern void davinci_watchdog_reset(struct platform_device *);
 
 #endif
 
index 94f27cb..1d25573 100644 (file)
@@ -37,26 +37,43 @@ void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context)
                pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
 }
 
-static struct davinci_id * __init davinci_get_id(u32 jtag_id)
+static int __init davinci_init_id(struct davinci_soc_info *soc_info)
 {
-       int i;
-       struct davinci_id *dip;
-       u8 variant = (jtag_id & 0xf0000000) >> 28;
-       u16 part_no = (jtag_id & 0x0ffff000) >> 12;
+       int                     i;
+       struct davinci_id       *dip;
+       u8                      variant;
+       u16                     part_no;
+       void __iomem            *base;
+
+       base = ioremap(soc_info->jtag_id_reg, SZ_4K);
+       if (!base) {
+               pr_err("Unable to map JTAG ID register\n");
+               return -ENOMEM;
+       }
+
+       soc_info->jtag_id = __raw_readl(base);
+       iounmap(base);
+
+       variant = (soc_info->jtag_id & 0xf0000000) >> 28;
+       part_no = (soc_info->jtag_id & 0x0ffff000) >> 12;
 
-       for (i = 0, dip = davinci_soc_info.ids; i < davinci_soc_info.ids_num;
+       for (i = 0, dip = soc_info->ids; i < soc_info->ids_num;
                        i++, dip++)
                /* Don't care about the manufacturer right now */
-               if ((dip->part_no == part_no) && (dip->variant == variant))
-                       return dip;
-
-       return NULL;
+               if ((dip->part_no == part_no) && (dip->variant == variant)) {
+                       soc_info->cpu_id = dip->cpu_id;
+                       pr_info("DaVinci %s variant 0x%x\n", dip->name,
+                                       dip->variant);
+                       return 0;
+               }
+
+       pr_err("Unknown DaVinci JTAG ID 0x%x\n", soc_info->jtag_id);
+       return -EINVAL;
 }
 
 void __init davinci_common_init(struct davinci_soc_info *soc_info)
 {
        int ret;
-       struct davinci_id *dip;
 
        if (!soc_info) {
                ret = -EINVAL;
@@ -77,22 +94,16 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
        local_flush_tlb_all();
        flush_cache_all();
 
+       if (!davinci_soc_info.reset)
+               davinci_soc_info.reset = davinci_watchdog_reset;
+
        /*
         * We want to check CPU revision early for cpu_is_xxxx() macros.
         * IO space mapping must be initialized before we can do that.
         */
-       davinci_soc_info.jtag_id = __raw_readl(davinci_soc_info.jtag_id_base);
-
-       dip = davinci_get_id(davinci_soc_info.jtag_id);
-       if (!dip) {
-               ret = -EINVAL;
-               pr_err("Unknown DaVinci JTAG ID 0x%x\n",
-                                               davinci_soc_info.jtag_id);
+       ret = davinci_init_id(&davinci_soc_info);
+       if (ret < 0)
                goto err;
-       }
-
-       davinci_soc_info.cpu_id = dip->cpu_id;
-       pr_info("DaVinci %s variant 0x%x\n", dip->name, dip->variant);
 
        if (davinci_soc_info.cpu_clks) {
                ret = davinci_clk_init(davinci_soc_info.cpu_clks);
@@ -101,8 +112,6 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info)
                        goto err;
        }
 
-       davinci_intc_base = davinci_soc_info.intc_base;
-       davinci_intc_type = davinci_soc_info.intc_type;
        return;
 
 err:
index 37311d1..bb4c40e 100644 (file)
 #include <linux/irq.h>
 #include <linux/io.h>
 
+#include <mach/common.h>
 #include <mach/cp_intc.h>
 
-static void __iomem *cp_intc_base;
-
 static inline unsigned int cp_intc_read(unsigned offset)
 {
-       return __raw_readl(cp_intc_base + offset);
+       return __raw_readl(davinci_intc_base + offset);
 }
 
 static inline void cp_intc_write(unsigned long value, unsigned offset)
 {
-       __raw_writel(value, cp_intc_base + offset);
+       __raw_writel(value, davinci_intc_base + offset);
 }
 
 static void cp_intc_ack_irq(unsigned int irq)
@@ -100,13 +99,18 @@ static struct irq_chip cp_intc_irq_chip = {
        .set_wake       = cp_intc_set_wake,
 };
 
-void __init cp_intc_init(void __iomem *base, unsigned short num_irq,
-                        u8 *irq_prio)
+void __init cp_intc_init(void)
 {
+       unsigned long num_irq   = davinci_soc_info.intc_irq_num;
+       u8 *irq_prio            = davinci_soc_info.intc_irq_prios;
+       u32 *host_map           = davinci_soc_info.intc_host_map;
        unsigned num_reg        = BITS_TO_LONGS(num_irq);
        int i;
 
-       cp_intc_base = base;
+       davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC;
+       davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K);
+       if (WARN_ON(!davinci_intc_base))
+               return;
 
        cp_intc_write(0, CP_INTC_GLOBAL_ENABLE);
 
@@ -157,6 +161,10 @@ void __init cp_intc_init(void __iomem *base, unsigned short num_irq,
                        cp_intc_write(0x0f0f0f0f, CP_INTC_CHAN_MAP(i));
        }
 
+       if (host_map)
+               for (i = 0; host_map[i] != -1; i++)
+                       cp_intc_write(host_map[i], CP_INTC_HOST_MAP(i));
+
        /* Set up genirq dispatching for cp_intc */
        for (i = 0; i < num_irq; i++) {
                set_irq_chip(i, &cp_intc_irq_chip);
index 122e61a..23e9eda 100644 (file)
@@ -19,6 +19,7 @@
 #include <mach/common.h>
 #include <mach/time.h>
 #include <mach/da8xx.h>
+#include <mach/gpio.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -410,7 +411,7 @@ static struct clk_lookup da830_clks[] = {
        CLK("davinci-mcasp.0",  NULL,           &mcasp0_clk),
        CLK("davinci-mcasp.1",  NULL,           &mcasp1_clk),
        CLK("davinci-mcasp.2",  NULL,           &mcasp2_clk),
-       CLK("musb_hdrc",        NULL,           &usb20_clk),
+       CLK(NULL,               "usb20",        &usb20_clk),
        CLK(NULL,               "aemif",        &aemif_clk),
        CLK(NULL,               "aintc",        &aintc_clk),
        CLK(NULL,               "secu_mgr",     &secu_mgr_clk),
@@ -1126,10 +1127,7 @@ static struct map_desc da830_io_desc[] = {
        },
 };
 
-static void __iomem *da830_psc_bases[] = {
-       IO_ADDRESS(DA8XX_PSC0_BASE),
-       IO_ADDRESS(DA8XX_PSC1_BASE),
-};
+static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
 
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id da830_ids[] = {
@@ -1158,14 +1156,14 @@ static struct davinci_id da830_ids[] = {
 
 static struct davinci_timer_instance da830_timer_instance[2] = {
        {
-               .base           = IO_ADDRESS(DA8XX_TIMER64P0_BASE),
+               .base           = DA8XX_TIMER64P0_BASE,
                .bottom_irq     = IRQ_DA8XX_TINT12_0,
                .top_irq        = IRQ_DA8XX_TINT34_0,
                .cmp_off        = DA830_CMP12_0,
                .cmp_irq        = IRQ_DA830_T12CMPINT0_0,
        },
        {
-               .base           = IO_ADDRESS(DA8XX_TIMER64P1_BASE),
+               .base           = DA8XX_TIMER64P1_BASE,
                .bottom_irq     = IRQ_DA8XX_TINT12_1,
                .top_irq        = IRQ_DA8XX_TINT34_1,
                .cmp_off        = DA830_CMP12_0,
@@ -1187,34 +1185,33 @@ static struct davinci_timer_info da830_timer_info = {
 static struct davinci_soc_info davinci_soc_info_da830 = {
        .io_desc                = da830_io_desc,
        .io_desc_num            = ARRAY_SIZE(da830_io_desc),
+       .jtag_id_reg            = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
        .ids                    = da830_ids,
        .ids_num                = ARRAY_SIZE(da830_ids),
        .cpu_clks               = da830_clks,
        .psc_bases              = da830_psc_bases,
        .psc_bases_num          = ARRAY_SIZE(da830_psc_bases),
+       .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da830_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da830_pins),
-       .intc_base              = (void __iomem *)DA8XX_CP_INTC_VIRT,
+       .intc_base              = DA8XX_CP_INTC_BASE,
        .intc_type              = DAVINCI_INTC_TYPE_CP_INTC,
        .intc_irq_prios         = da830_default_priorities,
        .intc_irq_num           = DA830_N_CP_INTC_IRQ,
        .timer_info             = &da830_timer_info,
-       .gpio_base              = IO_ADDRESS(DA8XX_GPIO_BASE),
+       .gpio_type              = GPIO_TYPE_DAVINCI,
+       .gpio_base              = DA8XX_GPIO_BASE,
        .gpio_num               = 128,
        .gpio_irq               = IRQ_DA8XX_GPIO0,
        .serial_dev             = &da8xx_serial_device,
        .emac_pdata             = &da8xx_emac_pdata,
+       .reset_device           = &da8xx_wdt_device,
 };
 
 void __init da830_init(void)
 {
-       da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
-       if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
-               return;
-
-       davinci_soc_info_da830.jtag_id_base =
-                                       DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG);
-       davinci_soc_info_da830.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120);
-
        davinci_common_init(&davinci_soc_info_da830);
+
+       da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+       WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
 }
index d0fd756..6b8331b 100644 (file)
@@ -27,6 +27,7 @@
 #include <mach/da8xx.h>
 #include <mach/cpufreq.h>
 #include <mach/pm.h>
+#include <mach/gpio.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -781,10 +782,7 @@ static struct map_desc da850_io_desc[] = {
        },
 };
 
-static void __iomem *da850_psc_bases[] = {
-       IO_ADDRESS(DA8XX_PSC0_BASE),
-       IO_ADDRESS(DA8XX_PSC1_BASE),
-};
+static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
 
 /* Contents of JTAG ID register used to identify exact cpu type */
 static struct davinci_id da850_ids[] = {
@@ -799,22 +797,22 @@ static struct davinci_id da850_ids[] = {
 
 static struct davinci_timer_instance da850_timer_instance[4] = {
        {
-               .base           = IO_ADDRESS(DA8XX_TIMER64P0_BASE),
+               .base           = DA8XX_TIMER64P0_BASE,
                .bottom_irq     = IRQ_DA8XX_TINT12_0,
                .top_irq        = IRQ_DA8XX_TINT34_0,
        },
        {
-               .base           = IO_ADDRESS(DA8XX_TIMER64P1_BASE),
+               .base           = DA8XX_TIMER64P1_BASE,
                .bottom_irq     = IRQ_DA8XX_TINT12_1,
                .top_irq        = IRQ_DA8XX_TINT34_1,
        },
        {
-               .base           = IO_ADDRESS(DA850_TIMER64P2_BASE),
+               .base           = DA850_TIMER64P2_BASE,
                .bottom_irq     = IRQ_DA850_TINT12_2,
                .top_irq        = IRQ_DA850_TINT34_2,
        },
        {
-               .base           = IO_ADDRESS(DA850_TIMER64P3_BASE),
+               .base           = DA850_TIMER64P3_BASE,
                .bottom_irq     = IRQ_DA850_TINT12_3,
                .top_irq        = IRQ_DA850_TINT34_3,
        },
@@ -1072,31 +1070,37 @@ no_ddrpll_mem:
 static struct davinci_soc_info davinci_soc_info_da850 = {
        .io_desc                = da850_io_desc,
        .io_desc_num            = ARRAY_SIZE(da850_io_desc),
+       .jtag_id_reg            = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
        .ids                    = da850_ids,
        .ids_num                = ARRAY_SIZE(da850_ids),
        .cpu_clks               = da850_clks,
        .psc_bases              = da850_psc_bases,
        .psc_bases_num          = ARRAY_SIZE(da850_psc_bases),
+       .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da850_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da850_pins),
-       .intc_base              = (void __iomem *)DA8XX_CP_INTC_VIRT,
+       .intc_base              = DA8XX_CP_INTC_BASE,
        .intc_type              = DAVINCI_INTC_TYPE_CP_INTC,
        .intc_irq_prios         = da850_default_priorities,
        .intc_irq_num           = DA850_N_CP_INTC_IRQ,
        .timer_info             = &da850_timer_info,
-       .gpio_base              = IO_ADDRESS(DA8XX_GPIO_BASE),
+       .gpio_type              = GPIO_TYPE_DAVINCI,
+       .gpio_base              = DA8XX_GPIO_BASE,
        .gpio_num               = 144,
        .gpio_irq               = IRQ_DA8XX_GPIO0,
        .serial_dev             = &da8xx_serial_device,
        .emac_pdata             = &da8xx_emac_pdata,
        .sram_dma               = DA8XX_ARM_RAM_BASE,
        .sram_len               = SZ_8K,
+       .reset_device           = &da8xx_wdt_device,
 };
 
 void __init da850_init(void)
 {
        unsigned int v;
 
+       davinci_common_init(&davinci_soc_info_da850);
+
        da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
        if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
                return;
@@ -1105,12 +1109,6 @@ void __init da850_init(void)
        if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
                return;
 
-       davinci_soc_info_da850.jtag_id_base =
-                                       DA8XX_SYSCFG0_VIRT(DA8XX_JTAG_ID_REG);
-       davinci_soc_info_da850.pinmux_base = DA8XX_SYSCFG0_VIRT(0x120);
-
-       davinci_common_init(&davinci_soc_info_da850);
-
        /*
         * Move the clock source of Async3 domain to PLL1 SYSCLK2.
         * This helps keeping the peripherals on this domain insulated
index 0a96791..8cda729 100644 (file)
@@ -326,7 +326,7 @@ static struct resource da8xx_watchdog_resources[] = {
        },
 };
 
-struct platform_device davinci_wdt_device = {
+struct platform_device da8xx_wdt_device = {
        .name           = "watchdog",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(da8xx_watchdog_resources),
@@ -335,7 +335,7 @@ struct platform_device davinci_wdt_device = {
 
 int __init da8xx_register_watchdog(void)
 {
-       return platform_device_register(&davinci_wdt_device);
+       return platform_device_register(&da8xx_wdt_device);
 }
 
 static struct resource da8xx_emac_resources[] = {
@@ -584,10 +584,17 @@ static struct platform_device da8xx_rtc_device = {
 int da8xx_register_rtc(void)
 {
        int ret;
+       void __iomem *base;
+
+       base = ioremap(DA8XX_RTC_BASE, SZ_4K);
+       if (WARN_ON(!base))
+               return -ENOMEM;
 
        /* Unlock the rtc's registers */
-       __raw_writel(0x83e70b13, IO_ADDRESS(DA8XX_RTC_BASE + 0x6c));
-       __raw_writel(0x95a4f1e0, IO_ADDRESS(DA8XX_RTC_BASE + 0x70));
+       __raw_writel(0x83e70b13, base + 0x6c);
+       __raw_writel(0x95a4f1e0, base + 0x70);
+
+       iounmap(base);
 
        ret = platform_device_register(&da8xx_rtc_device);
        if (!ret)
index 1479496..8b7201e 100644 (file)
 #include <mach/mmc.h>
 #include <mach/time.h>
 
+#include "clock.h"
+
 #define DAVINCI_I2C_BASE            0x01C21000
+#define DAVINCI_ATA_BASE            0x01C66000
 #define DAVINCI_MMCSD0_BASE         0x01E10000
 #define DM355_MMCSD0_BASE           0x01E11000
 #define DM355_MMCSD1_BASE           0x01E00000
@@ -58,6 +61,49 @@ void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
        (void) platform_device_register(&davinci_i2c_device);
 }
 
+static struct resource ide_resources[] = {
+       {
+               .start          = DAVINCI_ATA_BASE,
+               .end            = DAVINCI_ATA_BASE + 0x7ff,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = IRQ_IDE,
+               .end            = IRQ_IDE,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_device = {
+       .name           = "palm_bk3710",
+       .id             = -1,
+       .resource       = ide_resources,
+       .num_resources  = ARRAY_SIZE(ide_resources),
+       .dev = {
+               .dma_mask               = &ide_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+void __init davinci_init_ide(void)
+{
+       if (cpu_is_davinci_dm644x()) {
+               davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+               davinci_cfg_reg(DM644X_ATAEN);
+               davinci_cfg_reg(DM644X_HDIREN);
+       } else if (cpu_is_davinci_dm646x()) {
+               /* IRQ_DM646X_IDE is the same as IRQ_IDE */
+               davinci_cfg_reg(DM646X_ATAEN);
+       } else {
+               WARN_ON(1);
+               return;
+       }
+
+       platform_device_register(&ide_device);
+}
+
 #if    defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
 
 static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
@@ -251,12 +297,12 @@ static void davinci_init_wdt(void)
 
 struct davinci_timer_instance davinci_timer_instance[2] = {
        {
-               .base           = IO_ADDRESS(DAVINCI_TIMER0_BASE),
+               .base           = DAVINCI_TIMER0_BASE,
                .bottom_irq     = IRQ_TINT0_TINT12,
                .top_irq        = IRQ_TINT0_TINT34,
        },
        {
-               .base           = IO_ADDRESS(DAVINCI_TIMER1_BASE),
+               .base           = DAVINCI_TIMER1_BASE,
                .bottom_irq     = IRQ_TINT1_TINT12,
                .top_irq        = IRQ_TINT1_TINT34,
        },
index 3dc0a88..3834781 100644 (file)
@@ -450,11 +450,6 @@ void __init dm355_init_spi0(unsigned chipselect_mask,
 
 /*----------------------------------------------------------------------*/
 
-#define PINMUX0                0x00
-#define PINMUX1                0x04
-#define PINMUX2                0x08
-#define PINMUX3                0x0c
-#define PINMUX4                0x10
 #define INTMUX         0x18
 #define EVTMUX         0x1c
 
@@ -788,9 +783,7 @@ static struct davinci_id dm355_ids[] = {
        },
 };
 
-static void __iomem *dm355_psc_bases[] = {
-       IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
-};
+static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
 
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
@@ -798,7 +791,7 @@ static void __iomem *dm355_psc_bases[] = {
  * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
  * T1_TOP: Timer 1, top   :  <unused>
  */
-struct davinci_timer_info dm355_timer_info = {
+static struct davinci_timer_info dm355_timer_info = {
        .timers         = davinci_timer_instance,
        .clockevent_id  = T0_BOT,
        .clocksource_id = T0_TOP,
@@ -845,26 +838,28 @@ static struct platform_device dm355_serial_device = {
 static struct davinci_soc_info davinci_soc_info_dm355 = {
        .io_desc                = dm355_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm355_io_desc),
-       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .jtag_id_reg            = 0x01c40028,
        .ids                    = dm355_ids,
        .ids_num                = ARRAY_SIZE(dm355_ids),
        .cpu_clks               = dm355_clks,
        .psc_bases              = dm355_psc_bases,
        .psc_bases_num          = ARRAY_SIZE(dm355_psc_bases),
-       .pinmux_base            = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+       .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm355_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm355_pins),
-       .intc_base              = IO_ADDRESS(DAVINCI_ARM_INTC_BASE),
+       .intc_base              = DAVINCI_ARM_INTC_BASE,
        .intc_type              = DAVINCI_INTC_TYPE_AINTC,
        .intc_irq_prios         = dm355_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm355_timer_info,
-       .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
+       .gpio_type              = GPIO_TYPE_DAVINCI,
+       .gpio_base              = DAVINCI_GPIO_BASE,
        .gpio_num               = 104,
        .gpio_irq               = IRQ_DM355_GPIOBNK0,
        .serial_dev             = &dm355_serial_device,
        .sram_dma               = 0x00010000,
        .sram_len               = SZ_32K,
+       .reset_device           = &davinci_wdt_device,
 };
 
 void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
index 0d6ee58..a146849 100644 (file)
@@ -467,11 +467,6 @@ static struct clk_lookup dm365_clks[] = {
 
 /*----------------------------------------------------------------------*/
 
-#define PINMUX0                0x00
-#define PINMUX1                0x04
-#define PINMUX2                0x08
-#define PINMUX3                0x0c
-#define PINMUX4                0x10
 #define INTMUX         0x18
 #define EVTMUX         0x1c
 
@@ -490,11 +485,14 @@ MUX_CFG(DM365,    SD1_DATA0,      4,   22,    3,    1,     false)
 MUX_CFG(DM365, I2C_SDA,        3,   23,    3,    2,     false)
 MUX_CFG(DM365, I2C_SCL,        3,   21,    3,    2,     false)
 
-MUX_CFG(DM365, AEMIF_AR,       2,   0,     3,    1,     false)
+MUX_CFG(DM365, AEMIF_AR_A14,   2,   0,     3,    1,     false)
+MUX_CFG(DM365, AEMIF_AR_BA0,   2,   0,     3,    2,     false)
 MUX_CFG(DM365, AEMIF_A3,       2,   2,     3,    1,     false)
 MUX_CFG(DM365, AEMIF_A7,       2,   4,     3,    1,     false)
 MUX_CFG(DM365, AEMIF_D15_8,    2,   6,     1,    1,     false)
 MUX_CFG(DM365, AEMIF_CE0,      2,   7,     1,    0,     false)
+MUX_CFG(DM365, AEMIF_CE1,      2,   8,     1,    0,     false)
+MUX_CFG(DM365, AEMIF_WE_OE,    2,   9,     1,    0,     false)
 
 MUX_CFG(DM365, MCBSP0_BDX,     0,   23,    1,    1,     false)
 MUX_CFG(DM365, MCBSP0_X,       0,   22,    1,    1,     false)
@@ -573,9 +571,17 @@ MUX_CFG(DM365,     SPI4_SDO,       4,   16,    3,    1,     false)
 MUX_CFG(DM365, SPI4_SDENA0,    4,   20,    3,    1,     false)
 MUX_CFG(DM365, SPI4_SDENA1,    4,   16,    3,    2,     false)
 
+MUX_CFG(DM365, CLKOUT0,        4,   20,    3,    3,     false)
+MUX_CFG(DM365, CLKOUT1,        4,   16,    3,    3,     false)
+MUX_CFG(DM365, CLKOUT2,        4,   8,     3,    3,     false)
+
 MUX_CFG(DM365, GPIO20,         3,   21,    3,    0,     false)
+MUX_CFG(DM365, GPIO30,         4,   6,     3,    0,     false)
+MUX_CFG(DM365, GPIO31,         4,   8,     3,    0,     false)
+MUX_CFG(DM365, GPIO32,         4,   10,    3,    0,     false)
 MUX_CFG(DM365, GPIO33,         4,   12,    3,    0,     false)
 MUX_CFG(DM365, GPIO40,         4,   26,    3,    0,     false)
+MUX_CFG(DM365, GPIO64_57,      2,   6,     1,    0,     false)
 
 MUX_CFG(DM365, VOUT_FIELD,     1,   18,    3,    1,     false)
 MUX_CFG(DM365, VOUT_FIELD_G81, 1,   18,    3,    0,     false)
@@ -1006,11 +1012,9 @@ static struct davinci_id dm365_ids[] = {
        },
 };
 
-static void __iomem *dm365_psc_bases[] = {
-       IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
-};
+static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
 
-struct davinci_timer_info dm365_timer_info = {
+static struct davinci_timer_info dm365_timer_info = {
        .timers         = davinci_timer_instance,
        .clockevent_id  = T0_BOT,
        .clocksource_id = T0_TOP,
@@ -1049,21 +1053,22 @@ static struct platform_device dm365_serial_device = {
 static struct davinci_soc_info davinci_soc_info_dm365 = {
        .io_desc                = dm365_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm365_io_desc),
-       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .jtag_id_reg            = 0x01c40028,
        .ids                    = dm365_ids,
        .ids_num                = ARRAY_SIZE(dm365_ids),
        .cpu_clks               = dm365_clks,
        .psc_bases              = dm365_psc_bases,
        .psc_bases_num          = ARRAY_SIZE(dm365_psc_bases),
-       .pinmux_base            = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+       .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm365_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm365_pins),
-       .intc_base              = IO_ADDRESS(DAVINCI_ARM_INTC_BASE),
+       .intc_base              = DAVINCI_ARM_INTC_BASE,
        .intc_type              = DAVINCI_INTC_TYPE_AINTC,
        .intc_irq_prios         = dm365_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm365_timer_info,
-       .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
+       .gpio_type              = GPIO_TYPE_DAVINCI,
+       .gpio_base              = DAVINCI_GPIO_BASE,
        .gpio_num               = 104,
        .gpio_irq               = IRQ_DM365_GPIO0,
        .gpio_unbanked          = 8,    /* really 16 ... skip muxed GPIOs */
@@ -1071,6 +1076,7 @@ static struct davinci_soc_info davinci_soc_info_dm365 = {
        .emac_pdata             = &dm365_emac_pdata,
        .sram_dma               = 0x00010000,
        .sram_len               = SZ_32K,
+       .reset_device           = &davinci_wdt_device,
 };
 
 void __init dm365_init_asp(struct snd_platform_data *pdata)
index 2f2ae8b..7ad1520 100644 (file)
@@ -277,7 +277,7 @@ static struct clk timer2_clk = {
        .usecount = 1,              /* REVISIT: why cant' this be disabled? */
 };
 
-struct clk_lookup dm644x_clks[] = {
+static struct clk_lookup dm644x_clks[] = {
        CLK(NULL, "ref", &ref_clk),
        CLK(NULL, "pll1", &pll1_clk),
        CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
@@ -350,9 +350,6 @@ static struct platform_device dm644x_emac_device = {
        .resource       = dm644x_emac_resources,
 };
 
-#define PINMUX0                0x00
-#define PINMUX1                0x04
-
 /*
  * Device specific mux setup
  *
@@ -677,9 +674,7 @@ static struct davinci_id dm644x_ids[] = {
        },
 };
 
-static void __iomem *dm644x_psc_bases[] = {
-       IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
-};
+static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
 
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
@@ -687,7 +682,7 @@ static void __iomem *dm644x_psc_bases[] = {
  * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
  * T1_TOP: Timer 1, top   :  <unused>
  */
-struct davinci_timer_info dm644x_timer_info = {
+static struct davinci_timer_info dm644x_timer_info = {
        .timers         = davinci_timer_instance,
        .clockevent_id  = T0_BOT,
        .clocksource_id = T0_TOP,
@@ -734,27 +729,29 @@ static struct platform_device dm644x_serial_device = {
 static struct davinci_soc_info davinci_soc_info_dm644x = {
        .io_desc                = dm644x_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm644x_io_desc),
-       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .jtag_id_reg            = 0x01c40028,
        .ids                    = dm644x_ids,
        .ids_num                = ARRAY_SIZE(dm644x_ids),
        .cpu_clks               = dm644x_clks,
        .psc_bases              = dm644x_psc_bases,
        .psc_bases_num          = ARRAY_SIZE(dm644x_psc_bases),
-       .pinmux_base            = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+       .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm644x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm644x_pins),
-       .intc_base              = IO_ADDRESS(DAVINCI_ARM_INTC_BASE),
+       .intc_base              = DAVINCI_ARM_INTC_BASE,
        .intc_type              = DAVINCI_INTC_TYPE_AINTC,
        .intc_irq_prios         = dm644x_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm644x_timer_info,
-       .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
+       .gpio_type              = GPIO_TYPE_DAVINCI,
+       .gpio_base              = DAVINCI_GPIO_BASE,
        .gpio_num               = 71,
        .gpio_irq               = IRQ_GPIOBNK0,
        .serial_dev             = &dm644x_serial_device,
        .emac_pdata             = &dm644x_emac_pdata,
        .sram_dma               = 0x00008000,
        .sram_len               = SZ_16K,
+       .reset_device           = &davinci_wdt_device,
 };
 
 void __init dm644x_init_asp(struct snd_platform_data *pdata)
index 893baf4..9404565 100644 (file)
@@ -311,7 +311,7 @@ static struct clk vpif1_clk = {
        .flags = ALWAYS_ENABLED,
 };
 
-struct clk_lookup dm646x_clks[] = {
+static struct clk_lookup dm646x_clks[] = {
        CLK(NULL, "ref", &ref_clk),
        CLK(NULL, "aux", &aux_clkin),
        CLK(NULL, "pll1", &pll1_clk),
@@ -401,9 +401,6 @@ static struct platform_device dm646x_emac_device = {
        .resource       = dm646x_emac_resources,
 };
 
-#define PINMUX0                0x00
-#define PINMUX1                0x04
-
 /*
  * Device specific mux setup
  *
@@ -596,32 +593,6 @@ static struct platform_device dm646x_edma_device = {
        .resource               = edma_resources,
 };
 
-static struct resource ide_resources[] = {
-       {
-               .start          = DM646X_ATA_REG_BASE,
-               .end            = DM646X_ATA_REG_BASE + 0x7ff,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = IRQ_DM646X_IDE,
-               .end            = IRQ_DM646X_IDE,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static u64 ide_dma_mask = DMA_BIT_MASK(32);
-
-static struct platform_device ide_dev = {
-       .name           = "palm_bk3710",
-       .id             = -1,
-       .resource       = ide_resources,
-       .num_resources  = ARRAY_SIZE(ide_resources),
-       .dev = {
-               .dma_mask               = &ide_dma_mask,
-               .coherent_dma_mask      = DMA_BIT_MASK(32),
-       },
-};
-
 static struct resource dm646x_mcasp0_resources[] = {
        {
                .name   = "mcasp0",
@@ -787,9 +758,7 @@ static struct davinci_id dm646x_ids[] = {
        },
 };
 
-static void __iomem *dm646x_psc_bases[] = {
-       IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
-};
+static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
 
 /*
  * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
@@ -797,7 +766,7 @@ static void __iomem *dm646x_psc_bases[] = {
  * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
  * T1_TOP: Timer 1, top   :  <unused>
  */
-struct davinci_timer_info dm646x_timer_info = {
+static struct davinci_timer_info dm646x_timer_info = {
        .timers         = davinci_timer_instance,
        .clockevent_id  = T0_BOT,
        .clocksource_id = T0_TOP,
@@ -844,35 +813,31 @@ static struct platform_device dm646x_serial_device = {
 static struct davinci_soc_info davinci_soc_info_dm646x = {
        .io_desc                = dm646x_io_desc,
        .io_desc_num            = ARRAY_SIZE(dm646x_io_desc),
-       .jtag_id_base           = IO_ADDRESS(0x01c40028),
+       .jtag_id_reg            = 0x01c40028,
        .ids                    = dm646x_ids,
        .ids_num                = ARRAY_SIZE(dm646x_ids),
        .cpu_clks               = dm646x_clks,
        .psc_bases              = dm646x_psc_bases,
        .psc_bases_num          = ARRAY_SIZE(dm646x_psc_bases),
-       .pinmux_base            = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+       .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm646x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm646x_pins),
-       .intc_base              = IO_ADDRESS(DAVINCI_ARM_INTC_BASE),
+       .intc_base              = DAVINCI_ARM_INTC_BASE,
        .intc_type              = DAVINCI_INTC_TYPE_AINTC,
        .intc_irq_prios         = dm646x_default_priorities,
        .intc_irq_num           = DAVINCI_N_AINTC_IRQ,
        .timer_info             = &dm646x_timer_info,
-       .gpio_base              = IO_ADDRESS(DAVINCI_GPIO_BASE),
+       .gpio_type              = GPIO_TYPE_DAVINCI,
+       .gpio_base              = DAVINCI_GPIO_BASE,
        .gpio_num               = 43, /* Only 33 usable */
        .gpio_irq               = IRQ_DM646X_GPIOBNK0,
        .serial_dev             = &dm646x_serial_device,
        .emac_pdata             = &dm646x_emac_pdata,
        .sram_dma               = 0x10010000,
        .sram_len               = SZ_32K,
+       .reset_device           = &davinci_wdt_device,
 };
 
-void __init dm646x_init_ide()
-{
-       davinci_cfg_reg(DM646X_ATAEN);
-       platform_device_register(&ide_dev);
-}
-
 void __init dm646x_init_mcasp0(struct snd_platform_data *pdata)
 {
        dm646x_mcasp0_device.dev.platform_data = pdata;
index 5313738..d33827a 100644 (file)
@@ -243,7 +243,7 @@ struct edma {
        } intr_data[EDMA_MAX_DMACH];
 };
 
-static struct edma *edma_info[EDMA_MAX_CC];
+static struct edma *edma_cc[EDMA_MAX_CC];
 static int arch_num_cc;
 
 /* dummy param set used to (re)initialize parameter RAM slots */
@@ -261,7 +261,7 @@ static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
 
        /* default to low priority queue */
        if (queue_no == EVENTQ_DEFAULT)
-               queue_no = edma_info[ctlr]->default_queue;
+               queue_no = edma_cc[ctlr]->default_queue;
 
        queue_no &= 7;
        edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3),
@@ -310,29 +310,27 @@ setup_dma_interrupt(unsigned lch,
        ctlr = EDMA_CTLR(lch);
        lch = EDMA_CHAN_SLOT(lch);
 
-       if (!callback) {
+       if (!callback)
                edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5,
-                               (1 << (lch & 0x1f)));
-       }
+                               BIT(lch & 0x1f));
 
-       edma_info[ctlr]->intr_data[lch].callback = callback;
-       edma_info[ctlr]->intr_data[lch].data = data;
+       edma_cc[ctlr]->intr_data[lch].callback = callback;
+       edma_cc[ctlr]->intr_data[lch].data = data;
 
        if (callback) {
                edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5,
-                               (1 << (lch & 0x1f)));
+                               BIT(lch & 0x1f));
                edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5,
-                               (1 << (lch & 0x1f)));
+                               BIT(lch & 0x1f));
        }
 }
 
 static int irq2ctlr(int irq)
 {
-       if (irq >= edma_info[0]->irq_res_start &&
-               irq <= edma_info[0]->irq_res_end)
+       if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end)
                return 0;
-       else if (irq >= edma_info[1]->irq_res_start &&
-               irq <= edma_info[1]->irq_res_end)
+       else if (irq >= edma_cc[1]->irq_res_start &&
+               irq <= edma_cc[1]->irq_res_end)
                return 1;
 
        return -1;
@@ -353,15 +351,17 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
 
        dev_dbg(data, "dma_irq_handler\n");
 
-       if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0)
-           && (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
+       if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) &&
+           (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
                return IRQ_NONE;
 
        while (1) {
                int j;
-               if (edma_shadow0_read_array(ctlr, SH_IPR, 0))
+               if (edma_shadow0_read_array(ctlr, SH_IPR, 0) &
+                               edma_shadow0_read_array(ctlr, SH_IER, 0))
                        j = 0;
-               else if (edma_shadow0_read_array(ctlr, SH_IPR, 1))
+               else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) &
+                               edma_shadow0_read_array(ctlr, SH_IER, 1))
                        j = 1;
                else
                        break;
@@ -369,17 +369,17 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
                                edma_shadow0_read_array(ctlr, SH_IPR, j));
                for (i = 0; i < 32; i++) {
                        int k = (j << 5) + i;
-                       if (edma_shadow0_read_array(ctlr, SH_IPR, j) &
-                                                       (1 << i)) {
+                       if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i))
+                                       && (edma_shadow0_read_array(ctlr,
+                                                       SH_IER, j) & BIT(i))) {
                                /* Clear the corresponding IPR bits */
                                edma_shadow0_write_array(ctlr, SH_ICR, j,
-                                                       (1 << i));
-                               if (edma_info[ctlr]->intr_data[k].callback) {
-                                       edma_info[ctlr]->intr_data[k].callback(
+                                                       BIT(i));
+                               if (edma_cc[ctlr]->intr_data[k].callback)
+                                       edma_cc[ctlr]->intr_data[k].callback(
                                                k, DMA_COMPLETE,
-                                               edma_info[ctlr]->intr_data[k].
+                                               edma_cc[ctlr]->intr_data[k].
                                                data);
-                               }
                        }
                }
                cnt++;
@@ -423,19 +423,19 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
                        for (i = 0; i < 32; i++) {
                                int k = (j << 5) + i;
                                if (edma_read_array(ctlr, EDMA_EMR, j) &
-                                                       (1 << i)) {
+                                                       BIT(i)) {
                                        /* Clear the corresponding EMR bits */
                                        edma_write_array(ctlr, EDMA_EMCR, j,
-                                                       1 << i);
+                                                       BIT(i));
                                        /* Clear any SER */
                                        edma_shadow0_write_array(ctlr, SH_SECR,
-                                                               j, (1 << i));
-                                       if (edma_info[ctlr]->intr_data[k].
+                                                               j, BIT(i));
+                                       if (edma_cc[ctlr]->intr_data[k].
                                                                callback) {
-                                               edma_info[ctlr]->intr_data[k].
+                                               edma_cc[ctlr]->intr_data[k].
                                                callback(k,
                                                DMA_CC_ERROR,
-                                               edma_info[ctlr]->intr_data
+                                               edma_cc[ctlr]->intr_data
                                                [k].data);
                                        }
                                }
@@ -444,11 +444,11 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
                        dev_dbg(data, "QEMR %02x\n",
                                edma_read(ctlr, EDMA_QEMR));
                        for (i = 0; i < 8; i++) {
-                               if (edma_read(ctlr, EDMA_QEMR) & (1 << i)) {
+                               if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) {
                                        /* Clear the corresponding IPR bits */
-                                       edma_write(ctlr, EDMA_QEMCR, 1 << i);
+                                       edma_write(ctlr, EDMA_QEMCR, BIT(i));
                                        edma_shadow0_write(ctlr, SH_QSECR,
-                                                               (1 << i));
+                                                               BIT(i));
 
                                        /* NOTE:  not reported!! */
                                }
@@ -460,20 +460,19 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
                         * to just write CCERRCLR with CCERR value...
                         */
                        for (i = 0; i < 8; i++) {
-                               if (edma_read(ctlr, EDMA_CCERR) & (1 << i)) {
+                               if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) {
                                        /* Clear the corresponding IPR bits */
-                                       edma_write(ctlr, EDMA_CCERRCLR, 1 << i);
+                                       edma_write(ctlr, EDMA_CCERRCLR, BIT(i));
 
                                        /* NOTE:  not reported!! */
                                }
                        }
                }
-               if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0)
-                   && (edma_read_array(ctlr, EDMA_EMR, 1) == 0)
-                   && (edma_read(ctlr, EDMA_QEMR) == 0)
-                   && (edma_read(ctlr, EDMA_CCERR) == 0)) {
+               if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+                   (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+                   (edma_read(ctlr, EDMA_QEMR) == 0) &&
+                   (edma_read(ctlr, EDMA_CCERR) == 0))
                        break;
-               }
                cnt++;
                if (cnt > 10)
                        break;
@@ -511,9 +510,9 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
        int stop_slot = start_slot;
        DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
 
-       for (i = start_slot; i < edma_info[ctlr]->num_slots; ++i) {
+       for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) {
                j = EDMA_CHAN_SLOT(i);
-               if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse)) {
+               if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) {
                        /* Record our current beginning slot */
                        if (count == num_slots)
                                stop_slot = i;
@@ -529,8 +528,9 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
                        if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
                                stop_slot = i;
                                break;
-                       } else
+                       } else {
                                count = num_slots;
+                       }
                }
        }
 
@@ -540,12 +540,12 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id,
         * of contiguous parameter RAM slots but do not find the exact number
         * requested as we may reach the total number of parameter RAM slots
         */
-       if (i == edma_info[ctlr]->num_slots)
+       if (i == edma_cc[ctlr]->num_slots)
                stop_slot = i;
 
        for (j = start_slot; j < stop_slot; j++)
                if (test_bit(j, tmp_inuse))
-                       clear_bit(j, edma_info[ctlr]->edma_inuse);
+                       clear_bit(j, edma_cc[ctlr]->edma_inuse);
 
        if (count)
                return -EBUSY;
@@ -567,7 +567,7 @@ static int prepare_unused_channel_list(struct device *dev, void *data)
                                (int)pdev->resource[i].start >= 0) {
                        ctlr = EDMA_CTLR(pdev->resource[i].start);
                        clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
-                                       edma_info[ctlr]->edma_unused);
+                                       edma_cc[ctlr]->edma_unused);
                }
        }
 
@@ -641,14 +641,13 @@ int edma_alloc_channel(int channel,
                for (i = 0; i < arch_num_cc; i++) {
                        channel = 0;
                        for (;;) {
-                               channel = find_next_bit(edma_info[i]->
-                                               edma_unused,
-                                               edma_info[i]->num_channels,
+                               channel = find_next_bit(edma_cc[i]->edma_unused,
+                                               edma_cc[i]->num_channels,
                                                channel);
-                               if (channel == edma_info[i]->num_channels)
+                               if (channel == edma_cc[i]->num_channels)
                                        break;
                                if (!test_and_set_bit(channel,
-                                               edma_info[i]->edma_inuse)) {
+                                               edma_cc[i]->edma_inuse)) {
                                        done = 1;
                                        ctlr = i;
                                        break;
@@ -660,14 +659,14 @@ int edma_alloc_channel(int channel,
                }
                if (!done)
                        return -ENOMEM;
-       } else if (channel >= edma_info[ctlr]->num_channels) {
+       } else if (channel >= edma_cc[ctlr]->num_channels) {
                return -EINVAL;
-       } else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) {
+       } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) {
                return -EBUSY;
        }
 
        /* ensure access through shadow region 0 */
-       edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, 1 << (channel & 0x1f));
+       edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f));
 
        /* ensure no events are pending */
        edma_stop(EDMA_CTLR_CHAN(ctlr, channel));
@@ -703,7 +702,7 @@ void edma_free_channel(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel >= edma_info[ctlr]->num_channels)
+       if (channel >= edma_cc[ctlr]->num_channels)
                return;
 
        setup_dma_interrupt(channel, NULL, NULL);
@@ -711,7 +710,7 @@ void edma_free_channel(unsigned channel)
 
        memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
                        &dummy_paramset, PARM_SIZE);
-       clear_bit(channel, edma_info[ctlr]->edma_inuse);
+       clear_bit(channel, edma_cc[ctlr]->edma_inuse);
 }
 EXPORT_SYMBOL(edma_free_channel);
 
@@ -735,20 +734,19 @@ int edma_alloc_slot(unsigned ctlr, int slot)
                slot = EDMA_CHAN_SLOT(slot);
 
        if (slot < 0) {
-               slot = edma_info[ctlr]->num_channels;
+               slot = edma_cc[ctlr]->num_channels;
                for (;;) {
-                       slot = find_next_zero_bit(edma_info[ctlr]->edma_inuse,
-                                       edma_info[ctlr]->num_slots, slot);
-                       if (slot == edma_info[ctlr]->num_slots)
+                       slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse,
+                                       edma_cc[ctlr]->num_slots, slot);
+                       if (slot == edma_cc[ctlr]->num_slots)
                                return -ENOMEM;
-                       if (!test_and_set_bit(slot,
-                                               edma_info[ctlr]->edma_inuse))
+                       if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse))
                                break;
                }
-       } else if (slot < edma_info[ctlr]->num_channels ||
-                       slot >= edma_info[ctlr]->num_slots) {
+       } else if (slot < edma_cc[ctlr]->num_channels ||
+                       slot >= edma_cc[ctlr]->num_slots) {
                return -EINVAL;
-       } else if (test_and_set_bit(slot, edma_info[ctlr]->edma_inuse)) {
+       } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) {
                return -EBUSY;
        }
 
@@ -774,13 +772,13 @@ void edma_free_slot(unsigned slot)
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_channels ||
-               slot >= edma_info[ctlr]->num_slots)
+       if (slot < edma_cc[ctlr]->num_channels ||
+               slot >= edma_cc[ctlr]->num_slots)
                return;
 
        memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
                        &dummy_paramset, PARM_SIZE);
-       clear_bit(slot, edma_info[ctlr]->edma_inuse);
+       clear_bit(slot, edma_cc[ctlr]->edma_inuse);
 }
 EXPORT_SYMBOL(edma_free_slot);
 
@@ -818,8 +816,8 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
         * of slots
         */
        if ((id != EDMA_CONT_PARAMS_ANY) &&
-               (slot < edma_info[ctlr]->num_channels ||
-               slot >= edma_info[ctlr]->num_slots))
+               (slot < edma_cc[ctlr]->num_channels ||
+               slot >= edma_cc[ctlr]->num_slots))
                return -EINVAL;
 
        /*
@@ -828,13 +826,13 @@ int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
         * channels
         */
        if (count < 1 || count >
-               (edma_info[ctlr]->num_slots - edma_info[ctlr]->num_channels))
+               (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels))
                return -EINVAL;
 
        switch (id) {
        case EDMA_CONT_PARAMS_ANY:
                return reserve_contiguous_slots(ctlr, id, count,
-                                                edma_info[ctlr]->num_channels);
+                                                edma_cc[ctlr]->num_channels);
        case EDMA_CONT_PARAMS_FIXED_EXACT:
        case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
                return reserve_contiguous_slots(ctlr, id, count, slot);
@@ -866,8 +864,8 @@ int edma_free_cont_slots(unsigned slot, int count)
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_channels ||
-               slot >= edma_info[ctlr]->num_slots ||
+       if (slot < edma_cc[ctlr]->num_channels ||
+               slot >= edma_cc[ctlr]->num_slots ||
                count < 1)
                return -EINVAL;
 
@@ -877,7 +875,7 @@ int edma_free_cont_slots(unsigned slot, int count)
 
                memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
                        &dummy_paramset, PARM_SIZE);
-               clear_bit(slot_to_free, edma_info[ctlr]->edma_inuse);
+               clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse);
        }
 
        return 0;
@@ -907,7 +905,7 @@ void edma_set_src(unsigned slot, dma_addr_t src_port,
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_slots) {
+       if (slot < edma_cc[ctlr]->num_slots) {
                unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
 
                if (mode) {
@@ -945,7 +943,7 @@ void edma_set_dest(unsigned slot, dma_addr_t dest_port,
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_slots) {
+       if (slot < edma_cc[ctlr]->num_slots) {
                unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
 
                if (mode) {
@@ -1005,7 +1003,7 @@ void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_slots) {
+       if (slot < edma_cc[ctlr]->num_slots) {
                edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
                                0xffff0000, src_bidx);
                edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
@@ -1031,7 +1029,7 @@ void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_slots) {
+       if (slot < edma_cc[ctlr]->num_slots) {
                edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
                                0x0000ffff, dest_bidx << 16);
                edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
@@ -1078,7 +1076,7 @@ void edma_set_transfer_params(unsigned slot,
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot < edma_info[ctlr]->num_slots) {
+       if (slot < edma_cc[ctlr]->num_slots) {
                edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot,
                                0x0000ffff, bcnt_rld << 16);
                if (sync_mode == ASYNC)
@@ -1108,9 +1106,9 @@ void edma_link(unsigned from, unsigned to)
        ctlr_to = EDMA_CTLR(to);
        to = EDMA_CHAN_SLOT(to);
 
-       if (from >= edma_info[ctlr_from]->num_slots)
+       if (from >= edma_cc[ctlr_from]->num_slots)
                return;
-       if (to >= edma_info[ctlr_to]->num_slots)
+       if (to >= edma_cc[ctlr_to]->num_slots)
                return;
        edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000,
                                PARM_OFFSET(to));
@@ -1131,7 +1129,7 @@ void edma_unlink(unsigned from)
        ctlr = EDMA_CTLR(from);
        from = EDMA_CHAN_SLOT(from);
 
-       if (from >= edma_info[ctlr]->num_slots)
+       if (from >= edma_cc[ctlr]->num_slots)
                return;
        edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff);
 }
@@ -1158,7 +1156,7 @@ void edma_write_slot(unsigned slot, const struct edmacc_param *param)
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot >= edma_info[ctlr]->num_slots)
+       if (slot >= edma_cc[ctlr]->num_slots)
                return;
        memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param,
                        PARM_SIZE);
@@ -1180,7 +1178,7 @@ void edma_read_slot(unsigned slot, struct edmacc_param *param)
        ctlr = EDMA_CTLR(slot);
        slot = EDMA_CHAN_SLOT(slot);
 
-       if (slot >= edma_info[ctlr]->num_slots)
+       if (slot >= edma_cc[ctlr]->num_slots)
                return;
        memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
                        PARM_SIZE);
@@ -1205,8 +1203,8 @@ void edma_pause(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel < edma_info[ctlr]->num_channels) {
-               unsigned int mask = (1 << (channel & 0x1f));
+       if (channel < edma_cc[ctlr]->num_channels) {
+               unsigned int mask = BIT(channel & 0x1f);
 
                edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask);
        }
@@ -1226,8 +1224,8 @@ void edma_resume(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel < edma_info[ctlr]->num_channels) {
-               unsigned int mask = (1 << (channel & 0x1f));
+       if (channel < edma_cc[ctlr]->num_channels) {
+               unsigned int mask = BIT(channel & 0x1f);
 
                edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask);
        }
@@ -1252,12 +1250,12 @@ int edma_start(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel < edma_info[ctlr]->num_channels) {
+       if (channel < edma_cc[ctlr]->num_channels) {
                int j = channel >> 5;
-               unsigned int mask = (1 << (channel & 0x1f));
+               unsigned int mask = BIT(channel & 0x1f);
 
                /* EDMA channels without event association */
-               if (test_bit(channel, edma_info[ctlr]->edma_unused)) {
+               if (test_bit(channel, edma_cc[ctlr]->edma_unused)) {
                        pr_debug("EDMA: ESR%d %08x\n", j,
                                edma_shadow0_read_array(ctlr, SH_ESR, j));
                        edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
@@ -1298,9 +1296,9 @@ void edma_stop(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel < edma_info[ctlr]->num_channels) {
+       if (channel < edma_cc[ctlr]->num_channels) {
                int j = channel >> 5;
-               unsigned int mask = (1 << (channel & 0x1f));
+               unsigned int mask = BIT(channel & 0x1f);
 
                edma_shadow0_write_array(ctlr, SH_EECR, j, mask);
                edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
@@ -1337,9 +1335,9 @@ void edma_clean_channel(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel < edma_info[ctlr]->num_channels) {
+       if (channel < edma_cc[ctlr]->num_channels) {
                int j = (channel >> 5);
-               unsigned int mask = 1 << (channel & 0x1f);
+               unsigned int mask = BIT(channel & 0x1f);
 
                pr_debug("EDMA: EMR%d %08x\n", j,
                                edma_read_array(ctlr, EDMA_EMR, j));
@@ -1348,7 +1346,7 @@ void edma_clean_channel(unsigned channel)
                edma_write_array(ctlr, EDMA_EMCR, j, mask);
                /* Clear any SER */
                edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
-               edma_write(ctlr, EDMA_CCERRCLR, (1 << 16) | 0x3);
+               edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0));
        }
 }
 EXPORT_SYMBOL(edma_clean_channel);
@@ -1365,12 +1363,12 @@ void edma_clear_event(unsigned channel)
        ctlr = EDMA_CTLR(channel);
        channel = EDMA_CHAN_SLOT(channel);
 
-       if (channel >= edma_info[ctlr]->num_channels)
+       if (channel >= edma_cc[ctlr]->num_channels)
                return;
        if (channel < 32)
-               edma_write(ctlr, EDMA_ECR, 1 << channel);
+               edma_write(ctlr, EDMA_ECR, BIT(channel));
        else
-               edma_write(ctlr, EDMA_ECRH, 1 << (channel - 32));
+               edma_write(ctlr, EDMA_ECRH, BIT(channel - 32));
 }
 EXPORT_SYMBOL(edma_clear_event);
 
@@ -1402,8 +1400,9 @@ static int __init edma_probe(struct platform_device *pdev)
                                break;
                        else
                                return -ENODEV;
-               } else
+               } else {
                        found = 1;
+               }
 
                len[j] = resource_size(r[j]);
 
@@ -1420,38 +1419,37 @@ static int __init edma_probe(struct platform_device *pdev)
                        goto fail1;
                }
 
-               edma_info[j] = kmalloc(sizeof(struct edma), GFP_KERNEL);
-               if (!edma_info[j]) {
+               edma_cc[j] = kmalloc(sizeof(struct edma), GFP_KERNEL);
+               if (!edma_cc[j]) {
                        status = -ENOMEM;
                        goto fail1;
                }
-               memset(edma_info[j], 0, sizeof(struct edma));
+               memset(edma_cc[j], 0, sizeof(struct edma));
 
-               edma_info[j]->num_channels = min_t(unsigned, info[j].n_channel,
+               edma_cc[j]->num_channels = min_t(unsigned, info[j].n_channel,
                                                        EDMA_MAX_DMACH);
-               edma_info[j]->num_slots = min_t(unsigned, info[j].n_slot,
+               edma_cc[j]->num_slots = min_t(unsigned, info[j].n_slot,
                                                        EDMA_MAX_PARAMENTRY);
-               edma_info[j]->num_cc = min_t(unsigned, info[j].n_cc,
-                                                       EDMA_MAX_CC);
+               edma_cc[j]->num_cc = min_t(unsigned, info[j].n_cc, EDMA_MAX_CC);
 
-               edma_info[j]->default_queue = info[j].default_queue;
-               if (!edma_info[j]->default_queue)
-                       edma_info[j]->default_queue = EVENTQ_1;
+               edma_cc[j]->default_queue = info[j].default_queue;
+               if (!edma_cc[j]->default_queue)
+                       edma_cc[j]->default_queue = EVENTQ_1;
 
                dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
                        edmacc_regs_base[j]);
 
-               for (i = 0; i < edma_info[j]->num_slots; i++)
+               for (i = 0; i < edma_cc[j]->num_slots; i++)
                        memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
                                        &dummy_paramset, PARM_SIZE);
 
                /* Mark all channels as unused */
-               memset(edma_info[j]->edma_unused, 0xff,
-                       sizeof(edma_info[j]->edma_unused));
+               memset(edma_cc[j]->edma_unused, 0xff,
+                       sizeof(edma_cc[j]->edma_unused));
 
                sprintf(irq_name, "edma%d", j);
                irq[j] = platform_get_irq_byname(pdev, irq_name);
-               edma_info[j]->irq_res_start = irq[j];
+               edma_cc[j]->irq_res_start = irq[j];
                status = request_irq(irq[j], dma_irq_handler, 0, "edma",
                                        &pdev->dev);
                if (status < 0) {
@@ -1462,7 +1460,7 @@ static int __init edma_probe(struct platform_device *pdev)
 
                sprintf(irq_name, "edma%d_err", j);
                err_irq[j] = platform_get_irq_byname(pdev, irq_name);
-               edma_info[j]->irq_res_end = err_irq[j];
+               edma_cc[j]->irq_res_end = err_irq[j];
                status = request_irq(err_irq[j], dma_ccerr_handler, 0,
                                        "edma_error", &pdev->dev);
                if (status < 0) {
@@ -1475,7 +1473,7 @@ static int __init edma_probe(struct platform_device *pdev)
                 * specified. This way, long transfers on the low priority queue
                 * started by the codec engine will not cause audio defects.
                 */
-               for (i = 0; i < edma_info[j]->num_channels; i++)
+               for (i = 0; i < edma_cc[j]->num_channels; i++)
                        map_dmach_queue(j, i, EVENTQ_1);
 
                queue_tc_mapping = info[j].queue_tc_mapping;
@@ -1538,7 +1536,7 @@ fail1:
                        release_mem_region(r[i]->start, len[i]);
                if (edmacc_regs_base[i])
                        iounmap(edmacc_regs_base[i]);
-               kfree(edma_info[i]);
+               kfree(edma_cc[i]);
        }
        return status;
 }
index 744755b..bf0ff58 100644 (file)
 
 #include <asm/mach/irq.h>
 
-static DEFINE_SPINLOCK(gpio_lock);
-
-struct davinci_gpio {
-       struct gpio_chip        chip;
-       struct gpio_controller  *__iomem regs;
-       int                     irq_base;
+struct davinci_gpio_regs {
+       u32     dir;
+       u32     out_data;
+       u32     set_data;
+       u32     clr_data;
+       u32     in_data;
+       u32     set_rising;
+       u32     clr_rising;
+       u32     set_falling;
+       u32     clr_falling;
+       u32     intstat;
 };
 
-static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
+#define chip2controller(chip)  \
+       container_of(chip, struct davinci_gpio_controller, chip)
+
+static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
+static void __iomem *gpio_base;
+
+static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
+{
+       void __iomem *ptr;
+
+       if (gpio < 32 * 1)
+               ptr = gpio_base + 0x10;
+       else if (gpio < 32 * 2)
+               ptr = gpio_base + 0x38;
+       else if (gpio < 32 * 3)
+               ptr = gpio_base + 0x60;
+       else if (gpio < 32 * 4)
+               ptr = gpio_base + 0x88;
+       else if (gpio < 32 * 5)
+               ptr = gpio_base + 0xb0;
+       else
+               ptr = NULL;
+       return ptr;
+}
 
-/* create a non-inlined version */
-static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
+static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
 {
-       return __gpio_to_controller(gpio);
+       struct davinci_gpio_regs __iomem *g;
+
+       g = (__force struct davinci_gpio_regs __iomem *)get_irq_chip_data(irq);
+
+       return g;
 }
 
 static int __init davinci_gpio_irq_setup(void);
 
 /*--------------------------------------------------------------------------*/
 
-/*
- * board setup code *MUST* set PINMUX0 and PINMUX1 as
- * needed, and enable the GPIO clock.
- */
-
-static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
+/* board setup code *MUST* setup pinmux and enable the GPIO clock. */
+static inline int __davinci_direction(struct gpio_chip *chip,
+                       unsigned offset, bool out, int value)
 {
-       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
-       struct gpio_controller *__iomem g = d->regs;
+       struct davinci_gpio_controller *d = chip2controller(chip);
+       struct davinci_gpio_regs __iomem *g = d->regs;
+       unsigned long flags;
        u32 temp;
+       u32 mask = 1 << offset;
 
-       spin_lock(&gpio_lock);
+       spin_lock_irqsave(&d->lock, flags);
        temp = __raw_readl(&g->dir);
-       temp |= (1 << offset);
+       if (out) {
+               temp &= ~mask;
+               __raw_writel(mask, value ? &g->set_data : &g->clr_data);
+       } else {
+               temp |= mask;
+       }
        __raw_writel(temp, &g->dir);
-       spin_unlock(&gpio_lock);
+       spin_unlock_irqrestore(&d->lock, flags);
 
        return 0;
 }
 
+static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+       return __davinci_direction(chip, offset, false, 0);
+}
+
+static int
+davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+       return __davinci_direction(chip, offset, true, value);
+}
+
 /*
  * Read the pin's value (works even if it's set up as output);
  * returns zero/nonzero.
@@ -69,37 +115,20 @@ static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
  */
 static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
-       struct gpio_controller *__iomem g = d->regs;
+       struct davinci_gpio_controller *d = chip2controller(chip);
+       struct davinci_gpio_regs __iomem *g = d->regs;
 
        return (1 << offset) & __raw_readl(&g->in_data);
 }
 
-static int
-davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
-{
-       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
-       struct gpio_controller *__iomem g = d->regs;
-       u32 temp;
-       u32 mask = 1 << offset;
-
-       spin_lock(&gpio_lock);
-       temp = __raw_readl(&g->dir);
-       temp &= ~mask;
-       __raw_writel(mask, value ? &g->set_data : &g->clr_data);
-       __raw_writel(temp, &g->dir);
-       spin_unlock(&gpio_lock);
-       return 0;
-}
-
 /*
  * Assuming the pin is muxed as a gpio output, set its output value.
  */
 static void
 davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
-       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
-       struct gpio_controller *__iomem g = d->regs;
+       struct davinci_gpio_controller *d = chip2controller(chip);
+       struct davinci_gpio_regs __iomem *g = d->regs;
 
        __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
 }
@@ -109,6 +138,10 @@ static int __init davinci_gpio_setup(void)
        int i, base;
        unsigned ngpio;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
+       struct davinci_gpio_regs *regs;
+
+       if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
+               return 0;
 
        /*
         * The gpio banks conceptually expose a segmented bitmap,
@@ -124,6 +157,10 @@ static int __init davinci_gpio_setup(void)
        if (WARN_ON(DAVINCI_N_GPIO < ngpio))
                ngpio = DAVINCI_N_GPIO;
 
+       gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
+       if (WARN_ON(!gpio_base))
+               return -ENOMEM;
+
        for (i = 0, base = 0; base < ngpio; i++, base += 32) {
                chips[i].chip.label = "DaVinci";
 
@@ -137,11 +174,20 @@ static int __init davinci_gpio_setup(void)
                if (chips[i].chip.ngpio > 32)
                        chips[i].chip.ngpio = 32;
 
-               chips[i].regs = gpio2controller(base);
+               spin_lock_init(&chips[i].lock);
+
+               regs = gpio2regs(base);
+               chips[i].regs = regs;
+               chips[i].set_data = &regs->set_data;
+               chips[i].clr_data = &regs->clr_data;
+               chips[i].in_data = &regs->in_data;
 
                gpiochip_add(&chips[i].chip);
        }
 
+       soc_info->gpio_ctlrs = chips;
+       soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
+
        davinci_gpio_irq_setup();
        return 0;
 }
@@ -161,7 +207,7 @@ pure_initcall(davinci_gpio_setup);
 
 static void gpio_irq_disable(unsigned irq)
 {
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       struct davinci_gpio_regs __iomem *g = irq2regs(irq);
        u32 mask = (u32) get_irq_data(irq);
 
        __raw_writel(mask, &g->clr_falling);
@@ -170,7 +216,7 @@ static void gpio_irq_disable(unsigned irq)
 
 static void gpio_irq_enable(unsigned irq)
 {
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       struct davinci_gpio_regs __iomem *g = irq2regs(irq);
        u32 mask = (u32) get_irq_data(irq);
        unsigned status = irq_desc[irq].status;
 
@@ -186,7 +232,7 @@ static void gpio_irq_enable(unsigned irq)
 
 static int gpio_irq_type(unsigned irq, unsigned trigger)
 {
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       struct davinci_gpio_regs __iomem *g = irq2regs(irq);
        u32 mask = (u32) get_irq_data(irq);
 
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
@@ -215,7 +261,7 @@ static struct irq_chip gpio_irqchip = {
 static void
 gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       struct davinci_gpio_regs __iomem *g = irq2regs(irq);
        u32 mask = 0xffff;
 
        /* we only care about one bank */
@@ -253,7 +299,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 
 static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
 {
-       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+       struct davinci_gpio_controller *d = chip2controller(chip);
 
        if (d->irq_base >= 0)
                return d->irq_base + offset;
@@ -276,7 +322,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
 
 static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger)
 {
-       struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+       struct davinci_gpio_regs __iomem *g = irq2regs(irq);
        u32 mask = (u32) get_irq_data(irq);
 
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
@@ -305,7 +351,7 @@ static int __init davinci_gpio_irq_setup(void)
        u32             binten = 0;
        unsigned        ngpio, bank_irq;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
-       struct gpio_controller  *__iomem g;
+       struct davinci_gpio_regs        __iomem *g;
 
        ngpio = soc_info->gpio_num;
 
@@ -354,7 +400,7 @@ static int __init davinci_gpio_irq_setup(void)
                gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked;
 
                /* default trigger: both edges */
-               g = gpio2controller(0);
+               g = gpio2regs(0);
                __raw_writel(~0, &g->set_falling);
                __raw_writel(~0, &g->set_rising);
 
@@ -362,7 +408,7 @@ static int __init davinci_gpio_irq_setup(void)
                for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
                        set_irq_chip(irq, &gpio_irqchip_unbanked);
                        set_irq_data(irq, (void *) __gpio_mask(gpio));
-                       set_irq_chip_data(irq, g);
+                       set_irq_chip_data(irq, (__force void *) g);
                        irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH;
                }
 
@@ -379,18 +425,18 @@ static int __init davinci_gpio_irq_setup(void)
                unsigned                i;
 
                /* disabled by default, enabled only as needed */
-               g = gpio2controller(gpio);
+               g = gpio2regs(gpio);
                __raw_writel(~0, &g->clr_falling);
                __raw_writel(~0, &g->clr_rising);
 
                /* set up all irqs in this bank */
                set_irq_chained_handler(bank_irq, gpio_irq_handler);
-               set_irq_chip_data(bank_irq, g);
-               set_irq_data(bank_irq, (void *)irq);
+               set_irq_chip_data(bank_irq, (__force void *) g);
+               set_irq_data(bank_irq, (void *) irq);
 
                for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
                        set_irq_chip(irq, &gpio_irqchip);
-                       set_irq_chip_data(irq, g);
+                       set_irq_chip_data(irq, (__force void *) g);
                        set_irq_data(irq, (void *) __gpio_mask(gpio));
                        set_irq_handler(irq, handle_simple_irq);
                        set_irq_flags(irq, IRQF_VALID);
@@ -403,7 +449,7 @@ done:
        /* BINTEN -- per-bank interrupt enable. genirq would also let these
         * bits be set/cleared dynamically.
         */
-       __raw_writel(binten, soc_info->gpio_base + 0x08);
+       __raw_writel(binten, gpio_base + 0x08);
 
        printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
 
index 50a955f..a57cba2 100644 (file)
@@ -12,6 +12,9 @@
 #ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
 #define __ARCH_ARM_MACH_DAVINCI_COMMON_H
 
+#include <linux/compiler.h>
+#include <linux/types.h>
+
 struct sys_timer;
 
 extern struct sys_timer davinci_timer;
@@ -21,7 +24,7 @@ extern void __iomem *davinci_intc_base;
 extern int davinci_intc_type;
 
 struct davinci_timer_instance {
-       void __iomem    *base;
+       u32             base;
        u32             bottom_irq;
        u32             top_irq;
        unsigned long   cmp_off;
@@ -34,39 +37,54 @@ struct davinci_timer_info {
        unsigned int                    clocksource_id;
 };
 
-/* SoC specific init support */
+struct davinci_gpio_controller;
+
+/*
+ * SoC info passed into common davinci modules.
+ *
+ * Base addresses in this structure should be physical and not virtual.
+ * Modules that take such base addresses, should internally ioremap() them to
+ * use.
+ */
 struct davinci_soc_info {
        struct map_desc                 *io_desc;
        unsigned long                   io_desc_num;
        u32                             cpu_id;
        u32                             jtag_id;
-       void __iomem                    *jtag_id_base;
+       u32                             jtag_id_reg;
        struct davinci_id               *ids;
        unsigned long                   ids_num;
        struct clk_lookup               *cpu_clks;
-       void __iomem                    **psc_bases;
+       u32                             *psc_bases;
        unsigned long                   psc_bases_num;
-       void __iomem                    *pinmux_base;
+       u32                             pinmux_base;
        const struct mux_config         *pinmux_pins;
        unsigned long                   pinmux_pins_num;
-       void __iomem                    *intc_base;
+       u32                             intc_base;
        int                             intc_type;
        u8                              *intc_irq_prios;
        unsigned long                   intc_irq_num;
+       u32                             *intc_host_map;
        struct davinci_timer_info       *timer_info;
-       void __iomem                    *gpio_base;
+       int                             gpio_type;
+       u32                             gpio_base;
        unsigned                        gpio_num;
        unsigned                        gpio_irq;
        unsigned                        gpio_unbanked;
+       struct davinci_gpio_controller  *gpio_ctlrs;
+       int                             gpio_ctlrs_num;
        struct platform_device          *serial_dev;
        struct emac_platform_data       *emac_pdata;
        dma_addr_t                      sram_dma;
        unsigned                        sram_len;
+       struct platform_device          *reset_device;
+       void                            (*reset)(struct platform_device *);
 };
 
 extern struct davinci_soc_info davinci_soc_info;
 
 extern void davinci_common_init(struct davinci_soc_info *soc_info);
+extern void davinci_init_ide(void);
 
 /* standard place to map on-chip SRAMs; they *may* support DMA */
 #define SRAM_VIRT      0xfffe0000
index c4d27ee..4e8190e 100644 (file)
@@ -51,7 +51,6 @@
 #define CP_INTC_HOST_PRIO_VECTOR(n)    (0x1600 + (n << 2))
 #define CP_INTC_VECTOR_ADDR(n)         (0x2000 + (n << 2))
 
-void __init cp_intc_init(void __iomem *base, unsigned short num_irq,
-                        u8 *irq_prio);
+void __init cp_intc_init(void);
 
 #endif /* __ASM_HARDWARE_CP_INTC_H */
index 189b1ff..cea6b89 100644 (file)
@@ -33,6 +33,7 @@ struct davinci_id {
 #define        DAVINCI_CPU_ID_DM365            0x03650000
 #define        DAVINCI_CPU_ID_DA830            0x08300000
 #define        DAVINCI_CPU_ID_DA850            0x08500000
+#define        DAVINCI_CPU_ID_TNETV107X        0x0b8a0000
 
 #define IS_DAVINCI_CPU(type, id)                                       \
 static inline int is_davinci_ ##type(void)                             \
@@ -46,6 +47,7 @@ IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
 IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365)
 IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830)
 IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850)
+IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X)
 
 #ifdef CONFIG_ARCH_DAVINCI_DM644x
 #define cpu_is_davinci_dm644x() is_davinci_dm644x()
@@ -83,4 +85,10 @@ IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850)
 #define cpu_is_davinci_da850() 0
 #endif
 
+#ifdef CONFIG_ARCH_DAVINCI_TNETV107X
+#define cpu_is_davinci_tnetv107x() is_davinci_tnetv107x()
+#else
+#define cpu_is_davinci_tnetv107x() 0
+#endif
+
 #endif
index 03acfd3..1b31a9a 100644 (file)
@@ -64,27 +64,6 @@ extern void __iomem *da8xx_syscfg1_base;
 #define DA8XX_DDR2_CTL_BASE    0xb0000000
 #define DA8XX_ARM_RAM_BASE     0xffff0000
 
-#define PINMUX0                        0x00
-#define PINMUX1                        0x04
-#define PINMUX2                        0x08
-#define PINMUX3                        0x0c
-#define PINMUX4                        0x10
-#define PINMUX5                        0x14
-#define PINMUX6                        0x18
-#define PINMUX7                        0x1c
-#define PINMUX8                        0x20
-#define PINMUX9                        0x24
-#define PINMUX10               0x28
-#define PINMUX11               0x2c
-#define PINMUX12               0x30
-#define PINMUX13               0x34
-#define PINMUX14               0x38
-#define PINMUX15               0x3c
-#define PINMUX16               0x40
-#define PINMUX17               0x44
-#define PINMUX18               0x48
-#define PINMUX19               0x4c
-
 void __init da830_init(void);
 void __init da850_init(void);
 
@@ -108,6 +87,8 @@ extern struct emac_platform_data da8xx_emac_pdata;
 extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
 extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
 
+extern struct platform_device da8xx_wdt_device;
+
 extern const short da830_emif25_pins[];
 extern const short da830_spi0_pins[];
 extern const short da830_spi1_pins[];
@@ -146,10 +127,4 @@ extern const short da850_mmcsd0_pins[];
 extern const short da850_nand_pins[];
 extern const short da850_nor_pins[];
 
-#ifdef CONFIG_DAVINCI_MUX
-int da8xx_pinmux_setup(const short pins[]);
-#else
-static inline int da8xx_pinmux_setup(const short pins[]) { return 0; }
-#endif
-
 #endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
index 85536d8..36dff4a 100644 (file)
@@ -15,6 +15,9 @@
 #include <mach/asp.h>
 #include <media/davinci/vpfe_capture.h>
 
+#define DM355_ASYNC_EMIF_CONTROL_BASE  0x01E10000
+#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
 #define ASP1_TX_EVT_EN 1
 #define ASP1_RX_EVT_EN 2
 
index 3a37b5a..ea5df3b 100644 (file)
 #define DAVINCI_DMA_VC_TX              2
 #define DAVINCI_DMA_VC_RX              3
 
+#define DM365_ASYNC_EMIF_CONTROL_BASE  0x01D10000
+#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+
 void __init dm365_init(void);
 void __init dm365_init_asp(struct snd_platform_data *pdata);
 void __init dm365_init_vc(struct snd_platform_data *pdata);
index 1a8b09c..6fca568 100644 (file)
 #define DM644X_EMAC_MDIO_OFFSET                (0x4000)
 #define DM644X_EMAC_CNTRL_RAM_SIZE     (0x2000)
 
+#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000
+#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
+#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
+
 void __init dm644x_init(void);
 void __init dm644x_init_asp(struct snd_platform_data *pdata);
 void dm644x_set_vpfe_config(struct vpfe_config *cfg);
index 846da98..add6f79 100644 (file)
 #define DM646X_EMAC_MDIO_OFFSET                (0x4000)
 #define DM646X_EMAC_CNTRL_RAM_SIZE     (0x2000)
 
-#define DM646X_ATA_REG_BASE            (0x01C66000)
+#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
+#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
 
 void __init dm646x_init(void);
-void __init dm646x_init_ide(void);
 void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
 void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
 void __init dm646x_board_setup_refclk(struct clk *clk);
index f3b8ef8..504cc18 100644 (file)
@@ -14,6 +14,8 @@
 #define        __DAVINCI_GPIO_H
 
 #include <linux/io.h>
+#include <linux/spinlock.h>
+
 #include <asm-generic/gpio.h>
 
 #include <mach/irqs.h>
 
 #define DAVINCI_GPIO_BASE 0x01C67000
 
+enum davinci_gpio_type {
+       GPIO_TYPE_DAVINCI = 0,
+};
+
 /*
  * basic gpio routines
  *
 /* Convert GPIO signal to GPIO pin number */
 #define GPIO_TO_PIN(bank, gpio)        (16 * (bank) + (gpio))
 
-struct gpio_controller {
-       u32     dir;
-       u32     out_data;
-       u32     set_data;
-       u32     clr_data;
-       u32     in_data;
-       u32     set_rising;
-       u32     clr_rising;
-       u32     set_falling;
-       u32     clr_falling;
-       u32     intstat;
+struct davinci_gpio_controller {
+       struct gpio_chip        chip;
+       int                     irq_base;
+       spinlock_t              lock;
+       void __iomem            *regs;
+       void __iomem            *set_data;
+       void __iomem            *clr_data;
+       void __iomem            *in_data;
 };
 
 /* The __gpio_to_controller() and __gpio_mask() functions inline to constants
@@ -67,25 +70,16 @@ struct gpio_controller {
  *
  * These are NOT part of the cross-platform GPIO interface
  */
-static inline struct gpio_controller *__iomem
+static inline struct davinci_gpio_controller *
 __gpio_to_controller(unsigned gpio)
 {
-       void *__iomem ptr;
-       void __iomem *base = davinci_soc_info.gpio_base;
-
-       if (gpio < 32 * 1)
-               ptr = base + 0x10;
-       else if (gpio < 32 * 2)
-               ptr = base + 0x38;
-       else if (gpio < 32 * 3)
-               ptr = base + 0x60;
-       else if (gpio < 32 * 4)
-               ptr = base + 0x88;
-       else if (gpio < 32 * 5)
-               ptr = base + 0xb0;
-       else
-               ptr = NULL;
-       return ptr;
+       struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
+       int index = gpio / 32;
+
+       if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
+               return NULL;
+
+       return ctlrs + index;
 }
 
 static inline u32 __gpio_mask(unsigned gpio)
@@ -101,16 +95,16 @@ static inline u32 __gpio_mask(unsigned gpio)
  */
 static inline void gpio_set_value(unsigned gpio, int value)
 {
-       if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) {
-               struct gpio_controller  *__iomem g;
-               u32                     mask;
+       if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) {
+               struct davinci_gpio_controller *ctlr;
+               u32                             mask;
 
-               g = __gpio_to_controller(gpio);
+               ctlr = __gpio_to_controller(gpio);
                mask = __gpio_mask(gpio);
                if (value)
-                       __raw_writel(mask, &g->set_data);
+                       __raw_writel(mask, ctlr->set_data);
                else
-                       __raw_writel(mask, &g->clr_data);
+                       __raw_writel(mask, ctlr->clr_data);
                return;
        }
 
@@ -128,18 +122,18 @@ static inline void gpio_set_value(unsigned gpio, int value)
  */
 static inline int gpio_get_value(unsigned gpio)
 {
-       struct gpio_controller  *__iomem g;
+       struct davinci_gpio_controller *ctlr;
 
-       if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO)
+       if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num)
                return __gpio_get_value(gpio);
 
-       g = __gpio_to_controller(gpio);
-       return __gpio_mask(gpio) & __raw_readl(&g->in_data);
+       ctlr = __gpio_to_controller(gpio);
+       return __gpio_mask(gpio) & __raw_readl(ctlr->in_data);
 }
 
 static inline int gpio_cansleep(unsigned gpio)
 {
-       if (__builtin_constant_p(gpio) && gpio < DAVINCI_N_GPIO)
+       if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num)
                return 0;
        else
                return __gpio_cansleep(gpio);
index 354af71..ec76c77 100644 (file)
 
 #define DA850_N_CP_INTC_IRQ            101
 
+
+/* TNETV107X specific interrupts */
+#define IRQ_TNETV107X_TDM1_TXDMA               0
+#define IRQ_TNETV107X_EXT_INT_0                        1
+#define IRQ_TNETV107X_EXT_INT_1                        2
+#define IRQ_TNETV107X_GPIO_INT12               3
+#define IRQ_TNETV107X_GPIO_INT13               4
+#define IRQ_TNETV107X_TIMER_0_TINT12           5
+#define IRQ_TNETV107X_TIMER_1_TINT12           6
+#define IRQ_TNETV107X_UART0                    7
+#define IRQ_TNETV107X_TDM1_RXDMA               8
+#define IRQ_TNETV107X_MCDMA_INT0               9
+#define IRQ_TNETV107X_MCDMA_INT1               10
+#define IRQ_TNETV107X_TPCC                     11
+#define IRQ_TNETV107X_TPCC_INT0                        12
+#define IRQ_TNETV107X_TPCC_INT1                        13
+#define IRQ_TNETV107X_TPCC_INT2                        14
+#define IRQ_TNETV107X_TPCC_INT3                        15
+#define IRQ_TNETV107X_TPTC0                    16
+#define IRQ_TNETV107X_TPTC1                    17
+#define IRQ_TNETV107X_TIMER_0_TINT34           18
+#define IRQ_TNETV107X_ETHSS                    19
+#define IRQ_TNETV107X_TIMER_1_TINT34           20
+#define IRQ_TNETV107X_DSP2ARM_INT0             21
+#define IRQ_TNETV107X_DSP2ARM_INT1             22
+#define IRQ_TNETV107X_ARM_NPMUIRQ              23
+#define IRQ_TNETV107X_USB1                     24
+#define IRQ_TNETV107X_VLYNQ                    25
+#define IRQ_TNETV107X_UART0_DMATX              26
+#define IRQ_TNETV107X_UART0_DMARX              27
+#define IRQ_TNETV107X_TDM1_TXMCSP              28
+#define IRQ_TNETV107X_SSP                      29
+#define IRQ_TNETV107X_MCDMA_INT2               30
+#define IRQ_TNETV107X_MCDMA_INT3               31
+#define IRQ_TNETV107X_TDM_CODECIF_EOT          32
+#define IRQ_TNETV107X_IMCOP_SQR_ARM            33
+#define IRQ_TNETV107X_USB0                     34
+#define IRQ_TNETV107X_USB_CDMA                 35
+#define IRQ_TNETV107X_LCD                      36
+#define IRQ_TNETV107X_KEYPAD                   37
+#define IRQ_TNETV107X_KEYPAD_FREE              38
+#define IRQ_TNETV107X_RNG                      39
+#define IRQ_TNETV107X_PKA                      40
+#define IRQ_TNETV107X_TDM0_TXDMA               41
+#define IRQ_TNETV107X_TDM0_RXDMA               42
+#define IRQ_TNETV107X_TDM0_TXMCSP              43
+#define IRQ_TNETV107X_TDM0_RXMCSP              44
+#define IRQ_TNETV107X_TDM1_RXMCSP              45
+#define IRQ_TNETV107X_SDIO1                    46
+#define IRQ_TNETV107X_SDIO0                    47
+#define IRQ_TNETV107X_TSC                      48
+#define IRQ_TNETV107X_TS                       49
+#define IRQ_TNETV107X_UART1                    50
+#define IRQ_TNETV107X_MBX_LITE                 51
+#define IRQ_TNETV107X_GPIO_INT00               52
+#define IRQ_TNETV107X_GPIO_INT01               53
+#define IRQ_TNETV107X_GPIO_INT02               54
+#define IRQ_TNETV107X_GPIO_INT03               55
+#define IRQ_TNETV107X_UART2                    56
+#define IRQ_TNETV107X_UART2_DMATX              57
+#define IRQ_TNETV107X_UART2_DMARX              58
+#define IRQ_TNETV107X_IMCOP_IMX                        59
+#define IRQ_TNETV107X_IMCOP_VLCD               60
+#define IRQ_TNETV107X_AES                      61
+#define IRQ_TNETV107X_DES                      62
+#define IRQ_TNETV107X_SHAMD5                   63
+#define IRQ_TNETV107X_TPCC_ERR                 68
+#define IRQ_TNETV107X_TPCC_PROT                        69
+#define IRQ_TNETV107X_TPTC0_ERR                        70
+#define IRQ_TNETV107X_TPTC1_ERR                        71
+#define IRQ_TNETV107X_UART0_ERR                        72
+#define IRQ_TNETV107X_UART1_ERR                        73
+#define IRQ_TNETV107X_AEMIF_ERR                        74
+#define IRQ_TNETV107X_DDR_ERR                  75
+#define IRQ_TNETV107X_WDTARM_INT0              76
+#define IRQ_TNETV107X_MCDMA_ERR                        77
+#define IRQ_TNETV107X_GPIO_ERR                 78
+#define IRQ_TNETV107X_MPU_ADDR                 79
+#define IRQ_TNETV107X_MPU_PROT                 80
+#define IRQ_TNETV107X_IOPU_ADDR                        81
+#define IRQ_TNETV107X_IOPU_PROT                        82
+#define IRQ_TNETV107X_KEYPAD_ADDR_ERR          83
+#define IRQ_TNETV107X_WDT0_ADDR_ERR            84
+#define IRQ_TNETV107X_WDT1_ADDR_ERR            85
+#define IRQ_TNETV107X_CLKCTL_ADDR_ERR          86
+#define IRQ_TNETV107X_PLL_UNLOCK               87
+#define IRQ_TNETV107X_WDTDSP_INT0              88
+#define IRQ_TNETV107X_SEC_CTRL_VIOLATION       89
+#define IRQ_TNETV107X_KEY_MNG_VIOLATION                90
+#define IRQ_TNETV107X_PBIST_CPU                        91
+#define IRQ_TNETV107X_WDTARM                   92
+#define IRQ_TNETV107X_PSC                      93
+#define IRQ_TNETV107X_MMC0                     94
+#define IRQ_TNETV107X_MMC1                     95
+
+#define TNETV107X_N_CP_INTC_IRQ                        96
+
 /* da850 currently has the most gpio pins (144) */
 #define DAVINCI_N_GPIO                 144
 /* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */
index 2a68c1d..de11aac 100644 (file)
@@ -194,11 +194,14 @@ enum davinci_dm365_index {
        DM365_I2C_SCL,
 
        /* AEMIF */
-       DM365_AEMIF_AR,
+       DM365_AEMIF_AR_A14,
+       DM365_AEMIF_AR_BA0,
        DM365_AEMIF_A3,
        DM365_AEMIF_A7,
        DM365_AEMIF_D15_8,
        DM365_AEMIF_CE0,
+       DM365_AEMIF_CE1,
+       DM365_AEMIF_WE_OE,
 
        /* ASP0 function */
        DM365_MCBSP0_BDX,
@@ -287,10 +290,19 @@ enum davinci_dm365_index {
        DM365_SPI4_SDENA0,
        DM365_SPI4_SDENA1,
 
+       /* Clock */
+       DM365_CLKOUT0,
+       DM365_CLKOUT1,
+       DM365_CLKOUT2,
+
        /* GPIO */
        DM365_GPIO20,
+       DM365_GPIO30,
+       DM365_GPIO31,
+       DM365_GPIO32,
        DM365_GPIO33,
        DM365_GPIO40,
+       DM365_GPIO64_57,
 
        /* Video */
        DM365_VOUT_FIELD,
@@ -904,12 +916,288 @@ enum davinci_da850_index {
        DA850_RTC_ALARM,
 };
 
+enum davinci_tnetv107x_index {
+       TNETV107X_ASR_A00,
+       TNETV107X_GPIO32,
+       TNETV107X_ASR_A01,
+       TNETV107X_GPIO33,
+       TNETV107X_ASR_A02,
+       TNETV107X_GPIO34,
+       TNETV107X_ASR_A03,
+       TNETV107X_GPIO35,
+       TNETV107X_ASR_A04,
+       TNETV107X_GPIO36,
+       TNETV107X_ASR_A05,
+       TNETV107X_GPIO37,
+       TNETV107X_ASR_A06,
+       TNETV107X_GPIO38,
+       TNETV107X_ASR_A07,
+       TNETV107X_GPIO39,
+       TNETV107X_ASR_A08,
+       TNETV107X_GPIO40,
+       TNETV107X_ASR_A09,
+       TNETV107X_GPIO41,
+       TNETV107X_ASR_A10,
+       TNETV107X_GPIO42,
+       TNETV107X_ASR_A11,
+       TNETV107X_BOOT_STRP_0,
+       TNETV107X_ASR_A12,
+       TNETV107X_BOOT_STRP_1,
+       TNETV107X_ASR_A13,
+       TNETV107X_GPIO43,
+       TNETV107X_ASR_A14,
+       TNETV107X_GPIO44,
+       TNETV107X_ASR_A15,
+       TNETV107X_GPIO45,
+       TNETV107X_ASR_A16,
+       TNETV107X_GPIO46,
+       TNETV107X_ASR_A17,
+       TNETV107X_GPIO47,
+       TNETV107X_ASR_A18,
+       TNETV107X_GPIO48,
+       TNETV107X_SDIO1_DATA3_0,
+       TNETV107X_ASR_A19,
+       TNETV107X_GPIO49,
+       TNETV107X_SDIO1_DATA2_0,
+       TNETV107X_ASR_A20,
+       TNETV107X_GPIO50,
+       TNETV107X_SDIO1_DATA1_0,
+       TNETV107X_ASR_A21,
+       TNETV107X_GPIO51,
+       TNETV107X_SDIO1_DATA0_0,
+       TNETV107X_ASR_A22,
+       TNETV107X_GPIO52,
+       TNETV107X_SDIO1_CMD_0,
+       TNETV107X_ASR_A23,
+       TNETV107X_GPIO53,
+       TNETV107X_SDIO1_CLK_0,
+       TNETV107X_ASR_BA_1,
+       TNETV107X_GPIO54,
+       TNETV107X_SYS_PLL_CLK,
+       TNETV107X_ASR_CS0,
+       TNETV107X_ASR_CS1,
+       TNETV107X_ASR_CS2,
+       TNETV107X_TDM_PLL_CLK,
+       TNETV107X_ASR_CS3,
+       TNETV107X_ETH_PHY_CLK,
+       TNETV107X_ASR_D00,
+       TNETV107X_GPIO55,
+       TNETV107X_ASR_D01,
+       TNETV107X_GPIO56,
+       TNETV107X_ASR_D02,
+       TNETV107X_GPIO57,
+       TNETV107X_ASR_D03,
+       TNETV107X_GPIO58,
+       TNETV107X_ASR_D04,
+       TNETV107X_GPIO59_0,
+       TNETV107X_ASR_D05,
+       TNETV107X_GPIO60_0,
+       TNETV107X_ASR_D06,
+       TNETV107X_GPIO61_0,
+       TNETV107X_ASR_D07,
+       TNETV107X_GPIO62_0,
+       TNETV107X_ASR_D08,
+       TNETV107X_GPIO63_0,
+       TNETV107X_ASR_D09,
+       TNETV107X_GPIO64_0,
+       TNETV107X_ASR_D10,
+       TNETV107X_SDIO1_DATA3_1,
+       TNETV107X_ASR_D11,
+       TNETV107X_SDIO1_DATA2_1,
+       TNETV107X_ASR_D12,
+       TNETV107X_SDIO1_DATA1_1,
+       TNETV107X_ASR_D13,
+       TNETV107X_SDIO1_DATA0_1,
+       TNETV107X_ASR_D14,
+       TNETV107X_SDIO1_CMD_1,
+       TNETV107X_ASR_D15,
+       TNETV107X_SDIO1_CLK_1,
+       TNETV107X_ASR_OE,
+       TNETV107X_BOOT_STRP_2,
+       TNETV107X_ASR_RNW,
+       TNETV107X_GPIO29_0,
+       TNETV107X_ASR_WAIT,
+       TNETV107X_GPIO30_0,
+       TNETV107X_ASR_WE,
+       TNETV107X_BOOT_STRP_3,
+       TNETV107X_ASR_WE_DQM0,
+       TNETV107X_GPIO31,
+       TNETV107X_LCD_PD17_0,
+       TNETV107X_ASR_WE_DQM1,
+       TNETV107X_ASR_BA0_0,
+       TNETV107X_VLYNQ_CLK,
+       TNETV107X_GPIO14,
+       TNETV107X_LCD_PD19_0,
+       TNETV107X_VLYNQ_RXD0,
+       TNETV107X_GPIO15,
+       TNETV107X_LCD_PD20_0,
+       TNETV107X_VLYNQ_RXD1,
+       TNETV107X_GPIO16,
+       TNETV107X_LCD_PD21_0,
+       TNETV107X_VLYNQ_TXD0,
+       TNETV107X_GPIO17,
+       TNETV107X_LCD_PD22_0,
+       TNETV107X_VLYNQ_TXD1,
+       TNETV107X_GPIO18,
+       TNETV107X_LCD_PD23_0,
+       TNETV107X_SDIO0_CLK,
+       TNETV107X_GPIO19,
+       TNETV107X_SDIO0_CMD,
+       TNETV107X_GPIO20,
+       TNETV107X_SDIO0_DATA0,
+       TNETV107X_GPIO21,
+       TNETV107X_SDIO0_DATA1,
+       TNETV107X_GPIO22,
+       TNETV107X_SDIO0_DATA2,
+       TNETV107X_GPIO23,
+       TNETV107X_SDIO0_DATA3,
+       TNETV107X_GPIO24,
+       TNETV107X_EMU0,
+       TNETV107X_EMU1,
+       TNETV107X_RTCK,
+       TNETV107X_TRST_N,
+       TNETV107X_TCK,
+       TNETV107X_TDI,
+       TNETV107X_TDO,
+       TNETV107X_TMS,
+       TNETV107X_TDM1_CLK,
+       TNETV107X_TDM1_RX,
+       TNETV107X_TDM1_TX,
+       TNETV107X_TDM1_FS,
+       TNETV107X_KEYPAD_R0,
+       TNETV107X_KEYPAD_R1,
+       TNETV107X_KEYPAD_R2,
+       TNETV107X_KEYPAD_R3,
+       TNETV107X_KEYPAD_R4,
+       TNETV107X_KEYPAD_R5,
+       TNETV107X_KEYPAD_R6,
+       TNETV107X_GPIO12,
+       TNETV107X_KEYPAD_R7,
+       TNETV107X_GPIO10,
+       TNETV107X_KEYPAD_C0,
+       TNETV107X_KEYPAD_C1,
+       TNETV107X_KEYPAD_C2,
+       TNETV107X_KEYPAD_C3,
+       TNETV107X_KEYPAD_C4,
+       TNETV107X_KEYPAD_C5,
+       TNETV107X_KEYPAD_C6,
+       TNETV107X_GPIO13,
+       TNETV107X_TEST_CLK_IN,
+       TNETV107X_KEYPAD_C7,
+       TNETV107X_GPIO11,
+       TNETV107X_SSP0_0,
+       TNETV107X_SCC_DCLK,
+       TNETV107X_LCD_PD20_1,
+       TNETV107X_SSP0_1,
+       TNETV107X_SCC_CS_N,
+       TNETV107X_LCD_PD21_1,
+       TNETV107X_SSP0_2,
+       TNETV107X_SCC_D,
+       TNETV107X_LCD_PD22_1,
+       TNETV107X_SSP0_3,
+       TNETV107X_SCC_RESETN,
+       TNETV107X_LCD_PD23_1,
+       TNETV107X_SSP1_0,
+       TNETV107X_GPIO25,
+       TNETV107X_UART2_CTS,
+       TNETV107X_SSP1_1,
+       TNETV107X_GPIO26,
+       TNETV107X_UART2_RD,
+       TNETV107X_SSP1_2,
+       TNETV107X_GPIO27,
+       TNETV107X_UART2_RTS,
+       TNETV107X_SSP1_3,
+       TNETV107X_GPIO28,
+       TNETV107X_UART2_TD,
+       TNETV107X_UART0_CTS,
+       TNETV107X_UART0_RD,
+       TNETV107X_UART0_RTS,
+       TNETV107X_UART0_TD,
+       TNETV107X_UART1_RD,
+       TNETV107X_UART1_TD,
+       TNETV107X_LCD_AC_NCS,
+       TNETV107X_LCD_HSYNC_RNW,
+       TNETV107X_LCD_VSYNC_A0,
+       TNETV107X_LCD_MCLK,
+       TNETV107X_LCD_PD16_0,
+       TNETV107X_LCD_PCLK_E,
+       TNETV107X_LCD_PD00,
+       TNETV107X_LCD_PD01,
+       TNETV107X_LCD_PD02,
+       TNETV107X_LCD_PD03,
+       TNETV107X_LCD_PD04,
+       TNETV107X_LCD_PD05,
+       TNETV107X_LCD_PD06,
+       TNETV107X_LCD_PD07,
+       TNETV107X_LCD_PD08,
+       TNETV107X_GPIO59_1,
+       TNETV107X_LCD_PD09,
+       TNETV107X_GPIO60_1,
+       TNETV107X_LCD_PD10,
+       TNETV107X_ASR_BA0_1,
+       TNETV107X_GPIO61_1,
+       TNETV107X_LCD_PD11,
+       TNETV107X_GPIO62_1,
+       TNETV107X_LCD_PD12,
+       TNETV107X_GPIO63_1,
+       TNETV107X_LCD_PD13,
+       TNETV107X_GPIO64_1,
+       TNETV107X_LCD_PD14,
+       TNETV107X_GPIO29_1,
+       TNETV107X_LCD_PD15,
+       TNETV107X_GPIO30_1,
+       TNETV107X_EINT0,
+       TNETV107X_GPIO08,
+       TNETV107X_EINT1,
+       TNETV107X_GPIO09,
+       TNETV107X_GPIO00,
+       TNETV107X_LCD_PD20_2,
+       TNETV107X_TDM_CLK_IN_2,
+       TNETV107X_GPIO01,
+       TNETV107X_LCD_PD21_2,
+       TNETV107X_24M_CLK_OUT_1,
+       TNETV107X_GPIO02,
+       TNETV107X_LCD_PD22_2,
+       TNETV107X_GPIO03,
+       TNETV107X_LCD_PD23_2,
+       TNETV107X_GPIO04,
+       TNETV107X_LCD_PD16_1,
+       TNETV107X_USB0_RXERR,
+       TNETV107X_GPIO05,
+       TNETV107X_LCD_PD17_1,
+       TNETV107X_TDM_CLK_IN_1,
+       TNETV107X_GPIO06,
+       TNETV107X_LCD_PD18,
+       TNETV107X_24M_CLK_OUT_2,
+       TNETV107X_GPIO07,
+       TNETV107X_LCD_PD19_1,
+       TNETV107X_USB1_RXERR,
+       TNETV107X_ETH_PLL_CLK,
+       TNETV107X_MDIO,
+       TNETV107X_MDC,
+       TNETV107X_AIC_MUTE_STAT_N,
+       TNETV107X_TDM0_CLK,
+       TNETV107X_AIC_HNS_EN_N,
+       TNETV107X_TDM0_FS,
+       TNETV107X_AIC_HDS_EN_STAT_N,
+       TNETV107X_TDM0_TX,
+       TNETV107X_AIC_HNF_EN_STAT_N,
+       TNETV107X_TDM0_RX,
+};
+
+#define PINMUX(x)              (4 * (x))
+
 #ifdef CONFIG_DAVINCI_MUX
 /* setup pin muxing */
 extern int davinci_cfg_reg(unsigned long reg_cfg);
+extern int davinci_cfg_reg_list(const short pins[]);
 #else
 /* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
 static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
+static inline int davinci_cfg_reg_list(const short pins[])
+{
+       return 0;
+}
 #endif
 
 #endif /* __INC_MACH_MUX_H */
index 651f6d8..983da6e 100644 (file)
 #define DA8XX_LPSC1_CR_P3_SS           26
 #define DA8XX_LPSC1_L3_CBA_RAM         31
 
+/* TNETV107X LPSC Assignments */
+#define TNETV107X_LPSC_ARM                     0
+#define TNETV107X_LPSC_GEM                     1
+#define TNETV107X_LPSC_DDR2_PHY                        2
+#define TNETV107X_LPSC_TPCC                    3
+#define TNETV107X_LPSC_TPTC0                   4
+#define TNETV107X_LPSC_TPTC1                   5
+#define TNETV107X_LPSC_RAM                     6
+#define TNETV107X_LPSC_MBX_LITE                        7
+#define TNETV107X_LPSC_LCD                     8
+#define TNETV107X_LPSC_ETHSS                   9
+#define TNETV107X_LPSC_AEMIF                   10
+#define TNETV107X_LPSC_CHIP_CFG                        11
+#define TNETV107X_LPSC_TSC                     12
+#define TNETV107X_LPSC_ROM                     13
+#define TNETV107X_LPSC_UART2                   14
+#define TNETV107X_LPSC_PKTSEC                  15
+#define TNETV107X_LPSC_SECCTL                  16
+#define TNETV107X_LPSC_KEYMGR                  17
+#define TNETV107X_LPSC_KEYPAD                  18
+#define TNETV107X_LPSC_GPIO                    19
+#define TNETV107X_LPSC_MDIO                    20
+#define TNETV107X_LPSC_SDIO0                   21
+#define TNETV107X_LPSC_UART0                   22
+#define TNETV107X_LPSC_UART1                   23
+#define TNETV107X_LPSC_TIMER0                  24
+#define TNETV107X_LPSC_TIMER1                  25
+#define TNETV107X_LPSC_WDT_ARM                 26
+#define TNETV107X_LPSC_WDT_DSP                 27
+#define TNETV107X_LPSC_SSP                     28
+#define TNETV107X_LPSC_TDM0                    29
+#define TNETV107X_LPSC_VLYNQ                   30
+#define TNETV107X_LPSC_MCDMA                   31
+#define TNETV107X_LPSC_USB0                    32
+#define TNETV107X_LPSC_TDM1                    33
+#define TNETV107X_LPSC_DEBUGSS                 34
+#define TNETV107X_LPSC_ETHSS_RGMII             35
+#define TNETV107X_LPSC_SYSTEM                  36
+#define TNETV107X_LPSC_IMCOP                   37
+#define TNETV107X_LPSC_SPARE                   38
+#define TNETV107X_LPSC_SDIO1                   39
+#define TNETV107X_LPSC_USB1                    40
+#define TNETV107X_LPSC_USBSS                   41
+#define TNETV107X_LPSC_DDR2_EMIF1_VRST         42
+#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST     43
+#define TNETV107X_LPSC_MAX                     44
+
 /* PSC register offsets */
 #define EPCPR          0x070
 #define PTCMD          0x120
 #define MDSTAT         0x800
 #define MDCTL          0xA00
 
+/* PSC module states */
+#define PSC_STATE_SWRSTDISABLE 0
+#define PSC_STATE_SYNCRST      1
+#define PSC_STATE_DISABLE      2
+#define PSC_STATE_ENABLE       3
+
 #define MDSTAT_STATE_MASK 0x1f
 
 #ifndef __ASSEMBLER__
 
 extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
 extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, char enable);
+               unsigned int id, u32 next_state);
 
 #endif
 
index a584697..f6c4f34 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <mach/hardware.h>
 
-#define DAVINCI_MAX_NR_UARTS   3
 #define DAVINCI_UART0_BASE     (IO_PHYS + 0x20000)
 #define DAVINCI_UART1_BASE     (IO_PHYS + 0x20400)
 #define DAVINCI_UART2_BASE     (IO_PHYS + 0x20800)
index 5a7d758..e65629c 100644 (file)
@@ -11,7 +11,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-extern void davinci_watchdog_reset(void);
+#include <mach/common.h>
 
 static inline void arch_idle(void)
 {
@@ -20,7 +20,8 @@ static inline void arch_idle(void)
 
 static inline void arch_reset(char mode, const char *cmd)
 {
-       davinci_watchdog_reset();
+       if (davinci_soc_info.reset)
+               davinci_soc_info.reset(davinci_soc_info.reset_device);
 }
 
 #endif /* __ASM_ARCH_SYSTEM_H */
index a1c0b6b..8ea60a8 100644 (file)
 #include <linux/io.h>
 
 #include <asm/tlb.h>
+#include <asm/mach/map.h>
 
-#define BETWEEN(p, st, sz)     ((p) >= (st) && (p) < ((st) + (sz)))
-#define XLATE(p, pst, vst)     ((void __iomem *)((p) - (pst) + (vst)))
+#include <mach/common.h>
 
 /*
  * Intercept ioremap() requests for addresses in our fixed mapping regions.
  */
 void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
 {
-       if (BETWEEN(p, IO_PHYS, IO_SIZE))
-               return XLATE(p, IO_PHYS, IO_VIRT);
+       struct map_desc *desc = davinci_soc_info.io_desc;
+       int desc_num = davinci_soc_info.io_desc_num;
+       int i;
 
-       return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
+       for (i = 0; i < desc_num; i++, desc++) {
+               unsigned long iophys = __pfn_to_phys(desc->pfn);
+               unsigned long iosize = desc->length;
+
+               if (p >= iophys && (p + size) <= (iophys + iosize))
+                       return __io(desc->virtual + p - iophys);
+       }
+
+       return __arm_ioremap_caller(p, size, type,
+                                       __builtin_return_address(0));
 }
 EXPORT_SYMBOL(davinci_ioremap);
 
index af92ffe..784ddf3 100644 (file)
@@ -116,6 +116,11 @@ void __init davinci_irq_init(void)
        unsigned i;
        const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios;
 
+       davinci_intc_type = DAVINCI_INTC_TYPE_AINTC;
+       davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_4K);
+       if (WARN_ON(!davinci_intc_base))
+               return;
+
        /* Clear all interrupt requests */
        davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
        davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
@@ -148,7 +153,7 @@ void __init davinci_irq_init(void)
        }
 
        /* set up genirq dispatch for ARM INTC */
-       for (i = 0; i < DAVINCI_N_AINTC_IRQ; i++) {
+       for (i = 0; i < davinci_soc_info.intc_irq_num; i++) {
                set_irq_chip(i, &davinci_irq_chip_0);
                set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
                if (i != IRQ_TINT1_TINT34)
index f757e83..f34a8dc 100644 (file)
@@ -22,6 +22,8 @@
 #include <mach/mux.h>
 #include <mach/common.h>
 
+static void __iomem *pinmux_base;
+
 /*
  * Sets the DAVINCI MUX register based on the table
  */
@@ -29,14 +31,19 @@ int __init_or_module davinci_cfg_reg(const unsigned long index)
 {
        static DEFINE_SPINLOCK(mux_spin_lock);
        struct davinci_soc_info *soc_info = &davinci_soc_info;
-       void __iomem *base = soc_info->pinmux_base;
        unsigned long flags;
        const struct mux_config *cfg;
        unsigned int reg_orig = 0, reg = 0;
        unsigned int mask, warn = 0;
 
-       if (!soc_info->pinmux_pins)
-               BUG();
+       if (WARN_ON(!soc_info->pinmux_pins))
+               return -ENODEV;
+
+       if (!pinmux_base) {
+               pinmux_base = ioremap(soc_info->pinmux_base, SZ_4K);
+               if (WARN_ON(!pinmux_base))
+                       return -ENOMEM;
+       }
 
        if (index >= soc_info->pinmux_pins_num) {
                printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
@@ -57,7 +64,7 @@ int __init_or_module davinci_cfg_reg(const unsigned long index)
                unsigned        tmp1, tmp2;
 
                spin_lock_irqsave(&mux_spin_lock, flags);
-               reg_orig = __raw_readl(base + cfg->mux_reg);
+               reg_orig = __raw_readl(pinmux_base + cfg->mux_reg);
 
                mask = (cfg->mask << cfg->mask_offset);
                tmp1 = reg_orig & mask;
@@ -69,7 +76,7 @@ int __init_or_module davinci_cfg_reg(const unsigned long index)
                if (tmp1 != tmp2)
                        warn = 1;
 
-               __raw_writel(reg, base + cfg->mux_reg);
+               __raw_writel(reg, pinmux_base + cfg->mux_reg);
                spin_unlock_irqrestore(&mux_spin_lock, flags);
        }
 
@@ -91,7 +98,7 @@ int __init_or_module davinci_cfg_reg(const unsigned long index)
 }
 EXPORT_SYMBOL(davinci_cfg_reg);
 
-int da8xx_pinmux_setup(const short pins[])
+int __init_or_module davinci_cfg_reg_list(const short pins[])
 {
        int i, error = -EINVAL;
 
index adc8694..5aad1e7 100644 (file)
@@ -20,7 +20,7 @@
                        .name =  #desc,                                 \
                        .debug = dbg,                                   \
                        .mux_reg_name = "PINMUX"#muxreg,                \
-                       .mux_reg = PINMUX##muxreg,                      \
+                       .mux_reg = PINMUX(muxreg),                      \
                        .mask_offset = mode_offset,                     \
                        .mask = mode_mask,                              \
                        .mode = mux_mode,                               \
index adf6b5c..1b15dbd 100644 (file)
@@ -38,8 +38,9 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
                return 0;
        }
 
-       psc_base = soc_info->psc_bases[ctlr];
+       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
        mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+       iounmap(psc_base);
 
        /* if clocked, state can be "Enable" or "SyncReset" */
        return mdstat & BIT(12);
@@ -47,12 +48,11 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
 
 /* Enable or disable a PSC domain */
 void davinci_psc_config(unsigned int domain, unsigned int ctlr,
-               unsigned int id, char enable)
+               unsigned int id, u32 next_state)
 {
        u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
        void __iomem *psc_base;
        struct davinci_soc_info *soc_info = &davinci_soc_info;
-       u32 next_state = enable ? 0x3 : 0x2; /* 0x3 enables, 0x2 disables */
 
        if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
                pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
@@ -60,7 +60,7 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
                return;
        }
 
-       psc_base = soc_info->psc_bases[ctlr];
+       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
 
        mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
        mdctl &= ~MDSTAT_STATE_MASK;
@@ -100,4 +100,6 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr,
        do {
                mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
        } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+
+       iounmap(psc_base);
 }
index 7ce5ba0..1875740 100644 (file)
@@ -35,14 +35,20 @@ static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
                                           int offset)
 {
        offset <<= up->regshift;
-       return (unsigned int)__raw_readl(IO_ADDRESS(up->mapbase) + offset);
+
+       WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset);
+
+       return (unsigned int)__raw_readl(up->membase + offset);
 }
 
 static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
                                    int value)
 {
        offset <<= p->regshift;
-       __raw_writel(value, IO_ADDRESS(p->mapbase) + offset);
+
+       WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
+
+       __raw_writel(value, p->membase + offset);
 }
 
 static void __init davinci_serial_reset(struct plat_serial8250_port *p)
@@ -77,20 +83,32 @@ int __init davinci_serial_init(struct davinci_uart_config *info)
         * Make sure the serial ports are muxed on at this point.
         * You have to mux them off in device drivers later on if not needed.
         */
-       for (i = 0; i < DAVINCI_MAX_NR_UARTS; i++, p++) {
+       for (i = 0; p->flags; i++, p++) {
                if (!(info->enabled_uarts & (1 << i)))
                        continue;
 
                sprintf(name, "uart%d", i);
                uart_clk = clk_get(dev, name);
-               if (IS_ERR(uart_clk))
+               if (IS_ERR(uart_clk)) {
                        printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
                                        __func__, __LINE__, i);
-               else {
-                       clk_enable(uart_clk);
-                       p->uartclk = clk_get_rate(uart_clk);
-                       davinci_serial_reset(p);
+                       continue;
                }
+
+               clk_enable(uart_clk);
+               p->uartclk = clk_get_rate(uart_clk);
+
+               if (!p->membase && p->mapbase) {
+                       p->membase = ioremap(p->mapbase, SZ_4K);
+
+                       if (p->membase)
+                               p->flags &= ~UPF_IOREMAP;
+                       else
+                               pr_err("uart regs ioremap failed\n");
+               }
+
+               if (p->membase && p->type != PORT_AR7)
+                       davinci_serial_reset(p);
        }
 
        return platform_device_register(soc_info->serial_dev);
index 9e0b106..0f21c36 100644 (file)
@@ -197,32 +197,36 @@ static void __init timer_init(void)
 {
        struct davinci_soc_info *soc_info = &davinci_soc_info;
        struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
+       void __iomem *base[2];
        int i;
 
        /* Global init of each 64-bit timer as a whole */
        for(i=0; i<2; i++) {
                u32 tgcr;
-               void __iomem *base = dtip[i].base;
+
+               base[i] = ioremap(dtip[i].base, SZ_4K);
+               if (WARN_ON(!base[i]))
+                       continue;
 
                /* Disabled, Internal clock source */
-               __raw_writel(0, base + TCR);
+               __raw_writel(0, base[i] + TCR);
 
                /* reset both timers, no pre-scaler for timer34 */
                tgcr = 0;
-               __raw_writel(tgcr, base + TGCR);
+               __raw_writel(tgcr, base[i] + TGCR);
 
                /* Set both timers to unchained 32-bit */
                tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
-               __raw_writel(tgcr, base + TGCR);
+               __raw_writel(tgcr, base[i] + TGCR);
 
                /* Unreset timers */
                tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
                        (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
-               __raw_writel(tgcr, base + TGCR);
+               __raw_writel(tgcr, base[i] + TGCR);
 
                /* Init both counters to zero */
-               __raw_writel(0, base + TIM12);
-               __raw_writel(0, base + TIM34);
+               __raw_writel(0, base[i] + TIM12);
+               __raw_writel(0, base[i] + TIM34);
        }
 
        /* Init of each timer as a 32-bit timer */
@@ -231,7 +235,9 @@ static void __init timer_init(void)
                int timer = ID_TO_TIMER(t->id);
                u32 irq;
 
-               t->base = dtip[timer].base;
+               t->base = base[timer];
+               if (!t->base)
+                       continue;
 
                if (IS_TIMER_BOT(t->id)) {
                        t->enamode_shift = 6;
@@ -361,13 +367,13 @@ static void __init davinci_timer_init(void)
                }
        }
 
-       /* init timer hw */
-       timer_init();
-
        timer_clk = clk_get(NULL, "timer0");
        BUG_ON(IS_ERR(timer_clk));
        clk_enable(timer_clk);
 
+       /* init timer hw */
+       timer_init();
+
        davinci_clock_tick_rate = clk_get_rate(timer_clk);
 
        /* setup clocksource */
@@ -399,13 +405,16 @@ struct sys_timer davinci_timer = {
 
 
 /* reset board using watchdog timer */
-void davinci_watchdog_reset(void)
+void davinci_watchdog_reset(struct platform_device *pdev)
 {
        u32 tgcr, wdtcr;
-       struct platform_device *pdev = &davinci_wdt_device;
-       void __iomem *base = IO_ADDRESS(pdev->resource[0].start);
+       void __iomem *base;
        struct clk *wd_clk;
 
+       base = ioremap(pdev->resource[0].start, SZ_4K);
+       if (WARN_ON(!base))
+               return;
+
        wd_clk = clk_get(&pdev->dev, NULL);
        if (WARN_ON(IS_ERR(wd_clk)))
                return;
index caf6d51..3a1a855 100644 (file)
@@ -41,7 +41,7 @@ static struct platform_device adssphere_flash = {
        .resource       = &adssphere_flash_resource,
 };
 
-static struct ep93xx_eth_data adssphere_eth_data = {
+static struct ep93xx_eth_data __initdata adssphere_eth_data = {
        .phy_id         = 1,
 };
 
index 5f80092..e29bdef 100644 (file)
@@ -96,6 +96,10 @@ static struct clk clk_keypad = {
        .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
        .set_rate       = set_keytchclk_rate,
 };
+static struct clk clk_spi = {
+       .parent         = &clk_xtali,
+       .rate           = EP93XX_EXT_CLK_RATE,
+};
 static struct clk clk_pwm = {
        .parent         = &clk_xtali,
        .rate           = EP93XX_EXT_CLK_RATE,
@@ -186,6 +190,7 @@ static struct clk_lookup clocks[] = {
        INIT_CK("ep93xx-ohci",          NULL,           &clk_usb_host),
        INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
        INIT_CK("ep93xx-fb",            NULL,           &clk_video),
+       INIT_CK("ep93xx-spi.0",         NULL,           &clk_spi),
        INIT_CK(NULL,                   "pwm_clk",      &clk_pwm),
        INIT_CK(NULL,                   "m2p0",         &clk_m2p0),
        INIT_CK(NULL,                   "m2p1",         &clk_m2p1),
@@ -473,6 +478,14 @@ static int __init ep93xx_clock_init(void)
        /* Initialize the pll2 derived clocks */
        clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
 
+       /*
+        * EP93xx SSP clock rate was doubled in version E2. For more information
+        * see:
+        *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+        */
+       if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
+               clk_spi.rate /= 2;
+
        pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
                clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
        pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
index 90fb591..9092677 100644 (file)
 #include <linux/amba/serial.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
 
 #include <mach/hardware.h>
 #include <mach/fb.h>
 #include <mach/ep93xx_keypad.h>
+#include <mach/ep93xx_spi.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -222,6 +224,20 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
 }
 EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
 
+/**
+ * ep93xx_chip_revision() - returns the EP93xx chip revision
+ *
+ * See <mach/platform.h> for more information.
+ */
+unsigned int ep93xx_chip_revision(void)
+{
+       unsigned int v;
+
+       v = __raw_readl(EP93XX_SYSCON_SYSCFG);
+       v &= EP93XX_SYSCON_SYSCFG_REV_MASK;
+       v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
+       return v;
+}
 
 /*************************************************************************
  * EP93xx peripheral handling
@@ -330,6 +346,10 @@ static struct platform_device ep93xx_ohci_device = {
        .resource       = ep93xx_ohci_resources,
 };
 
+
+/*************************************************************************
+ * EP93xx ethernet peripheral handling
+ *************************************************************************/
 static struct ep93xx_eth_data ep93xx_eth_data;
 
 static struct resource ep93xx_eth_resource[] = {
@@ -354,6 +374,12 @@ static struct platform_device ep93xx_eth_device = {
        .resource       = ep93xx_eth_resource,
 };
 
+/**
+ * ep93xx_register_eth - Register the built-in ethernet platform device.
+ * @data:      platform specific ethernet configuration (__initdata)
+ * @copy_addr: flag indicating that the MAC address should be copied
+ *             from the IndAd registers (as programmed by the bootloader)
+ */
 void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
 {
        if (copy_addr)
@@ -370,11 +396,19 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
 static struct i2c_gpio_platform_data ep93xx_i2c_data;
 
 static struct platform_device ep93xx_i2c_device = {
-       .name                   = "i2c-gpio",
-       .id                     = 0,
-       .dev.platform_data      = &ep93xx_i2c_data,
+       .name           = "i2c-gpio",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &ep93xx_i2c_data,
+       },
 };
 
+/**
+ * ep93xx_register_i2c - Register the i2c platform device.
+ * @data:      platform specific i2c-gpio configuration (__initdata)
+ * @devices:   platform specific i2c bus device information (__initdata)
+ * @num:       the number of devices on the i2c bus
+ */
 void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
                                struct i2c_board_info *devices, int num)
 {
@@ -398,17 +432,67 @@ void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
        platform_device_register(&ep93xx_i2c_device);
 }
 
+/*************************************************************************
+ * EP93xx SPI peripheral handling
+ *************************************************************************/
+static struct ep93xx_spi_info ep93xx_spi_master_data;
+
+static struct resource ep93xx_spi_resources[] = {
+       {
+               .start  = EP93XX_SPI_PHYS_BASE,
+               .end    = EP93XX_SPI_PHYS_BASE + 0x18 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = IRQ_EP93XX_SSP,
+               .end    = IRQ_EP93XX_SSP,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device ep93xx_spi_device = {
+       .name           = "ep93xx-spi",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &ep93xx_spi_master_data,
+       },
+       .num_resources  = ARRAY_SIZE(ep93xx_spi_resources),
+       .resource       = ep93xx_spi_resources,
+};
+
+/**
+ * ep93xx_register_spi() - registers spi platform device
+ * @info: ep93xx board specific spi master info (__initdata)
+ * @devices: SPI devices to register (__initdata)
+ * @num: number of SPI devices to register
+ *
+ * This function registers platform device for the EP93xx SPI controller and
+ * also makes sure that SPI pins are muxed so that I2S is not using those pins.
+ */
+void __init ep93xx_register_spi(struct ep93xx_spi_info *info,
+                               struct spi_board_info *devices, int num)
+{
+       /*
+        * When SPI is used, we need to make sure that I2S is muxed off from
+        * SPI pins.
+        */
+       ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONSSP);
+
+       ep93xx_spi_master_data = *info;
+       spi_register_board_info(devices, num);
+       platform_device_register(&ep93xx_spi_device);
+}
 
 /*************************************************************************
  * EP93xx LEDs
  *************************************************************************/
 static struct gpio_led ep93xx_led_pins[] = {
        {
-               .name                   = "platform:grled",
-               .gpio                   = EP93XX_GPIO_LINE_GRLED,
+               .name   = "platform:grled",
+               .gpio   = EP93XX_GPIO_LINE_GRLED,
        }, {
-               .name                   = "platform:rdled",
-               .gpio                   = EP93XX_GPIO_LINE_RDLED,
+               .name   = "platform:rdled",
+               .gpio   = EP93XX_GPIO_LINE_RDLED,
        },
 };
 
@@ -528,7 +612,7 @@ static struct platform_device ep93xx_fb_device = {
        .name                   = "ep93xx-fb",
        .id                     = -1,
        .dev                    = {
-               .platform_data  = &ep93xxfb_data,
+               .platform_data          = &ep93xxfb_data,
                .coherent_dma_mask      = DMA_BIT_MASK(32),
                .dma_mask               = &ep93xx_fb_device.dev.coherent_dma_mask,
        },
@@ -536,6 +620,10 @@ static struct platform_device ep93xx_fb_device = {
        .resource               = ep93xx_fb_resource,
 };
 
+/**
+ * ep93xx_register_fb - Register the framebuffer platform device.
+ * @data:      platform specific framebuffer configuration (__initdata)
+ */
 void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
 {
        ep93xxfb_data = *data;
@@ -546,6 +634,8 @@ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
 /*************************************************************************
  * EP93xx matrix keypad peripheral handling
  *************************************************************************/
+static struct ep93xx_keypad_platform_data ep93xx_keypad_data;
+
 static struct resource ep93xx_keypad_resource[] = {
        {
                .start  = EP93XX_KEY_MATRIX_PHYS_BASE,
@@ -559,15 +649,22 @@ static struct resource ep93xx_keypad_resource[] = {
 };
 
 static struct platform_device ep93xx_keypad_device = {
-       .name                   = "ep93xx-keypad",
-       .id                     = -1,
-       .num_resources          = ARRAY_SIZE(ep93xx_keypad_resource),
-       .resource               = ep93xx_keypad_resource,
+       .name           = "ep93xx-keypad",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &ep93xx_keypad_data,
+       },
+       .num_resources  = ARRAY_SIZE(ep93xx_keypad_resource),
+       .resource       = ep93xx_keypad_resource,
 };
 
+/**
+ * ep93xx_register_keypad - Register the keypad platform device.
+ * @data:      platform specific keypad configuration (__initdata)
+ */
 void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data)
 {
-       ep93xx_keypad_device.dev.platform_data = data;
+       ep93xx_keypad_data = *data;
        platform_device_register(&ep93xx_keypad_device);
 }
 
index d22d67a..3884182 100644 (file)
@@ -74,7 +74,7 @@ static void __init edb93xx_register_flash(void)
        }
 }
 
-static struct ep93xx_eth_data edb93xx_eth_data = {
+static struct ep93xx_eth_data __initdata edb93xx_eth_data = {
        .phy_id         = 1,
 };
 
@@ -82,7 +82,7 @@ static struct ep93xx_eth_data edb93xx_eth_data = {
 /*************************************************************************
  * EDB93xx i2c peripheral handling
  *************************************************************************/
-static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = {
+static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = {
        .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
        .sda_is_open_drain      = 0,
        .scl_pin                = EP93XX_GPIO_LINE_EECLK,
index 3da7ca8..a809618 100644 (file)
@@ -41,7 +41,7 @@ static struct platform_device gesbc9312_flash = {
        .resource       = &gesbc9312_flash_resource,
 };
 
-static struct ep93xx_eth_data gesbc9312_eth_data = {
+static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
        .phy_id         = 1,
 };
 
index cc377ae..cf547ad 100644 (file)
@@ -25,7 +25,7 @@
 #include <mach/hardware.h>
 
 /*************************************************************************
- * GPIO handling for EP93xx
+ * Interrupt handling for EP93xx on-chip GPIOs
  *************************************************************************/
 static unsigned char gpio_int_unmasked[3];
 static unsigned char gpio_int_enabled[3];
@@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3]                = { 0x98, 0xb4, 0x54 };
 static const u8 int_en_register_offset[3]      = { 0x9c, 0xb8, 0x58 };
 static const u8 int_debounce_register_offset[3]        = { 0xa8, 0xc4, 0x64 };
 
-void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(unsigned port)
 {
        BUG_ON(port > 2);
 
@@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port)
                EP93XX_GPIO_REG(int_en_register_offset[port]));
 }
 
-void ep93xx_gpio_int_mask(unsigned line)
+static inline void ep93xx_gpio_int_mask(unsigned line)
 {
        gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 }
index 93e2ecc..b1e096f 100644 (file)
 
 #define EP93XX_AAC_BASE                        EP93XX_APB_IOMEM(0x00080000)
 
+#define EP93XX_SPI_PHYS_BASE           EP93XX_APB_PHYS(0x000a0000)
 #define EP93XX_SPI_BASE                        EP93XX_APB_IOMEM(0x000a0000)
 
 #define EP93XX_IRDA_BASE               EP93XX_APB_IOMEM(0x000b0000)
index c6dc14d..9a4413d 100644 (file)
@@ -6,9 +6,11 @@
 
 struct i2c_gpio_platform_data;
 struct i2c_board_info;
+struct spi_board_info;
 struct platform_device;
 struct ep93xxfb_mach_info;
 struct ep93xx_keypad_platform_data;
+struct ep93xx_spi_info;
 
 struct ep93xx_eth_data
 {
@@ -33,9 +35,19 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
        ep93xx_devcfg_set_clear(0x00, bits);
 }
 
+#define EP93XX_CHIP_REV_D0     3
+#define EP93XX_CHIP_REV_D1     4
+#define EP93XX_CHIP_REV_E0     5
+#define EP93XX_CHIP_REV_E1     6
+#define EP93XX_CHIP_REV_E2     7
+
+unsigned int ep93xx_chip_revision(void);
+
 void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
 void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
                         struct i2c_board_info *devices, int num);
+void ep93xx_register_spi(struct ep93xx_spi_info *info,
+                        struct spi_board_info *devices, int num);
 void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
 void ep93xx_register_pwm(int pwm0, int pwm1);
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
index c33360e..1cc911b 100644 (file)
@@ -80,7 +80,7 @@ static void __init micro9_register_flash(void)
 /*************************************************************************
  * Micro9 Ethernet
  *************************************************************************/
-static struct ep93xx_eth_data micro9_eth_data = {
+static struct ep93xx_eth_data __initdata micro9_eth_data = {
        .phy_id         = 0x1f,
 };
 
index cd93990..388aec9 100644 (file)
@@ -49,17 +49,17 @@ static struct platform_device simone_flash = {
        },
 };
 
-static struct ep93xx_eth_data simone_eth_data = {
+static struct ep93xx_eth_data __initdata simone_eth_data = {
        .phy_id         = 1,
 };
 
-static struct ep93xxfb_mach_info simone_fb_info = {
+static struct ep93xxfb_mach_info __initdata simone_fb_info = {
        .num_modes      = EP93XXFB_USE_MODEDB,
        .bpp            = 16,
        .flags          = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
 };
 
-static struct i2c_gpio_platform_data simone_i2c_gpio_data = {
+static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
        .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
        .sda_is_open_drain      = 0,
        .scl_pin                = EP93XX_GPIO_LINE_EECLK,
index 51134b0..38deaee 100644 (file)
@@ -125,11 +125,11 @@ static struct platform_device snappercl15_nand_device = {
        .num_resources          = ARRAY_SIZE(snappercl15_nand_resource),
 };
 
-static struct ep93xx_eth_data snappercl15_eth_data = {
+static struct ep93xx_eth_data __initdata snappercl15_eth_data = {
        .phy_id                 = 1,
 };
 
-static struct i2c_gpio_platform_data snappercl15_i2c_gpio_data = {
+static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = {
        .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
        .sda_is_open_drain      = 0,
        .scl_pin                = EP93XX_GPIO_LINE_EECLK,
@@ -145,7 +145,7 @@ static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
        },
 };
 
-static struct ep93xxfb_mach_info snappercl15_fb_info = {
+static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
        .num_modes              = EP93XXFB_USE_MODEDB,
        .bpp                    = 16,
 };
index fac1ec7..9553031 100644 (file)
@@ -186,7 +186,7 @@ static struct platform_device ts72xx_wdt_device = {
        .resource       = ts72xx_wdt_resources,
 };
 
-static struct ep93xx_eth_data ts72xx_eth_data = {
+static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
        .phy_id         = 1,
 };
 
index df97d16..27db275 100644 (file)
@@ -11,6 +11,7 @@ config ARCH_INTEGRATOR_AP
 config ARCH_INTEGRATOR_CP
        bool "Support Integrator/CP platform"
        select ARCH_CINTEGRATOR
+       select ARM_TIMER_SP804
        help
          Include support for the ARM(R) Integrator CP platform.
 
index 6a5ef8d..ebeef96 100644 (file)
@@ -4,7 +4,7 @@
 
 # Object file lists.
 
-obj-y                                  := clock.o core.o lm.o
+obj-y                                  := core.o lm.o
 obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += integrator_ap.o
 obj-$(CONFIG_ARCH_INTEGRATOR_CP)       += integrator_cp.o
 
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
deleted file mode 100644 (file)
index 989ecf5..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/clock.c
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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/errno.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/clkdev.h>
-#include <mach/clkdev.h>
-
-int clk_enable(struct clk *clk)
-{
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       struct icst525_vco vco;
-       vco = icst525_khz_to_vco(clk->params, rate / 1000);
-       return icst525_khz(clk->params, vco) * 1000;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       int ret = -EIO;
-
-       if (clk->setvco) {
-               struct icst525_vco vco;
-
-               vco = icst525_khz_to_vco(clk->params, rate / 1000);
-               clk->rate = icst525_khz(clk->params, vco) * 1000;
-               clk->setvco(clk, vco);
-               ret = 0;
-       }
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
deleted file mode 100644 (file)
index 609c49d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-extern void integrator_time_init(unsigned long, unsigned int);
-extern unsigned long integrator_gettimeoffset(void);
index 8b390e3..b02cfc0 100644 (file)
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/irq.h>
-#include <asm/hardware/arm_timer.h>
 #include <mach/cm.h>
 #include <asm/system.h>
 #include <asm/leds.h>
 #include <asm/mach/time.h>
 
-#include "common.h"
-
 static struct amba_pl010_data integrator_uart_data;
 
 static struct amba_device rtc_device = {
@@ -163,8 +161,8 @@ arch_initcall(integrator_init);
  *  UART0  7    6
  *  UART1  5    4
  */
-#define SC_CTRLC       (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
-#define SC_CTRLS       (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
+#define SC_CTRLC       IO_ADDRESS(INTEGRATOR_SC_CTRLC)
+#define SC_CTRLS       IO_ADDRESS(INTEGRATOR_SC_CTRLS)
 
 static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
 {
@@ -196,7 +194,7 @@ static struct amba_pl010_data integrator_uart_data = {
        .set_mctrl = integrator_uart_set_mctrl,
 };
 
-#define CM_CTRL        IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET
+#define CM_CTRL        IO_ADDRESS(INTEGRATOR_HDR_CTRL)
 
 static DEFINE_SPINLOCK(cm_lock);
 
@@ -217,120 +215,3 @@ void cm_control(u32 mask, u32 set)
 }
 
 EXPORT_SYMBOL(cm_control);
-
-/*
- * Where is the timer (VA)?
- */
-#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
-#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
-#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
-#define VA_IC_BASE     IO_ADDRESS(INTEGRATOR_IC_BASE) 
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
-static unsigned long timer_reload;
-
-/*
- * Returns number of ms since last clock interrupt.  Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-unsigned long integrator_gettimeoffset(void)
-{
-       unsigned long ticks1, ticks2, status;
-
-       /*
-        * Get the current number of ticks.  Note that there is a race
-        * condition between us reading the timer and checking for
-        * an interrupt.  We get around this by ensuring that the
-        * counter has not reloaded between our two reads.
-        */
-       ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
-       do {
-               ticks1 = ticks2;
-               status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
-               ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
-       } while (ticks2 > ticks1);
-
-       /*
-        * Number of ticks since last interrupt.
-        */
-       ticks1 = timer_reload - ticks2;
-
-       /*
-        * Interrupt pending?  If so, we've reloaded once already.
-        */
-       if (status & (1 << IRQ_TIMERINT1))
-               ticks1 += timer_reload;
-
-       /*
-        * Convert the ticks to usecs
-        */
-       return TICKS2USECS(ticks1);
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-integrator_timer_interrupt(int irq, void *dev_id)
-{
-       /*
-        * clear the interrupt
-        */
-       writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
-
-       timer_tick();
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction integrator_timer_irq = {
-       .name           = "Integrator Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = integrator_timer_interrupt,
-};
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
-{
-       unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
-
-       timer_reload = reload;
-       timer_ctrl |= ctrl;
-
-       if (timer_reload > 0x100000) {
-               timer_reload >>= 8;
-               timer_ctrl |= TIMER_CTRL_DIV256;
-       } else if (timer_reload > 0x010000) {
-               timer_reload >>= 4;
-               timer_ctrl |= TIMER_CTRL_DIV16;
-       }
-
-       /*
-        * Initialise to a known state (all timers off)
-        */
-       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
-       writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
-       writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
-       writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
-
-       /*
-        * Make irqs happen for the system timer
-        */
-       setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
-}
index f77f202..a3fbcb3 100644 (file)
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/icst525.h>
+#include <asm/hardware/icst.h>
 
 static struct cpufreq_driver integrator_driver;
 
-#define CM_ID          (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_ID_OFFSET)
-#define CM_OSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_OSC_OFFSET)
-#define CM_STAT (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_STAT_OFFSET)
-#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_ID          IO_ADDRESS(INTEGRATOR_HDR_ID)
+#define CM_OSC IO_ADDRESS(INTEGRATOR_HDR_OSC)
+#define CM_STAT IO_ADDRESS(INTEGRATOR_HDR_STAT)
+#define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK)
 
-static const struct icst525_params lclk_params = {
-       .ref            = 24000,
-       .vco_max        = 320000,
+static const struct icst_params lclk_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
        .vd_min         = 8,
        .vd_max         = 132,
        .rd_min         = 24,
        .rd_max         = 24,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
 };
 
-static const struct icst525_params cclk_params = {
-       .ref            = 24000,
-       .vco_max        = 320000,
+static const struct icst_params cclk_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
        .vd_min         = 12,
        .vd_max         = 160,
        .rd_min         = 24,
        .rd_max         = 24,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
 };
 
 /*
@@ -52,17 +59,17 @@ static const struct icst525_params cclk_params = {
  */
 static int integrator_verify_policy(struct cpufreq_policy *policy)
 {
-       struct icst525_vco vco;
+       struct icst_vco vco;
 
        cpufreq_verify_within_limits(policy, 
                                     policy->cpuinfo.min_freq, 
                                     policy->cpuinfo.max_freq);
 
-       vco = icst525_khz_to_vco(&cclk_params, policy->max);
-       policy->max = icst525_khz(&cclk_params, vco);
+       vco = icst_hz_to_vco(&cclk_params, policy->max * 1000);
+       policy->max = icst_hz(&cclk_params, vco) / 1000;
 
-       vco = icst525_khz_to_vco(&cclk_params, policy->min);
-       policy->min = icst525_khz(&cclk_params, vco);
+       vco = icst_hz_to_vco(&cclk_params, policy->min * 1000);
+       policy->min = icst_hz(&cclk_params, vco) / 1000;
 
        cpufreq_verify_within_limits(policy, 
                                     policy->cpuinfo.min_freq, 
@@ -78,7 +85,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
 {
        cpumask_t cpus_allowed;
        int cpu = policy->cpu;
-       struct icst525_vco vco;
+       struct icst_vco vco;
        struct cpufreq_freqs freqs;
        u_int cm_osc;
 
@@ -104,17 +111,17 @@ static int integrator_set_target(struct cpufreq_policy *policy,
        }
        vco.v = cm_osc & 255;
        vco.r = 22;
-       freqs.old = icst525_khz(&cclk_params, vco);
+       freqs.old = icst_hz(&cclk_params, vco) / 1000;
 
-       /* icst525_khz_to_vco rounds down -- so we need the next
+       /* icst_hz_to_vco rounds down -- so we need the next
         * larger freq in case of CPUFREQ_RELATION_L.
         */
        if (relation == CPUFREQ_RELATION_L)
                target_freq += 999;
        if (target_freq > policy->max)
                target_freq = policy->max;
-       vco = icst525_khz_to_vco(&cclk_params, target_freq);
-       freqs.new = icst525_khz(&cclk_params, vco);
+       vco = icst_hz_to_vco(&cclk_params, target_freq * 1000);
+       freqs.new = icst_hz(&cclk_params, vco) / 1000;
 
        freqs.cpu = policy->cpu;
 
@@ -154,7 +161,7 @@ static unsigned int integrator_get(unsigned int cpu)
        cpumask_t cpus_allowed;
        unsigned int current_freq;
        u_int cm_osc;
-       struct icst525_vco vco;
+       struct icst_vco vco;
 
        cpus_allowed = current->cpus_allowed;
 
@@ -172,7 +179,7 @@ static unsigned int integrator_get(unsigned int cpu)
        vco.v = cm_osc & 255;
        vco.r = 22;
 
-       current_freq = icst525_khz(&cclk_params, vco); /* current freq */
+       current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */
 
        set_cpus_allowed(current, cpus_allowed);
 
index 41b1072..fd684bf 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
-#include <asm/hardware/icst525.h>
+#include <asm/hardware/icst.h>
 #include <mach/lm.h>
 #include <mach/impd1.h>
 #include <asm/sizes.h>
@@ -41,32 +41,25 @@ struct impd1_module {
        struct clk_lookup *clks[3];
 };
 
-static const struct icst525_params impd1_vco_params = {
-       .ref            = 24000,        /* 24 MHz */
-       .vco_max        = 200000,       /* 200 MHz */
+static const struct icst_params impd1_vco_params = {
+       .ref            = 24000000,     /* 24 MHz */
+       .vco_max        = ICST525_VCO_MAX_3V,
+       .vco_min        = ICST525_VCO_MIN,
        .vd_min         = 12,
        .vd_max         = 519,
        .rd_min         = 3,
        .rd_max         = 120,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
 };
 
-static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
+static void impd1_setvco(struct clk *clk, struct icst_vco vco)
 {
        struct impd1_module *impd1 = clk->data;
-       int vconr = clk - impd1->vcos;
-       u32 val;
-
-       val = vco.v | (vco.r << 9) | (vco.s << 16);
+       u32 val = vco.v | (vco.r << 9) | (vco.s << 16);
 
        writel(0xa05f, impd1->base + IMPD1_LOCK);
-       switch (vconr) {
-       case 0:
-               writel(val, impd1->base + IMPD1_OSC1);
-               break;
-       case 1:
-               writel(val, impd1->base + IMPD1_OSC2);
-               break;
-       }
+       writel(val, clk->vcoreg);
        writel(0, impd1->base + IMPD1_LOCK);
 
 #ifdef DEBUG
@@ -74,11 +67,17 @@ static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
        vco.r = (val >> 9) & 0x7f;
        vco.s = (val >> 16) & 7;
 
-       pr_debug("IM-PD1: VCO%d clock is %ld kHz\n",
-                vconr, icst525_khz(&impd1_vco_params, vco));
+       pr_debug("IM-PD1: VCO%d clock is %ld Hz\n",
+                vconr, icst525_hz(&impd1_vco_params, vco));
 #endif
 }
 
+static const struct clk_ops impd1_clk_ops = {
+       .round  = icst_clk_round,
+       .set    = icst_clk_set,
+       .setvco = impd1_setvco,
+};
+
 void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
 {
        struct impd1_module *impd1 = dev_get_drvdata(dev);
@@ -374,11 +373,13 @@ static int impd1_probe(struct lm_device *dev)
                (unsigned long)dev->resource.start);
 
        for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
+               impd1->vcos[i].ops = &impd1_clk_ops,
                impd1->vcos[i].owner = THIS_MODULE,
                impd1->vcos[i].params = &impd1_vco_params,
-               impd1->vcos[i].data = impd1,
-               impd1->vcos[i].setvco = impd1_setvco;
+               impd1->vcos[i].data = impd1;
        }
+       impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1;
+       impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2;
 
        impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
                                        dev->id);
index 9293e41..bfe0767 100644 (file)
@@ -2,14 +2,15 @@
 #define __ASM_MACH_CLKDEV_H
 
 #include <linux/module.h>
-#include <asm/hardware/icst525.h>
+#include <plat/clock.h>
 
 struct clk {
        unsigned long           rate;
+       const struct clk_ops    *ops;
        struct module           *owner;
-       const struct icst525_params *params;
+       const struct icst_params *params;
+       void __iomem            *vcoreg;
        void                    *data;
-       void                    (*setvco)(struct clk *, struct icst525_vco vco);
 };
 
 static inline int __clk_get(struct clk *clk)
index 7649c57..3d029c9 100644 (file)
@@ -8,6 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <mach/irqs.h>
 
                .macro  disable_fiq
index d795642..8e26360 100644 (file)
@@ -23,7 +23,6 @@
 #define __ASM_ARCH_HARDWARE_H
 
 #include <asm/sizes.h>
-#include <mach/platform.h>
 
 /*
  * Where in virtual memory the IO devices (timers, system controllers
 #define PCIO_BASE              PCI_IO_VADDR
 #define PCIMEM_BASE            PCI_MEMORY_VADDR
 
-#ifdef CONFIG_MMU
-/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) 
-#else
-#define IO_ADDRESS(x) (x)
-#endif
-
 #define pcibios_assign_all_busses()    1
 
 #define PCIBIOS_MIN_IO         0x6000
 #define PCIBIOS_MIN_MEM        0x00100000
 
+/* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
+#define IO_ADDRESS(x)  (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
+#else
+#define IO_ADDRESS(x)  (x)
+#endif
+
+#define __io_address(n)                ((void __iomem *)IO_ADDRESS(n))
+
 #endif
 
index e00a262..5e6ea5c 100644 (file)
@@ -23,9 +23,6 @@
  *
  *   Integrator address map
  *
- *     NOTE: This is a multi-hosted header file for use with uHAL and
- *           supported debuggers.
- *
  * ***********************************************************************/
 
 #ifndef __address_h
 #define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
 #define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
 
+#define INTEGRATOR_AP_GPIO_BASE                0x1B000000      /* GPIO */
 
-#if defined(CONFIG_ARCH_INTEGRATOR_AP)
-#define INTEGRATOR_GPIO_BASE            0x1B000000      /*  GPIO */
-#elif defined(CONFIG_ARCH_INTEGRATOR_CP)
-#define INTEGRATOR_GPIO_BASE            0xC9000000      /*  GPIO */
-#endif
+#define INTEGRATOR_CP_MMC_BASE         0x1C000000      /* MMC */
+#define INTEGRATOR_CP_AACI_BASE                0x1D000000      /* AACI */
+#define INTEGRATOR_CP_ETH_BASE         0xC8000000      /* Ethernet */
+#define INTEGRATOR_CP_GPIO_BASE                0xC9000000      /* GPIO */
+#define INTEGRATOR_CP_SIC_BASE         0xCA000000      /* SIC */
+#define INTEGRATOR_CP_CTL_BASE         0xCB000000      /* CP system control */
 
 /* ------------------------------------------------------------------------
  *  KMI keyboard/mouse definitions
  */
 #define PHYS_PCI_V3_BASE                0x62000000
 
-#define PCI_DRAMSIZE                    INTEGRATOR_SSRAM_SIZE
-
-/* 'export' these to UHAL */
-#define UHAL_PCI_IO                     PCI_IO_BASE
-#define UHAL_PCI_MEM                    PCI_MEM_BASE
-#define UHAL_PCI_ALLOC_IO_BASE          0x00004000
-#define UHAL_PCI_ALLOC_MEM_BASE         PCI_MEM_BASE
-#define UHAL_PCI_MAX_SLOT               20
-
-/* ========================================================================
- *  Start of uHAL definitions
- * ========================================================================
- */
-
 /* ------------------------------------------------------------------------
  *  Integrator Interrupt Controllers
  * ------------------------------------------------------------------------
  */
 
 /* ------------------------------------------------------------------------
- *  LED's - The header LED is not accessible via the uHAL API
+ *  LED's
  * ------------------------------------------------------------------------
  *
  */
 
 #define LED_BANK                        INTEGRATOR_DBG_LEDS
 
-/*
- *  Memory definitions - run uHAL out of SSRAM.
- *
- */
-#define uHAL_MEMORY_SIZE                INTEGRATOR_SSRAM_SIZE
-
-/*
- *  Clean base - dummy
- *
- */
-#define CLEAN_BASE                      INTEGRATOR_BOOT_ROM_HI
-
 /*
  *  Timer definitions
  *
  *  Only use timer 1 & 2
  *  (both run at 24MHz and will need the clock divider set to 16).
  *
- *  Timer 0 runs at bus frequency and therefore could vary and currently
- *  uHAL can't handle that.
- *
+ *  Timer 0 runs at bus frequency
  */
 
 #define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
 #define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
 #define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
 
-#define MAX_TIMER                       2
-#define MAX_PERIOD                      699050
 #define TICKS_PER_uSEC                  24
 
 /*
  *
  */
 #define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
 #define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
 
 #define INTEGRATOR_CSR_BASE             0x10000000
 #define INTEGRATOR_CSR_SIZE             0x10000000
 
 #endif
-
-/*     END */
index 8138a7e..227cf4d 100644 (file)
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/hardware/arm_timer.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/param.h>         /* HZ */
@@ -43,8 +48,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include "common.h"
-
 /* 
  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
  * is the (PA >> 12).
@@ -55,7 +58,7 @@
 #define VA_IC_BASE     IO_ADDRESS(INTEGRATOR_IC_BASE) 
 #define VA_SC_BASE     IO_ADDRESS(INTEGRATOR_SC_BASE)
 #define VA_EBI_BASE    IO_ADDRESS(INTEGRATOR_EBI_BASE)
-#define VA_CMIC_BASE   IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET
+#define VA_CMIC_BASE   IO_ADDRESS(INTEGRATOR_HDR_IC)
 
 /*
  * Logical      Physical
@@ -117,8 +120,8 @@ static struct map_desc ap_io_desc[] __initdata = {
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }, {
-               .virtual        = IO_ADDRESS(INTEGRATOR_GPIO_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+               .virtual        = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }, {
@@ -334,14 +337,163 @@ static void __init ap_init(void)
        }
 }
 
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE)
+#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE)
+#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
+#else
+#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
+#endif
+
+static unsigned long timer_reload;
+
+static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE;
+
+static cycle_t timersp_read(struct clocksource *cs)
+{
+       return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff);
+}
+
+static struct clocksource clocksource_timersp = {
+       .name           = "timer2",
+       .rating         = 200,
+       .read           = timersp_read,
+       .mask           = CLOCKSOURCE_MASK(16),
+       .shift          = 16,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void integrator_clocksource_init(u32 khz)
+{
+       struct clocksource *cs = &clocksource_timersp;
+       void __iomem *base = clksrc_base;
+       u32 ctrl = TIMER_CTRL_ENABLE;
+
+       if (khz >= 1500) {
+               khz /= 16;
+               ctrl = TIMER_CTRL_DIV16;
+       }
+
+       writel(ctrl, base + TIMER_CTRL);
+       writel(0xffff, base + TIMER_LOAD);
+
+       cs->mult = clocksource_khz2mult(khz, cs->shift);
+       clocksource_register(cs);
+}
+
+static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       /* clear the interrupt */
+       writel(1, clkevt_base + TIMER_INTCLR);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
+{
+       u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
+
+       BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT);
+
+       if (mode == CLOCK_EVT_MODE_PERIODIC) {
+               writel(ctrl, clkevt_base + TIMER_CTRL);
+               writel(timer_reload, clkevt_base + TIMER_LOAD);
+               ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+       }
+
+       writel(ctrl, clkevt_base + TIMER_CTRL);
+}
+
+static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
+{
+       unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+       writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+       writel(next, clkevt_base + TIMER_LOAD);
+       writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+       return 0;
+}
+
+static struct clock_event_device integrator_clockevent = {
+       .name           = "timer1",
+       .shift          = 34,
+       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .set_mode       = clkevt_set_mode,
+       .set_next_event = clkevt_set_next_event,
+       .rating         = 300,
+       .cpumask        = cpu_all_mask,
+};
+
+static struct irqaction integrator_timer_irq = {
+       .name           = "timer",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = integrator_timer_interrupt,
+       .dev_id         = &integrator_clockevent,
+};
+
+static void integrator_clockevent_init(u32 khz)
+{
+       struct clock_event_device *evt = &integrator_clockevent;
+       unsigned int ctrl = 0;
+
+       if (khz * 1000 > 0x100000 * HZ) {
+               khz /= 256;
+               ctrl |= TIMER_CTRL_DIV256;
+       } else if (khz * 1000 > 0x10000 * HZ) {
+               khz /= 16;
+               ctrl |= TIMER_CTRL_DIV16;
+       }
+
+       timer_reload = khz * 1000 / HZ;
+       writel(ctrl, clkevt_base + TIMER_CTRL);
+
+       evt->irq = IRQ_TIMERINT1;
+       evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift);
+       evt->max_delta_ns = clockevent_delta2ns(0xffff, evt);
+       evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
+
+       setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
+       clockevents_register_device(evt);
+}
+
+/*
+ * Set up timer(s).
+ */
 static void __init ap_init_timer(void)
 {
-       integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0);
+       u32 khz = TICKS_PER_uSEC * 1000;
+
+       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+       integrator_clocksource_init(khz);
+       integrator_clockevent_init(khz);
 }
 
 static struct sys_timer ap_timer = {
        .init           = ap_init_timer,
-       .offset         = integrator_gettimeoffset,
 };
 
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
index 15e6cc5..cde57b2 100644 (file)
 #include <asm/clkdev.h>
 #include <mach/clkdev.h>
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/icst525.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst.h>
 
 #include <mach/cm.h>
 #include <mach/lm.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include "common.h"
-
-#define INTCP_PA_MMC_BASE              0x1c000000
-#define INTCP_PA_AACI_BASE             0x1d000000
+#include <plat/timer-sp.h>
 
 #define INTCP_PA_FLASH_BASE            0x24000000
 #define INTCP_FLASH_SIZE               SZ_32M
 
 #define INTCP_PA_CLCD_BASE             0xc0000000
 
-#define INTCP_VA_CIC_BASE              IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40
+#define INTCP_VA_CIC_BASE              IO_ADDRESS(INTEGRATOR_HDR_BASE + 0x40)
 #define INTCP_VA_PIC_BASE              IO_ADDRESS(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE              IO_ADDRESS(0xca000000)
+#define INTCP_VA_SIC_BASE              IO_ADDRESS(INTEGRATOR_CP_SIC_BASE)
 
-#define INTCP_PA_ETH_BASE              0xc8000000
 #define INTCP_ETH_SIZE                 0x10
 
-#define INTCP_VA_CTRL_BASE             IO_ADDRESS(0xcb000000)
+#define INTCP_VA_CTRL_BASE             IO_ADDRESS(INTEGRATOR_CP_CTL_BASE)
 #define INTCP_FLASHPROG                        0x04
 #define CINTEGRATOR_FLASHPROG_FLVPPEN  (1 << 0)
 #define CINTEGRATOR_FLASHPROG_FLWREN   (1 << 1)
@@ -71,7 +69,9 @@
  * f1600000    16000000        UART 0
  * f1700000    17000000        UART 1
  * f1a00000    1a000000        Debug LEDs
- * f1b00000    1b000000        GPIO
+ * fc900000    c9000000        GPIO
+ * fca00000    ca000000        SIC
+ * fcb00000    cb000000        CP system control
  */
 
 static struct map_desc intcp_io_desc[] __initdata = {
@@ -116,18 +116,18 @@ static struct map_desc intcp_io_desc[] __initdata = {
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }, {
-               .virtual        = IO_ADDRESS(INTEGRATOR_GPIO_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_GPIO_BASE),
+               .virtual        = IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }, {
-               .virtual        = IO_ADDRESS(0xca000000),
-               .pfn            = __phys_to_pfn(0xca000000),
+               .virtual        = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }, {
-               .virtual        = IO_ADDRESS(0xcb000000),
-               .pfn            = __phys_to_pfn(0xcb000000),
+               .virtual        = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
                .length         = SZ_4K,
                .type           = MT_DEVICE
        }
@@ -266,33 +266,43 @@ static void __init intcp_init_irq(void)
 /*
  * Clock handling
  */
-#define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
-#define CM_AUXOSC (IO_ADDRESS(INTEGRATOR_HDR_BASE)+0x1c)
+#define CM_LOCK                (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_AUXOSC      (__io_address(INTEGRATOR_HDR_BASE)+0x1c)
 
-static const struct icst525_params cp_auxvco_params = {
-       .ref            = 24000,
-       .vco_max        = 320000,
+static const struct icst_params cp_auxvco_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST525_VCO_MAX_5V,
+       .vco_min        = ICST525_VCO_MIN,
        .vd_min         = 8,
        .vd_max         = 263,
        .rd_min         = 3,
        .rd_max         = 65,
+       .s2div          = icst525_s2div,
+       .idx2s          = icst525_idx2s,
 };
 
-static void cp_auxvco_set(struct clk *clk, struct icst525_vco vco)
+static void cp_auxvco_set(struct clk *clk, struct icst_vco vco)
 {
        u32 val;
 
-       val = readl(CM_AUXOSC) & ~0x7ffff;
+       val = readl(clk->vcoreg) & ~0x7ffff;
        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
        writel(0xa05f, CM_LOCK);
-       writel(val, CM_AUXOSC);
+       writel(val, clk->vcoreg);
        writel(0, CM_LOCK);
 }
 
+static const struct clk_ops cp_auxclk_ops = {
+       .round  = icst_clk_round,
+       .set    = icst_clk_set,
+       .setvco = cp_auxvco_set,
+};
+
 static struct clk cp_auxclk = {
+       .ops    = &cp_auxclk_ops,
        .params = &cp_auxvco_params,
-       .setvco = cp_auxvco_set,
+       .vcoreg = CM_AUXOSC,
 };
 
 static struct clk_lookup cp_lookups[] = {
@@ -363,8 +373,8 @@ static struct platform_device intcp_flash_device = {
 
 static struct resource smc91x_resources[] = {
        [0] = {
-               .start  = INTCP_PA_ETH_BASE,
-               .end    = INTCP_PA_ETH_BASE + INTCP_ETH_SIZE - 1,
+               .start  = INTEGRATOR_CP_ETH_BASE,
+               .end    = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
@@ -394,8 +404,8 @@ static struct platform_device *intcp_devs[] __initdata = {
  */
 static unsigned int mmc_status(struct device *dev)
 {
-       unsigned int status = readl(IO_ADDRESS(0xca000000) + 4);
-       writel(8, IO_ADDRESS(0xcb000000) + 8);
+       unsigned int status = readl(IO_ADDRESS(0xca000000 + 4));
+       writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8));
 
        return status & 8;
 }
@@ -413,8 +423,8 @@ static struct amba_device mmc_device = {
                .platform_data = &mmc_data,
        },
        .res            = {
-               .start  = INTCP_PA_MMC_BASE,
-               .end    = INTCP_PA_MMC_BASE + SZ_4K - 1,
+               .start  = INTEGRATOR_CP_MMC_BASE,
+               .end    = INTEGRATOR_CP_MMC_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
        .irq            = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 },
@@ -426,8 +436,8 @@ static struct amba_device aaci_device = {
                .init_name = "mb:1d",
        },
        .res            = {
-               .start  = INTCP_PA_AACI_BASE,
-               .end    = INTCP_PA_AACI_BASE + SZ_4K - 1,
+               .start  = INTEGRATOR_CP_AACI_BASE,
+               .end    = INTEGRATOR_CP_AACI_BASE + SZ_4K - 1,
                .flags  = IORESOURCE_MEM,
        },
        .irq            = { IRQ_CP_AACIINT, NO_IRQ },
@@ -567,16 +577,22 @@ static void __init intcp_init(void)
        }
 }
 
-#define TIMER_CTRL_IE  (1 << 5)                        /* Interrupt Enable */
+#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
+#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
+#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
 
 static void __init intcp_timer_init(void)
 {
-       integrator_time_init(1000000 / HZ, TIMER_CTRL_IE);
+       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+       sp804_clocksource_init(TIMER2_VA_BASE);
+       sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1);
 }
 
 static struct sys_timer cp_timer = {
        .init           = intcp_timer_init,
-       .offset         = integrator_gettimeoffset,
 };
 
 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
index 8dcc823..28be186 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/leds.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
index ffbd349..9cef059 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/irq.h>
 #include <asm/signal.h>
 #include <asm/system.h>
@@ -389,9 +390,9 @@ static int __init pci_v3_setup_resources(struct resource **resource)
  * means I can't get additional information on the reason for the pm2fb
  * problems.  I suppose I'll just have to mind-meld with the machine. ;)
  */
-#define SC_PCI     (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_PCIENABLE_OFFSET)
-#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20)
-#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24)
+#define SC_PCI     IO_ADDRESS(INTEGRATOR_SC_PCIENABLE)
+#define SC_LBFADDR IO_ADDRESS(INTEGRATOR_SC_BASE + 0x20)
+#define SC_LBFCODE IO_ADDRESS(INTEGRATOR_SC_BASE + 0x24)
 
 static int
 v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
index 5d99039..f108a31 100644 (file)
@@ -176,7 +176,7 @@ static struct plat_serial8250_port n2100_serial_port[] = {
                .mapbase        = N2100_UART,
                .membase        = (char *)N2100_UART,
                .irq            = 0,
-               .flags          = UPF_SKIP_TEST,
+               .flags          = UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ,
                .iotype         = UPIO_MEM,
                .regshift       = 0,
                .uartclk        = 1843200,
index 71728d3..0bce097 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/tty.h>
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
-#include <linux/bootmem.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
 #include <linux/time.h>
index 17879a8..29b2163 100644 (file)
@@ -38,6 +38,12 @@ config MACH_ESATA_SHEEVAPLUG
          Say 'Y' here if you want your kernel to support the
          Marvell eSATA SheevaPlug Reference Board.
 
+config MACH_GURUPLUG
+       bool "Marvell GuruPlug Reference Board"
+       help
+         Say 'Y' here if you want your kernel to support the
+         Marvell GuruPlug Reference Board.
+
 config MACH_TS219
        bool "QNAP TS-110, TS-119, TS-210, TS-219 and TS-219P Turbo NAS"
        help
@@ -81,6 +87,18 @@ config MACH_INETSPACE_V2
          Say 'Y' here if you want your kernel to support the
          LaCie Internet Space v2 NAS.
 
+config MACH_NET2BIG_V2
+       bool "LaCie 2Big Network v2 NAS Board"
+       help
+         Say 'Y' here if you want your kernel to support the
+         LaCie 2Big Network v2 NAS.
+
+config MACH_NET5BIG_V2
+       bool "LaCie 5Big Network v2 NAS Board"
+       help
+         Say 'Y' here if you want your kernel to support the
+         LaCie 5Big Network v2 NAS.
+
 endmenu
 
 endif
index a5530e3..c0cd5d3 100644 (file)
@@ -6,10 +6,13 @@ obj-$(CONFIG_MACH_RD88F6281)          += rd88f6281-setup.o
 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_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_NET2BIG_V2)          += netxbig_v2-setup.o
+obj-$(CONFIG_MACH_NET5BIG_V2)          += netxbig_v2-setup.o
 
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c
new file mode 100644 (file)
index 0000000..54d07c8
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * arch/arm/mach-kirkwood/guruplug-setup.c
+ *
+ * Marvell GuruPlug Reference Board 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/mtd/partitions.h>
+#include <linux/ata_platform.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 guruplug_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 guruplug_ge00_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data guruplug_ge01_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(1),
+};
+
+static struct mv_sata_platform_data guruplug_sata_data = {
+       .n_ports        = 1,
+};
+
+static struct mvsdio_platform_data guruplug_mvsdio_data = {
+       /* unfortunately the CD signal has not been connected */
+};
+
+static struct gpio_led guruplug_led_pins[] = {
+       {
+               .name                   = "guruplug:red:health",
+               .gpio                   = 46,
+               .active_low             = 1,
+       },
+       {
+               .name                   = "guruplug:green:health",
+               .gpio                   = 47,
+               .active_low             = 1,
+       },
+       {
+               .name                   = "guruplug:red:wmode",
+               .gpio                   = 48,
+               .active_low             = 1,
+       },
+       {
+               .name                   = "guruplug:green:wmode",
+               .gpio                   = 49,
+               .active_low             = 1,
+       },
+};
+
+static struct gpio_led_platform_data guruplug_led_data = {
+       .leds           = guruplug_led_pins,
+       .num_leds       = ARRAY_SIZE(guruplug_led_pins),
+};
+
+static struct platform_device guruplug_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &guruplug_led_data,
+       }
+};
+
+static unsigned int guruplug_mpp_config[] __initdata = {
+       MPP46_GPIO,     /* M_RLED */
+       MPP47_GPIO,     /* M_GLED */
+       MPP48_GPIO,     /* B_RLED */
+       MPP49_GPIO,     /* B_GLED */
+       0
+};
+
+static void __init guruplug_init(void)
+{
+       /*
+        * Basic setup. Needs to be called early.
+        */
+       kirkwood_init();
+       kirkwood_mpp_conf(guruplug_mpp_config);
+
+       kirkwood_uart0_init();
+       kirkwood_nand_init(ARRAY_AND_SIZE(guruplug_nand_parts), 25);
+
+       kirkwood_ehci_init();
+       kirkwood_ge00_init(&guruplug_ge00_data);
+       kirkwood_ge01_init(&guruplug_ge01_data);
+       kirkwood_sata_init(&guruplug_sata_data);
+       kirkwood_sdio_init(&guruplug_mvsdio_data);
+
+       platform_device_register(&guruplug_leds);
+}
+
+MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board")
+       /* Maintainer: Siddarth Gore <gores@marvell.com> */
+       .phys_io        = KIRKWOOD_REGS_PHYS_BASE,
+       .io_pg_offst    = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .init_machine   = guruplug_init,
+       .map_io         = kirkwood_map_io,
+       .init_irq       = kirkwood_init_irq,
+       .timer          = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
new file mode 100644 (file)
index 0000000..8a2bb02
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ * arch/arm/mach-kirkwood/netxbig_v2-setup.c
+ *
+ * LaCie 2Big and 5Big Network 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/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 "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,
+       },
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = {
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
+};
+
+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
+ ****************************************************************************/
+
+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
+ ****************************************************************************/
+
+#define NETXBIG_V2_GPIO_SWITCH_POWER_ON                13
+#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF       15
+#define NETXBIG_V2_GPIO_FUNC_BUTTON            34
+
+#define NETXBIG_V2_SWITCH_POWER_ON             0x1
+#define NETXBIG_V2_SWITCH_POWER_OFF            0x2
+
+static struct gpio_keys_button netxbig_v2_buttons[] = {
+       [0] = {
+               .type           = EV_SW,
+               .code           = NETXBIG_V2_SWITCH_POWER_ON,
+               .gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_ON,
+               .desc           = "Back power switch (on|auto)",
+               .active_low     = 1,
+       },
+       [1] = {
+               .type           = EV_SW,
+               .code           = NETXBIG_V2_SWITCH_POWER_OFF,
+               .gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_OFF,
+               .desc           = "Back power switch (auto|off)",
+               .active_low     = 1,
+       },
+       [2] = {
+               .code           = KEY_OPTION,
+               .gpio           = NETXBIG_V2_GPIO_FUNC_BUTTON,
+               .desc           = "Function button",
+               .active_low     = 1,
+       },
+};
+
+static struct gpio_keys_platform_data netxbig_v2_button_data = {
+       .buttons        = netxbig_v2_buttons,
+       .nbuttons       = ARRAY_SIZE(netxbig_v2_buttons),
+};
+
+static struct platform_device netxbig_v2_gpio_buttons = {
+       .name           = "gpio-keys",
+       .id             = -1,
+       .dev            = {
+               .platform_data  = &netxbig_v2_button_data,
+       },
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+/*
+ * The LEDs are controlled by a CPLD and can be configured through a GPIO
+ * extension bus:
+ *
+ * - address register : bit [0-2] -> GPIO [47-49]
+ * - data register    : bit [0-2] -> GPIO [44-46]
+ * - enable register  : GPIO 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
+ *
+ * Data register configuration:
+ *
+ * data | LED brightness
+ * -------------------------------------------------
+ *   0  | min (off)
+ *   -  | -
+ *   7  | max
+ *
+ * data | front LED mode
+ * -------------------------------------------------
+ *   0  | fix off
+ *   1  | fix blue on
+ *   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
+ *
+ * data | HDD LED mode
+ * -------------------------------------------------
+ *   0  | fix blue on
+ *   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
+ */
+
+/*****************************************************************************
+ * Timer
+ ****************************************************************************/
+
+static void netxbig_v2_timer_init(void)
+{
+       kirkwood_tclk = 166666667;
+       orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer netxbig_v2_timer = {
+       .init = netxbig_v2_timer_init,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int net2big_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_TW_SDA,
+       MPP9_TW_SCK,
+       MPP10_UART0_TXD,
+       MPP11_UART0_RXD,
+       MPP13_GPIO,             /* Rear power switch (on|auto) */
+       MPP14_GPIO,             /* USB fuse alarm */
+       MPP15_GPIO,             /* Rear power switch (auto|off) */
+       MPP16_GPIO,             /* SATA HDD1 power */
+       MPP17_GPIO,             /* SATA HDD2 power */
+       MPP20_SATA1_ACTn,
+       MPP21_SATA0_ACTn,
+       MPP24_GPIO,             /* USB mode select */
+       MPP26_GPIO,             /* USB device vbus */
+       MPP28_GPIO,             /* USB enable host vbus */
+       MPP29_GPIO,             /* CPLD 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) */
+       0
+};
+
+static unsigned int net5big_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_TW_SDA,
+       MPP9_TW_SCK,
+       MPP10_UART0_TXD,
+       MPP11_UART0_RXD,
+       MPP13_GPIO,             /* Rear power switch (on|auto) */
+       MPP14_GPIO,             /* USB fuse alarm */
+       MPP15_GPIO,             /* Rear power switch (auto|off) */
+       MPP16_GPIO,             /* SATA HDD1 power */
+       MPP17_GPIO,             /* SATA HDD2 power */
+       MPP20_GE1_0,
+       MPP21_GE1_1,
+       MPP22_GE1_2,
+       MPP23_GE1_3,
+       MPP24_GE1_4,
+       MPP25_GE1_5,
+       MPP26_GE1_6,
+       MPP27_GE1_7,
+       MPP28_GPIO,             /* USB enable host vbus */
+       MPP29_GPIO,             /* CPLD extension ALE */
+       MPP30_GE1_10,
+       MPP31_GE1_11,
+       MPP32_GE1_12,
+       MPP33_GE1_13,
+       MPP34_GPIO,             /* Rear Push button */
+       MPP35_GPIO,             /* Inhibit switch power-off */
+       MPP36_GPIO,             /* SATA HDD1 presence */
+       MPP37_GPIO,             /* SATA HDD2 presence */
+       MPP38_GPIO,             /* SATA HDD3 presence */
+       MPP39_GPIO,             /* SATA HDD4 presence */
+       MPP40_GPIO,             /* SATA HDD5 presence */
+       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) */
+       0
+};
+
+#define NETXBIG_V2_GPIO_POWER_OFF              7
+
+static void netxbig_v2_power_off(void)
+{
+       gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init netxbig_v2_init(void)
+{
+       /*
+        * Basic setup. Needs to be called early.
+        */
+       kirkwood_init();
+       if (machine_is_net2big_v2())
+               kirkwood_mpp_conf(net2big_v2_mpp_config);
+       else
+               kirkwood_mpp_conf(net5big_v2_mpp_config);
+
+       netxbig_v2_sata_power_init();
+
+       kirkwood_ehci_init();
+       kirkwood_ge00_init(&netxbig_v2_ge00_data);
+       if (machine_is_net5big_v2())
+               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));
+
+       platform_device_register(&netxbig_v2_gpio_buttons);
+
+       if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+           gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0)
+               pm_power_off = netxbig_v2_power_off;
+       else
+               pr_err("netxbig_v2: failed to configure power-off GPIO\n");
+}
+
+#ifdef CONFIG_MACH_NET2BIG_V2
+MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
+       .phys_io        = KIRKWOOD_REGS_PHYS_BASE,
+       .io_pg_offst    = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .init_machine   = netxbig_v2_init,
+       .map_io         = kirkwood_map_io,
+       .init_irq       = kirkwood_init_irq,
+       .timer          = &netxbig_v2_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_NET5BIG_V2
+MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
+       .phys_io        = KIRKWOOD_REGS_PHYS_BASE,
+       .io_pg_offst    = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .init_machine   = netxbig_v2_init,
+       .map_io         = kirkwood_map_io,
+       .init_irq       = kirkwood_init_irq,
+       .timer          = &netxbig_v2_timer,
+MACHINE_END
+#endif
index a2d307e..244655d 100644 (file)
@@ -59,6 +59,13 @@ static unsigned long common_pin_config[] __initdata = {
        /* UART1 */
        GPIO107_UART1_RXD,
        GPIO108_UART1_TXD,
+
+       /* SSP1 */
+       GPIO113_I2S_MCLK,
+       GPIO114_I2S_FRM,
+       GPIO115_I2S_BCLK,
+       GPIO116_I2S_RXD,
+       GPIO117_I2S_TXD,
 };
 
 static struct smc91x_platdata smc91x_info = {
@@ -123,12 +130,18 @@ static struct pxa3xx_nand_platform_data aspenite_nand_info = {
        .nr_parts       = ARRAY_SIZE(aspenite_nand_partitions),
 };
 
+static struct i2c_board_info aspenite_i2c_info[] __initdata = {
+       { I2C_BOARD_INFO("wm8753", 0x1b), },
+};
+
 static void __init common_init(void)
 {
        mfp_config(ARRAY_AND_SIZE(common_pin_config));
 
        /* on-chip devices */
        pxa168_add_uart(1);
+       pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
+       pxa168_add_ssp(1);
        pxa168_add_nand(&aspenite_nand_info);
 
        /* off-chip devices */
index ab26d13..ee8b02e 100644 (file)
@@ -10,7 +10,7 @@
 #define BANK_OFF(n)    (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
 #define GPIO_REG(x)    (*((volatile u32 *)(GPIO_REGS_VIRT + (x))))
 
-#define NR_BUILTIN_GPIO        (128)
+#define NR_BUILTIN_GPIO        (192)
 
 #define gpio_to_bank(gpio)     ((gpio) >> 5)
 #define gpio_to_irq(gpio)      (IRQ_GPIO_START + (gpio))
index 0270119..b379cde 100644 (file)
@@ -5,10 +5,10 @@
  * Interrupt numbers for PXA168
  */
 #define IRQ_PXA168_NONE                        (-1)
-#define IRQ_PXA168_SSP3                        0
-#define IRQ_PXA168_SSP2                        1
-#define IRQ_PXA168_SSP1                        2
-#define IRQ_PXA168_SSP0                        3
+#define IRQ_PXA168_SSP4                        0
+#define IRQ_PXA168_SSP3                        1
+#define IRQ_PXA168_SSP2                        2
+#define IRQ_PXA168_SSP1                        3
 #define IRQ_PXA168_PMIC_INT            4
 #define IRQ_PXA168_RTC_INT             5
 #define IRQ_PXA168_RTC_ALARM           6
@@ -20,7 +20,7 @@
 #define IRQ_PXA168_TIMER2              14
 #define IRQ_PXA168_TIMER3              15
 #define IRQ_PXA168_CMU                 16
-#define IRQ_PXA168_SSP4                        17
+#define IRQ_PXA168_SSP5                        17
 #define IRQ_PXA168_MSP_WAKEUP          19
 #define IRQ_PXA168_CF_WAKEUP           20
 #define IRQ_PXA168_XD_WAKEUP           21
index 9f9f814..761c2da 100644 (file)
@@ -9,6 +9,175 @@
 #define MFP_DRIVE_FAST         (0x8 << 13)
 
 /* GPIO */
+#define GPIO0_GPIO0            MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO1            MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO2            MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO3            MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO4            MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO5            MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO6            MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO7            MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO8            MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO9            MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO10          MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO11          MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO12          MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO13          MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO14          MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO15          MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO16          MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO17          MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO18          MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO19          MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO20          MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO21          MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO22          MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO23          MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO24          MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO25          MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO26          MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO27          MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO28          MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO29          MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO30          MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO31          MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO32          MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO33          MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO34          MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO35          MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO36          MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO37          MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO38          MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO39          MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO40          MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO41          MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO42          MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO43          MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO44          MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO45          MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO46          MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO47          MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO48          MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO49          MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO50          MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO51          MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO52          MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO53          MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO54          MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO55          MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO56          MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO57          MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO58          MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO59          MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO60          MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO61          MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO62          MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO63          MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO64          MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO65          MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO66          MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO67          MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO68          MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO69          MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO70          MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO71          MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO72          MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO73          MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO74          MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO75          MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO76          MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO77          MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO78          MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO79          MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO80          MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO81          MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO82          MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO83          MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO84          MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO85          MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO86          MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO87          MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO88          MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO89          MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO90          MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO91          MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO92          MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO93          MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO94          MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO95          MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO96          MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO97          MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO98          MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO99          MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO100                MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO101                MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO102                MFP_CFG(GPIO102, AF1)
+#define GPIO103_GPIO103                MFP_CFG(GPIO103, AF1)
+#define GPIO104_GPIO104                MFP_CFG(GPIO104, AF1)
+#define GPIO105_GPIO105                MFP_CFG(GPIO105, AF1)
+#define GPIO106_GPIO106                MFP_CFG(GPIO106, AF1)
+#define GPIO107_GPIO107                MFP_CFG(GPIO107, AF1)
+#define GPIO108_GPIO108                MFP_CFG(GPIO108, AF1)
+#define GPIO109_GPIO109                MFP_CFG(GPIO109, AF1)
+#define GPIO110_GPIO110                MFP_CFG(GPIO110, AF1)
+#define GPIO111_GPIO111                MFP_CFG(GPIO111, AF1)
+#define GPIO112_GPIO112                MFP_CFG(GPIO112, AF1)
+#define GPIO113_GPIO113                MFP_CFG(GPIO113, AF1)
+#define GPIO114_GPIO114                MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO115                MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO116                MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO117                MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO118                MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO119                MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO120                MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO121                MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO122                MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO123                MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO124                MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO125                MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO126                MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO127                MFP_CFG(GPIO127, AF0)
+#define GPIO128_GPIO128                MFP_CFG(GPIO128, AF0)
+#define GPIO129_GPIO129                MFP_CFG(GPIO129, AF0)
+#define GPIO130_GPIO130                MFP_CFG(GPIO130, AF0)
+#define GPIO131_GPIO131                MFP_CFG(GPIO131, AF0)
+#define GPIO132_GPIO132                MFP_CFG(GPIO132, AF0)
+#define GPIO133_GPIO133                MFP_CFG(GPIO133, AF0)
+#define GPIO134_GPIO134                MFP_CFG(GPIO134, AF0)
+#define GPIO135_GPIO135                MFP_CFG(GPIO135, AF0)
+#define GPIO136_GPIO136                MFP_CFG(GPIO136, AF0)
+#define GPIO137_GPIO137                MFP_CFG(GPIO137, AF0)
+#define GPIO138_GPIO138                MFP_CFG(GPIO138, AF0)
+#define GPIO139_GPIO139                MFP_CFG(GPIO139, AF0)
+#define GPIO140_GPIO140                MFP_CFG(GPIO140, AF0)
+#define GPIO141_GPIO141                MFP_CFG(GPIO141, AF0)
+#define GPIO142_GPIO142                MFP_CFG(GPIO142, AF1)
+#define GPIO143_GPIO143                MFP_CFG(GPIO143, AF1)
+#define GPIO144_GPIO144                MFP_CFG(GPIO144, AF1)
+#define GPIO145_GPIO145                MFP_CFG(GPIO145, AF1)
+#define GPIO146_GPIO146                MFP_CFG(GPIO146, AF1)
+#define GPIO147_GPIO147                MFP_CFG(GPIO147, AF1)
+#define GPIO148_GPIO148                MFP_CFG(GPIO148, AF1)
+#define GPIO149_GPIO149                MFP_CFG(GPIO149, AF1)
+#define GPIO150_GPIO150                MFP_CFG(GPIO150, AF1)
+#define GPIO151_GPIO151                MFP_CFG(GPIO151, AF1)
+#define GPIO152_GPIO152                MFP_CFG(GPIO152, AF1)
+#define GPIO153_GPIO153                MFP_CFG(GPIO153, AF1)
+#define GPIO154_GPIO154                MFP_CFG(GPIO154, AF1)
+#define GPIO155_GPIO155                MFP_CFG(GPIO155, AF1)
+#define GPIO156_GPIO156                MFP_CFG(GPIO156, AF1)
+#define GPIO157_GPIO157                MFP_CFG(GPIO157, AF1)
+#define GPIO158_GPIO158                MFP_CFG(GPIO158, AF1)
+#define GPIO159_GPIO159                MFP_CFG(GPIO159, AF1)
+#define GPIO160_GPIO160                MFP_CFG(GPIO160, AF1)
+#define GPIO161_GPIO161                MFP_CFG(GPIO161, AF1)
+#define GPIO162_GPIO162                MFP_CFG(GPIO162, AF1)
+#define GPIO163_GPIO163                MFP_CFG(GPIO163, AF1)
+#define GPIO164_GPIO164                MFP_CFG(GPIO164, AF1)
+#define GPIO165_GPIO165                MFP_CFG(GPIO165, AF1)
+#define GPIO166_GPIO166                MFP_CFG(GPIO166, AF1)
+#define GPIO167_GPIO167                MFP_CFG(GPIO167, AF1)
+#define GPIO168_GPIO168                MFP_CFG(GPIO168, AF1)
 
 /* DFI */
 #define GPIO108_DFI_D15                MFP_CFG(GPIO108, AF0)
 
 /* Ethernet */
 #define GPIO155_SM_ADVMUX      MFP_CFG(GPIO155, AF2)
-#define GPIO155_GPIO155                MFP_CFG(GPIO155, AF1)
 
 /* UART1 */
 #define GPIO45_UART1_RXD       MFP_CFG(GPIO45, AF1)
 #define GPIO44_TWSI2_SDA       MFP_CFG_DRV(GPIO44, AF1, SLOW)
 #define GPIO71_TWSI3_SCL       MFP_CFG_DRV(GPIO71, AF1, SLOW)
 #define GPIO72_TWSI3_SDA       MFP_CFG_DRV(GPIO72, AF1, SLOW)
+#define TWSI4_SCL              MFP_CFG_DRV(TWSI4_SCL, AF0, SLOW)
+#define TWSI4_SDA              MFP_CFG_DRV(TWSI4_SDA, AF0, SLOW)
 #define GPIO99_TWSI5_SCL       MFP_CFG_DRV(GPIO99, AF4, SLOW)
 #define GPIO100_TWSI5_SDA      MFP_CFG_DRV(GPIO100, AF4, SLOW)
 #define GPIO97_TWSI6_SCL       MFP_CFG_DRV(GPIO97, AF2, SLOW)
 #define GPIO69_CAM_MCLK                MFP_CFG_DRV(GPIO69, AF1, FAST)
 #define GPIO70_CAM_PCLK                MFP_CFG_DRV(GPIO70, AF1, FAST)
 
-/* Wifi */
-#define GPIO45_GPIO45          MFP_CFG(GPIO45, AF0)
-#define GPIO46_GPIO46          MFP_CFG(GPIO46, AF0)
-#define GPIO21_GPIO21          MFP_CFG(GPIO21, AF0)
-#define GPIO22_GPIO22          MFP_CFG(GPIO22, AF0)
-#define GPIO55_GPIO55          MFP_CFG(GPIO55, AF0)
-#define GPIO56_GPIO56          MFP_CFG(GPIO56, AF0)
-#define GPIO57_GPIO57          MFP_CFG(GPIO57, AF0)
-#define GPIO58_GPIO58          MFP_CFG(GPIO58, AF0)
-
-/* Codec*/
-#define GPIO23_GPIO23          MFP_CFG(GPIO23, AF0)
-
-#define GPIO101_GPIO101                MFP_CFG(GPIO101, AF0)
-
 /* PMIC */
 #define PMIC_PMIC_INT          MFP_CFG(PMIC_INT, AF0)
 
index 459f3be..fec220b 100644 (file)
@@ -39,17 +39,17 @@ static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
        int ret;
 
        switch (id) {
-       case 0: d = &mmp2_device_twsi1; break;
-       case 1: d = &mmp2_device_twsi2; break;
-       case 2: d = &mmp2_device_twsi3; break;
-       case 3: d = &mmp2_device_twsi4; break;
-       case 4: d = &mmp2_device_twsi5; break;
-       case 5: d = &mmp2_device_twsi6; break;
+       case 1: d = &mmp2_device_twsi1; break;
+       case 2: d = &mmp2_device_twsi2; break;
+       case 3: d = &mmp2_device_twsi3; break;
+       case 4: d = &mmp2_device_twsi4; break;
+       case 5: d = &mmp2_device_twsi5; break;
+       case 6: d = &mmp2_device_twsi6; break;
        default:
                return -EINVAL;
        }
 
-       ret = i2c_register_board_info(id, info, size);
+       ret = i2c_register_board_info(id - 1, info, size);
        if (ret)
                return ret;
 
index 3ad612c..3b2bd5d 100644 (file)
@@ -14,6 +14,11 @@ extern struct pxa_device_desc pxa168_device_pwm1;
 extern struct pxa_device_desc pxa168_device_pwm2;
 extern struct pxa_device_desc pxa168_device_pwm3;
 extern struct pxa_device_desc pxa168_device_pwm4;
+extern struct pxa_device_desc pxa168_device_ssp1;
+extern struct pxa_device_desc pxa168_device_ssp2;
+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;
 
 static inline int pxa168_add_uart(int id)
@@ -67,6 +72,22 @@ static inline int pxa168_add_pwm(int id)
        return pxa_register_device(d, NULL, 0);
 }
 
+static inline int pxa168_add_ssp(int id)
+{
+       struct pxa_device_desc *d = NULL;
+
+       switch (id) {
+       case 1: d = &pxa168_device_ssp1; break;
+       case 2: d = &pxa168_device_ssp2; break;
+       case 3: d = &pxa168_device_ssp3; break;
+       case 4: d = &pxa168_device_ssp4; break;
+       case 5: d = &pxa168_device_ssp5; break;
+       default:
+               return -EINVAL;
+       }
+       return pxa_register_device(d, NULL, 0);
+}
+
 static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
 {
        return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
index 712af03..1a96585 100644 (file)
@@ -26,8 +26,6 @@
 #define APBC_PXA168_PWM2       APBC_REG(0x010)
 #define APBC_PXA168_PWM3       APBC_REG(0x014)
 #define APBC_PXA168_PWM4       APBC_REG(0x018)
-#define APBC_PXA168_SSP1       APBC_REG(0x01c)
-#define APBC_PXA168_SSP2       APBC_REG(0x020)
 #define APBC_PXA168_RTC                APBC_REG(0x028)
 #define APBC_PXA168_TWSI0      APBC_REG(0x02c)
 #define APBC_PXA168_KPC                APBC_REG(0x030)
 #define APBC_PXA168_AIB                APBC_REG(0x03c)
 #define APBC_PXA168_SW_JTAG    APBC_REG(0x040)
 #define APBC_PXA168_ONEWIRE    APBC_REG(0x048)
-#define APBC_PXA168_SSP3       APBC_REG(0x04c)
 #define APBC_PXA168_ASFAR      APBC_REG(0x050)
 #define APBC_PXA168_ASSAR      APBC_REG(0x054)
-#define APBC_PXA168_SSP4       APBC_REG(0x058)
-#define APBC_PXA168_SSP5       APBC_REG(0x05c)
 #define APBC_PXA168_TWSI1      APBC_REG(0x06c)
 #define APBC_PXA168_UART3      APBC_REG(0x070)
 #define APBC_PXA168_AC97       APBC_REG(0x084)
+#define APBC_PXA168_SSP1       APBC_REG(0x81c)
+#define APBC_PXA168_SSP2       APBC_REG(0x820)
+#define APBC_PXA168_SSP3       APBC_REG(0x84c)
+#define APBC_PXA168_SSP4       APBC_REG(0x858)
+#define APBC_PXA168_SSP5       APBC_REG(0x85c)
 
 /*
  * APB Clock register offsets for PXA910
diff --git a/arch/arm/mach-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h
new file mode 100644 (file)
index 0000000..e484d40
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-smc.h
+ *
+ *  Static Memory Controller Registers
+ *
+ * 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_MACH_REGS_SMC_H
+#define __ASM_MACH_REGS_SMC_H
+
+#include <mach/addr-map.h>
+
+#define SMC_VIRT_BASE          (AXI_VIRT_BASE + 0x83800)
+#define SMC_REG(x)             (SMC_VIRT_BASE + (x))
+
+#define SMC_MSC0               SMC_REG(0x0020)
+#define SMC_MSC1               SMC_REG(0x0024)
+#define SMC_SXCNFG0            SMC_REG(0x0030)
+#define SMC_SXCNFG1            SMC_REG(0x0034)
+#define SMC_MEMCLKCFG          SMC_REG(0x0068)
+#define SMC_CSDFICFG0          SMC_REG(0x0090)
+#define SMC_CSDFICFG1          SMC_REG(0x0094)
+#define SMC_CLK_RET_DEL                SMC_REG(0x00b0)
+#define SMC_ADV_RET_DEL                SMC_REG(0x00b4)
+#define SMC_CSADRMAP0          SMC_REG(0x00c0)
+#define SMC_CSADRMAP1          SMC_REG(0x00c4)
+#define SMC_WE_AP0             SMC_REG(0x00e0)
+#define SMC_WE_AP1             SMC_REG(0x00e4)
+#define SMC_OE_AP0             SMC_REG(0x00f0)
+#define SMC_OE_AP1             SMC_REG(0x00f4)
+#define SMC_ADV_AP0            SMC_REG(0x0100)
+#define SMC_ADV_AP1            SMC_REG(0x0104)
+
+#endif /* __ASM_MACH_REGS_SMC_H */
index 6cebbd0..70c9f1d 100644 (file)
@@ -6,4 +6,8 @@
  * published by the Free Software Foundation.
  */
 
+#ifdef CONFIG_CPU_MMP2
+#define CLOCK_TICK_RATE                6500000
+#else
 #define CLOCK_TICK_RATE                3250000
+#endif
index cfd4d66..d77dd41 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/mfd/max8925.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"
 
@@ -58,6 +62,63 @@ static unsigned long jasper_pin_config[] __initdata = {
        GPIO149_ND_CLE,
        GPIO112_ND_RDY0,
        GPIO160_ND_RDY1,
+
+       /* PMIC */
+       PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,
+};
+
+static struct regulator_consumer_supply max8649_supply[] = {
+       REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data max8649_init_data = {
+       .constraints    = {
+               .name           = "vcc_core range",
+               .min_uV         = 1150000,
+               .max_uV         = 1280000,
+               .always_on      = 1,
+               .boot_on        = 1,
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &max8649_supply[0],
+};
+
+static struct max8649_platform_data jasper_max8649_info = {
+       .mode           = 2,    /* VID1 = 1, VID0 = 0 */
+       .extclk         = 0,
+       .ramp_timing    = MAX8649_RAMP_32MV,
+       .regulator      = &max8649_init_data,
+};
+
+static struct max8925_backlight_pdata jasper_backlight_data = {
+       .dual_string    = 0,
+};
+
+static struct max8925_power_pdata jasper_power_data = {
+       .batt_detect            = 0,    /* can't detect battery by ID pin */
+       .topoff_threshold       = MAX8925_TOPOFF_THR_10PER,
+       .fast_charge            = MAX8925_FCHG_1000MA,
+};
+
+static struct max8925_platform_data jasper_max8925_info = {
+       .backlight              = &jasper_backlight_data,
+       .power                  = &jasper_power_data,
+       .irq_base               = IRQ_BOARD_START,
+};
+
+static struct i2c_board_info jasper_twsi1_info[] = {
+       [0] = {
+               .type           = "max8649",
+               .addr           = 0x60,
+               .platform_data  = &jasper_max8649_info,
+       },
+       [1] = {
+               .type           = "max8925",
+               .addr           = 0x3c,
+               .irq            = IRQ_MMP2_PMIC,
+               .platform_data  = &jasper_max8925_info,
+       },
 };
 
 static void __init jasper_init(void)
@@ -67,6 +128,9 @@ static void __init jasper_init(void)
        /* on-chip devices */
        mmp2_add_uart(1);
        mmp2_add_uart(3);
+       mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info));
+
+       regulator_has_full_constraints();
 }
 
 MACHINE_START(MARVELL_JASPER, "Jasper Development Platform")
index 72eb9da..7f5eb05 100644 (file)
 #include <linux/init.h>
 #include <linux/io.h>
 
+#include <asm/hardware/cache-tauros2.h>
+
 #include <mach/addr-map.h>
 #include <mach/regs-apbc.h>
 #include <mach/regs-apmu.h>
 #include <mach/cputype.h>
 #include <mach/irqs.h>
+#include <mach/dma.h>
 #include <mach/mfp.h>
 #include <mach/gpio.h>
 #include <mach/devices.h>
 #define APMASK(i)      (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c)
 
 static struct mfp_addr_map mmp2_addr_map[] __initdata = {
+
+       MFP_ADDR_X(GPIO0, GPIO58, 0x54),
+       MFP_ADDR_X(GPIO59, GPIO73, 0x280),
+       MFP_ADDR_X(GPIO74, GPIO101, 0x170),
+
+       MFP_ADDR(GPIO102, 0x0),
+       MFP_ADDR(GPIO103, 0x4),
+       MFP_ADDR(GPIO104, 0x1fc),
+       MFP_ADDR(GPIO105, 0x1f8),
+       MFP_ADDR(GPIO106, 0x1f4),
+       MFP_ADDR(GPIO107, 0x1f0),
+       MFP_ADDR(GPIO108, 0x21c),
+       MFP_ADDR(GPIO109, 0x218),
+       MFP_ADDR(GPIO110, 0x214),
+       MFP_ADDR(GPIO111, 0x200),
+       MFP_ADDR(GPIO112, 0x244),
+       MFP_ADDR(GPIO113, 0x25c),
+       MFP_ADDR(GPIO114, 0x164),
+       MFP_ADDR_X(GPIO115, GPIO122, 0x260),
+
+       MFP_ADDR(GPIO123, 0x148),
+       MFP_ADDR_X(GPIO124, GPIO141, 0xc),
+
+       MFP_ADDR(GPIO142, 0x8),
+       MFP_ADDR_X(GPIO143, GPIO151, 0x220),
+       MFP_ADDR_X(GPIO152, GPIO153, 0x248),
+       MFP_ADDR_X(GPIO154, GPIO155, 0x254),
+       MFP_ADDR_X(GPIO156, GPIO159, 0x14c),
+
+       MFP_ADDR(GPIO160, 0x250),
+       MFP_ADDR(GPIO161, 0x210),
+       MFP_ADDR(GPIO162, 0x20c),
+       MFP_ADDR(GPIO163, 0x208),
+       MFP_ADDR(GPIO164, 0x204),
+       MFP_ADDR(GPIO165, 0x1ec),
+       MFP_ADDR(GPIO166, 0x1e8),
+       MFP_ADDR(GPIO167, 0x1e4),
+       MFP_ADDR(GPIO168, 0x1e0),
+
+       MFP_ADDR_X(TWSI1_SCL, TWSI1_SDA, 0x140),
+       MFP_ADDR_X(TWSI4_SCL, TWSI4_SDA, 0x2bc),
+
        MFP_ADDR(PMIC_INT, 0x2c4),
+       MFP_ADDR(CLK_REQ, 0x160),
 
        MFP_ADDR_END,
 };
@@ -99,9 +145,13 @@ static struct clk_lookup mmp2_clkregs[] = {
 static int __init mmp2_init(void)
 {
        if (cpu_is_mmp2()) {
+#ifdef CONFIG_CACHE_TAUROS2
+               tauros2_init();
+#endif
                mfp_init_base(MFPR_VIRT_BASE);
                mfp_init_addr(mmp2_addr_map);
-               clks_register(ARRAY_AND_SIZE(mmp2_clkregs));
+               pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16);
+               clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
        }
 
        return 0;
index 1873c82..652ae66 100644 (file)
@@ -72,6 +72,11 @@ static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000);
 static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000);
 static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000);
 static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000);
+static APBC_CLK(ssp1, PXA168_SSP1, 4, 0);
+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 APMU_CLK(nand, NAND, 0x01db, 208000000);
 
@@ -85,6 +90,11 @@ static struct clk_lookup pxa168_clkregs[] = {
        INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
        INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
        INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
+       INIT_CLKREG(&clk_ssp1, "pxa168-ssp.0", NULL),
+       INIT_CLKREG(&clk_ssp2, "pxa168-ssp.1", NULL),
+       INIT_CLKREG(&clk_ssp3, "pxa168-ssp.2", NULL),
+       INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
+       INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
        INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
 };
 
@@ -132,3 +142,8 @@ PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10);
 PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10);
 PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10);
 PXA168_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
+PXA168_DEVICE(ssp1, "pxa168-ssp", 0, SSP1, 0xd401b000, 0x40, 52, 53);
+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);
index f780086..47264a7 100644 (file)
@@ -1,7 +1,80 @@
 if ARCH_MSM
 
-comment "MSM Board Type"
+choice
+       prompt "Qualcomm MSM SoC Type"
+       default ARCH_MSM7X00A
+
+config ARCH_MSM7X00A
+       bool "MSM7x00A / MSM7x01A"
+       select ARCH_MSM_ARM11
+       select MSM_SMD
+       select MSM_SMD_PKG3
+       select CPU_V6
+
+config ARCH_MSM7X30
+       bool "MSM7x30"
+       select ARCH_MSM_SCORPION
+       select MSM_SMD
+       select MSM_VIC
+       select CPU_V7
+       select MSM_REMOTE_SPINLOCK_DEKKERS
+
+config ARCH_QSD8X50
+       bool "QSD8X50"
+       select ARCH_MSM_SCORPION
+       select MSM_SMD
+       select MSM_VIC
+       select CPU_V7
+       select MSM_REMOTE_SPINLOCK_LDREX
+endchoice
+
+config MSM_SOC_REV_A
+       bool
+
+config  ARCH_MSM_ARM11
+       bool
+config  ARCH_MSM_SCORPION
+       bool
+
+config  MSM_VIC
+       bool
+
+menu "Qualcomm MSM Board Type"
+
+config MACH_HALIBUT
        depends on ARCH_MSM
+       depends on ARCH_MSM7X00A
+       bool "Halibut Board (QCT SURF7201A)"
+       help
+         Support for the Qualcomm SURF7201A eval board.
+
+config MACH_TROUT
+       depends on ARCH_MSM
+       depends on ARCH_MSM7X00A
+       bool "HTC Dream (aka trout)"
+       help
+         Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
+
+config MACH_MSM7X30_SURF
+       depends on ARCH_MSM7X30
+       bool "MSM7x30 SURF"
+       help
+         Support for the Qualcomm MSM7x30 SURF eval board.
+
+config MACH_QSD8X50_SURF
+       depends on ARCH_QSD8X50
+       bool "QSD8x50 SURF"
+       help
+         Support for the Qualcomm QSD8x50 SURF eval board.
+
+config MACH_QSD8X50A_ST1_5
+       depends on ARCH_QSD8X50
+       select MSM_SOC_REV_A
+       bool "QSD8x50A ST1.5"
+       help
+         Support for the Qualcomm ST1.5.
+
+endmenu
 
 config MSM_DEBUG_UART
        int
@@ -27,17 +100,10 @@ choice
                bool "UART3"
 endchoice
 
-config MACH_HALIBUT
-       depends on ARCH_MSM
-       default y
-       bool "Halibut Board (QCT SURF7201A)"
-       help
-         Support for the Qualcomm SURF7201A eval board.
+config MSM_SMD_PKG3
+       bool
 
-config MACH_TROUT
-       default y
-       bool "HTC Dream (aka trout)"
-       help
-         Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
+config MSM_SMD
+       bool
 
 endif
index 91e6f5c..66677f0 100644 (file)
@@ -1,9 +1,22 @@
-obj-y += io.o idle.o irq.o timer.o dma.o
-obj-y += devices.o
 obj-y += proc_comm.o
+obj-y += io.o idle.o timer.o dma.o
 obj-y += vreg.o
-obj-y += clock.o clock-7x01a.o
+obj-y += acpuclock-arm11.o
+obj-y += clock.o clock-pcom.o
+obj-y += gpio.o
 
-obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o
+ifdef CONFIG_MSM_VIC
+obj-y += irq-vic.o
+else
+obj-y += irq.o
+endif
+
+obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
+obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
+obj-$(CONFIG_MSM_SMD) += last_radio_log.o
+
+obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o
+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_MACH_TROUT) += board-dream.o
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c
new file mode 100644 (file)
index 0000000..af5e85b
--- /dev/null
@@ -0,0 +1,526 @@
+/* arch/arm/mach-msm/acpuclock.c
+ *
+ * MSM architecture clock driver
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ * Author: San Mehat <san@android.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 <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include "proc_comm.h"
+#include "acpuclock.h"
+
+
+#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
+#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
+#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
+
+/*
+ * ARM11 clock configuration for specific ACPU speeds
+ */
+
+#define ACPU_PLL_TCXO  -1
+#define ACPU_PLL_0     0
+#define ACPU_PLL_1     1
+#define ACPU_PLL_2     2
+#define ACPU_PLL_3     3
+
+#define PERF_SWITCH_DEBUG 0
+#define PERF_SWITCH_STEP_DEBUG 0
+
+struct clock_state
+{
+       struct clkctl_acpu_speed        *current_speed;
+       struct mutex                    lock;
+       uint32_t                        acpu_switch_time_us;
+       uint32_t                        max_speed_delta_khz;
+       uint32_t                        vdd_switch_time_us;
+       unsigned long                   power_collapse_khz;
+       unsigned long                   wait_for_irq_khz;
+};
+
+static struct clk *ebi1_clk;
+static struct clock_state drv_state = { 0 };
+
+static void __init acpuclk_init(void);
+
+/* MSM7201A Levels 3-6 all correspond to 1.2V, level 7 corresponds to 1.325V. */
+enum {
+       VDD_0 = 0,
+       VDD_1 = 1,
+       VDD_2 = 2,
+       VDD_3 = 3,
+       VDD_4 = 3,
+       VDD_5 = 3,
+       VDD_6 = 3,
+       VDD_7 = 7,
+       VDD_END
+};
+
+struct clkctl_acpu_speed {
+       unsigned int    a11clk_khz;
+       int             pll;
+       unsigned int    a11clk_src_sel;
+       unsigned int    a11clk_src_div;
+       unsigned int    ahbclk_khz;
+       unsigned int    ahbclk_div;
+       int             vdd;
+       unsigned int    axiclk_khz;
+       unsigned long   lpj; /* loops_per_jiffy */
+/* Index in acpu_freq_tbl[] for steppings. */
+       short           down;
+       short           up;
+};
+
+/*
+ * ACPU speed table. Complete table is shown but certain speeds are commented
+ * out to optimized speed switching. Initalize loops_per_jiffy to 0.
+ *
+ * Table stepping up/down is optimized for 256mhz jumps while staying on the
+ * same PLL.
+ */
+#if (0)
+static struct clkctl_acpu_speed  acpu_freq_tbl[] = {
+       { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 8 },
+       { 61440, ACPU_PLL_0,  4, 3, 61440,  0, VDD_0, 30720,  0, 0, 8 },
+       { 81920, ACPU_PLL_0,  4, 2, 40960,  1, VDD_0, 61440,  0, 0, 8 },
+       { 96000, ACPU_PLL_1,  1, 7, 48000,  1, VDD_0, 61440,  0, 0, 9 },
+       { 122880, ACPU_PLL_0, 4, 1, 61440,  1, VDD_3, 61440,  0, 0, 8 },
+       { 128000, ACPU_PLL_1, 1, 5, 64000,  1, VDD_3, 61440,  0, 0, 12 },
+       { 176000, ACPU_PLL_2, 2, 5, 88000,  1, VDD_3, 61440,  0, 0, 11 },
+       { 192000, ACPU_PLL_1, 1, 3, 64000,  2, VDD_3, 61440,  0, 0, 12 },
+       { 245760, ACPU_PLL_0, 4, 0, 81920,  2, VDD_4, 61440,  0, 0, 12 },
+       { 256000, ACPU_PLL_1, 1, 2, 128000, 2, VDD_5, 128000, 0, 0, 12 },
+       { 264000, ACPU_PLL_2, 2, 3, 88000,  2, VDD_5, 128000, 0, 6, 13 },
+       { 352000, ACPU_PLL_2, 2, 2, 88000,  3, VDD_5, 128000, 0, 6, 13 },
+       { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 5, -1 },
+       { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 11, -1 },
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+#else /* Table of freq we currently use. */
+static struct clkctl_acpu_speed  acpu_freq_tbl[] = {
+       { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 4 },
+       { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 4 },
+       { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 6 },
+       { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 5 },
+       { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 5 },
+       { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 3, 7 },
+       { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 2, -1 },
+       { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 5, -1 },
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+#endif
+
+
+#ifdef CONFIG_CPU_FREQ_TABLE
+static struct cpufreq_frequency_table freq_table[] = {
+       { 0, 122880 },
+       { 1, 128000 },
+       { 2, 245760 },
+       { 3, 384000 },
+       { 4, 528000 },
+       { 5, CPUFREQ_TABLE_END },
+};
+#endif
+
+static int pc_pll_request(unsigned id, unsigned on)
+{
+       int res;
+       on = !!on;
+
+#if PERF_SWITCH_DEBUG
+       if (on)
+               printk(KERN_DEBUG "Enabling PLL %d\n", id);
+       else
+               printk(KERN_DEBUG "Disabling PLL %d\n", id);
+#endif
+
+       res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
+       if (res < 0)
+               return res;
+
+#if PERF_SWITCH_DEBUG
+       if (on)
+               printk(KERN_DEBUG "PLL %d enabled\n", id);
+       else
+               printk(KERN_DEBUG "PLL %d disabled\n", id);
+#endif
+       return res;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ARM11 'owned' clock control
+ *---------------------------------------------------------------------------*/
+
+unsigned long acpuclk_power_collapse(void) {
+       int ret = acpuclk_get_rate();
+       ret *= 1000;
+       if (ret > drv_state.power_collapse_khz)
+               acpuclk_set_rate(drv_state.power_collapse_khz, 1);
+       return ret;
+}
+
+unsigned long acpuclk_get_wfi_rate(void)
+{
+       return drv_state.wait_for_irq_khz;
+}
+
+unsigned long acpuclk_wait_for_irq(void) {
+       int ret = acpuclk_get_rate();
+       ret *= 1000;
+       if (ret > drv_state.wait_for_irq_khz)
+               acpuclk_set_rate(drv_state.wait_for_irq_khz, 1);
+       return ret;
+}
+
+static int acpuclk_set_vdd_level(int vdd)
+{
+       uint32_t current_vdd;
+
+       current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07;
+
+#if PERF_SWITCH_DEBUG
+       printk(KERN_DEBUG "acpuclock: Switching VDD from %u -> %d\n",
+              current_vdd, vdd);
+#endif
+       writel((1 << 7) | (vdd << 3), A11S_VDD_SVS_PLEVEL_ADDR);
+       udelay(drv_state.vdd_switch_time_us);
+       if ((readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x7) != vdd) {
+#if PERF_SWITCH_DEBUG
+               printk(KERN_ERR "acpuclock: VDD set failed\n");
+#endif
+               return -EIO;
+       }
+
+#if PERF_SWITCH_DEBUG
+       printk(KERN_DEBUG "acpuclock: VDD switched\n");
+#endif
+       return 0;
+}
+
+/* Set proper dividers for the given clock speed. */
+static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s) {
+       uint32_t reg_clkctl, reg_clksel, clk_div;
+
+       /* AHB_CLK_DIV */
+       clk_div = (readl(A11S_CLK_SEL_ADDR) >> 1) & 0x03;
+       /*
+        * If the new clock divider is higher than the previous, then
+        * program the divider before switching the clock
+        */
+       if (hunt_s->ahbclk_div > clk_div) {
+               reg_clksel = readl(A11S_CLK_SEL_ADDR);
+               reg_clksel &= ~(0x3 << 1);
+               reg_clksel |= (hunt_s->ahbclk_div << 1);
+               writel(reg_clksel, A11S_CLK_SEL_ADDR);
+       }
+       if ((readl(A11S_CLK_SEL_ADDR) & 0x01) == 0) {
+               /* SRC0 */
+
+               /* Program clock source */
+               reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+               reg_clkctl &= ~(0x07 << 4);
+               reg_clkctl |= (hunt_s->a11clk_src_sel << 4);
+               writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+               /* Program clock divider */
+               reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+               reg_clkctl &= ~0xf;
+               reg_clkctl |= hunt_s->a11clk_src_div;
+               writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+               /* Program clock source selection */
+               reg_clksel = readl(A11S_CLK_SEL_ADDR);
+               reg_clksel |= 1; /* CLK_SEL_SRC1NO  == SRC1 */
+               writel(reg_clksel, A11S_CLK_SEL_ADDR);
+       } else {
+               /* SRC1 */
+
+               /* Program clock source */
+               reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+               reg_clkctl &= ~(0x07 << 12);
+               reg_clkctl |= (hunt_s->a11clk_src_sel << 12);
+               writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+               /* Program clock divider */
+               reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+               reg_clkctl &= ~(0xf << 8);
+               reg_clkctl |= (hunt_s->a11clk_src_div << 8);
+               writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+               /* Program clock source selection */
+               reg_clksel = readl(A11S_CLK_SEL_ADDR);
+               reg_clksel &= ~1; /* CLK_SEL_SRC1NO  == SRC0 */
+               writel(reg_clksel, A11S_CLK_SEL_ADDR);
+       }
+
+       /*
+        * If the new clock divider is lower than the previous, then
+        * program the divider after switching the clock
+        */
+       if (hunt_s->ahbclk_div < clk_div) {
+               reg_clksel = readl(A11S_CLK_SEL_ADDR);
+               reg_clksel &= ~(0x3 << 1);
+               reg_clksel |= (hunt_s->ahbclk_div << 1);
+               writel(reg_clksel, A11S_CLK_SEL_ADDR);
+       }
+}
+
+int acpuclk_set_rate(unsigned long rate, int for_power_collapse)
+{
+       uint32_t reg_clkctl;
+       struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s;
+       int rc = 0;
+       unsigned int plls_enabled = 0, pll;
+
+       strt_s = cur_s = drv_state.current_speed;
+
+       WARN_ONCE(cur_s == NULL, "acpuclk_set_rate: not initialized\n");
+       if (cur_s == NULL)
+               return -ENOENT;
+
+       if (rate == (cur_s->a11clk_khz * 1000))
+               return 0;
+
+       for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) {
+               if (tgt_s->a11clk_khz == (rate / 1000))
+                       break;
+       }
+
+       if (tgt_s->a11clk_khz == 0)
+               return -EINVAL;
+
+       /* Choose the highest speed speed at or below 'rate' with same PLL. */
+       if (for_power_collapse && tgt_s->a11clk_khz < cur_s->a11clk_khz) {
+               while (tgt_s->pll != ACPU_PLL_TCXO && tgt_s->pll != cur_s->pll)
+                       tgt_s--;
+       }
+
+       if (strt_s->pll != ACPU_PLL_TCXO)
+               plls_enabled |= 1 << strt_s->pll;
+
+       if (!for_power_collapse) {
+               mutex_lock(&drv_state.lock);
+               if (strt_s->pll != tgt_s->pll && tgt_s->pll != ACPU_PLL_TCXO) {
+                       rc = pc_pll_request(tgt_s->pll, 1);
+                       if (rc < 0) {
+                               pr_err("PLL%d enable failed (%d)\n",
+                                       tgt_s->pll, rc);
+                               goto out;
+                       }
+                       plls_enabled |= 1 << tgt_s->pll;
+               }
+               /* Increase VDD if needed. */
+               if (tgt_s->vdd > cur_s->vdd) {
+                       if ((rc = acpuclk_set_vdd_level(tgt_s->vdd)) < 0) {
+                               printk(KERN_ERR "Unable to switch ACPU vdd\n");
+                               goto out;
+                       }
+               }
+       }
+
+       /* Set wait states for CPU inbetween frequency changes */
+       reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+       reg_clkctl |= (100 << 16); /* set WT_ST_CNT */
+       writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+#if PERF_SWITCH_DEBUG
+       printk(KERN_INFO "acpuclock: Switching from ACPU rate %u -> %u\n",
+              strt_s->a11clk_khz * 1000, tgt_s->a11clk_khz * 1000);
+#endif
+
+       while (cur_s != tgt_s) {
+               /*
+                * Always jump to target freq if within 256mhz, regulardless of
+                * PLL. If differnece is greater, use the predefinied
+                * steppings in the table.
+                */
+               int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz));
+               if (d > drv_state.max_speed_delta_khz) {
+                       /* Step up or down depending on target vs current. */
+                       int clk_index = tgt_s->a11clk_khz > cur_s->a11clk_khz ?
+                               cur_s->up : cur_s->down;
+                       if (clk_index < 0) { /* This should not happen. */
+                               printk(KERN_ERR "cur:%u target: %u\n",
+                                       cur_s->a11clk_khz, tgt_s->a11clk_khz);
+                               rc = -EINVAL;
+                               goto out;
+                       }
+                       cur_s = &acpu_freq_tbl[clk_index];
+               } else {
+                       cur_s = tgt_s;
+               }
+#if PERF_SWITCH_STEP_DEBUG
+               printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n",
+                       __FUNCTION__, cur_s->a11clk_khz, cur_s->pll);
+#endif
+               if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO
+                   && !(plls_enabled & (1 << cur_s->pll))) {
+                       rc = pc_pll_request(cur_s->pll, 1);
+                       if (rc < 0) {
+                               pr_err("PLL%d enable failed (%d)\n",
+                                       cur_s->pll, rc);
+                               goto out;
+                       }
+                       plls_enabled |= 1 << cur_s->pll;
+               }
+
+               acpuclk_set_div(cur_s);
+               drv_state.current_speed = cur_s;
+               /* Re-adjust lpj for the new clock speed. */
+               loops_per_jiffy = cur_s->lpj;
+               udelay(drv_state.acpu_switch_time_us);
+       }
+
+       /* Nothing else to do for power collapse. */
+       if (for_power_collapse)
+               return 0;
+
+       /* Disable PLLs we are not using anymore. */
+       plls_enabled &= ~(1 << tgt_s->pll);
+       for (pll = ACPU_PLL_0; pll <= ACPU_PLL_2; pll++)
+               if (plls_enabled & (1 << pll)) {
+                       rc = pc_pll_request(pll, 0);
+                       if (rc < 0) {
+                               pr_err("PLL%d disable failed (%d)\n", pll, rc);
+                               goto out;
+                       }
+               }
+
+       /* Change the AXI bus frequency if we can. */
+       if (strt_s->axiclk_khz != tgt_s->axiclk_khz) {
+               rc = clk_set_rate(ebi1_clk, tgt_s->axiclk_khz * 1000);
+               if (rc < 0)
+                       pr_err("Setting AXI min rate failed!\n");
+       }
+
+       /* Drop VDD level if we can. */
+       if (tgt_s->vdd < strt_s->vdd) {
+               if (acpuclk_set_vdd_level(tgt_s->vdd) < 0)
+                       printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd\n");
+       }
+
+#if PERF_SWITCH_DEBUG
+       printk(KERN_DEBUG "%s: ACPU speed change complete\n", __FUNCTION__);
+#endif
+out:
+       if (!for_power_collapse)
+               mutex_unlock(&drv_state.lock);
+       return rc;
+}
+
+static void __init acpuclk_init(void)
+{
+       struct clkctl_acpu_speed *speed;
+       uint32_t div, sel;
+       int rc;
+
+       /*
+        * Determine the rate of ACPU clock
+        */
+
+       if (!(readl(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */
+               /* CLK_SRC0_SEL */
+               sel = (readl(A11S_CLK_CNTL_ADDR) >> 12) & 0x7;
+               /* CLK_SRC0_DIV */
+               div = (readl(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f;
+       } else {
+               /* CLK_SRC1_SEL */
+               sel = (readl(A11S_CLK_CNTL_ADDR) >> 4) & 0x07;
+               /* CLK_SRC1_DIV */
+               div = readl(A11S_CLK_CNTL_ADDR) & 0x0f;
+       }
+
+       for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) {
+               if (speed->a11clk_src_sel == sel
+                && (speed->a11clk_src_div == div))
+                       break;
+       }
+       if (speed->a11clk_khz == 0) {
+               printk(KERN_WARNING "Warning - ACPU clock reports invalid speed\n");
+               return;
+       }
+
+       drv_state.current_speed = speed;
+
+       rc = clk_set_rate(ebi1_clk, speed->axiclk_khz * 1000);
+       if (rc < 0)
+               pr_err("Setting AXI min rate failed!\n");
+
+       printk(KERN_INFO "ACPU running at %d KHz\n", speed->a11clk_khz);
+}
+
+unsigned long acpuclk_get_rate(void)
+{
+       WARN_ONCE(drv_state.current_speed == NULL,
+                 "acpuclk_get_rate: not initialized\n");
+       if (drv_state.current_speed)
+               return drv_state.current_speed->a11clk_khz;
+       else
+               return 0;
+}
+
+uint32_t acpuclk_get_switch_time(void)
+{
+       return drv_state.acpu_switch_time_us;
+}
+
+/*----------------------------------------------------------------------------
+ * Clock driver initialization
+ *---------------------------------------------------------------------------*/
+
+/* Initalize the lpj field in the acpu_freq_tbl. */
+static void __init lpj_init(void)
+{
+       int i;
+       const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+       for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
+               acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
+                                               base_clk->a11clk_khz,
+                                               acpu_freq_tbl[i].a11clk_khz);
+       }
+}
+
+void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
+{
+       pr_info("acpu_clock_init()\n");
+
+       ebi1_clk = clk_get(NULL, "ebi1_clk");
+
+       mutex_init(&drv_state.lock);
+       drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us;
+       drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz;
+       drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
+       drv_state.power_collapse_khz = clkdata->power_collapse_khz;
+       drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz;
+       acpuclk_init();
+       lpj_init();
+#ifdef CONFIG_CPU_FREQ_TABLE
+       cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
+#endif
+}
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
new file mode 100644 (file)
index 0000000..415de2e
--- /dev/null
@@ -0,0 +1,32 @@
+/* arch/arm/mach-msm/acpuclock.h
+ *
+ * MSM architecture clock driver header
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ * Author: San Mehat <san@android.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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_H
+#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_H
+
+int acpuclk_set_rate(unsigned long rate, int for_power_collapse);
+unsigned long acpuclk_get_rate(void);
+uint32_t acpuclk_get_switch_time(void);
+unsigned long acpuclk_wait_for_irq(void);
+unsigned long acpuclk_power_collapse(void);
+unsigned long acpuclk_get_wfi_rate(void);
+
+
+#endif
+
diff --git a/arch/arm/mach-msm/board-dream.c b/arch/arm/mach-msm/board-dream.c
deleted file mode 100644 (file)
index 21afa85..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* linux/arch/arm/mach-msm/board-dream.c
- *
- * Copyright (C) 2009 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 <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/setup.h>
-
-#include <mach/board.h>
-#include <mach/hardware.h>
-#include <mach/msm_iomap.h>
-
-#include "devices.h"
-#include "board-dream.h"
-
-static struct platform_device *devices[] __initdata = {
-       &msm_device_uart3,
-       &msm_device_smd,
-       &msm_device_nand,
-       &msm_device_hsusb,
-       &msm_device_i2c,
-};
-
-extern struct sys_timer msm_timer;
-
-static void __init trout_init_irq(void)
-{
-       msm_init_irq();
-}
-
-static void __init trout_fixup(struct machine_desc *desc, struct tag *tags,
-                               char **cmdline, struct meminfo *mi)
-{
-       mi->nr_banks = 1;
-       mi->bank[0].start = PHYS_OFFSET;
-       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
-       mi->bank[0].size = (101*1024*1024);
-}
-
-static void __init trout_init(void)
-{
-       platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-static struct map_desc trout_io_desc[] __initdata = {
-       {
-               .virtual = TROUT_CPLD_BASE,
-               .pfn     = __phys_to_pfn(TROUT_CPLD_START),
-               .length  = TROUT_CPLD_SIZE,
-               .type    = MT_DEVICE_NONSHARED
-       }
-};
-
-static void __init trout_map_io(void)
-{
-       msm_map_common_io();
-       iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc));
-
-#ifdef CONFIG_MSM_DEBUG_UART3
-       /* route UART3 to the "H2W" extended usb connector */
-       writeb(0x80, TROUT_CPLD_BASE + 0x00);
-#endif
-
-       msm_clock_init();
-}
-
-MACHINE_START(TROUT, "HTC Dream")
-       .phys_io        = MSM_DEBUG_UART_PHYS,
-       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
-       .boot_params    = 0x10000100,
-       .fixup          = trout_fixup,
-       .map_io         = trout_map_io,
-       .init_irq       = trout_init_irq,
-       .init_machine   = trout_init,
-       .timer          = &msm_timer,
-MACHINE_END
diff --git a/arch/arm/mach-msm/board-dream.h b/arch/arm/mach-msm/board-dream.h
deleted file mode 100644 (file)
index 4f345a5..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-
-#define TROUT_CPLD_BASE   0xE8100000
-#define TROUT_CPLD_START  0x98000000
-#define TROUT_CPLD_SIZE   SZ_4K
-
index e61967d..7bd72e8 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
+#include <asm/setup.h>
 
 #include <mach/irqs.h>
 #include <mach/board.h>
@@ -77,14 +78,28 @@ static void __init halibut_init(void)
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
+static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
+                                char **cmdline, struct meminfo *mi)
+{
+       mi->nr_banks=1;
+       mi->bank[0].start = PHYS_OFFSET;
+       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+       mi->bank[0].size = (101*1024*1024);
+}
+
 static void __init halibut_map_io(void)
 {
        msm_map_common_io();
-       msm_clock_init();
+       msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
 }
 
 MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
        .boot_params    = 0x10000100,
+       .fixup          = halibut_fixup,
        .map_io         = halibut_map_io,
        .init_irq       = halibut_init_irq,
        .init_machine   = halibut_init,
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
new file mode 100644 (file)
index 0000000..bcbefdf
--- /dev/null
@@ -0,0 +1,87 @@
+/* linux/arch/arm/mach-msm/board-mahimahi.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2009 HTC Corporation.
+ * Author: Dima Zavin <dima@android.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 <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/io.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/setup.h>
+
+#include <mach/board.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+
+#include "board-mahimahi.h"
+#include "devices.h"
+#include "proc_comm.h"
+
+static uint debug_uart;
+
+module_param_named(debug_uart, debug_uart, uint, 0);
+
+static struct platform_device *devices[] __initdata = {
+#if !defined(CONFIG_MSM_SERIAL_DEBUGGER)
+       &msm_device_uart1,
+#endif
+       &msm_device_uart_dm1,
+       &msm_device_nand,
+};
+
+static void __init mahimahi_init(void)
+{
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mahimahi_fixup(struct machine_desc *desc, struct tag *tags,
+                                char **cmdline, struct meminfo *mi)
+{
+       mi->nr_banks = 2;
+       mi->bank[0].start = PHYS_OFFSET;
+       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+       mi->bank[0].size = (219*1024*1024);
+       mi->bank[1].start = MSM_HIGHMEM_BASE;
+       mi->bank[1].node = PHYS_TO_NID(MSM_HIGHMEM_BASE);
+       mi->bank[1].size = MSM_HIGHMEM_SIZE;
+}
+
+static void __init mahimahi_map_io(void)
+{
+       msm_map_common_io();
+       msm_clock_init();
+}
+
+extern struct sys_timer msm_timer;
+
+MACHINE_START(MAHIMAHI, "mahimahi")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = 0x20000100,
+       .fixup          = mahimahi_fixup,
+       .map_io         = mahimahi_map_io,
+       .init_irq       = msm_init_irq,
+       .init_machine   = mahimahi_init,
+       .timer          = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
new file mode 100644 (file)
index 0000000..cccb9f3
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2009, 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/power_supply.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/setup.h>
+#ifdef CONFIG_CACHE_L2X0
+#include <asm/hardware/cache-l2x0.h>
+#endif
+
+#include <mach/vreg.h>
+#include <mach/mpp.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "devices.h"
+#include "socinfo.h"
+#include "clock.h"
+
+static struct resource smc91x_resources[] = {
+       [0] = {
+               .start  = 0x9C004300,
+               .end    = 0x9C0043ff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = MSM_GPIO_TO_INT(132),
+               .end    = MSM_GPIO_TO_INT(132),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device smc91x_device = {
+       .name           = "smc91x",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .resource       = smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+       &msm_device_uart3,
+       &msm_device_smd,
+       &msm_device_dmov,
+       &msm_device_nand,
+       &smc91x_device,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init msm7x2x_init_irq(void)
+{
+       msm_init_irq();
+}
+
+static void __init msm7x2x_init(void)
+{
+       if (socinfo_init() < 0)
+               BUG();
+
+       if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) {
+               smc91x_resources[0].start = 0x98000300;
+               smc91x_resources[0].end = 0x980003ff;
+               smc91x_resources[1].start = MSM_GPIO_TO_INT(85);
+               smc91x_resources[1].end = MSM_GPIO_TO_INT(85);
+               if (gpio_tlmm_config(GPIO_CFG(85, 0,
+                                             GPIO_INPUT,
+                                             GPIO_PULL_DOWN,
+                                             GPIO_2MA),
+                                    GPIO_ENABLE)) {
+                       printk(KERN_ERR
+                              "%s: Err: Config GPIO-85 INT\n",
+                               __func__);
+               }
+       }
+
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init msm7x2x_map_io(void)
+{
+       msm_map_common_io();
+       /* Technically dependent on the SoC but using machine_is
+        * macros since socinfo is not available this early and there
+        * are plans to restructure the code which will eliminate the
+        * need for socinfo.
+        */
+       if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa())
+               msm_clock_init(msm_clocks_7x27, msm_num_clocks_7x27);
+
+       if (machine_is_msm7x25_surf() || machine_is_msm7x25_ffa())
+               msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25);
+
+#ifdef CONFIG_CACHE_L2X0
+       if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) {
+               /* 7x27 has 256KB L2 cache:
+                       64Kb/Way and 4-Way Associativity;
+                       R/W latency: 3 cycles;
+                       evmon/parity/share disabled. */
+               l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000);
+       }
+#endif
+}
+
+MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = PHYS_OFFSET + 0x100,
+       .map_io         = msm7x2x_map_io,
+       .init_irq       = msm7x2x_init_irq,
+       .init_machine   = msm7x2x_init,
+       .timer          = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = PHYS_OFFSET + 0x100,
+       .map_io         = msm7x2x_map_io,
+       .init_irq       = msm7x2x_init_irq,
+       .init_machine   = msm7x2x_init,
+       .timer          = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = PHYS_OFFSET + 0x100,
+       .map_io         = msm7x2x_map_io,
+       .init_irq       = msm7x2x_init_irq,
+       .init_machine   = msm7x2x_init,
+       .timer          = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = PHYS_OFFSET + 0x100,
+       .map_io         = msm7x2x_map_io,
+       .init_irq       = msm7x2x_init_irq,
+       .init_machine   = msm7x2x_init,
+       .timer          = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
new file mode 100644 (file)
index 0000000..bac1f3c
--- /dev/null
@@ -0,0 +1,120 @@
+/* Copyright (c) 2009-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/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/memory.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+
+#include <mach/vreg.h>
+#include "devices.h"
+#include "proc_comm.h"
+
+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
+
+};
+
+static void __init msm7x30_init_irq(void)
+{
+       msm_init_irq();
+}
+
+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)
+{
+       msm_map_msm7x30_io();
+       msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
+}
+
+MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io  = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params = PHYS_OFFSET + 0x100,
+       .map_io = msm7x30_map_io,
+       .init_irq = msm7x30_init_irq,
+       .init_machine = msm7x30_init,
+       .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io  = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params = PHYS_OFFSET + 0x100,
+       .map_io = msm7x30_map_io,
+       .init_irq = msm7x30_init_irq,
+       .init_machine = msm7x30_init,
+       .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io  = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params = PHYS_OFFSET + 0x100,
+       .map_io = msm7x30_map_io,
+       .init_irq = msm7x30_init_irq,
+       .init_machine = msm7x30_init,
+       .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
new file mode 100644 (file)
index 0000000..ec46066
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (c) 2008-2009, 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/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/irqs.h>
+#include <mach/sirc.h>
+#include <mach/gpio.h>
+
+#include "devices.h"
+
+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 struct platform_device *devices[] __initdata = {
+       &msm_device_uart3,
+};
+
+static void msm8x50_init_uart3(void)
+{
+       msm_gpios_request_enable(uart3_config_data,
+                               ARRAY_SIZE(uart3_config_data));
+}
+
+static void __init qsd8x50_map_io(void)
+{
+       msm_map_qsd8x50_io();
+       msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);
+}
+
+static void __init qsd8x50_init_irq(void)
+{
+       msm_init_irq();
+       msm_init_sirc();
+}
+
+static void __init qsd8x50_init(void)
+{
+       msm8x50_init_uart3();
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io  = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params = PHYS_OFFSET + 0x100,
+       .map_io = qsd8x50_map_io,
+       .init_irq = qsd8x50_init_irq,
+       .init_machine = qsd8x50_init,
+       .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io  = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params = PHYS_OFFSET + 0x100,
+       .map_io = qsd8x50_map_io,
+       .init_irq = qsd8x50_init_irq,
+       .init_machine = qsd8x50_init,
+       .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
new file mode 100644 (file)
index 0000000..2bc1b9d
--- /dev/null
@@ -0,0 +1,118 @@
+/* linux/arch/arm/mach-msm/board-sapphire.c
+ * Copyright (C) 2007-2009 HTC Corporation.
+ * Author: Thomas Tsai <thomas_tsai@htc.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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sysdev.h>
+
+#include <linux/delay.h>
+
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/system.h>
+#include <mach/system.h>
+#include <mach/vreg.h>
+#include <mach/board.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/setup.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "gpio_chip.h"
+#include "board-sapphire.h"
+#include "proc_comm.h"
+#include "devices.h"
+
+void msm_init_irq(void);
+void msm_init_gpio(void);
+
+static struct platform_device *devices[] __initdata = {
+       &msm_device_smd,
+       &msm_device_dmov,
+       &msm_device_nand,
+       &msm_device_uart1,
+       &msm_device_uart3,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init sapphire_init_irq(void)
+{
+       msm_init_irq();
+}
+
+static void __init sapphire_init(void)
+{
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc sapphire_io_desc[] __initdata = {
+       {
+               .virtual = SAPPHIRE_CPLD_BASE,
+               .pfn     = __phys_to_pfn(SAPPHIRE_CPLD_START),
+               .length  = SAPPHIRE_CPLD_SIZE,
+               .type    = MT_DEVICE_NONSHARED
+       }
+};
+
+static void __init sapphire_fixup(struct machine_desc *desc, struct tag *tags,
+                                 char **cmdline, struct meminfo *mi)
+{
+       int smi_sz = parse_tag_smi((const struct tag *)tags);
+
+       mi->nr_banks = 1;
+       mi->bank[0].start = PHYS_OFFSET;
+       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+       if (smi_sz == 32) {
+               mi->bank[0].size = (84*1024*1024);
+       } else if (smi_sz == 64) {
+               mi->bank[0].size = (101*1024*1024);
+       } else {
+               /* Give a default value when not get smi size */
+               smi_sz = 64;
+               mi->bank[0].size = (101*1024*1024);
+       }
+}
+
+static void __init sapphire_map_io(void)
+{
+       msm_map_common_io();
+       iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc));
+       msm_clock_init();
+}
+
+MACHINE_START(SAPPHIRE, "sapphire")
+/* Maintainer: Brian Swetland <swetland@google.com> */
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = PHYS_OFFSET + 0x100,
+       .fixup          = sapphire_fixup,
+       .map_io         = sapphire_map_io,
+       .init_irq       = sapphire_init_irq,
+       .init_machine   = sapphire_init,
+       .timer          = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
new file mode 100644 (file)
index 0000000..dca5a5f
--- /dev/null
@@ -0,0 +1,95 @@
+/* linux/arch/arm/mach-msm/board-trout.c
+ *
+ * Copyright (C) 2009 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/hardware.h>
+#include <mach/msm_iomap.h>
+
+#include "devices.h"
+#include "board-trout.h"
+
+static struct platform_device *devices[] __initdata = {
+       &msm_device_uart3,
+       &msm_device_smd,
+       &msm_device_nand,
+       &msm_device_hsusb,
+       &msm_device_i2c,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init trout_init_irq(void)
+{
+       msm_init_irq();
+}
+
+static void __init trout_fixup(struct machine_desc *desc, struct tag *tags,
+                               char **cmdline, struct meminfo *mi)
+{
+       mi->nr_banks = 1;
+       mi->bank[0].start = PHYS_OFFSET;
+       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+       mi->bank[0].size = (101*1024*1024);
+}
+
+static void __init trout_init(void)
+{
+       platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc trout_io_desc[] __initdata = {
+       {
+               .virtual = TROUT_CPLD_BASE,
+               .pfn     = __phys_to_pfn(TROUT_CPLD_START),
+               .length  = TROUT_CPLD_SIZE,
+               .type    = MT_DEVICE_NONSHARED
+       }
+};
+
+static void __init trout_map_io(void)
+{
+       msm_map_common_io();
+       iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc));
+
+#ifdef CONFIG_MSM_DEBUG_UART3
+       /* route UART3 to the "H2W" extended usb connector */
+       writeb(0x80, TROUT_CPLD_BASE + 0x00);
+#endif
+
+       msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
+}
+
+MACHINE_START(TROUT, "HTC Dream")
+#ifdef CONFIG_MSM_DEBUG_UART
+       .phys_io        = MSM_DEBUG_UART_PHYS,
+       .io_pg_offst    = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc,
+#endif
+       .boot_params    = 0x10000100,
+       .fixup          = trout_fixup,
+       .map_io         = trout_map_io,
+       .init_irq       = trout_init_irq,
+       .init_machine   = trout_init,
+       .timer          = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-trout.h b/arch/arm/mach-msm/board-trout.h
new file mode 100644 (file)
index 0000000..4f345a5
--- /dev/null
@@ -0,0 +1,5 @@
+
+#define TROUT_CPLD_BASE   0xE8100000
+#define TROUT_CPLD_START  0x98000000
+#define TROUT_CPLD_SIZE   SZ_4K
+
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c
deleted file mode 100644 (file)
index 62230a3..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* arch/arm/mach-msm/clock-7x01a.c
- *
- * Clock tables for MSM7X01A
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007 QUALCOMM Incorporated
- *
- * 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 <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include "clock.h"
-#include "devices.h"
-
-/* clock IDs used by the modem processor */
-
-#define ACPU_CLK       0   /* Applications processor clock */
-#define ADM_CLK                1   /* Applications data mover clock */
-#define ADSP_CLK       2   /* ADSP clock */
-#define EBI1_CLK       3   /* External bus interface 1 clock */
-#define EBI2_CLK       4   /* External bus interface 2 clock */
-#define ECODEC_CLK     5   /* External CODEC clock */
-#define EMDH_CLK       6   /* External MDDI host clock */
-#define GP_CLK         7   /* General purpose clock */
-#define GRP_CLK                8   /* Graphics clock */
-#define I2C_CLK                9   /* I2C clock */
-#define ICODEC_RX_CLK  10  /* Internal CODEX RX clock */
-#define ICODEC_TX_CLK  11  /* Internal CODEX TX clock */
-#define IMEM_CLK       12  /* Internal graphics memory clock */
-#define MDC_CLK                13  /* MDDI client clock */
-#define MDP_CLK                14  /* Mobile display processor clock */
-#define PBUS_CLK       15  /* Peripheral bus clock */
-#define PCM_CLK                16  /* PCM clock */
-#define PMDH_CLK       17  /* Primary MDDI host clock */
-#define SDAC_CLK       18  /* Stereo DAC clock */
-#define SDC1_CLK       19  /* Secure Digital Card clocks */
-#define SDC1_PCLK      20
-#define SDC2_CLK       21
-#define SDC2_PCLK      22
-#define SDC3_CLK       23
-#define SDC3_PCLK      24
-#define SDC4_CLK       25
-#define SDC4_PCLK      26
-#define TSIF_CLK       27  /* Transport Stream Interface clocks */
-#define TSIF_REF_CLK   28
-#define TV_DAC_CLK     29  /* TV clocks */
-#define TV_ENC_CLK     30
-#define UART1_CLK      31  /* UART clocks */
-#define UART2_CLK      32
-#define UART3_CLK      33
-#define UART1DM_CLK    34
-#define UART2DM_CLK    35
-#define USB_HS_CLK     36  /* High speed USB core clock */
-#define USB_HS_PCLK    37  /* High speed USB pbus clock */
-#define USB_OTG_CLK    38  /* Full speed USB clock */
-#define VDC_CLK                39  /* Video controller clock */
-#define VFE_CLK                40  /* Camera / Video Front End clock */
-#define VFE_MDC_CLK    41  /* VFE MDDI client clock */
-
-#define NR_CLKS                42
-
-#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) {  \
-       .name = clk_name, \
-       .id = clk_id, \
-       .flags = clk_flags, \
-       .dev = clk_dev, \
-       }
-
-#define OFF CLKFLAG_AUTO_OFF
-#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
-
-struct clk msm_clocks[] = {
-       CLOCK("adm_clk",        ADM_CLK,        NULL, 0),
-       CLOCK("adsp_clk",       ADSP_CLK,       NULL, 0),
-       CLOCK("ebi1_clk",       EBI1_CLK,       NULL, 0),
-       CLOCK("ebi2_clk",       EBI2_CLK,       NULL, 0),
-       CLOCK("ecodec_clk",     ECODEC_CLK,     NULL, 0),
-       CLOCK("emdh_clk",       EMDH_CLK,       NULL, OFF),
-       CLOCK("gp_clk",         GP_CLK,         NULL, 0),
-       CLOCK("grp_clk",        GRP_CLK,        NULL, OFF),
-       CLOCK("i2c_clk",        I2C_CLK,        &msm_device_i2c.dev, 0),
-       CLOCK("icodec_rx_clk",  ICODEC_RX_CLK,  NULL, 0),
-       CLOCK("icodec_tx_clk",  ICODEC_TX_CLK,  NULL, 0),
-       CLOCK("imem_clk",       IMEM_CLK,       NULL, OFF),
-       CLOCK("mdc_clk",        MDC_CLK,        NULL, 0),
-       CLOCK("mdp_clk",        MDP_CLK,        NULL, OFF),
-       CLOCK("pbus_clk",       PBUS_CLK,       NULL, 0),
-       CLOCK("pcm_clk",        PCM_CLK,        NULL, 0),
-       CLOCK("pmdh_clk",       PMDH_CLK,       NULL, OFF | MINMAX),
-       CLOCK("sdac_clk",       SDAC_CLK,       NULL, OFF),
-       CLOCK("sdc_clk",        SDC1_CLK,       &msm_device_sdc1.dev, OFF),
-       CLOCK("sdc_pclk",       SDC1_PCLK,      &msm_device_sdc1.dev, OFF),
-       CLOCK("sdc_clk",        SDC2_CLK,       &msm_device_sdc2.dev, OFF),
-       CLOCK("sdc_pclk",       SDC2_PCLK,      &msm_device_sdc2.dev, OFF),
-       CLOCK("sdc_clk",        SDC3_CLK,       &msm_device_sdc3.dev, OFF),
-       CLOCK("sdc_pclk",       SDC3_PCLK,      &msm_device_sdc3.dev, OFF),
-       CLOCK("sdc_clk",        SDC4_CLK,       &msm_device_sdc4.dev, OFF),
-       CLOCK("sdc_pclk",       SDC4_PCLK,      &msm_device_sdc4.dev, OFF),
-       CLOCK("tsif_clk",       TSIF_CLK,       NULL, 0),
-       CLOCK("tsif_ref_clk",   TSIF_REF_CLK,   NULL, 0),
-       CLOCK("tv_dac_clk",     TV_DAC_CLK,     NULL, 0),
-       CLOCK("tv_enc_clk",     TV_ENC_CLK,     NULL, 0),
-       CLOCK("uart_clk",       UART1_CLK,      &msm_device_uart1.dev, OFF),
-       CLOCK("uart_clk",       UART2_CLK,      &msm_device_uart2.dev, 0),
-       CLOCK("uart_clk",       UART3_CLK,      &msm_device_uart3.dev, OFF),
-       CLOCK("uart1dm_clk",    UART1DM_CLK,    NULL, OFF),
-       CLOCK("uart2dm_clk",    UART2DM_CLK,    NULL, 0),
-       CLOCK("usb_hs_clk",     USB_HS_CLK,     &msm_device_hsusb.dev, OFF),
-       CLOCK("usb_hs_pclk",    USB_HS_PCLK,    &msm_device_hsusb.dev, OFF),
-       CLOCK("usb_otg_clk",    USB_OTG_CLK,    NULL, 0),
-       CLOCK("vdc_clk",        VDC_CLK,        NULL, OFF | MINMAX),
-       CLOCK("vfe_clk",        VFE_CLK,        NULL, OFF),
-       CLOCK("vfe_mdc_clk",    VFE_MDC_CLK,    NULL, OFF),
-};
-
-unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);
diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h
new file mode 100644 (file)
index 0000000..e16f72f
--- /dev/null
@@ -0,0 +1,168 @@
+/* Copyright (c) 2009, 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 Forum, Inc. 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 "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 __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
+
+enum {
+       L_7X30_NONE_CLK = -1,
+       L_7X30_ADM_CLK,
+       L_7X30_I2C_CLK,
+       L_7X30_I2C_2_CLK,
+       L_7X30_QUP_I2C_CLK,
+       L_7X30_UART1DM_CLK,
+       L_7X30_UART1DM_P_CLK,
+       L_7X30_UART2DM_CLK,
+       L_7X30_UART2DM_P_CLK,
+       L_7X30_EMDH_CLK,
+       L_7X30_EMDH_P_CLK,
+       L_7X30_PMDH_CLK,
+       L_7X30_PMDH_P_CLK,
+       L_7X30_GRP_2D_CLK,
+       L_7X30_GRP_2D_P_CLK,
+       L_7X30_GRP_3D_SRC_CLK,
+       L_7X30_GRP_3D_CLK,
+       L_7X30_GRP_3D_P_CLK,
+       L_7X30_IMEM_CLK,
+       L_7X30_SDC1_CLK,
+       L_7X30_SDC1_P_CLK,
+       L_7X30_SDC2_CLK,
+       L_7X30_SDC2_P_CLK,
+       L_7X30_SDC3_CLK,
+       L_7X30_SDC3_P_CLK,
+       L_7X30_SDC4_CLK,
+       L_7X30_SDC4_P_CLK,
+       L_7X30_MDP_CLK,
+       L_7X30_MDP_P_CLK,
+       L_7X30_MDP_LCDC_PCLK_CLK,
+       L_7X30_MDP_LCDC_PAD_PCLK_CLK,
+       L_7X30_MDP_VSYNC_CLK,
+       L_7X30_MI2S_CODEC_RX_M_CLK,
+       L_7X30_MI2S_CODEC_RX_S_CLK,
+       L_7X30_MI2S_CODEC_TX_M_CLK,
+       L_7X30_MI2S_CODEC_TX_S_CLK,
+       L_7X30_MI2S_M_CLK,
+       L_7X30_MI2S_S_CLK,
+       L_7X30_LPA_CODEC_CLK,
+       L_7X30_LPA_CORE_CLK,
+       L_7X30_LPA_P_CLK,
+       L_7X30_MIDI_CLK,
+       L_7X30_MDC_CLK,
+       L_7X30_ROTATOR_IMEM_CLK,
+       L_7X30_ROTATOR_P_CLK,
+       L_7X30_SDAC_M_CLK,
+       L_7X30_SDAC_CLK,
+       L_7X30_UART1_CLK,
+       L_7X30_UART2_CLK,
+       L_7X30_UART3_CLK,
+       L_7X30_TV_CLK,
+       L_7X30_TV_DAC_CLK,
+       L_7X30_TV_ENC_CLK,
+       L_7X30_HDMI_CLK,
+       L_7X30_TSIF_REF_CLK,
+       L_7X30_TSIF_P_CLK,
+       L_7X30_USB_HS_SRC_CLK,
+       L_7X30_USB_HS_CLK,
+       L_7X30_USB_HS_CORE_CLK,
+       L_7X30_USB_HS_P_CLK,
+       L_7X30_USB_HS2_CLK,
+       L_7X30_USB_HS2_CORE_CLK,
+       L_7X30_USB_HS2_P_CLK,
+       L_7X30_USB_HS3_CLK,
+       L_7X30_USB_HS3_CORE_CLK,
+       L_7X30_USB_HS3_P_CLK,
+       L_7X30_VFE_CLK,
+       L_7X30_VFE_P_CLK,
+       L_7X30_VFE_MDC_CLK,
+       L_7X30_VFE_CAMIF_CLK,
+       L_7X30_CAMIF_PAD_P_CLK,
+       L_7X30_CAM_M_CLK,
+       L_7X30_JPEG_CLK,
+       L_7X30_JPEG_P_CLK,
+       L_7X30_VPE_CLK,
+       L_7X30_MFC_CLK,
+       L_7X30_MFC_DIV2_CLK,
+       L_7X30_MFC_P_CLK,
+       L_7X30_SPI_CLK,
+       L_7X30_SPI_P_CLK,
+       L_7X30_CSI0_CLK,
+       L_7X30_CSI0_VFE_CLK,
+       L_7X30_CSI0_P_CLK,
+       L_7X30_CSI1_CLK,
+       L_7X30_CSI1_VFE_CLK,
+       L_7X30_CSI1_P_CLK,
+       L_7X30_GLBL_ROOT_CLK,
+
+       L_7X30_AXI_LI_VG_CLK,
+       L_7X30_AXI_LI_GRP_CLK,
+       L_7X30_AXI_LI_JPEG_CLK,
+       L_7X30_AXI_GRP_2D_CLK,
+       L_7X30_AXI_MFC_CLK,
+       L_7X30_AXI_VPE_CLK,
+       L_7X30_AXI_LI_VFE_CLK,
+       L_7X30_AXI_LI_APPS_CLK,
+       L_7X30_AXI_MDP_CLK,
+       L_7X30_AXI_IMEM_CLK,
+       L_7X30_AXI_LI_ADSP_A_CLK,
+       L_7X30_AXI_ROTATOR_CLK,
+
+       L_7X30_NR_CLKS
+};
+
+struct clk_ops;
+extern struct clk_ops clk_ops_7x30;
+
+struct clk_ops *clk_7x30_is_local(uint32_t id);
+int clk_7x30_init(void);
+
+void pll_enable(uint32_t pll);
+void pll_disable(uint32_t pll);
+
+extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable);
+
+#define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) {       \
+       .name = clk_name, \
+       .id = L_7X30_##clk_id, \
+       .remote_id = P_##clk_id, \
+       .flags = clk_flags, \
+       .dev = clk_dev, \
+       .dbg_name = #clk_id, \
+       }
+
+#define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) {  \
+       .name = clk_name, \
+       .id = L_7X30_##l_id, \
+       .remote_id = P_##r_id, \
+       .flags = clk_flags, \
+       .dev = clk_dev, \
+       .dbg_name = #l_id, \
+       }
+
+#endif
+
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
new file mode 100644 (file)
index 0000000..a3b4562
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-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.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <mach/clk.h>
+
+#include "proc_comm.h"
+#include "clock.h"
+
+/*
+ * glue for the proc_comm interface
+ */
+int pc_clk_enable(unsigned id)
+{
+       int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
+       if (rc < 0)
+               return rc;
+       else
+               return (int)id < 0 ? -EINVAL : 0;
+}
+
+void pc_clk_disable(unsigned id)
+{
+       msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
+}
+
+int pc_clk_reset(unsigned id, enum clk_reset_action action)
+{
+       int rc;
+
+       if (action == CLK_RESET_ASSERT)
+               rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
+       else
+               rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
+
+       if (rc < 0)
+               return rc;
+       else
+               return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_rate(unsigned id, unsigned rate)
+{
+       /* The rate _might_ be rounded off to the nearest KHz value by the
+        * remote function. So a return value of 0 doesn't necessarily mean
+        * that the exact rate was set successfully.
+        */
+       int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+       if (rc < 0)
+               return rc;
+       else
+               return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_min_rate(unsigned id, unsigned rate)
+{
+       int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
+       if (rc < 0)
+               return rc;
+       else
+               return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_max_rate(unsigned id, unsigned rate)
+{
+       int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
+       if (rc < 0)
+               return rc;
+       else
+               return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_flags(unsigned id, unsigned flags)
+{
+       int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
+       if (rc < 0)
+               return rc;
+       else
+               return (int)id < 0 ? -EINVAL : 0;
+}
+
+unsigned pc_clk_get_rate(unsigned id)
+{
+       if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
+               return 0;
+       else
+               return id;
+}
+
+unsigned pc_clk_is_enabled(unsigned id)
+{
+       if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
+               return 0;
+       else
+               return id;
+}
+
+long pc_clk_round_rate(unsigned id, unsigned rate)
+{
+
+       /* Not really supported; pc_clk_set_rate() does rounding on it's own. */
+       return rate;
+}
+
+struct clk_ops clk_ops_pcom = {
+       .enable = pc_clk_enable,
+       .disable = pc_clk_disable,
+       .auto_off = pc_clk_disable,
+       .reset = pc_clk_reset,
+       .set_rate = pc_clk_set_rate,
+       .set_min_rate = pc_clk_set_min_rate,
+       .set_max_rate = pc_clk_set_max_rate,
+       .set_flags = pc_clk_set_flags,
+       .get_rate = pc_clk_get_rate,
+       .is_enabled = pc_clk_is_enabled,
+       .round_rate = pc_clk_round_rate,
+};
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
new file mode 100644 (file)
index 0000000..17d027b
--- /dev/null
@@ -0,0 +1,153 @@
+/* Copyright (c) 2009, 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 Forum, Inc. 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 "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 __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
+
+/* clock IDs used by the modem processor */
+
+#define P_ACPU_CLK     0   /* Applications processor clock */
+#define P_ADM_CLK      1   /* Applications data mover clock */
+#define P_ADSP_CLK     2   /* ADSP clock */
+#define P_EBI1_CLK     3   /* External bus interface 1 clock */
+#define P_EBI2_CLK     4   /* External bus interface 2 clock */
+#define P_ECODEC_CLK   5   /* External CODEC clock */
+#define P_EMDH_CLK     6   /* External MDDI host clock */
+#define P_GP_CLK       7   /* General purpose clock */
+#define P_GRP_3D_CLK   8   /* Graphics clock */
+#define P_I2C_CLK      9   /* I2C clock */
+#define P_ICODEC_RX_CLK        10  /* Internal CODEX RX clock */
+#define P_ICODEC_TX_CLK        11  /* Internal CODEX TX clock */
+#define P_IMEM_CLK     12  /* Internal graphics memory clock */
+#define P_MDC_CLK      13  /* MDDI client clock */
+#define P_MDP_CLK      14  /* Mobile display processor clock */
+#define P_PBUS_CLK     15  /* Peripheral bus clock */
+#define P_PCM_CLK      16  /* PCM clock */
+#define P_PMDH_CLK     17  /* Primary MDDI host clock */
+#define P_SDAC_CLK     18  /* Stereo DAC clock */
+#define P_SDC1_CLK     19  /* Secure Digital Card clocks */
+#define P_SDC1_P_CLK   20
+#define P_SDC2_CLK     21
+#define P_SDC2_P_CLK   22
+#define P_SDC3_CLK     23
+#define P_SDC3_P_CLK   24
+#define P_SDC4_CLK     25
+#define P_SDC4_P_CLK   26
+#define P_TSIF_CLK     27  /* Transport Stream Interface clocks */
+#define P_TSIF_REF_CLK 28
+#define P_TV_DAC_CLK   29  /* TV clocks */
+#define P_TV_ENC_CLK   30
+#define P_UART1_CLK    31  /* UART clocks */
+#define P_UART2_CLK    32
+#define P_UART3_CLK    33
+#define P_UART1DM_CLK  34
+#define P_UART2DM_CLK  35
+#define P_USB_HS_CLK   36  /* High speed USB core clock */
+#define P_USB_HS_P_CLK 37  /* High speed USB pbus clock */
+#define P_USB_OTG_CLK  38  /* Full speed USB clock */
+#define P_VDC_CLK      39  /* Video controller clock */
+#define P_VFE_MDC_CLK  40  /* Camera / Video Front End clock */
+#define P_VFE_CLK      41  /* VFE MDDI client clock */
+#define P_MDP_LCDC_PCLK_CLK    42
+#define P_MDP_LCDC_PAD_PCLK_CLK 43
+#define P_MDP_VSYNC_CLK        44
+#define P_SPI_CLK      45
+#define P_VFE_AXI_CLK  46
+#define P_USB_HS2_CLK  47  /* High speed USB 2 core clock */
+#define P_USB_HS2_P_CLK        48  /* High speed USB 2 pbus clock */
+#define P_USB_HS3_CLK  49  /* High speed USB 3 core clock */
+#define P_USB_HS3_P_CLK        50  /* High speed USB 3 pbus clock */
+#define P_GRP_3D_P_CLK 51  /* Graphics pbus clock */
+#define P_USB_PHY_CLK  52  /* USB PHY clock */
+#define P_USB_HS_CORE_CLK      53  /* High speed USB 1 core clock */
+#define P_USB_HS2_CORE_CLK     54  /* High speed USB 2 core clock */
+#define P_USB_HS3_CORE_CLK     55  /* High speed USB 3 core clock */
+#define P_CAM_M_CLK            56
+#define P_CAMIF_PAD_P_CLK      57
+#define P_GRP_2D_CLK           58
+#define P_GRP_2D_P_CLK         59
+#define P_I2S_CLK              60
+#define P_JPEG_CLK             61
+#define P_JPEG_P_CLK           62
+#define P_LPA_CODEC_CLK                63
+#define P_LPA_CORE_CLK         64
+#define P_LPA_P_CLK            65
+#define P_MDC_IO_CLK           66
+#define P_MDC_P_CLK            67
+#define P_MFC_CLK              68
+#define P_MFC_DIV2_CLK         69
+#define P_MFC_P_CLK            70
+#define P_QUP_I2C_CLK          71
+#define P_ROTATOR_IMEM_CLK     72
+#define P_ROTATOR_P_CLK                73
+#define P_VFE_CAMIF_CLK                74
+#define P_VFE_P_CLK            75
+#define P_VPE_CLK              76
+#define P_I2C_2_CLK            77
+#define P_MI2S_CODEC_RX_S_CLK  78
+#define P_MI2S_CODEC_RX_M_CLK  79
+#define P_MI2S_CODEC_TX_S_CLK  80
+#define P_MI2S_CODEC_TX_M_CLK  81
+#define P_PMDH_P_CLK           82
+#define P_EMDH_P_CLK           83
+#define P_SPI_P_CLK            84
+#define P_TSIF_P_CLK           85
+#define P_MDP_P_CLK            86
+#define P_SDAC_M_CLK           87
+#define P_MI2S_S_CLK           88
+#define P_MI2S_M_CLK           89
+#define P_AXI_ROTATOR_CLK      90
+#define P_HDMI_CLK             91
+#define P_CSI0_CLK             92
+#define P_CSI0_VFE_CLK         93
+#define P_CSI0_P_CLK           94
+#define P_CSI1_CLK             95
+#define P_CSI1_VFE_CLK         96
+#define P_CSI1_P_CLK           97
+#define P_GSBI_CLK             98
+#define P_GSBI_P_CLK           99
+
+#define P_NR_CLKS              100
+
+struct clk_ops;
+extern struct clk_ops clk_ops_pcom;
+
+int pc_clk_reset(unsigned id, enum clk_reset_action action);
+
+#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) {       \
+       .name = clk_name, \
+       .id = P_##clk_id, \
+       .remote_id = P_##clk_id, \
+       .ops = &clk_ops_pcom, \
+       .flags = clk_flags, \
+       .dev = clk_dev, \
+       .dbg_name = #clk_id, \
+       }
+
+#endif
index 3b1ce36..9cb1276 100644 (file)
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.c
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007-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/err.h>
 #include <linux/clk.h>
 #include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/ctype.h>
+#include <linux/pm_qos_params.h>
+#include <mach/clk.h>
 
 #include "clock.h"
 #include "proc_comm.h"
+#include "clock-7x30.h"
 
 static DEFINE_MUTEX(clocks_mutex);
 static DEFINE_SPINLOCK(clocks_lock);
 static LIST_HEAD(clocks);
+struct clk *msm_clocks;
+unsigned msm_num_clocks;
 
 /*
- * glue for the proc_comm interface
+ * Bitmap of enabled clocks, excluding ACPU which is always
+ * enabled
  */
-static inline int pc_clk_enable(unsigned id)
-{
-       return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
-}
-
-static inline void pc_clk_disable(unsigned id)
-{
-       msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
-}
-
-static inline int pc_clk_set_rate(unsigned id, unsigned rate)
-{
-       return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
-}
-
-static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
-{
-       return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
-}
-
-static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
-{
-       return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
-}
-
-static inline int pc_clk_set_flags(unsigned id, unsigned flags)
-{
-       return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
-}
-
-static inline unsigned pc_clk_get_rate(unsigned id)
-{
-       if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
-               return 0;
-       else
-               return id;
-}
-
-static inline unsigned pc_clk_is_enabled(unsigned id)
-{
-       if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
-               return 0;
-       else
-               return id;
-}
-
-static inline int pc_pll_request(unsigned id, unsigned on)
-{
-       on = !!on;
-       return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
-}
+static DECLARE_BITMAP(clock_map_enabled, NR_CLKS);
+static DEFINE_SPINLOCK(clock_map_lock);
 
 /*
  * Standard clock functions defined in include/linux/clk.h
@@ -119,8 +78,12 @@ int clk_enable(struct clk *clk)
        unsigned long flags;
        spin_lock_irqsave(&clocks_lock, flags);
        clk->count++;
-       if (clk->count == 1)
-               pc_clk_enable(clk->id);
+       if (clk->count == 1) {
+               clk->ops->enable(clk->id);
+               spin_lock(&clock_map_lock);
+               clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id);
+               spin_unlock(&clock_map_lock);
+       }
        spin_unlock_irqrestore(&clocks_lock, flags);
        return 0;
 }
@@ -132,31 +95,54 @@ void clk_disable(struct clk *clk)
        spin_lock_irqsave(&clocks_lock, flags);
        BUG_ON(clk->count == 0);
        clk->count--;
-       if (clk->count == 0)
-               pc_clk_disable(clk->id);
+       if (clk->count == 0) {
+               clk->ops->disable(clk->id);
+               spin_lock(&clock_map_lock);
+               clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id);
+               spin_unlock(&clock_map_lock);
+       }
        spin_unlock_irqrestore(&clocks_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
+int clk_reset(struct clk *clk, enum clk_reset_action action)
+{
+       if (!clk->ops->reset)
+               clk->ops->reset = &pc_clk_reset;
+       return clk->ops->reset(clk->remote_id, action);
+}
+EXPORT_SYMBOL(clk_reset);
+
 unsigned long clk_get_rate(struct clk *clk)
 {
-       return pc_clk_get_rate(clk->id);
+       return clk->ops->get_rate(clk->id);
 }
 EXPORT_SYMBOL(clk_get_rate);
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
-       int ret;
-       if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
-               ret = pc_clk_set_max_rate(clk->id, rate);
-               if (ret)
-                       return ret;
-               return pc_clk_set_min_rate(clk->id, rate);
-       }
-       return pc_clk_set_rate(clk->id, rate);
+       return clk->ops->set_rate(clk->id, rate);
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       return clk->ops->round_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_min_rate(struct clk *clk, unsigned long rate)
+{
+       return clk->ops->set_min_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_min_rate);
+
+int clk_set_max_rate(struct clk *clk, unsigned long rate)
+{
+       return clk->ops->set_max_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_max_rate);
+
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
        return -ENOSYS;
@@ -173,22 +159,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags)
 {
        if (clk == NULL || IS_ERR(clk))
                return -EINVAL;
-       return pc_clk_set_flags(clk->id, flags);
+       return clk->ops->set_flags(clk->id, flags);
 }
 EXPORT_SYMBOL(clk_set_flags);
 
+/* EBI1 is the only shared clock that several clients want to vote on as of
+ * this commit. If this changes in the future, then it might be better to
+ * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
+ * generic to support different clocks.
+ */
+static struct clk *ebi1_clk;
 
-void __init msm_clock_init(void)
+static void __init set_clock_ops(struct clk *clk)
+{
+       if (!clk->ops) {
+               clk->ops = &clk_ops_pcom;
+               clk->id = clk->remote_id;
+       }
+}
+
+void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks)
 {
        unsigned n;
 
        spin_lock_init(&clocks_lock);
        mutex_lock(&clocks_mutex);
-       for (n = 0; n < msm_num_clocks; n++)
+       msm_clocks = clock_tbl;
+       msm_num_clocks = num_clocks;
+       for (n = 0; n < msm_num_clocks; n++) {
+               set_clock_ops(&msm_clocks[n]);
                list_add_tail(&msm_clocks[n].list, &clocks);
+       }
        mutex_unlock(&clocks_mutex);
+
+       ebi1_clk = clk_get(NULL, "ebi1_clk");
+       BUG_ON(ebi1_clk == NULL);
+
+}
+
+#if defined(CONFIG_DEBUG_FS)
+static struct clk *msm_clock_get_nth(unsigned index)
+{
+       if (index < msm_num_clocks)
+               return msm_clocks + index;
+       else
+               return 0;
+}
+
+static int clock_debug_rate_set(void *data, u64 val)
+{
+       struct clk *clock = data;
+       int ret;
+
+       /* Only increases to max rate will succeed, but that's actually good
+        * for debugging purposes. So we don't check for error. */
+       if (clock->flags & CLK_MAX)
+               clk_set_max_rate(clock, val);
+       if (clock->flags & CLK_MIN)
+               ret = clk_set_min_rate(clock, val);
+       else
+               ret = clk_set_rate(clock, val);
+       if (ret != 0)
+               printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
+                       (clock->flags & CLK_MIN) ? "_min" : "", ret);
+       return ret;
+}
+
+static int clock_debug_rate_get(void *data, u64 *val)
+{
+       struct clk *clock = data;
+       *val = clk_get_rate(clock);
+       return 0;
+}
+
+static int clock_debug_enable_set(void *data, u64 val)
+{
+       struct clk *clock = data;
+       int rc = 0;
+
+       if (val)
+               rc = clock->ops->enable(clock->id);
+       else
+               clock->ops->disable(clock->id);
+
+       return rc;
 }
 
+static int clock_debug_enable_get(void *data, u64 *val)
+{
+       struct clk *clock = data;
+
+       *val = clock->ops->is_enabled(clock->id);
+
+       return 0;
+}
+
+static int clock_debug_local_get(void *data, u64 *val)
+{
+       struct clk *clock = data;
+
+       *val = clock->ops != &clk_ops_pcom;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
+                       clock_debug_rate_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
+                       clock_debug_enable_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
+                       NULL, "%llu\n");
+
+static int __init clock_debug_init(void)
+{
+       struct dentry *dent_rate, *dent_enable, *dent_local;
+       struct clk *clock;
+       unsigned n = 0;
+       char temp[50], *ptr;
+
+       dent_rate = debugfs_create_dir("clk_rate", 0);
+       if (IS_ERR(dent_rate))
+               return PTR_ERR(dent_rate);
+
+       dent_enable = debugfs_create_dir("clk_enable", 0);
+       if (IS_ERR(dent_enable))
+               return PTR_ERR(dent_enable);
+
+       dent_local = debugfs_create_dir("clk_local", NULL);
+       if (IS_ERR(dent_local))
+               return PTR_ERR(dent_local);
+
+       while ((clock = msm_clock_get_nth(n++)) != 0) {
+               strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
+               for (ptr = temp; *ptr; ptr++)
+                       *ptr = tolower(*ptr);
+               debugfs_create_file(temp, 0644, dent_rate,
+                                   clock, &clock_rate_fops);
+               debugfs_create_file(temp, 0644, dent_enable,
+                                   clock, &clock_enable_fops);
+               debugfs_create_file(temp, S_IRUGO, dent_local,
+                                   clock, &clock_local_fops);
+       }
+       return 0;
+}
+
+device_initcall(clock_debug_init);
+#endif
+
 /* The bootloader and/or AMSS may have left various clocks enabled.
  * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
  * not been explicitly enabled by a clk_enable() call.
@@ -205,7 +322,7 @@ static int __init clock_late_init(void)
                        spin_lock_irqsave(&clocks_lock, flags);
                        if (!clk->count) {
                                count++;
-                               pc_clk_disable(clk->id);
+                               clk->ops->auto_off(clk->id);
                        }
                        spin_unlock_irqrestore(&clocks_lock, flags);
                }
@@ -216,3 +333,4 @@ static int __init clock_late_init(void)
 }
 
 late_initcall(clock_late_init);
+
index f875e15..c270b55 100644 (file)
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/clock.h
  *
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007-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
 #define __ARCH_ARM_MACH_MSM_CLOCK_H
 
 #include <linux/list.h>
+#include <mach/clk.h>
+
+#include "clock-pcom.h"
+#include "clock-7x30.h"
 
 #define CLKFLAG_INVERT                 0x00000001
 #define CLKFLAG_NOINVERT               0x00000002
 #define CLKFLAG_NORESET                        0x00000008
 
 #define CLK_FIRST_AVAILABLE_FLAG       0x00000100
-#define CLKFLAG_USE_MIN_MAX_TO_SET     0x00000200
-#define CLKFLAG_AUTO_OFF               0x00000400
+#define CLKFLAG_AUTO_OFF               0x00000200
+#define CLKFLAG_MIN                    0x00000400
+#define CLKFLAG_MAX                    0x00000800
+
+struct clk_ops {
+       int (*enable)(unsigned id);
+       void (*disable)(unsigned id);
+       void (*auto_off)(unsigned id);
+       int (*reset)(unsigned id, enum clk_reset_action action);
+       int (*set_rate)(unsigned id, unsigned rate);
+       int (*set_min_rate)(unsigned id, unsigned rate);
+       int (*set_max_rate)(unsigned id, unsigned rate);
+       int (*set_flags)(unsigned id, unsigned flags);
+       unsigned (*get_rate)(unsigned id);
+       unsigned (*is_enabled)(unsigned id);
+       long (*round_rate)(unsigned id, unsigned rate);
+};
 
 struct clk {
        uint32_t id;
+       uint32_t remote_id;
        uint32_t count;
        uint32_t flags;
        const char *name;
+       struct clk_ops *ops;
+       const char *dbg_name;
        struct list_head list;
        struct device *dev;
 };
@@ -41,8 +63,47 @@ struct clk {
 #define A11S_CLK_SEL_ADDR              (MSM_CSR_BASE + 0x104)
 #define A11S_VDD_SVS_PLEVEL_ADDR       (MSM_CSR_BASE + 0x124)
 
-extern struct clk msm_clocks[];
-extern unsigned msm_num_clocks;
+#ifdef CONFIG_DEBUG_FS
+#define CLOCK_DBG_NAME(x) .dbg_name = x,
+#else
+#define CLOCK_DBG_NAME(x)
+#endif
+
+#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) {  \
+       .name = clk_name, \
+       .id = clk_id, \
+       .flags = clk_flags, \
+       .dev = clk_dev, \
+        CLOCK_DBG_NAME(#clk_id) \
+       }
+
+#define OFF CLKFLAG_AUTO_OFF
+#define CLK_MIN CLKFLAG_MIN
+#define CLK_MAX CLKFLAG_MAX
+#define CLK_MINMAX (CLK_MIN | CLK_MAX)
+#define NR_CLKS        P_NR_CLKS
+
+enum {
+       PLL_0 = 0,
+       PLL_1,
+       PLL_2,
+       PLL_3,
+       PLL_4,
+       PLL_5,
+       PLL_6,
+       NUM_PLL
+};
+
+enum clkvote_client {
+       CLKVOTE_ACPUCLK = 0,
+       CLKVOTE_PMQOS,
+       CLKVOTE_MAX,
+};
+
+int msm_clock_require_tcxo(unsigned long *reason, int nbits);
+int msm_clock_get_name(uint32_t id, char *name, uint32_t size);
+int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate);
+unsigned long clk_get_max_axi_khz(void);
 
 #endif
 
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
new file mode 100644 (file)
index 0000000..fde9d8f
--- /dev/null
@@ -0,0 +1,393 @@
+/* linux/arch/arm/mach-msm/devices.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+
+#include "clock.h"
+#include <mach/mmc.h>
+
+static struct resource resources_uart1[] = {
+       {
+               .start  = INT_UART1,
+               .end    = INT_UART1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART1_PHYS,
+               .end    = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource resources_uart2[] = {
+       {
+               .start  = INT_UART2,
+               .end    = INT_UART2,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART2_PHYS,
+               .end    = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource resources_uart3[] = {
+       {
+               .start  = INT_UART3,
+               .end    = INT_UART3,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART3_PHYS,
+               .end    = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device msm_device_uart1 = {
+       .name   = "msm_serial",
+       .id     = 0,
+       .num_resources  = ARRAY_SIZE(resources_uart1),
+       .resource       = resources_uart1,
+};
+
+struct platform_device msm_device_uart2 = {
+       .name   = "msm_serial",
+       .id     = 1,
+       .num_resources  = ARRAY_SIZE(resources_uart2),
+       .resource       = resources_uart2,
+};
+
+struct platform_device msm_device_uart3 = {
+       .name   = "msm_serial",
+       .id     = 2,
+       .num_resources  = ARRAY_SIZE(resources_uart3),
+       .resource       = resources_uart3,
+};
+
+static struct resource resources_i2c[] = {
+       {
+               .start  = MSM_I2C_PHYS,
+               .end    = MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_PWB_I2C,
+               .end    = INT_PWB_I2C,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_i2c = {
+       .name           = "msm_i2c",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(resources_i2c),
+       .resource       = resources_i2c,
+};
+
+static struct resource resources_hsusb[] = {
+       {
+               .start  = MSM_HSUSB_PHYS,
+               .end    = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_USB_HS,
+               .end    = INT_USB_HS,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device msm_device_hsusb = {
+       .name           = "msm_hsusb",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(resources_hsusb),
+       .resource       = resources_hsusb,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct flash_platform_data msm_nand_data = {
+       .parts          = NULL,
+       .nr_parts       = 0,
+};
+
+static struct resource resources_nand[] = {
+       [0] = {
+               .start  = 7,
+               .end    = 7,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device msm_device_nand = {
+       .name           = "msm_nand",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(resources_nand),
+       .resource       = resources_nand,
+       .dev            = {
+               .platform_data  = &msm_nand_data,
+       },
+};
+
+struct platform_device msm_device_smd = {
+       .name   = "msm_smd",
+       .id     = -1,
+};
+
+static struct resource resources_sdc1[] = {
+       {
+               .start  = MSM_SDC1_PHYS,
+               .end    = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC1_0,
+               .end    = INT_SDC1_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+       {
+               .start  = INT_SDC1_1,
+               .end    = INT_SDC1_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc2[] = {
+       {
+               .start  = MSM_SDC2_PHYS,
+               .end    = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC2_0,
+               .end    = INT_SDC2_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+               {
+               .start  = INT_SDC2_1,
+               .end    = INT_SDC2_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc3[] = {
+       {
+               .start  = MSM_SDC3_PHYS,
+               .end    = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC3_0,
+               .end    = INT_SDC3_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+               {
+               .start  = INT_SDC3_1,
+               .end    = INT_SDC3_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource resources_sdc4[] = {
+       {
+               .start  = MSM_SDC4_PHYS,
+               .end    = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = INT_SDC4_0,
+               .end    = INT_SDC4_0,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "cmd_irq",
+       },
+               {
+               .start  = INT_SDC4_1,
+               .end    = INT_SDC4_1,
+               .flags  = IORESOURCE_IRQ,
+               .name   = "pio_irq",
+       },
+       {
+               .flags  = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+               .name   = "status_irq"
+       },
+       {
+               .start  = 8,
+               .end    = 8,
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device msm_device_sdc1 = {
+       .name           = "msm_sdcc",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(resources_sdc1),
+       .resource       = resources_sdc1,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc2 = {
+       .name           = "msm_sdcc",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(resources_sdc2),
+       .resource       = resources_sdc2,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc3 = {
+       .name           = "msm_sdcc",
+       .id             = 3,
+       .num_resources  = ARRAY_SIZE(resources_sdc3),
+       .resource       = resources_sdc3,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+struct platform_device msm_device_sdc4 = {
+       .name           = "msm_sdcc",
+       .id             = 4,
+       .num_resources  = ARRAY_SIZE(resources_sdc4),
+       .resource       = resources_sdc4,
+       .dev            = {
+               .coherent_dma_mask      = 0xffffffff,
+       },
+};
+
+static struct platform_device *msm_sdcc_devices[] __initdata = {
+       &msm_device_sdc1,
+       &msm_device_sdc2,
+       &msm_device_sdc3,
+       &msm_device_sdc4,
+};
+
+int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat,
+                       unsigned int stat_irq, unsigned long stat_irq_flags)
+{
+       struct platform_device  *pdev;
+       struct resource *res;
+
+       if (controller < 1 || controller > 4)
+               return -EINVAL;
+
+       pdev = msm_sdcc_devices[controller-1];
+       pdev->dev.platform_data = plat;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
+       if (!res)
+               return -EINVAL;
+       else if (stat_irq) {
+               res->start = res->end = stat_irq;
+               res->flags &= ~IORESOURCE_DISABLED;
+               res->flags |= stat_irq_flags;
+       }
+
+       return platform_device_register(pdev);
+}
+
+struct clk msm_clocks_7x01a[] = {
+       CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
+       CLK_PCOM("adsp_clk",    ADSP_CLK,       NULL, 0),
+       CLK_PCOM("ebi1_clk",    EBI1_CLK,       NULL, 0),
+       CLK_PCOM("ebi2_clk",    EBI2_CLK,       NULL, 0),
+       CLK_PCOM("ecodec_clk",  ECODEC_CLK,     NULL, 0),
+       CLK_PCOM("emdh_clk",    EMDH_CLK,       NULL, OFF),
+       CLK_PCOM("gp_clk",              GP_CLK,         NULL, 0),
+       CLK_PCOM("grp_clk",     GRP_3D_CLK,     NULL, OFF),
+       CLK_PCOM("i2c_clk",     I2C_CLK,        &msm_device_i2c.dev, 0),
+       CLK_PCOM("icodec_rx_clk",       ICODEC_RX_CLK,  NULL, 0),
+       CLK_PCOM("icodec_tx_clk",       ICODEC_TX_CLK,  NULL, 0),
+       CLK_PCOM("imem_clk",    IMEM_CLK,       NULL, OFF),
+       CLK_PCOM("mdc_clk",     MDC_CLK,        NULL, 0),
+       CLK_PCOM("mdp_clk",     MDP_CLK,        NULL, OFF),
+       CLK_PCOM("pbus_clk",    PBUS_CLK,       NULL, 0),
+       CLK_PCOM("pcm_clk",     PCM_CLK,        NULL, 0),
+       CLK_PCOM("pmdh_clk",    PMDH_CLK,       NULL, OFF ),
+       CLK_PCOM("sdac_clk",    SDAC_CLK,       NULL, OFF),
+       CLK_PCOM("sdc_clk",     SDC1_CLK,       &msm_device_sdc1.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC1_P_CLK,     &msm_device_sdc1.dev, OFF),
+       CLK_PCOM("sdc_clk",     SDC2_CLK,       &msm_device_sdc2.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC2_P_CLK,     &msm_device_sdc2.dev, OFF),
+       CLK_PCOM("sdc_clk",     SDC3_CLK,       &msm_device_sdc3.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC3_P_CLK,     &msm_device_sdc3.dev, OFF),
+       CLK_PCOM("sdc_clk",     SDC4_CLK,       &msm_device_sdc4.dev, OFF),
+       CLK_PCOM("sdc_pclk",    SDC4_P_CLK,     &msm_device_sdc4.dev, OFF),
+       CLK_PCOM("tsif_clk",    TSIF_CLK,       NULL, 0),
+       CLK_PCOM("tsif_ref_clk",        TSIF_REF_CLK,   NULL, 0),
+       CLK_PCOM("tv_dac_clk",  TV_DAC_CLK,     NULL, 0),
+       CLK_PCOM("tv_enc_clk",  TV_ENC_CLK,     NULL, 0),
+       CLK_PCOM("uart_clk",    UART1_CLK,      &msm_device_uart1.dev, OFF),
+       CLK_PCOM("uart_clk",    UART2_CLK,      &msm_device_uart2.dev, 0),
+       CLK_PCOM("uart_clk",    UART3_CLK,      &msm_device_uart3.dev, OFF),
+       CLK_PCOM("uart1dm_clk", UART1DM_CLK,    NULL, OFF),
+       CLK_PCOM("uart2dm_clk", UART2DM_CLK,    NULL, 0),
+       CLK_PCOM("usb_hs_clk",  USB_HS_CLK,     &msm_device_hsusb.dev, OFF),
+       CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK,   &msm_device_hsusb.dev, OFF),
+       CLK_PCOM("usb_otg_clk", USB_OTG_CLK,    NULL, 0),
+       CLK_PCOM("vdc_clk",     VDC_CLK,        NULL, OFF ),
+       CLK_PCOM("vfe_clk",     VFE_CLK,        NULL, OFF),
+       CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK,    NULL, OFF),
+};
+
+unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
new file mode 100644 (file)
index 0000000..b449e8a
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/dma-mapping.h>
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include <mach/board.h>
+
+#include "devices.h"
+#include "smd_private.h"
+
+#include <asm/mach/flash.h>
+
+#include "clock-pcom.h"
+
+#include <mach/mmc.h>
+
+static struct resource resources_uart2[] = {
+       {
+               .start  = INT_UART2,
+               .end    = INT_UART2,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART2_PHYS,
+               .end    = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device msm_device_uart2 = {
+       .name   = "msm_serial",
+       .id     = 1,
+       .num_resources  = ARRAY_SIZE(resources_uart2),
+       .resource       = resources_uart2,
+};
+
+struct clk msm_clocks_7x30[] = {
+       CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
+       CLK_PCOM("adsp_clk",    ADSP_CLK,       NULL, 0),
+       CLK_PCOM("cam_m_clk",   CAM_M_CLK,      NULL, 0),
+       CLK_PCOM("camif_pad_pclk",      CAMIF_PAD_P_CLK,        NULL, OFF),
+       CLK_PCOM("ebi1_clk",    EBI1_CLK,       NULL, CLK_MIN),
+       CLK_PCOM("ecodec_clk",  ECODEC_CLK,     NULL, 0),
+       CLK_PCOM("emdh_clk",    EMDH_CLK,       NULL, OFF | CLK_MINMAX),
+       CLK_PCOM("emdh_pclk",   EMDH_P_CLK,     NULL, OFF),
+       CLK_PCOM("gp_clk",      GP_CLK,         NULL, 0),
+       CLK_PCOM("grp_2d_clk",  GRP_2D_CLK,     NULL, 0),
+       CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK,   NULL, 0),
+       CLK_PCOM("grp_clk",     GRP_3D_CLK,     NULL, 0),
+       CLK_PCOM("grp_pclk",    GRP_3D_P_CLK,   NULL, 0),
+       CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK,    NULL, 0),
+       CLK_PCOM("hdmi_clk",    HDMI_CLK,       NULL, 0),
+       CLK_PCOM("imem_clk",    IMEM_CLK,       NULL, OFF),
+       CLK_PCOM("jpeg_clk",    JPEG_CLK,       NULL, OFF),
+       CLK_PCOM("jpeg_pclk",   JPEG_P_CLK,     NULL, OFF),
+       CLK_PCOM("lpa_codec_clk",       LPA_CODEC_CLK,          NULL, 0),
+       CLK_PCOM("lpa_core_clk",        LPA_CORE_CLK,           NULL, 0),
+       CLK_PCOM("lpa_pclk",            LPA_P_CLK,              NULL, 0),
+       CLK_PCOM("mdc_clk",     MDC_CLK,        NULL, 0),
+       CLK_PCOM("mddi_clk",    PMDH_CLK,       NULL, OFF | CLK_MINMAX),
+       CLK_PCOM("mddi_pclk",   PMDH_P_CLK,     NULL, 0),
+       CLK_PCOM("mdp_clk",     MDP_CLK,        NULL, OFF),
+       CLK_PCOM("mdp_pclk",    MDP_P_CLK,      NULL, 0),
+       CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
+       CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
+       CLK_PCOM("mdp_vsync_clk",       MDP_VSYNC_CLK,  NULL, 0),
+       CLK_PCOM("mfc_clk",             MFC_CLK,                NULL, 0),
+       CLK_PCOM("mfc_div2_clk",        MFC_DIV2_CLK,           NULL, 0),
+       CLK_PCOM("mfc_pclk",            MFC_P_CLK,              NULL, 0),
+       CLK_PCOM("mi2s_m_clk",          MI2S_M_CLK,             NULL, 0),
+       CLK_PCOM("mi2s_s_clk",          MI2S_S_CLK,             NULL, 0),
+       CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK,  NULL, 0),
+       CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK,  NULL, 0),
+       CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK,  NULL, 0),
+       CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK,  NULL, 0),
+       CLK_PCOM("pbus_clk",    PBUS_CLK,       NULL, CLK_MIN),
+       CLK_PCOM("pcm_clk",     PCM_CLK,        NULL, 0),
+       CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK,                NULL, 0),
+       CLK_PCOM("rotator_imem_clk",    ROTATOR_IMEM_CLK,       NULL, OFF),
+       CLK_PCOM("rotator_pclk",        ROTATOR_P_CLK,          NULL, OFF),
+       CLK_PCOM("sdac_clk",    SDAC_CLK,       NULL, OFF),
+       CLK_PCOM("spi_clk",     SPI_CLK,        NULL, 0),
+       CLK_PCOM("spi_pclk",    SPI_P_CLK,      NULL, 0),
+       CLK_7X30S("tv_src_clk", TV_CLK,         TV_ENC_CLK,     NULL, 0),
+       CLK_PCOM("tv_dac_clk",  TV_DAC_CLK,     NULL, 0),
+       CLK_PCOM("tv_enc_clk",  TV_ENC_CLK,     NULL, 0),
+       CLK_PCOM("uart_clk",    UART2_CLK,      &msm_device_uart2.dev, 0),
+       CLK_PCOM("usb_hs_clk",          USB_HS_CLK,             NULL, OFF),
+       CLK_PCOM("usb_hs_pclk",         USB_HS_P_CLK,           NULL, OFF),
+       CLK_PCOM("usb_hs_core_clk",     USB_HS_CORE_CLK,        NULL, OFF),
+       CLK_PCOM("usb_hs2_clk",         USB_HS2_CLK,            NULL, OFF),
+       CLK_PCOM("usb_hs2_pclk",        USB_HS2_P_CLK,          NULL, OFF),
+       CLK_PCOM("usb_hs2_core_clk",    USB_HS2_CORE_CLK,       NULL, OFF),
+       CLK_PCOM("usb_hs3_clk",         USB_HS3_CLK,            NULL, OFF),
+       CLK_PCOM("usb_hs3_pclk",        USB_HS3_P_CLK,          NULL, OFF),
+       CLK_PCOM("usb_hs3_core_clk",    USB_HS3_CORE_CLK,       NULL, OFF),
+       CLK_PCOM("vdc_clk",     VDC_CLK,        NULL, OFF | CLK_MIN),
+       CLK_PCOM("vfe_camif_clk",       VFE_CAMIF_CLK,  NULL, 0),
+       CLK_PCOM("vfe_clk",     VFE_CLK,        NULL, 0),
+       CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK,    NULL, 0),
+       CLK_PCOM("vfe_pclk",    VFE_P_CLK,      NULL, OFF),
+       CLK_PCOM("vpe_clk",     VPE_CLK,        NULL, 0),
+
+       /* 7x30 v2 hardware only. */
+       CLK_PCOM("csi_clk",     CSI0_CLK,       NULL, 0),
+       CLK_PCOM("csi_pclk",    CSI0_P_CLK,     NULL, 0),
+       CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK,   NULL, 0),
+};
+
+unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30);
+
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
new file mode 100644 (file)
index 0000000..4d4a507
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/dma-mapping.h>
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include <mach/board.h>
+
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+
+#include <mach/mmc.h>
+
+static struct resource resources_uart3[] = {
+       {
+               .start  = INT_UART3,
+               .end    = INT_UART3,
+               .flags  = IORESOURCE_IRQ,
+       },
+       {
+               .start  = MSM_UART3_PHYS,
+               .end    = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device msm_device_uart3 = {
+       .name   = "msm_serial",
+       .id     = 2,
+       .num_resources  = ARRAY_SIZE(resources_uart3),
+       .resource       = resources_uart3,
+};
+
+struct clk msm_clocks_8x50[] = {
+       CLK_PCOM("adm_clk",     ADM_CLK,        NULL, 0),
+       CLK_PCOM("ebi1_clk",    EBI1_CLK,       NULL, CLK_MIN),
+       CLK_PCOM("ebi2_clk",    EBI2_CLK,       NULL, 0),
+       CLK_PCOM("ecodec_clk",  ECODEC_CLK,     NULL, 0),
+       CLK_PCOM("emdh_clk",    EMDH_CLK,       NULL, OFF | CLK_MINMAX),
+       CLK_PCOM("gp_clk",      GP_CLK,         NULL, 0),
+       CLK_PCOM("grp_clk",     GRP_3D_CLK,     NULL, 0),
+       CLK_PCOM("icodec_rx_clk",       ICODEC_RX_CLK,  NULL, 0),
+       CLK_PCOM("icodec_tx_clk",       ICODEC_TX_CLK,  NULL, 0),
+       CLK_PCOM("imem_clk",    IMEM_CLK,       NULL, OFF),
+       CLK_PCOM("mdc_clk",     MDC_CLK,        NULL, 0),
+       CLK_PCOM("mddi_clk",    PMDH_CLK,       NULL, OFF | CLK_MINMAX),
+       CLK_PCOM("mdp_clk",     MDP_CLK,        NULL, OFF),
+       CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
+       CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
+       CLK_PCOM("mdp_vsync_clk",       MDP_VSYNC_CLK,  NULL, 0),
+       CLK_PCOM("pbus_clk",    PBUS_CLK,       NULL, CLK_MIN),
+       CLK_PCOM("pcm_clk",     PCM_CLK,        NULL, 0),
+       CLK_PCOM("sdac_clk",    SDAC_CLK,       NULL, OFF),
+       CLK_PCOM("spi_clk",     SPI_CLK,        NULL, 0),
+       CLK_PCOM("tsif_clk",    TSIF_CLK,       NULL, 0),
+       CLK_PCOM("tsif_ref_clk",        TSIF_REF_CLK,   NULL, 0),
+       CLK_PCOM("tv_dac_clk",  TV_DAC_CLK,     NULL, 0),
+       CLK_PCOM("tv_enc_clk",  TV_ENC_CLK,     NULL, 0),
+       CLK_PCOM("uart_clk",    UART3_CLK,      &msm_device_uart3.dev, OFF),
+       CLK_PCOM("usb_hs_clk",  USB_HS_CLK,     NULL, OFF),
+       CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK,   NULL, OFF),
+       CLK_PCOM("usb_otg_clk", USB_OTG_CLK,    NULL, 0),
+       CLK_PCOM("vdc_clk",     VDC_CLK,        NULL, OFF | CLK_MIN),
+       CLK_PCOM("vfe_clk",     VFE_CLK,        NULL, OFF),
+       CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK,    NULL, OFF),
+       CLK_PCOM("vfe_axi_clk", VFE_AXI_CLK,    NULL, OFF),
+       CLK_PCOM("usb_hs2_clk", USB_HS2_CLK,    NULL, OFF),
+       CLK_PCOM("usb_hs2_pclk",        USB_HS2_P_CLK,  NULL, OFF),
+       CLK_PCOM("usb_hs3_clk", USB_HS3_CLK,    NULL, OFF),
+       CLK_PCOM("usb_hs3_pclk",        USB_HS3_P_CLK,  NULL, OFF),
+       CLK_PCOM("usb_phy_clk", USB_PHY_CLK,    NULL, 0),
+};
+
+unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50);
+
diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices.c
deleted file mode 100644 (file)
index 31b6b30..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/* linux/arch/arm/mach-msm/devices.c
- *
- * Copyright (C) 2008 Google, Inc.
- *
- * 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 <linux/kernel.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/msm_iomap.h>
-#include "devices.h"
-
-#include <asm/mach/flash.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-
-static struct resource resources_uart1[] = {
-       {
-               .start  = INT_UART1,
-               .end    = INT_UART1,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = MSM_UART1_PHYS,
-               .end    = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct resource resources_uart2[] = {
-       {
-               .start  = INT_UART2,
-               .end    = INT_UART2,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = MSM_UART2_PHYS,
-               .end    = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct resource resources_uart3[] = {
-       {
-               .start  = INT_UART3,
-               .end    = INT_UART3,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = MSM_UART3_PHYS,
-               .end    = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-struct platform_device msm_device_uart1 = {
-       .name   = "msm_serial",
-       .id     = 0,
-       .num_resources  = ARRAY_SIZE(resources_uart1),
-       .resource       = resources_uart1,
-};
-
-struct platform_device msm_device_uart2 = {
-       .name   = "msm_serial",
-       .id     = 1,
-       .num_resources  = ARRAY_SIZE(resources_uart2),
-       .resource       = resources_uart2,
-};
-
-struct platform_device msm_device_uart3 = {
-       .name   = "msm_serial",
-       .id     = 2,
-       .num_resources  = ARRAY_SIZE(resources_uart3),
-       .resource       = resources_uart3,
-};
-
-static struct resource resources_i2c[] = {
-       {
-               .start  = MSM_I2C_PHYS,
-               .end    = MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_PWB_I2C,
-               .end    = INT_PWB_I2C,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device msm_device_i2c = {
-       .name           = "msm_i2c",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(resources_i2c),
-       .resource       = resources_i2c,
-};
-
-static struct resource resources_hsusb[] = {
-       {
-               .start  = MSM_HSUSB_PHYS,
-               .end    = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_USB_HS,
-               .end    = INT_USB_HS,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device msm_device_hsusb = {
-       .name           = "msm_hsusb",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(resources_hsusb),
-       .resource       = resources_hsusb,
-       .dev            = {
-               .coherent_dma_mask      = 0xffffffff,
-       },
-};
-
-struct flash_platform_data msm_nand_data = {
-       .parts          = NULL,
-       .nr_parts       = 0,
-};
-
-static struct resource resources_nand[] = {
-       [0] = {
-               .start  = 7,
-               .end    = 7,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device msm_device_nand = {
-       .name           = "msm_nand",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(resources_nand),
-       .resource       = resources_nand,
-       .dev            = {
-               .platform_data  = &msm_nand_data,
-       },
-};
-
-struct platform_device msm_device_smd = {
-       .name   = "msm_smd",
-       .id     = -1,
-};
-
-static struct resource resources_sdc1[] = {
-       {
-               .start  = MSM_SDC1_PHYS,
-               .end    = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_SDC1_0,
-               .end    = INT_SDC1_1,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = 8,
-               .end    = 8,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-static struct resource resources_sdc2[] = {
-       {
-               .start  = MSM_SDC2_PHYS,
-               .end    = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_SDC2_0,
-               .end    = INT_SDC2_1,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = 8,
-               .end    = 8,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-static struct resource resources_sdc3[] = {
-       {
-               .start  = MSM_SDC3_PHYS,
-               .end    = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_SDC3_0,
-               .end    = INT_SDC3_1,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = 8,
-               .end    = 8,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-static struct resource resources_sdc4[] = {
-       {
-               .start  = MSM_SDC4_PHYS,
-               .end    = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
-               .flags  = IORESOURCE_MEM,
-       },
-       {
-               .start  = INT_SDC4_0,
-               .end    = INT_SDC4_1,
-               .flags  = IORESOURCE_IRQ,
-       },
-       {
-               .start  = 8,
-               .end    = 8,
-               .flags  = IORESOURCE_DMA,
-       },
-};
-
-struct platform_device msm_device_sdc1 = {
-       .name           = "msm_sdcc",
-       .id             = 1,
-       .num_resources  = ARRAY_SIZE(resources_sdc1),
-       .resource       = resources_sdc1,
-       .dev            = {
-               .coherent_dma_mask      = 0xffffffff,
-       },
-};
-
-struct platform_device msm_device_sdc2 = {
-       .name           = "msm_sdcc",
-       .id             = 2,
-       .num_resources  = ARRAY_SIZE(resources_sdc2),
-       .resource       = resources_sdc2,
-       .dev            = {
-               .coherent_dma_mask      = 0xffffffff,
-       },
-};
-
-struct platform_device msm_device_sdc3 = {
-       .name           = "msm_sdcc",
-       .id             = 3,
-       .num_resources  = ARRAY_SIZE(resources_sdc3),
-       .resource       = resources_sdc3,
-       .dev            = {
-               .coherent_dma_mask      = 0xffffffff,
-       },
-};
-
-struct platform_device msm_device_sdc4 = {
-       .name           = "msm_sdcc",
-       .id             = 4,
-       .num_resources  = ARRAY_SIZE(resources_sdc4),
-       .resource       = resources_sdc4,
-       .dev            = {
-               .coherent_dma_mask      = 0xffffffff,
-       },
-};
index 0744c4a..568443e 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
 #define __ARCH_ARM_MACH_MSM_DEVICES_H
 
+#include "clock.h"
+
 extern struct platform_device msm_device_uart1;
 extern struct platform_device msm_device_uart2;
 extern struct platform_device msm_device_uart3;
@@ -33,4 +35,13 @@ extern struct platform_device msm_device_smd;
 
 extern struct platform_device msm_device_nand;
 
+extern struct clk msm_clocks_7x01a[];
+extern unsigned msm_num_clocks_7x01a;
+
+extern struct clk msm_clocks_7x30[];
+extern unsigned msm_num_clocks_7x30;
+
+extern struct clk msm_clocks_8x50[];
+extern unsigned msm_num_clocks_8x50;
+
 #endif
index f5420f9..3d725ae 100644 (file)
@@ -13,6 +13,8 @@
  *
  */
 
+#include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <mach/dma.h>
@@ -26,6 +28,7 @@ enum {
 };
 
 static DEFINE_SPINLOCK(msm_dmov_lock);
+static struct clk *msm_dmov_clk;
 static unsigned int channel_active;
 static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
 static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
@@ -54,6 +57,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
        unsigned int status;
 
        spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+       if (!channel_active)
+               clk_enable(msm_dmov_clk);
+       dsb();
        status = readl(DMOV_STATUS(id));
        if (list_empty(&ready_commands[id]) &&
                (status & DMOV_STATUS_CMD_PTR_RDY)) {
@@ -70,6 +76,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
                channel_active |= 1U << id;
                writel(cmd->cmdptr, DMOV_CMD_PTR(id));
        } else {
+               if (!channel_active)
+                       clk_disable(msm_dmov_clk);
                if (list_empty(&active_commands[id]))
                        PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
 
@@ -165,6 +173,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                                        "for %p, result %x\n", id, cmd, ch_result);
                                if (cmd) {
                                        list_del(&cmd->list);
+                                       dsb();
                                        cmd->complete_func(cmd, ch_result, NULL);
                                }
                        }
@@ -181,6 +190,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                                PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
                                if (cmd) {
                                        list_del(&cmd->list);
+                                       dsb();
                                        cmd->complete_func(cmd, ch_result, &errdata);
                                }
                        }
@@ -198,6 +208,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                                PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
                                if (cmd) {
                                        list_del(&cmd->list);
+                                       dsb();
                                        cmd->complete_func(cmd, ch_result, &errdata);
                                }
                                /* this does not seem to work, once we get an error */
@@ -219,8 +230,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
                PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
        }
 
-       if (!channel_active)
-               disable_irq(INT_ADM_AARM);
+       if (!channel_active) {
+               disable_irq_nosync(INT_ADM_AARM);
+               clk_disable(msm_dmov_clk);
+       }
 
        spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
        return IRQ_HANDLED;
@@ -230,11 +243,17 @@ static int __init msm_init_datamover(void)
 {
        int i;
        int ret;
+       struct clk *clk;
+
        for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
                INIT_LIST_HEAD(&ready_commands[i]);
                INIT_LIST_HEAD(&active_commands[i]);
                writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
        }
+       clk = clk_get(NULL, "adm_clk");
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+       msm_dmov_clk = clk;
        ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
        if (ret)
                return ret;
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
new file mode 100644 (file)
index 0000000..bc32c84
--- /dev/null
@@ -0,0 +1,85 @@
+/* linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, 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.
+ *
+ */
+
+#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;
+               }
+       }
+       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));
+               }
+       }
+}
+EXPORT_SYMBOL(msm_gpios_disable);
+
+int msm_gpios_request_enable(const struct msm_gpio *table, int size)
+{
+       int rc = msm_gpios_enable(table, size);
+       return rc;
+}
+EXPORT_SYMBOL(msm_gpios_request_enable);
+
+void msm_gpios_disable_free(const struct msm_gpio *table, int size)
+{
+       msm_gpios_disable(table, size);
+}
+EXPORT_SYMBOL(msm_gpios_disable_free);
index 264d62e..e302fbd 100644 (file)
 
 /* platform device data structures */
 
-struct msm_mddi_platform_data
+struct msm_acpu_clock_platform_data
 {
-       void (*panel_power)(int on);
-       unsigned has_vsync_irq:1;
+       uint32_t acpu_switch_time_us;
+       uint32_t max_speed_delta_khz;
+       uint32_t vdd_switch_time_us;
+       unsigned long power_collapse_khz;
+       unsigned long wait_for_irq_khz;
 };
 
+struct clk;
+
 /* common init routines for use by arch/arm/mach-msm/board-*.c */
 
 void __init msm_add_devices(void);
 void __init msm_map_common_io(void);
 void __init msm_init_irq(void);
 void __init msm_init_gpio(void);
-void __init msm_clock_init(void);
+void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks);
+void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *);
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
new file mode 100644 (file)
index 0000000..c05ca40
--- /dev/null
@@ -0,0 +1,57 @@
+/* Copyright (c) 2009, 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 Forum, Inc. 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 "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 __MACH_CLK_H
+#define __MACH_CLK_H
+
+/* Magic rate value for use with PM QOS to request the board's maximum
+ * supported AXI rate. PM QOS will only pass positive s32 rate values
+ * through to the clock driver, so INT_MAX is used.
+ */
+#define MSM_AXI_MAX_FREQ       LONG_MAX
+
+enum clk_reset_action {
+       CLK_RESET_DEASSERT      = 0,
+       CLK_RESET_ASSERT        = 1
+};
+
+struct clk;
+
+/* Rate is minimum clock rate in Hz */
+int clk_set_min_rate(struct clk *clk, unsigned long rate);
+
+/* Rate is maximum clock rate in Hz */
+int clk_set_max_rate(struct clk *clk, unsigned long rate);
+
+/* Assert/Deassert reset to a hardware block associated with a clock */
+int clk_reset(struct clk *clk, enum clk_reset_action action);
+
+/* Set clock-specific configuration parameters */
+int clk_set_flags(struct clk *clk, unsigned long flags);
+
+#endif
index 5ab5bdf..04c51cc 100644 (file)
@@ -41,40 +41,42 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
 #define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
 #define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
 
-/* only security domain 3 is available to the ARM11
- * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM
- */
+#if defined(CONFIG_ARCH_MSM7X30)
+#define DMOV_SD_AARM DMOV_SD2
+#else
+#define DMOV_SD_AARM DMOV_SD3
+#endif
 
-#define DMOV_CMD_PTR(ch)      DMOV_SD3(0x000, ch)
+#define DMOV_CMD_PTR(ch)      DMOV_SD_AARM(0x000, ch)
 #define DMOV_CMD_LIST         (0 << 29) /* does not work */
 #define DMOV_CMD_PTR_LIST     (1 << 29) /* works */
 #define DMOV_CMD_INPUT_CFG    (2 << 29) /* untested */
 #define DMOV_CMD_OUTPUT_CFG   (3 << 29) /* untested */
 #define DMOV_CMD_ADDR(addr)   ((addr) >> 3)
 
-#define DMOV_RSLT(ch)         DMOV_SD3(0x040, ch)
+#define DMOV_RSLT(ch)         DMOV_SD_AARM(0x040, ch)
 #define DMOV_RSLT_VALID       (1 << 31) /* 0 == host has empties result fifo */
 #define DMOV_RSLT_ERROR       (1 << 3)
 #define DMOV_RSLT_FLUSH       (1 << 2)
 #define DMOV_RSLT_DONE        (1 << 1)  /* top pointer done */
 #define DMOV_RSLT_USER        (1 << 0)  /* command with FR force result */
 
-#define DMOV_FLUSH0(ch)       DMOV_SD3(0x080, ch)
-#define DMOV_FLUSH1(ch)       DMOV_SD3(0x0C0, ch)
-#define DMOV_FLUSH2(ch)       DMOV_SD3(0x100, ch)
-#define DMOV_FLUSH3(ch)       DMOV_SD3(0x140, ch)
-#define DMOV_FLUSH4(ch)       DMOV_SD3(0x180, ch)
-#define DMOV_FLUSH5(ch)       DMOV_SD3(0x1C0, ch)
+#define DMOV_FLUSH0(ch)       DMOV_SD_AARM(0x080, ch)
+#define DMOV_FLUSH1(ch)       DMOV_SD_AARM(0x0C0, ch)
+#define DMOV_FLUSH2(ch)       DMOV_SD_AARM(0x100, ch)
+#define DMOV_FLUSH3(ch)       DMOV_SD_AARM(0x140, ch)
+#define DMOV_FLUSH4(ch)       DMOV_SD_AARM(0x180, ch)
+#define DMOV_FLUSH5(ch)       DMOV_SD_AARM(0x1C0, ch)
 
-#define DMOV_STATUS(ch)       DMOV_SD3(0x200, ch)
+#define DMOV_STATUS(ch)       DMOV_SD_AARM(0x200, ch)
 #define DMOV_STATUS_RSLT_COUNT(n)    (((n) >> 29))
 #define DMOV_STATUS_CMD_COUNT(n)     (((n) >> 27) & 3)
 #define DMOV_STATUS_RSLT_VALID       (1 << 1)
 #define DMOV_STATUS_CMD_PTR_RDY      (1 << 0)
 
-#define DMOV_ISR              DMOV_SD3(0x380, 0)
-
-#define DMOV_CONFIG(ch)       DMOV_SD3(0x300, ch)
+#define DMOV_ISR              DMOV_SD_AARM(0x380, 0)
+  
+#define DMOV_CONFIG(ch)       DMOV_SD_AARM(0x300, ch)
 #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
 #define DMOV_CONFIG_FORCE_FLUSH_RSLT   (1 << 1)
 #define DMOV_CONFIG_IRQ_EN             (1 << 0)
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..262b441
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Author: Mike Lockwood <lockwood@android.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.
+ *
+ */
+#ifndef __ASM_ARCH_MSM_GPIO_H
+#define __ASM_ARCH_MSM_GPIO_H
+
+/**
+ * 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 aab9645..c35b29f 100644 (file)
@@ -26,4 +26,9 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m
 #define __io(a)                __typesafe_io(a)
 #define __mem_pci(a)    (a)
 
+void msm_map_qsd8x50_io(void);
+void msm_map_msm7x30_io(void);
+
+extern unsigned int msm_shared_ram_phys;
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h
new file mode 100644 (file)
index 0000000..f1fe706
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_7X00_H
+#define __ASM_ARCH_MSM_IRQS_7X00_H
+
+/* MSM ARM11 Interrupt Numbers */
+/* See 80-VE113-1 A, pp219-221     */
+
+#define INT_A9_M2A_0         0
+#define INT_A9_M2A_1         1
+#define INT_A9_M2A_2         2
+#define INT_A9_M2A_3         3
+#define INT_A9_M2A_4         4
+#define INT_A9_M2A_5         5
+#define INT_A9_M2A_6         6
+#define INT_GP_TIMER_EXP     7
+#define INT_DEBUG_TIMER_EXP  8
+#define INT_UART1            9
+#define INT_UART2            10
+#define INT_UART3            11
+#define INT_UART1_RX         12
+#define INT_UART2_RX         13
+#define INT_UART3_RX         14
+#define INT_USB_OTG          15
+#define INT_MDDI_PRI         16
+#define INT_MDDI_EXT         17
+#define INT_MDDI_CLIENT      18
+#define INT_MDP              19
+#define INT_GRAPHICS         20
+#define INT_ADM_AARM         21
+#define INT_ADSP_A11         22
+#define INT_ADSP_A9_A11      23
+#define INT_SDC1_0           24
+#define INT_SDC1_1           25
+#define INT_SDC2_0           26
+#define INT_SDC2_1           27
+#define INT_KEYSENSE         28
+#define INT_TCHSCRN_SSBI     29
+#define INT_TCHSCRN1         30
+#define INT_TCHSCRN2         31
+
+#define INT_GPIO_GROUP1      (32 + 0)
+#define INT_GPIO_GROUP2      (32 + 1)
+#define INT_PWB_I2C          (32 + 2)
+#define INT_SOFTRESET        (32 + 3)
+#define INT_NAND_WR_ER_DONE  (32 + 4)
+#define INT_NAND_OP_DONE     (32 + 5)
+#define INT_PBUS_ARM11       (32 + 6)
+#define INT_AXI_MPU_SMI      (32 + 7)
+#define INT_AXI_MPU_EBI1     (32 + 8)
+#define INT_AD_HSSD          (32 + 9)
+#define INT_ARM11_PMU        (32 + 10)
+#define INT_ARM11_DMA        (32 + 11)
+#define INT_TSIF_IRQ         (32 + 12)
+#define INT_UART1DM_IRQ      (32 + 13)
+#define INT_UART1DM_RX       (32 + 14)
+#define INT_USB_HS           (32 + 15)
+#define INT_SDC3_0           (32 + 16)
+#define INT_SDC3_1           (32 + 17)
+#define INT_SDC4_0           (32 + 18)
+#define INT_SDC4_1           (32 + 19)
+#define INT_UART2DM_RX       (32 + 20)
+#define INT_UART2DM_IRQ      (32 + 21)
+
+/* 22-31 are reserved */
+
+#define NR_MSM_IRQS 64
+#define NR_GPIO_IRQS 122
+#define NR_BOARD_IRQS 64
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h
new file mode 100644 (file)
index 0000000..67c5396
--- /dev/null
@@ -0,0 +1,170 @@
+/* Copyright (c) 2009, 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 Forum, Inc. 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 "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_IRQS_7X30_H
+#define __ASM_ARCH_MSM_IRQS_7X30_H
+
+/* MSM ACPU Interrupt Numbers */
+
+#define INT_DEBUG_TIMER_EXP    0
+#define INT_GPT0_TIMER_EXP     1
+#define INT_GPT1_TIMER_EXP     2
+#define INT_WDT0_ACCSCSSBARK   3
+#define INT_WDT1_ACCSCSSBARK   4
+#define INT_AVS_SVIC           5
+#define INT_AVS_SVIC_SW_DONE   6
+#define INT_SC_DBG_RX_FULL     7
+#define INT_SC_DBG_TX_EMPTY    8
+#define INT_ARM11_PM           9
+#define INT_AVS_REQ_DOWN       10
+#define INT_AVS_REQ_UP         11
+#define INT_SC_ACG             12
+/* SCSS_VICFIQSTS0[13:15] are RESERVED */
+#define INT_L2_SVICCPUIRPTREQ  16
+#define INT_L2_SVICDMANSIRPTREQ 17
+#define INT_L2_SVICDMASIRPTREQ  18
+#define INT_L2_SVICSLVIRPTREQ  19
+#define INT_AD5A_MPROC_APPS_0  20
+#define INT_AD5A_MPROC_APPS_1  21
+#define INT_A9_M2A_0           22
+#define INT_A9_M2A_1           23
+#define INT_A9_M2A_2           24
+#define INT_A9_M2A_3           25
+#define INT_A9_M2A_4           26
+#define INT_A9_M2A_5           27
+#define INT_A9_M2A_6           28
+#define INT_A9_M2A_7           29
+#define INT_A9_M2A_8           30
+#define INT_A9_M2A_9           31
+
+#define INT_AXI_EBI1_SC                (32 + 0)
+#define INT_IMEM_ERR           (32 + 1)
+#define INT_AXI_EBI0_SC                (32 + 2)
+#define INT_PBUS_SC_IRQC       (32 + 3)
+#define INT_PERPH_BUS_BPM      (32 + 4)
+#define INT_CC_TEMP_SENSE      (32 + 5)
+#define INT_UXMC_EBI0          (32 + 6)
+#define INT_UXMC_EBI1          (32 + 7)
+#define INT_EBI2_OP_DONE       (32 + 8)
+#define INT_EBI2_WR_ER_DONE    (32 + 9)
+#define INT_TCSR_SPSS_CE       (32 + 10)
+#define INT_EMDH               (32 + 11)
+#define INT_PMDH               (32 + 12)
+#define INT_MDC                        (32 + 13)
+#define INT_MIDI_TO_SUPSS      (32 + 14)
+#define INT_LPA_2              (32 + 15)
+#define INT_GPIO_GROUP1_SECURE (32 + 16)
+#define INT_GPIO_GROUP2_SECURE (32 + 17)
+#define INT_GPIO_GROUP1                (32 + 18)
+#define INT_GPIO_GROUP2                (32 + 19)
+#define INT_MPRPH_SOFTRESET    (32 + 20)
+#define INT_PWB_I2C            (32 + 21)
+#define INT_PWB_I2C_2          (32 + 22)
+#define INT_TSSC_SAMPLE                (32 + 23)
+#define INT_TSSC_PENUP         (32 + 24)
+#define INT_TCHSCRN_SSBI       (32 + 25)
+#define INT_FM_RDS             (32 + 26)
+#define INT_KEYSENSE           (32 + 27)
+#define INT_USB_OTG_HS         (32 + 28)
+#define INT_USB_OTG_HS2                (32 + 29)
+#define INT_USB_OTG_HS3                (32 + 30)
+#define INT_CSI                        (32 + 31)
+
+#define INT_SPI_OUTPUT         (64 + 0)
+#define INT_SPI_INPUT          (64 + 1)
+#define INT_SPI_ERROR          (64 + 2)
+#define INT_UART1              (64 + 3)
+#define INT_UART1_RX           (64 + 4)
+#define INT_UART2              (64 + 5)
+#define INT_UART2_RX           (64 + 6)
+#define INT_UART3              (64 + 7)
+#define INT_UART3_RX           (64 + 8)
+#define INT_UART1DM_IRQ                (64 + 9)
+#define INT_UART1DM_RX         (64 + 10)
+#define INT_UART2DM_IRQ                (64 + 11)
+#define INT_UART2DM_RX         (64 + 12)
+#define INT_TSIF               (64 + 13)
+#define INT_ADM_SC1            (64 + 14)
+#define INT_ADM_SC2            (64 + 15)
+#define INT_MDP                        (64 + 16)
+#define INT_VPE                        (64 + 17)
+#define INT_GRP_2D             (64 + 18)
+#define INT_GRP_3D             (64 + 19)
+#define INT_ROTATOR            (64 + 20)
+#define INT_MFC720             (64 + 21)
+#define INT_JPEG               (64 + 22)
+#define INT_VFE                        (64 + 23)
+#define INT_TV_ENC             (64 + 24)
+#define INT_PMIC_SSBI          (64 + 25)
+#define INT_MPM_1              (64 + 26)
+#define INT_TCSR_SPSS_SAMPLE   (64 + 27)
+#define INT_TCSR_SPSS_PENUP    (64 + 28)
+#define INT_MPM_2              (64 + 29)
+#define INT_SDC1_0             (64 + 30)
+#define INT_SDC1_1             (64 + 31)
+
+#define INT_SDC3_0             (96 + 0)
+#define INT_SDC3_1             (96 + 1)
+#define INT_SDC2_0             (96 + 2)
+#define INT_SDC2_1             (96 + 3)
+#define INT_SDC4_0             (96 + 4)
+#define INT_SDC4_1             (96 + 5)
+#define INT_PWB_QUP_IN         (96 + 6)
+#define INT_PWB_QUP_OUT                (96 + 7)
+#define INT_PWB_QUP_ERR                (96 + 8)
+#define INT_SCSS_WDT0_BITE     (96 + 9)
+/* SCSS_VICFIQSTS3[10:31] are RESERVED */
+
+/* Retrofit universal macro names */
+#define INT_ADM_AARM           INT_ADM_SC2
+#define INT_USB_HS             INT_USB_OTG_HS
+#define INT_USB_OTG            INT_USB_OTG_HS
+#define INT_TCHSCRN1           INT_TSSC_SAMPLE
+#define INT_TCHSCRN2           INT_TSSC_PENUP
+#define INT_GP_TIMER_EXP       INT_GPT0_TIMER_EXP
+#define INT_ADSP_A11           INT_AD5A_MPROC_APPS_0
+#define INT_ADSP_A9_A11        INT_AD5A_MPROC_APPS_1
+#define INT_MDDI_EXT           INT_EMDH
+#define INT_MDDI_PRI           INT_PMDH
+#define INT_MDDI_CLIENT                INT_MDC
+#define INT_NAND_WR_ER_DONE    INT_EBI2_WR_ER_DONE
+#define INT_NAND_OP_DONE       INT_EBI2_OP_DONE
+
+#define NR_MSM_IRQS            128
+#define NR_GPIO_IRQS           182
+#define PMIC8058_IRQ_BASE      (NR_MSM_IRQS + NR_GPIO_IRQS)
+#define NR_PMIC8058_GPIO_IRQS  40
+#define NR_PMIC8058_MPP_IRQS   12
+#define NR_PMIC8058_MISC_IRQS  8
+#define NR_PMIC8058_IRQS       (NR_PMIC8058_GPIO_IRQS +\
+                               NR_PMIC8058_MPP_IRQS +\
+                               NR_PMIC8058_MISC_IRQS)
+#define NR_BOARD_IRQS          NR_PMIC8058_IRQS
+
+#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h
new file mode 100644 (file)
index 0000000..de3d8fe
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright (c) 2008-2009, 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 Forum, Inc. 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 "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_IRQS_8XXX_H
+#define __ASM_ARCH_MSM_IRQS_8XXX_H
+
+/* MSM ACPU Interrupt Numbers */
+
+#define INT_A9_M2A_0         0
+#define INT_A9_M2A_1         1
+#define INT_A9_M2A_2         2
+#define INT_A9_M2A_3         3
+#define INT_A9_M2A_4         4
+#define INT_A9_M2A_5         5
+#define INT_A9_M2A_6         6
+#define INT_GP_TIMER_EXP     7
+#define INT_DEBUG_TIMER_EXP  8
+#define INT_SIRC_0           9
+#define INT_SDC3_0           10
+#define INT_SDC3_1           11
+#define INT_SDC4_0           12
+#define INT_SDC4_1           13
+#define INT_AD6_EXT_VFR      14
+#define INT_USB_OTG          15
+#define INT_MDDI_PRI         16
+#define INT_MDDI_EXT         17
+#define INT_MDDI_CLIENT      18
+#define INT_MDP              19
+#define INT_GRAPHICS         20
+#define INT_ADM_AARM         21
+#define INT_ADSP_A11         22
+#define INT_ADSP_A9_A11      23
+#define INT_SDC1_0           24
+#define INT_SDC1_1           25
+#define INT_SDC2_0           26
+#define INT_SDC2_1           27
+#define INT_KEYSENSE         28
+#define INT_TCHSCRN_SSBI     29
+#define INT_TCHSCRN1         30
+#define INT_TCHSCRN2         31
+
+#define INT_TCSR_MPRPH_SC1   (32 + 0)
+#define INT_USB_FS2          (32 + 1)
+#define INT_PWB_I2C          (32 + 2)
+#define INT_SOFTRESET        (32 + 3)
+#define INT_NAND_WR_ER_DONE  (32 + 4)
+#define INT_NAND_OP_DONE     (32 + 5)
+#define INT_TCSR_MPRPH_SC2   (32 + 6)
+#define INT_OP_PEN           (32 + 7)
+#define INT_AD_HSSD          (32 + 8)
+#define INT_ARM11_PM         (32 + 9)
+#define INT_SDMA_NON_SECURE  (32 + 10)
+#define INT_TSIF_IRQ         (32 + 11)
+#define INT_UART1DM_IRQ      (32 + 12)
+#define INT_UART1DM_RX       (32 + 13)
+#define INT_SDMA_SECURE      (32 + 14)
+#define INT_SI2S_SLAVE       (32 + 15)
+#define INT_SC_I2CPU         (32 + 16)
+#define INT_SC_DBG_RDTRFULL  (32 + 17)
+#define INT_SC_DBG_WDTRFULL  (32 + 18)
+#define INT_SCPLL_CTL_DONE   (32 + 19)
+#define INT_UART2DM_IRQ      (32 + 20)
+#define INT_UART2DM_RX       (32 + 21)
+#define INT_VDC_MEC          (32 + 22)
+#define INT_VDC_DB           (32 + 23)
+#define INT_VDC_AXI          (32 + 24)
+#define INT_VFE              (32 + 25)
+#define INT_USB_HS           (32 + 26)
+#define INT_AUDIO_OUT0       (32 + 27)
+#define INT_AUDIO_OUT1       (32 + 28)
+#define INT_CRYPTO           (32 + 29)
+#define INT_AD6M_IDLE        (32 + 30)
+#define INT_SIRC_1           (32 + 31)
+
+#define NR_GPIO_IRQS 165
+#define NR_MSM_IRQS 64
+#define NR_BOARD_IRQS 64
+
+#endif
index 9dd4cf8..164d355 100644 (file)
@@ -1,6 +1,6 @@
-/* arch/arm/mach-msm/include/mach/irqs.h
- *
+/*
  * 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
 #ifndef __ASM_ARCH_MSM_IRQS_H
 #define __ASM_ARCH_MSM_IRQS_H
 
-/* MSM ARM11 Interrupt Numbers */
-/* See 80-VE113-1 A, pp219-221     */
-
-#define INT_A9_M2A_0         0
-#define INT_A9_M2A_1         1
-#define INT_A9_M2A_2         2
-#define INT_A9_M2A_3         3
-#define INT_A9_M2A_4         4
-#define INT_A9_M2A_5         5
-#define INT_A9_M2A_6         6
-#define INT_GP_TIMER_EXP     7
-#define INT_DEBUG_TIMER_EXP  8
-#define INT_UART1            9
-#define INT_UART2            10
-#define INT_UART3            11
-#define INT_UART1_RX         12
-#define INT_UART2_RX         13
-#define INT_UART3_RX         14
-#define INT_USB_OTG          15
-#define INT_MDDI_PRI         16
-#define INT_MDDI_EXT         17
-#define INT_MDDI_CLIENT      18
-#define INT_MDP              19
-#define INT_GRAPHICS         20
-#define INT_ADM_AARM         21
-#define INT_ADSP_A11         22
-#define INT_ADSP_A9_A11      23
-#define INT_SDC1_0           24
-#define INT_SDC1_1           25
-#define INT_SDC2_0           26
-#define INT_SDC2_1           27
-#define INT_KEYSENSE         28
-#define INT_TCHSCRN_SSBI     29
-#define INT_TCHSCRN1         30
-#define INT_TCHSCRN2         31
-
-#define INT_GPIO_GROUP1      (32 + 0)
-#define INT_GPIO_GROUP2      (32 + 1)
-#define INT_PWB_I2C          (32 + 2)
-#define INT_SOFTRESET        (32 + 3)
-#define INT_NAND_WR_ER_DONE  (32 + 4)
-#define INT_NAND_OP_DONE     (32 + 5)
-#define INT_PBUS_ARM11       (32 + 6)
-#define INT_AXI_MPU_SMI      (32 + 7)
-#define INT_AXI_MPU_EBI1     (32 + 8)
-#define INT_AD_HSSD          (32 + 9)
-#define INT_ARM11_PMU        (32 + 10)
-#define INT_ARM11_DMA        (32 + 11)
-#define INT_TSIF_IRQ         (32 + 12)
-#define INT_UART1DM_IRQ      (32 + 13)
-#define INT_UART1DM_RX       (32 + 14)
-#define INT_USB_HS           (32 + 15)
-#define INT_SDC3_0           (32 + 16)
-#define INT_SDC3_1           (32 + 17)
-#define INT_SDC4_0           (32 + 18)
-#define INT_SDC4_1           (32 + 19)
-#define INT_UART2DM_RX       (32 + 20)
-#define INT_UART2DM_IRQ      (32 + 21)
-
-/* 22-31 are reserved */
-
 #define MSM_IRQ_BIT(irq)     (1 << ((irq) & 31))
 
-#define NR_MSM_IRQS 64
-#define NR_GPIO_IRQS 122
-#define NR_BOARD_IRQS 64
-#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
+#if defined(CONFIG_ARCH_MSM7X30)
+#include "irqs-7x30.h"
+#elif defined(CONFIG_ARCH_QSD8X50)
+#include "irqs-8x50.h"
+#include "sirc.h"
+#elif defined(CONFIG_ARCH_MSM_ARM11)
+#include "irqs-7x00.h"
+#else
+#error "Unknown architecture specification"
+#endif
 
+#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
 #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
+#define MSM_INT_TO_REG(base, irq) (base + irq / 32)
 
 #endif
index f4698ba..50c7847 100644 (file)
 #define __ASM_ARCH_MEMORY_H
 
 /* physical offset of RAM */
+#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A)
+#define PHYS_OFFSET            UL(0x00000000)
+#elif defined(CONFIG_ARCH_QSD8X50)
+#define PHYS_OFFSET            UL(0x20000000)
+#elif defined(CONFIG_ARCH_MSM7X30)
+#define PHYS_OFFSET            UL(0x00200000)
+#else
 #define PHYS_OFFSET            UL(0x10000000)
+#endif
 
 #endif
 
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h
new file mode 100644 (file)
index 0000000..1f4fc81
--- /dev/null
@@ -0,0 +1,147 @@
+/* arch/arm/mach-msm/include/mach/msm_fb.h
+ *
+ * Internal shared definitions for various MSM framebuffer parts.
+ *
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * 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 _MSM_FB_H_
+#define _MSM_FB_H_
+
+#include <linux/device.h>
+
+struct mddi_info;
+
+struct msm_fb_data {
+       int xres;       /* x resolution in pixels */
+       int yres;       /* y resolution in pixels */
+       int width;      /* disply width in mm */
+       int height;     /* display height in mm */
+       unsigned output_format;
+};
+
+struct msmfb_callback {
+       void (*func)(struct msmfb_callback *);
+};
+
+enum {
+       MSM_MDDI_PMDH_INTERFACE,
+       MSM_MDDI_EMDH_INTERFACE,
+       MSM_EBI2_INTERFACE,
+};
+
+#define MSMFB_CAP_PARTIAL_UPDATES      (1 << 0)
+
+struct msm_panel_data {
+       /* turns off the fb memory */
+       int (*suspend)(struct msm_panel_data *);
+       /* turns on the fb memory */
+       int (*resume)(struct msm_panel_data *);
+       /* turns off the panel */
+       int (*blank)(struct msm_panel_data *);
+       /* turns on the panel */
+       int (*unblank)(struct msm_panel_data *);
+       void (*wait_vsync)(struct msm_panel_data *);
+       void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *);
+       void (*clear_vsync)(struct msm_panel_data *);
+       /* from the enum above */
+       unsigned interface_type;
+       /* data to be passed to the fb driver */
+       struct msm_fb_data *fb_data;
+
+       /* capabilities supported by the panel */
+       uint32_t caps;
+};
+
+struct msm_mddi_client_data {
+       void (*suspend)(struct msm_mddi_client_data *);
+       void (*resume)(struct msm_mddi_client_data *);
+       void (*activate_link)(struct msm_mddi_client_data *);
+       void (*remote_write)(struct msm_mddi_client_data *, uint32_t val,
+                            uint32_t reg);
+       uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg);
+       void (*auto_hibernate)(struct msm_mddi_client_data *, int);
+       /* custom data that needs to be passed from the board file to a 
+        * particular client */
+       void *private_client_data;
+       struct resource *fb_resource;
+       /* from the list above */
+       unsigned interface_type;
+};
+
+struct msm_mddi_platform_data {
+       unsigned int clk_rate;
+       void (*power_client)(struct msm_mddi_client_data *, int on);
+
+       /* fixup the mfr name, product id */
+       void (*fixup)(uint16_t *mfr_name, uint16_t *product_id);
+
+       struct resource *fb_resource; /*optional*/
+       /* number of clients in the list that follows */
+       int num_clients;
+       /* array of client information of clients */
+       struct {
+               unsigned product_id; /* mfr id in top 16 bits, product id
+                                     * in lower 16 bits
+                                     */
+               char *name;     /* the device name will be the platform
+                                * device name registered for the client,
+                                * it should match the name of the associated
+                                * driver
+                                */
+               unsigned id;    /* id for mddi client device node, will also
+                                * be used as device id of panel devices, if
+                                * the client device will have multiple panels
+                                * space must be left here for them
+                                */
+               void *client_data;      /* required private client data */
+               unsigned int clk_rate;  /* optional: if the client requires a
+                                       * different mddi clk rate
+                                       */
+       } client_platform_data[];
+};
+
+struct mdp_blit_req;
+struct fb_info;
+struct mdp_device {
+       struct device dev;
+       void (*dma)(struct mdp_device *mpd, uint32_t addr,
+                   uint32_t stride, uint32_t w, uint32_t h, uint32_t x,
+                   uint32_t y, struct msmfb_callback *callback, int interface);
+       void (*dma_wait)(struct mdp_device *mdp);
+       int (*blit)(struct mdp_device *mdp, struct fb_info *fb,
+                   struct mdp_blit_req *req);
+       void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id);
+};
+
+struct class_interface;
+int register_mdp_client(struct class_interface *class_intf);
+
+/**** private client data structs go below this line ***/
+
+struct msm_mddi_bridge_platform_data {
+       /* from board file */
+       int (*init)(struct msm_mddi_bridge_platform_data *,
+                   struct msm_mddi_client_data *);
+       int (*uninit)(struct msm_mddi_bridge_platform_data *,
+                     struct msm_mddi_client_data *);
+       /* passed to panel for use by the fb driver */
+       int (*blank)(struct msm_mddi_bridge_platform_data *,
+                    struct msm_mddi_client_data *);
+       int (*unblank)(struct msm_mddi_bridge_platform_data *,
+                      struct msm_mddi_client_data *);
+       struct msm_fb_data fb_data;
+};
+
+
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
new file mode 100644 (file)
index 0000000..cfff0e7
--- /dev/null
@@ -0,0 +1,139 @@
+/* arch/arm/mach-msm/include/mach/msm_iomap.h
+ *
+ * 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.
+ *
+ *
+ * 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_7X00_H
+#define __ASM_ARCH_MSM_IOMAP_7X00_H
+
+#include <asm/sizes.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.
+ *
+ */
+
+#ifdef __ASSEMBLY__
+#define IOMEM(x)       x
+#else
+#define IOMEM(x)       ((void __force __iomem *)(x))
+#endif
+
+#define MSM_VIC_BASE          IOMEM(0xE0000000)
+#define MSM_VIC_PHYS          0xC0000000
+#define MSM_VIC_SIZE          SZ_4K
+
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
+#define MSM_CSR_PHYS          0xC0100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_GPT_PHYS          MSM_CSR_PHYS
+#define MSM_GPT_BASE          MSM_CSR_BASE
+#define MSM_GPT_SIZE          SZ_4K
+
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS         0xA9700000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xA9200000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xA9300000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS      0xA8600000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS   0x01F00000
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
+#define MSM_UART1_PHYS        0xA9A00000
+#define MSM_UART1_SIZE        SZ_4K
+
+#define MSM_UART2_PHYS        0xA9B00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_PHYS        0xA9C00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
+#define MSM_SDC1_PHYS         0xA0400000
+#define MSM_SDC1_SIZE         SZ_4K
+
+#define MSM_SDC2_PHYS         0xA0500000
+#define MSM_SDC2_SIZE         SZ_4K
+
+#define MSM_SDC3_PHYS         0xA0600000
+#define MSM_SDC3_SIZE         SZ_4K
+
+#define MSM_SDC4_PHYS         0xA0700000
+#define MSM_SDC4_SIZE         SZ_4K
+
+#define MSM_I2C_PHYS          0xA9900000
+#define MSM_I2C_SIZE          SZ_4K
+
+#define MSM_HSUSB_PHYS        0xA0800000
+#define MSM_HSUSB_SIZE        SZ_4K
+
+#define MSM_PMDH_PHYS         0xAA600000
+#define MSM_PMDH_SIZE         SZ_4K
+
+#define MSM_EMDH_PHYS         0xAA700000
+#define MSM_EMDH_SIZE         SZ_4K
+
+#define MSM_MDP_PHYS          0xAA200000
+#define MSM_MDP_SIZE          0x000F0000
+
+#define MSM_MDC_PHYS         0xAA500000
+#define MSM_MDC_SIZE         SZ_1M
+
+#define MSM_AD5_PHYS          0xAC000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define MSM_GCC_BASE          IOMEM(0xF8009000)
+#define MSM_GCC_PHYS          0xC0182000
+#define MSM_GCC_SIZE          SZ_4K
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
new file mode 100644 (file)
index 0000000..8a00c2d
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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_7X30_H
+#define __ASM_ARCH_MSM_IOMAP_7X30_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_VIC_BASE          IOMEM(0xE0000000)
+#define MSM_VIC_PHYS          0xC0080000
+#define MSM_VIC_SIZE          SZ_4K
+
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
+#define MSM_CSR_PHYS          0xC0100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_TMR_PHYS          MSM_CSR_PHYS
+#define MSM_TMR_BASE          MSM_CSR_BASE
+#define MSM_TMR_SIZE          SZ_4K
+
+#define MSM_GPT_BASE         (MSM_TMR_BASE + 0x4)
+#define MSM_DGT_BASE         (MSM_TMR_BASE + 0x24)
+
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS         0xAC400000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xAC001000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xAC101000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS      0xAB800000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_CLK_CTL_SH2_BASE  IOMEM(0xE0006000)
+#define MSM_CLK_CTL_SH2_PHYS  0xABA01000
+#define MSM_CLK_CTL_SH2_SIZE  SZ_4K
+
+#define MSM_ACC_BASE          IOMEM(0xE0007000)
+#define MSM_ACC_PHYS          0xC0101000
+#define MSM_ACC_SIZE          SZ_4K
+
+#define MSM_SAW_BASE          IOMEM(0xE0008000)
+#define MSM_SAW_PHYS          0xC0102000
+#define MSM_SAW_SIZE          SZ_4K
+
+#define MSM_GCC_BASE         IOMEM(0xE0009000)
+#define MSM_GCC_PHYS         0xC0182000
+#define MSM_GCC_SIZE         SZ_4K
+
+#define MSM_TCSR_BASE        IOMEM(0xE000A000)
+#define MSM_TCSR_PHYS        0xAB600000
+#define MSM_TCSR_SIZE        SZ_4K
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS   0x00100000
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
+#define MSM_UART1_PHYS        0xACA00000
+#define MSM_UART1_SIZE        SZ_4K
+
+#define MSM_UART2_PHYS        0xACB00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_PHYS        0xACC00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
+#define MSM_MDC_BASE         IOMEM(0xE0200000)
+#define MSM_MDC_PHYS         0xAA500000
+#define MSM_MDC_SIZE         SZ_1M
+
+#define MSM_AD5_BASE          IOMEM(0xE0300000)
+#define MSM_AD5_PHYS          0xA7000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
new file mode 100644 (file)
index 0000000..acc819e
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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_8X50_H
+#define __ASM_ARCH_MSM_IOMAP_8X50_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_VIC_BASE          IOMEM(0xE0000000)
+#define MSM_VIC_PHYS          0xAC000000
+#define MSM_VIC_SIZE          SZ_4K
+
+#define MSM_CSR_BASE          IOMEM(0xE0001000)
+#define MSM_CSR_PHYS          0xAC100000
+#define MSM_CSR_SIZE          SZ_4K
+
+#define MSM_TMR_PHYS          MSM_CSR_PHYS
+#define MSM_TMR_BASE          MSM_CSR_BASE
+#define MSM_TMR_SIZE          SZ_4K
+
+#define MSM_GPT_BASE          MSM_TMR_BASE
+#define MSM_DGT_BASE          (MSM_TMR_BASE + 0x10)
+
+#define MSM_DMOV_BASE         IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS         0xA9700000
+#define MSM_DMOV_SIZE         SZ_4K
+
+#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS        0xA9000000
+#define MSM_GPIO1_SIZE        SZ_4K
+
+#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS        0xA9100000
+#define MSM_GPIO2_SIZE        SZ_4K
+
+#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS      0xA8600000
+#define MSM_CLK_CTL_SIZE      SZ_4K
+
+#define MSM_SIRC_BASE         IOMEM(0xE1006000)
+#define MSM_SIRC_PHYS         0xAC200000
+#define MSM_SIRC_SIZE         SZ_4K
+
+#define MSM_SCPLL_BASE        IOMEM(0xE1007000)
+#define MSM_SCPLL_PHYS        0xA8800000
+#define MSM_SCPLL_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_SOC_REV_A
+#define MSM_SMI_BASE 0xE0000000
+#else
+#define MSM_SMI_BASE 0x00000000
+#endif
+
+#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
+#define MSM_SHARED_RAM_SIZE   SZ_1M
+
+#define MSM_UART1_PHYS        0xA9A00000
+#define MSM_UART1_SIZE        SZ_4K
+
+#define MSM_UART2_PHYS        0xA9B00000
+#define MSM_UART2_SIZE        SZ_4K
+
+#define MSM_UART3_PHYS        0xA9C00000
+#define MSM_UART3_SIZE        SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE   0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE   SZ_4K
+#endif
+
+#define MSM_MDC_BASE         IOMEM(0xE0200000)
+#define MSM_MDC_PHYS         0xAA500000
+#define MSM_MDC_SIZE         SZ_1M
+
+#define MSM_AD5_BASE          IOMEM(0xE0300000)
+#define MSM_AD5_PHYS          0xAC000000
+#define MSM_AD5_SIZE          (SZ_1M*13)
+
+
+#define MSM_I2C_SIZE          SZ_4K
+#define MSM_I2C_PHYS          0xA9900000
+
+#define MSM_HSUSB_PHYS        0xA0800000
+#define MSM_HSUSB_SIZE        SZ_1K
+
+#define MSM_NAND_PHYS           0xA0A00000
+
+
+#define MSM_TSIF_PHYS        (0xa0100000)
+#define MSM_TSIF_SIZE        (0x200)
+
+#define MSM_TSSC_PHYS         0xAA300000
+
+#define MSM_UART1DM_PHYS      0xA0200000
+#define MSM_UART2DM_PHYS      0xA0900000
+
+
+#define MSM_SDC1_PHYS          0xA0400000
+#define MSM_SDC1_SIZE          SZ_4K
+
+#define MSM_SDC2_PHYS          0xA0500000
+#define MSM_SDC2_SIZE          SZ_4K
+
+#define MSM_SDC3_PHYS          0xA0600000
+#define MSM_SDC3_SIZE           SZ_4K
+
+#define MSM_SDC4_PHYS          0xA0700000
+#define MSM_SDC4_SIZE          SZ_4K
+
+#endif
index 9dae1a9..e6b1821 100644 (file)
@@ -1,6 +1,6 @@
-/* arch/arm/mach-msm/include/mach/msm_iomap.h
- *
+/*
  * 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
 #define IOMEM(x)       ((void __force __iomem *)(x))
 #endif
 
-#define MSM_VIC_BASE          IOMEM(0xE0000000)
-#define MSM_VIC_PHYS          0xC0000000
-#define MSM_VIC_SIZE          SZ_4K
-
-#define MSM_CSR_BASE          IOMEM(0xE0001000)
-#define MSM_CSR_PHYS          0xC0100000
-#define MSM_CSR_SIZE          SZ_4K
-
-#define MSM_GPT_PHYS          MSM_CSR_PHYS
-#define MSM_GPT_BASE          MSM_CSR_BASE
-#define MSM_GPT_SIZE          SZ_4K
-
-#define MSM_DMOV_BASE         IOMEM(0xE0002000)
-#define MSM_DMOV_PHYS         0xA9700000
-#define MSM_DMOV_SIZE         SZ_4K
-
-#define MSM_GPIO1_BASE        IOMEM(0xE0003000)
-#define MSM_GPIO1_PHYS        0xA9200000
-#define MSM_GPIO1_SIZE        SZ_4K
-
-#define MSM_GPIO2_BASE        IOMEM(0xE0004000)
-#define MSM_GPIO2_PHYS        0xA9300000
-#define MSM_GPIO2_SIZE        SZ_4K
-
-#define MSM_CLK_CTL_BASE      IOMEM(0xE0005000)
-#define MSM_CLK_CTL_PHYS      0xA8600000
-#define MSM_CLK_CTL_SIZE      SZ_4K
-
-#define MSM_SHARED_RAM_BASE   IOMEM(0xE0100000)
-#define MSM_SHARED_RAM_PHYS   0x01F00000
-#define MSM_SHARED_RAM_SIZE   SZ_1M
-
-#define MSM_UART1_PHYS        0xA9A00000
-#define MSM_UART1_SIZE        SZ_4K
-
-#define MSM_UART2_PHYS        0xA9B00000
-#define MSM_UART2_SIZE        SZ_4K
-
-#define MSM_UART3_PHYS        0xA9C00000
-#define MSM_UART3_SIZE        SZ_4K
-
-#ifdef CONFIG_MSM_DEBUG_UART
-#define MSM_DEBUG_UART_BASE   0xE1000000
-#if CONFIG_MSM_DEBUG_UART == 1
-#define MSM_DEBUG_UART_PHYS   MSM_UART1_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 2
-#define MSM_DEBUG_UART_PHYS   MSM_UART2_PHYS
-#elif CONFIG_MSM_DEBUG_UART == 3
-#define MSM_DEBUG_UART_PHYS   MSM_UART3_PHYS
-#endif
-#define MSM_DEBUG_UART_SIZE   SZ_4K
+#if defined(CONFIG_ARCH_MSM7X30)
+#include "msm_iomap-7x30.h"
+#elif defined(CONFIG_ARCH_QSD8X50)
+#include "msm_iomap-8x50.h"
+#else
+#include "msm_iomap-7x00.h"
 #endif
 
-#define MSM_SDC1_PHYS         0xA0400000
-#define MSM_SDC1_SIZE         SZ_4K
-
-#define MSM_SDC2_PHYS         0xA0500000
-#define MSM_SDC2_SIZE         SZ_4K
-
-#define MSM_SDC3_PHYS         0xA0600000
-#define MSM_SDC3_SIZE         SZ_4K
-
-#define MSM_SDC4_PHYS         0xA0700000
-#define MSM_SDC4_SIZE         SZ_4K
-
-#define MSM_I2C_PHYS          0xA9900000
-#define MSM_I2C_SIZE          SZ_4K
-
-#define MSM_HSUSB_PHYS        0xA0800000
-#define MSM_HSUSB_SIZE        SZ_4K
-
-#define MSM_PMDH_PHYS         0xAA600000
-#define MSM_PMDH_SIZE         SZ_4K
-
-#define MSM_EMDH_PHYS         0xAA700000
-#define MSM_EMDH_SIZE         SZ_4K
-
-#define MSM_MDP_PHYS          0xAA200000
-#define MSM_MDP_SIZE          0x000F0000
-
-#define MSM_MDC_PHYS         0xAA500000
-#define MSM_MDC_SIZE         SZ_1M
-
-#define MSM_AD5_PHYS          0xAC000000
-#define MSM_AD5_SIZE          (SZ_1M*13)
-
-
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
new file mode 100644 (file)
index 0000000..029463e
--- /dev/null
@@ -0,0 +1,109 @@
+/* linux/include/asm-arm/arch-msm/msm_smd.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SMD_H
+#define __ASM_ARCH_MSM_SMD_H
+
+typedef struct smd_channel smd_channel_t;
+
+extern int (*msm_check_for_modem_crash)(void);
+
+/* warning: notify() may be called before open returns */
+int smd_open(const char *name, smd_channel_t **ch, void *priv,
+            void (*notify)(void *priv, unsigned event));
+
+#define SMD_EVENT_DATA 1
+#define SMD_EVENT_OPEN 2
+#define SMD_EVENT_CLOSE 3
+
+int smd_close(smd_channel_t *ch);
+
+/* passing a null pointer for data reads and discards */
+int smd_read(smd_channel_t *ch, void *data, int len);
+
+/* Write to stream channels may do a partial write and return
+** the length actually written.
+** Write to packet channels will never do a partial write --
+** it will return the requested length written or an error.
+*/
+int smd_write(smd_channel_t *ch, const void *data, int len);
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len);
+
+int smd_write_avail(smd_channel_t *ch);
+int smd_read_avail(smd_channel_t *ch);
+
+/* Returns the total size of the current packet being read.
+** Returns 0 if no packets available or a stream channel.
+*/
+int smd_cur_packet_size(smd_channel_t *ch);
+
+/* used for tty unthrottling and the like -- causes the notify()
+** callback to be called from the same lock context as is used
+** when it is called from channel updates
+*/
+void smd_kick(smd_channel_t *ch);
+
+
+#if 0
+/* these are interruptable waits which will block you until the specified
+** number of bytes are readable or writable.
+*/
+int smd_wait_until_readable(smd_channel_t *ch, int bytes);
+int smd_wait_until_writable(smd_channel_t *ch, int bytes);
+#endif
+
+typedef enum {
+       SMD_PORT_DS = 0,
+       SMD_PORT_DIAG,
+       SMD_PORT_RPC_CALL,
+       SMD_PORT_RPC_REPLY,
+       SMD_PORT_BT,
+       SMD_PORT_CONTROL,
+       SMD_PORT_MEMCPY_SPARE1,
+       SMD_PORT_DATA1,
+       SMD_PORT_DATA2,
+       SMD_PORT_DATA3,
+       SMD_PORT_DATA4,
+       SMD_PORT_DATA5,
+       SMD_PORT_DATA6,
+       SMD_PORT_DATA7,
+       SMD_PORT_DATA8,
+       SMD_PORT_DATA9,
+       SMD_PORT_DATA10,
+       SMD_PORT_DATA11,
+       SMD_PORT_DATA12,
+       SMD_PORT_DATA13,
+       SMD_PORT_DATA14,
+       SMD_PORT_DATA15,
+       SMD_PORT_DATA16,
+       SMD_PORT_DATA17,
+       SMD_PORT_DATA18,
+       SMD_PORT_DATA19,
+       SMD_PORT_DATA20,
+       SMD_PORT_GPS_NMEA,
+       SMD_PORT_BRIDGE_1,
+       SMD_PORT_BRIDGE_2,
+       SMD_PORT_BRIDGE_3,
+       SMD_PORT_BRIDGE_4,
+       SMD_PORT_BRIDGE_5,
+       SMD_PORT_LOOPBACK,
+       SMD_PORT_CS_APPS_MODEM,
+       SMD_PORT_CS_APPS_DSP,
+       SMD_PORT_CS_MODEM_DSP,
+       SMD_NUM_PORTS,
+} smd_port_id_type;
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h
new file mode 100644 (file)
index 0000000..7281337
--- /dev/null
@@ -0,0 +1,115 @@
+/* Copyright (c) 2008-2009, 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 Forum, Inc. 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 "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_SIRC_H
+#define __ASM_ARCH_MSM_SIRC_H
+
+struct sirc_regs_t {
+       void    *int_enable;
+       void    *int_enable_clear;
+       void    *int_enable_set;
+       void    *int_type;
+       void    *int_polarity;
+       void    *int_clear;
+};
+
+struct sirc_cascade_regs {
+       void    *int_status;
+       unsigned int    cascade_irq;
+};
+
+void msm_init_sirc(void);
+void msm_sirc_enter_sleep(void);
+void msm_sirc_exit_sleep(void);
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+
+#include <mach/msm_iomap.h>
+
+/*
+ * Secondary interrupt controller interrupts
+ */
+
+#define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+#define INT_UART1                     (FIRST_SIRC_IRQ + 0)
+#define INT_UART2                     (FIRST_SIRC_IRQ + 1)
+#define INT_UART3                     (FIRST_SIRC_IRQ + 2)
+#define INT_UART1_RX                  (FIRST_SIRC_IRQ + 3)
+#define INT_UART2_RX                  (FIRST_SIRC_IRQ + 4)
+#define INT_UART3_RX                  (FIRST_SIRC_IRQ + 5)
+#define INT_SPI_INPUT                 (FIRST_SIRC_IRQ + 6)
+#define INT_SPI_OUTPUT                (FIRST_SIRC_IRQ + 7)
+#define INT_SPI_ERROR                 (FIRST_SIRC_IRQ + 8)
+#define INT_GPIO_GROUP1               (FIRST_SIRC_IRQ + 9)
+#define INT_GPIO_GROUP2               (FIRST_SIRC_IRQ + 10)
+#define INT_GPIO_GROUP1_SECURE        (FIRST_SIRC_IRQ + 11)
+#define INT_GPIO_GROUP2_SECURE        (FIRST_SIRC_IRQ + 12)
+#define INT_AVS_SVIC                  (FIRST_SIRC_IRQ + 13)
+#define INT_AVS_REQ_UP                (FIRST_SIRC_IRQ + 14)
+#define INT_AVS_REQ_DOWN              (FIRST_SIRC_IRQ + 15)
+#define INT_PBUS_ERR                  (FIRST_SIRC_IRQ + 16)
+#define INT_AXI_ERR                   (FIRST_SIRC_IRQ + 17)
+#define INT_SMI_ERR                   (FIRST_SIRC_IRQ + 18)
+#define INT_EBI1_ERR                  (FIRST_SIRC_IRQ + 19)
+#define INT_IMEM_ERR                  (FIRST_SIRC_IRQ + 20)
+#define INT_TEMP_SENSOR               (FIRST_SIRC_IRQ + 21)
+#define INT_TV_ENC                    (FIRST_SIRC_IRQ + 22)
+#define INT_GRP2D                     (FIRST_SIRC_IRQ + 23)
+#define INT_GSBI_QUP                  (FIRST_SIRC_IRQ + 24)
+#define INT_SC_ACG                    (FIRST_SIRC_IRQ + 25)
+#define INT_WDT0                      (FIRST_SIRC_IRQ + 26)
+#define INT_WDT1                      (FIRST_SIRC_IRQ + 27)
+
+#if defined(CONFIG_MSM_SOC_REV_A)
+#define NR_SIRC_IRQS                  28
+#define SIRC_MASK                     0x0FFFFFFF
+#else
+#define NR_SIRC_IRQS                  23
+#define SIRC_MASK                     0x007FFFFF
+#endif
+
+#define LAST_SIRC_IRQ                 (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1)
+
+#define SPSS_SIRC_INT_SELECT          (MSM_SIRC_BASE + 0x00)
+#define SPSS_SIRC_INT_ENABLE          (MSM_SIRC_BASE + 0x04)
+#define SPSS_SIRC_INT_ENABLE_CLEAR    (MSM_SIRC_BASE + 0x08)
+#define SPSS_SIRC_INT_ENABLE_SET      (MSM_SIRC_BASE + 0x0C)
+#define SPSS_SIRC_INT_TYPE            (MSM_SIRC_BASE + 0x10)
+#define SPSS_SIRC_INT_POLARITY        (MSM_SIRC_BASE + 0x14)
+#define SPSS_SIRC_SECURITY            (MSM_SIRC_BASE + 0x18)
+#define SPSS_SIRC_IRQ_STATUS          (MSM_SIRC_BASE + 0x1C)
+#define SPSS_SIRC_IRQ1_STATUS         (MSM_SIRC_BASE + 0x20)
+#define SPSS_SIRC_RAW_STATUS          (MSM_SIRC_BASE + 0x24)
+#define SPSS_SIRC_INT_CLEAR           (MSM_SIRC_BASE + 0x28)
+#define SPSS_SIRC_SOFT_INT            (MSM_SIRC_BASE + 0x2C)
+
+#endif
+
+#endif
index 574ccc4..d2e83f4 100644 (file)
@@ -21,3 +21,8 @@ static inline void arch_reset(char mode, const char *cmd)
 {
        for (;;) ;  /* depends on IPC w/ other core */
 }
+
+/* low level hardware reset hook -- for example, hitting the
+ * PSHOLD line on the PMIC to hard reset the system
+ */
+extern void (*msm_hw_reset_hook)(void);
index 9f9e25c..6626e78 100644 (file)
@@ -23,7 +23,7 @@ struct vreg *vreg_get(struct device *dev, const char *id);
 void vreg_put(struct vreg *vreg);
 
 int vreg_enable(struct vreg *vreg);
-void vreg_disable(struct vreg *vreg);
+int vreg_disable(struct vreg *vreg);
 int vreg_set_level(struct vreg *vreg, unsigned mv);
 
 #endif
index 05f96b7..1c05060 100644 (file)
@@ -1,8 +1,9 @@
 /* arch/arm/mach-msm/io.c
  *
- * MSM7K io support
+ * MSM7K, QSD io support
  *
  * 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
@@ -34,6 +35,8 @@
                .type = MT_DEVICE_NONSHARED, \
         }
 
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27) \
+       || defined(CONFIG_ARCH_MSM7X25)
 static struct map_desc msm_io_desc[] __initdata = {
        MSM_DEVICE(VIC),
        MSM_DEVICE(CSR),
@@ -44,10 +47,13 @@ static struct map_desc msm_io_desc[] __initdata = {
        MSM_DEVICE(CLK_CTL),
 #ifdef CONFIG_MSM_DEBUG_UART
        MSM_DEVICE(DEBUG_UART),
+#endif
+#ifdef CONFIG_ARCH_MSM7X30
+       MSM_DEVICE(GCC),
 #endif
        {
                .virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
-               .pfn =      __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+               .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
                .length =   MSM_SHARED_RAM_SIZE,
                .type =     MT_DEVICE,
        },
@@ -60,9 +66,72 @@ void __init msm_map_common_io(void)
         * pages are peripheral interface or not.
         */
        asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
-
        iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc));
 }
+#endif
+
+#ifdef CONFIG_ARCH_QSD8X50
+static struct map_desc qsd8x50_io_desc[] __initdata = {
+       MSM_DEVICE(VIC),
+       MSM_DEVICE(CSR),
+       MSM_DEVICE(TMR),
+       MSM_DEVICE(DMOV),
+       MSM_DEVICE(GPIO1),
+       MSM_DEVICE(GPIO2),
+       MSM_DEVICE(CLK_CTL),
+       MSM_DEVICE(SIRC),
+       MSM_DEVICE(SCPLL),
+       MSM_DEVICE(AD5),
+       MSM_DEVICE(MDC),
+#ifdef CONFIG_MSM_DEBUG_UART
+       MSM_DEVICE(DEBUG_UART),
+#endif
+       {
+               .virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
+               .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+               .length =   MSM_SHARED_RAM_SIZE,
+               .type =     MT_DEVICE,
+       },
+};
+
+void __init msm_map_qsd8x50_io(void)
+{
+       iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc));
+}
+#endif /* CONFIG_ARCH_QSD8X50 */
+
+#ifdef CONFIG_ARCH_MSM7X30
+static struct map_desc msm7x30_io_desc[] __initdata = {
+       MSM_DEVICE(VIC),
+       MSM_DEVICE(CSR),
+       MSM_DEVICE(TMR),
+       MSM_DEVICE(DMOV),
+       MSM_DEVICE(GPIO1),
+       MSM_DEVICE(GPIO2),
+       MSM_DEVICE(CLK_CTL),
+       MSM_DEVICE(CLK_CTL_SH2),
+       MSM_DEVICE(AD5),
+       MSM_DEVICE(MDC),
+       MSM_DEVICE(ACC),
+       MSM_DEVICE(SAW),
+       MSM_DEVICE(GCC),
+       MSM_DEVICE(TCSR),
+#ifdef CONFIG_MSM_DEBUG_UART
+       MSM_DEVICE(DEBUG_UART),
+#endif
+       {
+               .virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
+               .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+               .length =   MSM_SHARED_RAM_SIZE,
+               .type =     MT_DEVICE,
+       },
+};
+
+void __init msm_map_msm7x30_io(void)
+{
+       iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM7X30 */
 
 void __iomem *
 __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
new file mode 100644 (file)
index 0000000..99f2c34
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, 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.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
+
+#include <mach/msm_iomap.h>
+
+#include "smd_private.h"
+
+enum {
+       IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0,
+       IRQ_DEBUG_SLEEP_INT = 1U << 1,
+       IRQ_DEBUG_SLEEP_ABORT = 1U << 2,
+       IRQ_DEBUG_SLEEP = 1U << 3,
+       IRQ_DEBUG_SLEEP_REQUEST = 1U << 4,
+};
+static int msm_irq_debug_mask;
+module_param_named(debug_mask, msm_irq_debug_mask, int,
+                  S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define VIC_REG(off) (MSM_VIC_BASE + (off))
+#define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4)
+#define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3)
+
+#define VIC_INT_SELECT0     VIC_REG(0x0000)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT1     VIC_REG(0x0004)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT2     VIC_REG(0x0008)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT3     VIC_REG(0x000C)  /* 1: FIQ, 0: IRQ */
+#define VIC_INT_EN0         VIC_REG(0x0010)
+#define VIC_INT_EN1         VIC_REG(0x0014)
+#define VIC_INT_EN2         VIC_REG(0x0018)
+#define VIC_INT_EN3         VIC_REG(0x001C)
+#define VIC_INT_ENCLEAR0    VIC_REG(0x0020)
+#define VIC_INT_ENCLEAR1    VIC_REG(0x0024)
+#define VIC_INT_ENCLEAR2    VIC_REG(0x0028)
+#define VIC_INT_ENCLEAR3    VIC_REG(0x002C)
+#define VIC_INT_ENSET0      VIC_REG(0x0030)
+#define VIC_INT_ENSET1      VIC_REG(0x0034)
+#define VIC_INT_ENSET2      VIC_REG(0x0038)
+#define VIC_INT_ENSET3      VIC_REG(0x003C)
+#define VIC_INT_TYPE0       VIC_REG(0x0040)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE1       VIC_REG(0x0044)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE2       VIC_REG(0x0048)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_TYPE3       VIC_REG(0x004C)  /* 1: EDGE, 0: LEVEL  */
+#define VIC_INT_POLARITY0   VIC_REG(0x0050)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY1   VIC_REG(0x0054)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY2   VIC_REG(0x0058)  /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY3   VIC_REG(0x005C)  /* 1: NEG, 0: POS */
+#define VIC_NO_PEND_VAL     VIC_REG(0x0060)
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+#define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064)
+#define VIC_INT_MASTEREN    VIC_REG(0x0068)  /* 1: IRQ, 2: FIQ     */
+#define VIC_CONFIG          VIC_REG(0x006C)  /* 1: USE SC VIC */
+#else
+#define VIC_INT_MASTEREN    VIC_REG(0x0064)  /* 1: IRQ, 2: FIQ     */
+#define VIC_PROTECTION      VIC_REG(0x006C)  /* 1: ENABLE          */
+#define VIC_CONFIG          VIC_REG(0x0068)  /* 1: USE ARM1136 VIC */
+#endif
+
+#define VIC_IRQ_STATUS0     VIC_REG(0x0080)
+#define VIC_IRQ_STATUS1     VIC_REG(0x0084)
+#define VIC_IRQ_STATUS2     VIC_REG(0x0088)
+#define VIC_IRQ_STATUS3     VIC_REG(0x008C)
+#define VIC_FIQ_STATUS0     VIC_REG(0x0090)
+#define VIC_FIQ_STATUS1     VIC_REG(0x0094)
+#define VIC_FIQ_STATUS2     VIC_REG(0x0098)
+#define VIC_FIQ_STATUS3     VIC_REG(0x009C)
+#define VIC_RAW_STATUS0     VIC_REG(0x00A0)
+#define VIC_RAW_STATUS1     VIC_REG(0x00A4)
+#define VIC_RAW_STATUS2     VIC_REG(0x00A8)
+#define VIC_RAW_STATUS3     VIC_REG(0x00AC)
+#define VIC_INT_CLEAR0      VIC_REG(0x00B0)
+#define VIC_INT_CLEAR1      VIC_REG(0x00B4)
+#define VIC_INT_CLEAR2      VIC_REG(0x00B8)
+#define VIC_INT_CLEAR3      VIC_REG(0x00BC)
+#define VIC_SOFTINT0        VIC_REG(0x00C0)
+#define VIC_SOFTINT1        VIC_REG(0x00C4)
+#define VIC_SOFTINT2        VIC_REG(0x00C8)
+#define VIC_SOFTINT3        VIC_REG(0x00CC)
+#define VIC_IRQ_VEC_RD      VIC_REG(0x00D0)  /* pending int # */
+#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4)  /* pending vector addr */
+#define VIC_IRQ_VEC_WR      VIC_REG(0x00D8)
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+#define VIC_FIQ_VEC_RD      VIC_REG(0x00DC)
+#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0)
+#define VIC_FIQ_VEC_WR      VIC_REG(0x00E4)
+#define VIC_IRQ_IN_SERVICE  VIC_REG(0x00E8)
+#define VIC_IRQ_IN_STACK    VIC_REG(0x00EC)
+#define VIC_FIQ_IN_SERVICE  VIC_REG(0x00F0)
+#define VIC_FIQ_IN_STACK    VIC_REG(0x00F4)
+#define VIC_TEST_BUS_SEL    VIC_REG(0x00F8)
+#define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC)
+#else
+#define VIC_IRQ_IN_SERVICE  VIC_REG(0x00E0)
+#define VIC_IRQ_IN_STACK    VIC_REG(0x00E4)
+#define VIC_TEST_BUS_SEL    VIC_REG(0x00E8)
+#endif
+
+#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
+#define VIC_VECTADDR(n)     VIC_REG(0x0400+((n) * 4))
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define VIC_NUM_REGS       4
+#else
+#define VIC_NUM_REGS       2
+#endif
+
+#if VIC_NUM_REGS == 2
+#define DPRINT_REGS(base_reg, format, ...)                             \
+       printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__,              \
+                       readl(base_reg ## 0), readl(base_reg ## 1))
+#define DPRINT_ARRAY(array, format, ...)                               \
+       printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__,              \
+                       array[0], array[1])
+#elif VIC_NUM_REGS == 4
+#define DPRINT_REGS(base_reg, format, ...) \
+       printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__,        \
+                       readl(base_reg ## 0), readl(base_reg ## 1),     \
+                       readl(base_reg ## 2), readl(base_reg ## 3))
+#define DPRINT_ARRAY(array, format, ...)                               \
+       printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__,        \
+                       array[0], array[1],                             \
+                       array[2], array[3])
+#else
+#error "VIC_NUM_REGS set to illegal value"
+#endif
+
+static uint32_t msm_irq_smsm_wake_enable[2];
+static struct {
+       uint32_t int_en[2];
+       uint32_t int_type;
+       uint32_t int_polarity;
+       uint32_t int_select;
+} msm_irq_shadow_reg[VIC_NUM_REGS];
+static uint32_t msm_irq_idle_disable[VIC_NUM_REGS];
+
+#define SMSM_FAKE_IRQ (0xff)
+static uint8_t msm_irq_to_smsm[NR_IRQS] = {
+       [INT_MDDI_EXT] = 1,
+       [INT_MDDI_PRI] = 2,
+       [INT_MDDI_CLIENT] = 3,
+       [INT_USB_OTG] = 4,
+
+       [INT_PWB_I2C] = 5,
+       [INT_SDC1_0] = 6,
+       [INT_SDC1_1] = 7,
+       [INT_SDC2_0] = 8,
+
+       [INT_SDC2_1] = 9,
+       [INT_ADSP_A9_A11] = 10,
+       [INT_UART1] = 11,
+       [INT_UART2] = 12,
+
+       [INT_UART3] = 13,
+       [INT_UART1_RX] = 14,
+       [INT_UART2_RX] = 15,
+       [INT_UART3_RX] = 16,
+
+       [INT_UART1DM_IRQ] = 17,
+       [INT_UART1DM_RX] = 18,
+       [INT_KEYSENSE] = 19,
+#if !defined(CONFIG_ARCH_MSM7X30)
+       [INT_AD_HSSD] = 20,
+#endif
+
+       [INT_NAND_WR_ER_DONE] = 21,
+       [INT_NAND_OP_DONE] = 22,
+       [INT_TCHSCRN1] = 23,
+       [INT_TCHSCRN2] = 24,
+
+       [INT_TCHSCRN_SSBI] = 25,
+       [INT_USB_HS] = 26,
+       [INT_UART2DM_RX] = 27,
+       [INT_UART2DM_IRQ] = 28,
+
+       [INT_SDC4_1] = 29,
+       [INT_SDC4_0] = 30,
+       [INT_SDC3_1] = 31,
+       [INT_SDC3_0] = 32,
+
+       /* fake wakeup interrupts */
+       [INT_GPIO_GROUP1] = SMSM_FAKE_IRQ,
+       [INT_GPIO_GROUP2] = SMSM_FAKE_IRQ,
+       [INT_A9_M2A_0] = SMSM_FAKE_IRQ,
+       [INT_A9_M2A_1] = SMSM_FAKE_IRQ,
+       [INT_A9_M2A_5] = SMSM_FAKE_IRQ,
+       [INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ,
+       [INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ,
+       [INT_ADSP_A11] = SMSM_FAKE_IRQ,
+#ifdef CONFIG_ARCH_QSD8X50
+       [INT_SIRC_0] = SMSM_FAKE_IRQ,
+       [INT_SIRC_1] = SMSM_FAKE_IRQ,
+#endif
+};
+
+static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val)
+{
+       int i;
+
+       for (i = 0; i < VIC_NUM_REGS; i++)
+               writel(val, base + (i * 4));
+}
+
+static void msm_irq_ack(unsigned int irq)
+{
+       void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, irq);
+       irq = 1 << (irq & 31);
+       writel(irq, reg);
+}
+
+static void msm_irq_mask(unsigned int irq)
+{
+       void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, irq);
+       unsigned index = VIC_INT_TO_REG_INDEX(irq);
+       uint32_t mask = 1UL << (irq & 31);
+       int smsm_irq = msm_irq_to_smsm[irq];
+
+       msm_irq_shadow_reg[index].int_en[0] &= ~mask;
+       writel(mask, reg);
+       if (smsm_irq == 0)
+               msm_irq_idle_disable[index] &= ~mask;
+       else {
+               mask = 1UL << (smsm_irq - 1);
+               msm_irq_smsm_wake_enable[0] &= ~mask;
+       }
+}
+
+static void msm_irq_unmask(unsigned int irq)
+{
+       void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, irq);
+       unsigned index = VIC_INT_TO_REG_INDEX(irq);
+       uint32_t mask = 1UL << (irq & 31);
+       int smsm_irq = msm_irq_to_smsm[irq];
+
+       msm_irq_shadow_reg[index].int_en[0] |= mask;
+       writel(mask, reg);
+
+       if (smsm_irq == 0)
+               msm_irq_idle_disable[index] |= mask;
+       else {
+               mask = 1UL << (smsm_irq - 1);
+               msm_irq_smsm_wake_enable[0] |= mask;
+       }
+}
+
+static int msm_irq_set_wake(unsigned int irq, unsigned int on)
+{
+       unsigned index = VIC_INT_TO_REG_INDEX(irq);
+       uint32_t mask = 1UL << (irq & 31);
+       int smsm_irq = msm_irq_to_smsm[irq];
+
+       if (smsm_irq == 0) {
+               printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", irq);
+               return -EINVAL;
+       }
+       if (on)
+               msm_irq_shadow_reg[index].int_en[1] |= mask;
+       else
+               msm_irq_shadow_reg[index].int_en[1] &= ~mask;
+
+       if (smsm_irq == SMSM_FAKE_IRQ)
+               return 0;
+
+       mask = 1UL << (smsm_irq - 1);
+       if (on)
+               msm_irq_smsm_wake_enable[1] |= mask;
+       else
+               msm_irq_smsm_wake_enable[1] &= ~mask;
+       return 0;
+}
+
+static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+       void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, irq);
+       void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, irq);
+       unsigned index = VIC_INT_TO_REG_INDEX(irq);
+       int b = 1 << (irq & 31);
+       uint32_t polarity;
+       uint32_t type;
+
+       polarity = msm_irq_shadow_reg[index].int_polarity;
+       if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+               polarity |= b;
+       if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+               polarity &= ~b;
+       writel(polarity, preg);
+       msm_irq_shadow_reg[index].int_polarity = polarity;
+
+       type = msm_irq_shadow_reg[index].int_type;
+       if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+               type |= b;
+               irq_desc[irq].handle_irq = handle_edge_irq;
+       }
+       if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
+               type &= ~b;
+               irq_desc[irq].handle_irq = handle_level_irq;
+       }
+       writel(type, treg);
+       msm_irq_shadow_reg[index].int_type = type;
+       return 0;
+}
+
+static struct irq_chip msm_irq_chip = {
+       .name      = "msm",
+       .disable   = msm_irq_mask,
+       .ack       = msm_irq_ack,
+       .mask      = msm_irq_mask,
+       .unmask    = msm_irq_unmask,
+       .set_wake  = msm_irq_set_wake,
+       .set_type  = msm_irq_set_type,
+};
+
+void __init msm_init_irq(void)
+{
+       unsigned n;
+
+       /* select level interrupts */
+       msm_irq_write_all_regs(VIC_INT_TYPE0, 0);
+
+       /* select highlevel interrupts */
+       msm_irq_write_all_regs(VIC_INT_POLARITY0, 0);
+
+       /* select IRQ for all INTs */
+       msm_irq_write_all_regs(VIC_INT_SELECT0, 0);
+
+       /* disable all INTs */
+       msm_irq_write_all_regs(VIC_INT_EN0, 0);
+
+       /* don't use vic */
+       writel(0, VIC_CONFIG);
+
+       /* enable interrupt controller */
+       writel(3, VIC_INT_MASTEREN);
+
+       for (n = 0; n < NR_MSM_IRQS; n++) {
+               set_irq_chip(n, &msm_irq_chip);
+               set_irq_handler(n, handle_level_irq);
+               set_irq_flags(n, IRQF_VALID);
+       }
+}
index 69ca0dd..6c8d5f8 100644 (file)
@@ -101,11 +101,11 @@ static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
 
        if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
                writel(readl(treg) | b, treg);
-               set_irq_handler(irq, handle_edge_irq);
+               irq_desc[irq].handle_irq = handle_edge_irq;
        }
        if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
                writel(readl(treg) & (~b), treg);
-               set_irq_handler(irq, handle_level_irq);
+               irq_desc[irq].handle_irq = handle_level_irq;
        }
        return 0;
 }
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c
new file mode 100644 (file)
index 0000000..b64ba5a
--- /dev/null
@@ -0,0 +1,82 @@
+/* arch/arm/mach-msm/last_radio_log.c
+ *
+ * Extract the log from a modem crash though SMEM
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+
+#include "smd_private.h"
+
+static void *radio_log_base;
+static size_t radio_log_size;
+
+extern void *smem_item(unsigned id, unsigned *size);
+
+static ssize_t last_radio_log_read(struct file *file, char __user *buf,
+                       size_t len, loff_t *offset)
+{
+       loff_t pos = *offset;
+       ssize_t count;
+
+       if (pos >= radio_log_size)
+               return 0;
+
+       count = min(len, (size_t)(radio_log_size - pos));
+       if (copy_to_user(buf, radio_log_base + pos, count)) {
+               pr_err("%s: copy to user failed\n", __func__);
+               return -EFAULT;
+       }
+
+       *offset += count;
+       return count;
+}
+
+static struct file_operations last_radio_log_fops = {
+       .read = last_radio_log_read
+};
+
+void msm_init_last_radio_log(struct module *owner)
+{
+       struct proc_dir_entry *entry;
+
+       if (last_radio_log_fops.owner) {
+               pr_err("%s: already claimed\n", __func__);
+               return;
+       }
+
+       radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size);
+       if (!radio_log_base) {
+               pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__);
+               return;
+       }
+
+       entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL);
+       if (!entry) {
+               pr_err("%s: could not create proc entry for radio log\n",
+                               __func__);
+               return;
+       }
+
+       pr_err("%s: last radio log is %d bytes long\n", __func__,
+               radio_log_size);
+       last_radio_log_fops.owner = owner;
+       entry->proc_fops = &last_radio_log_fops;
+       entry->size = radio_log_size;
+}
+EXPORT_SYMBOL(msm_init_last_radio_log);
index 915ee70..67e701c 100644 (file)
 
 #include "proc_comm.h"
 
-#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+static inline void msm_a2m_int(uint32_t irq)
+{
+#if defined(CONFIG_ARCH_MSM7X30)
+       writel(1 << irq, MSM_GCC_BASE + 0x8);
+#else
+       writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
+#endif
+}
 
 static inline void notify_other_proc_comm(void)
 {
-       writel(1, MSM_A2M_INT(6));
+       msm_a2m_int(6);
 }
 
 #define APP_COMMAND 0x00
@@ -107,4 +114,17 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
        return ret;
 }
 
-
+/*
+ * We need to wait for the ARM9 to at least partially boot
+ * up before we can continue. Since the ARM9 does resource
+ * allocation, if we dont' wait we could end up crashing or in
+ * and unknown state. This function should be called early to
+ * wait on the ARM9.
+ */
+void __init proc_comm_boot_wait(void)
+{
+       void __iomem *base = MSM_SHARED_RAM_BASE;
+       proc_comm_wait_for(base + MDM_STATUS, PCOM_READY);
+}
index 834760f..12da4ca 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
 #define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
 
+#include <linux/init.h>
+
 enum {
        PCOM_CMD_IDLE = 0x0,
        PCOM_CMD_DONE,
@@ -62,19 +64,104 @@ enum {
        PCOM_RESET_CHIP_IMM,
        PCOM_PM_VID_EN,
        PCOM_VREG_PULLDOWN,
+       PCOM_GET_MODEM_VERSION,
+       PCOM_CLK_REGIME_SEC_RESET,
+       PCOM_CLK_REGIME_SEC_RESET_ASSERT,
+       PCOM_CLK_REGIME_SEC_RESET_DEASSERT,
+       PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP,
+       PCOM_CLK_REGIME_SEC_ENABLE,
+       PCOM_CLK_REGIME_SEC_DISABLE,
+       PCOM_CLK_REGIME_SEC_IS_ON,
+       PCOM_CLK_REGIME_SEC_SEL_CLK_INV,
+       PCOM_CLK_REGIME_SEC_SEL_CLK_SRC,
+       PCOM_CLK_REGIME_SEC_SEL_CLK_DIV,
+       PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE,
+       PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE,
+       PCOM_CLK_REGIME_SEC_SEL_SPEED,
+       PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP,
+       PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP,
+       PCOM_CLK_REGIME_SEC_USB_XTAL_ON,
+       PCOM_CLK_REGIME_SEC_USB_XTAL_OFF,
+       PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE,
+       PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK,
+       PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ,
+       PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ,
+       PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ,
+       PCOM_CLK_REGIME_SEC_SEL_VFE_SRC,
+       PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK,
+       PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK,
+       PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF,
+       PCOM_CLK_REGIME_SEC_VFE_RAIL_ON,
+       PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF,
+       PCOM_CLK_REGIME_SEC_GRP_RAIL_ON,
+       PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF,
+       PCOM_CLK_REGIME_SEC_VDC_RAIL_ON,
+       PCOM_CLK_REGIME_SEC_LCD_CTRL,
+       PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE,
+       PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE,
+       PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP,
+       PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER,
+       PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP,
+       PCOM_GPIO_CONFIG,
+       PCOM_GPIO_CONFIGURE_GROUP,
+       PCOM_GPIO_TLMM_SET_PORT,
+       PCOM_GPIO_TLMM_CONFIG_EX,
+       PCOM_SET_FTM_BOOT_COUNT,
+       PCOM_RESERVED0,
+       PCOM_RESERVED1,
+       PCOM_CUSTOMER_CMD1,
+       PCOM_CUSTOMER_CMD2,
+       PCOM_CUSTOMER_CMD3,
+       PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE,
+       PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE,
+       PCOM_CLK_REGIME_SEC_RAIL_DISABLE,
+       PCOM_CLK_REGIME_SEC_RAIL_ENABLE,
+       PCOM_CLK_REGIME_SEC_RAIL_CONTROL,
+       PCOM_SET_SW_WATCHDOG_STATE,
+       PCOM_PM_MPP_CONFIG_DIGITAL_INPUT,
+       PCOM_PM_MPP_CONFIG_I_SINK,
+       PCOM_RESERVED_101,
+       PCOM_MSM_HSUSB_PHY_RESET,
+       PCOM_GET_BATT_MV_LEVEL,
+       PCOM_CHG_USB_IS_PC_CONNECTED,
+       PCOM_CHG_USB_IS_CHARGER_CONNECTED,
+       PCOM_CHG_USB_IS_DISCONNECTED,
+       PCOM_CHG_USB_IS_AVAILABLE,
+       PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ,
+       PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY,
+       PCOM_CLKCTL_RPC_RESET_ASSERT,
+       PCOM_CLKCTL_RPC_RESET_DEASSERT,
+       PCOM_CLKCTL_RPC_RAIL_ON,
+       PCOM_CLKCTL_RPC_RAIL_OFF,
+       PCOM_CLKCTL_RPC_RAIL_ENABLE,
+       PCOM_CLKCTL_RPC_RAIL_DISABLE,
+       PCOM_CLKCTL_RPC_RAIL_CONTROL,
+       PCOM_CLKCTL_RPC_MIN_MSMC1,
        PCOM_NUM_CMDS,
 };
 
 enum {
-        PCOM_INVALID_STATUS = 0x0,
-        PCOM_READY,
-        PCOM_CMD_RUNNING,
-        PCOM_CMD_SUCCESS,
-        PCOM_CMD_FAIL,
+       PCOM_INVALID_STATUS = 0x0,
+       PCOM_READY,
+       PCOM_CMD_RUNNING,
+       PCOM_CMD_SUCCESS,
+       PCOM_CMD_FAIL,
+       PCOM_CMD_FAIL_FALSE_RETURNED,
+       PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER,
+       PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT,
+       PCOM_CMD_FAIL_CMD_UNREGISTERED,
+       PCOM_CMD_FAIL_CMD_LOCKED,
+       PCOM_CMD_FAIL_SERVER_NOT_YET_READY,
+       PCOM_CMD_FAIL_BAD_DESTINATION,
+       PCOM_CMD_FAIL_SERVER_RESET,
+       PCOM_CMD_FAIL_SMSM_NOT_INIT,
+       PCOM_CMD_FAIL_PROC_COMM_BUSY,
+       PCOM_CMD_FAIL_PROC_COMM_NOT_INIT,
+
 };
 
 /* List of VREGs that support the Pull Down Resistor setting. */
-enum {
+enum vreg_pdown_id {
        PM_VREG_PDOWN_MSMA_ID,
        PM_VREG_PDOWN_MSMP_ID,
        PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
@@ -131,6 +218,11 @@ enum {
        PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
 };
 
+enum {
+       PCOM_CLKRGM_APPS_RESET_USB_PHY  = 34,
+       PCOM_CLKRGM_APPS_RESET_USBH     = 37,
+};
+
 /* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
 
 #define GPIO_ENABLE    0
@@ -161,5 +253,6 @@ enum {
                (((drvstr) & 0xF) << 17))
 
 int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
+void __init proc_comm_boot_wait(void);
 
 #endif
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
new file mode 100644 (file)
index 0000000..b079452
--- /dev/null
@@ -0,0 +1,177 @@
+/* Copyright (c) 2008-2009, 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 <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+
+static unsigned int int_enable;
+static unsigned int wake_enable;
+
+static struct sirc_regs_t sirc_regs = {
+       .int_enable       = SPSS_SIRC_INT_ENABLE,
+       .int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR,
+       .int_enable_set   = SPSS_SIRC_INT_ENABLE_SET,
+       .int_type         = SPSS_SIRC_INT_TYPE,
+       .int_polarity     = SPSS_SIRC_INT_POLARITY,
+       .int_clear        = SPSS_SIRC_INT_CLEAR,
+};
+
+static struct sirc_cascade_regs sirc_reg_table[] = {
+       {
+               .int_status  = SPSS_SIRC_IRQ_STATUS,
+               .cascade_irq = INT_SIRC_0,
+       }
+};
+
+static unsigned int save_type;
+static unsigned int save_polarity;
+
+/* Mask off the given interrupt. Keep the int_enable mask in sync with
+   the enable reg, so it can be restored after power collapse. */
+static void sirc_irq_mask(unsigned int irq)
+{
+       unsigned int mask;
+
+
+       mask = 1 << (irq - FIRST_SIRC_IRQ);
+       writel(mask, sirc_regs.int_enable_clear);
+       int_enable &= ~mask;
+       return;
+}
+
+/* Unmask the given interrupt. Keep the int_enable mask in sync with
+   the enable reg, so it can be restored after power collapse. */
+static void sirc_irq_unmask(unsigned int irq)
+{
+       unsigned int mask;
+
+       mask = 1 << (irq - FIRST_SIRC_IRQ);
+       writel(mask, sirc_regs.int_enable_set);
+       int_enable |= mask;
+       return;
+}
+
+static void sirc_irq_ack(unsigned int irq)
+{
+       unsigned int mask;
+
+       mask = 1 << (irq - FIRST_SIRC_IRQ);
+       writel(mask, sirc_regs.int_clear);
+       return;
+}
+
+static int sirc_irq_set_wake(unsigned int irq, unsigned int on)
+{
+       unsigned int mask;
+
+       /* Used to set the interrupt enable mask during power collapse. */
+       mask = 1 << (irq - FIRST_SIRC_IRQ);
+       if (on)
+               wake_enable |= mask;
+       else
+               wake_enable &= ~mask;
+
+       return 0;
+}
+
+static int sirc_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+       unsigned int mask;
+       unsigned int val;
+
+       mask = 1 << (irq - FIRST_SIRC_IRQ);
+       val = readl(sirc_regs.int_polarity);
+
+       if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING))
+               val |= mask;
+       else
+               val &= ~mask;
+
+       writel(val, sirc_regs.int_polarity);
+
+       val = readl(sirc_regs.int_type);
+       if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+               val |= mask;
+               irq_desc[irq].handle_irq = handle_edge_irq;
+       } else {
+               val &= ~mask;
+               irq_desc[irq].handle_irq = handle_level_irq;
+       }
+
+       writel(val, sirc_regs.int_type);
+
+       return 0;
+}
+
+/* Finds the pending interrupt on the passed cascade irq and redrives it */
+static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned int reg = 0;
+       unsigned int sirq;
+       unsigned int status;
+
+       while ((reg < ARRAY_SIZE(sirc_reg_table)) &&
+               (sirc_reg_table[reg].cascade_irq != irq))
+               reg++;
+
+       status = readl(sirc_reg_table[reg].int_status);
+       status &= SIRC_MASK;
+       if (status == 0)
+               return;
+
+       for (sirq = 0;
+            (sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0);
+            sirq++)
+               ;
+       generic_handle_irq(sirq+FIRST_SIRC_IRQ);
+
+       desc->chip->ack(irq);
+}
+
+static struct irq_chip sirc_irq_chip = {
+       .name      = "sirc",
+       .ack       = sirc_irq_ack,
+       .mask      = sirc_irq_mask,
+       .unmask    = sirc_irq_unmask,
+       .set_wake  = sirc_irq_set_wake,
+       .set_type  = sirc_irq_set_type,
+};
+
+void __init msm_init_sirc(void)
+{
+       int i;
+
+       int_enable = 0;
+       wake_enable = 0;
+
+       for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) {
+               set_irq_chip(i, &sirc_irq_chip);
+               set_irq_handler(i, handle_edge_irq);
+               set_irq_flags(i, IRQF_VALID);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
+               set_irq_chained_handler(sirc_reg_table[i].cascade_irq,
+                                       sirc_irq_handler);
+               set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
+       }
+       return;
+}
+
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
new file mode 100644 (file)
index 0000000..cf11d41
--- /dev/null
@@ -0,0 +1,1046 @@
+/* arch/arm/mach-msm/smd.c
+ *
+ * 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 <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+
+#include <mach/msm_smd.h>
+#include <mach/system.h>
+
+#include "smd_private.h"
+#include "proc_comm.h"
+
+#if defined(CONFIG_ARCH_QSD8X50)
+#define CONFIG_QDSP6 1
+#endif
+
+void (*msm_hw_reset_hook)(void);
+
+#define MODULE_NAME "msm_smd"
+
+enum {
+       MSM_SMD_DEBUG = 1U << 0,
+       MSM_SMSM_DEBUG = 1U << 0,
+};
+
+static int msm_smd_debug_mask;
+
+struct shared_info {
+       int ready;
+       unsigned state;
+};
+
+static unsigned dummy_state[SMSM_STATE_COUNT];
+
+static struct shared_info smd_info = {
+       .state = (unsigned) &dummy_state,
+};
+
+module_param_named(debug_mask, msm_smd_debug_mask,
+                  int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static unsigned last_heap_free = 0xffffffff;
+
+static inline void notify_other_smsm(void)
+{
+       msm_a2m_int(5);
+#ifdef CONFIG_QDSP6
+       msm_a2m_int(8);
+#endif
+}
+
+static inline void notify_modem_smd(void)
+{
+       msm_a2m_int(0);
+}
+
+static inline void notify_dsp_smd(void)
+{
+       msm_a2m_int(8);
+}
+
+static void smd_diag(void)
+{
+       char *x;
+
+       x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+       if (x != 0) {
+               x[SZ_DIAG_ERR_MSG - 1] = 0;
+               pr_info("smem: DIAG '%s'\n", x);
+       }
+}
+
+/* call when SMSM_RESET flag is set in the A9's smsm_state */
+static void handle_modem_crash(void)
+{
+       pr_err("ARM9 has CRASHED\n");
+       smd_diag();
+
+       /* hard reboot if possible */
+       if (msm_hw_reset_hook)
+               msm_hw_reset_hook();
+
+       /* in this case the modem or watchdog should reboot us */
+       for (;;)
+               ;
+}
+
+uint32_t raw_smsm_get_state(enum smsm_state_item item)
+{
+       return readl(smd_info.state + item * 4);
+}
+
+static int check_for_modem_crash(void)
+{
+       if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
+               handle_modem_crash();
+               return -1;
+       }
+       return 0;
+}
+
+/* the spinlock is used to synchronize between the
+ * irq handler and code that mutates the channel
+ * list or fiddles with channel state
+ */
+DEFINE_SPINLOCK(smd_lock);
+DEFINE_SPINLOCK(smem_lock);
+
+/* the mutex is used during open() and close()
+ * operations to avoid races while creating or
+ * destroying smd_channel structures
+ */
+static DEFINE_MUTEX(smd_creation_mutex);
+
+static int smd_initialized;
+
+LIST_HEAD(smd_ch_closed_list);
+LIST_HEAD(smd_ch_list_modem);
+LIST_HEAD(smd_ch_list_dsp);
+
+static unsigned char smd_ch_allocated[64];
+static struct work_struct probe_work;
+
+/* how many bytes are available for reading */
+static int smd_stream_read_avail(struct smd_channel *ch)
+{
+       return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
+}
+
+/* how many bytes we are free to write */
+static int smd_stream_write_avail(struct smd_channel *ch)
+{
+       return ch->fifo_mask -
+               ((ch->send->head - ch->send->tail) & ch->fifo_mask);
+}
+
+static int smd_packet_read_avail(struct smd_channel *ch)
+{
+       if (ch->current_packet) {
+               int n = smd_stream_read_avail(ch);
+               if (n > ch->current_packet)
+                       n = ch->current_packet;
+               return n;
+       } else {
+               return 0;
+       }
+}
+
+static int smd_packet_write_avail(struct smd_channel *ch)
+{
+       int n = smd_stream_write_avail(ch);
+       return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
+}
+
+static int ch_is_open(struct smd_channel *ch)
+{
+       return (ch->recv->state == SMD_SS_OPENED) &&
+               (ch->send->state == SMD_SS_OPENED);
+}
+
+/* provide a pointer and length to readable data in the fifo */
+static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
+{
+       unsigned head = ch->recv->head;
+       unsigned tail = ch->recv->tail;
+       *ptr = (void *) (ch->recv_data + tail);
+
+       if (tail <= head)
+               return head - tail;
+       else
+               return ch->fifo_size - tail;
+}
+
+/* advance the fifo read pointer after data from ch_read_buffer is consumed */
+static void ch_read_done(struct smd_channel *ch, unsigned count)
+{
+       BUG_ON(count > smd_stream_read_avail(ch));
+       ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
+       ch->send->fTAIL = 1;
+}
+
+/* basic read interface to ch_read_{buffer,done} used
+ * by smd_*_read() and update_packet_state()
+ * will read-and-discard if the _data pointer is null
+ */
+static int ch_read(struct smd_channel *ch, void *_data, int len)
+{
+       void *ptr;
+       unsigned n;
+       unsigned char *data = _data;
+       int orig_len = len;
+
+       while (len > 0) {
+               n = ch_read_buffer(ch, &ptr);
+               if (n == 0)
+                       break;
+
+               if (n > len)
+                       n = len;
+               if (_data)
+                       memcpy(data, ptr, n);
+
+               data += n;
+               len -= n;
+               ch_read_done(ch, n);
+       }
+
+       return orig_len - len;
+}
+
+static void update_stream_state(struct smd_channel *ch)
+{
+       /* streams have no special state requiring updating */
+}
+
+static void update_packet_state(struct smd_channel *ch)
+{
+       unsigned hdr[5];
+       int r;
+
+       /* can't do anything if we're in the middle of a packet */
+       if (ch->current_packet != 0)
+               return;
+
+       /* don't bother unless we can get the full header */
+       if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
+               return;
+
+       r = ch_read(ch, hdr, SMD_HEADER_SIZE);
+       BUG_ON(r != SMD_HEADER_SIZE);
+
+       ch->current_packet = hdr[0];
+}
+
+/* provide a pointer and length to next free space in the fifo */
+static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
+{
+       unsigned head = ch->send->head;
+       unsigned tail = ch->send->tail;
+       *ptr = (void *) (ch->send_data + head);
+
+       if (head < tail) {
+               return tail - head - 1;
+       } else {
+               if (tail == 0)
+                       return ch->fifo_size - head - 1;
+               else
+                       return ch->fifo_size - head;
+       }
+}
+
+/* advace the fifo write pointer after freespace
+ * from ch_write_buffer is filled
+ */
+static void ch_write_done(struct smd_channel *ch, unsigned count)
+{
+       BUG_ON(count > smd_stream_write_avail(ch));
+       ch->send->head = (ch->send->head + count) & ch->fifo_mask;
+       ch->send->fHEAD = 1;
+}
+
+static void ch_set_state(struct smd_channel *ch, unsigned n)
+{
+       if (n == SMD_SS_OPENED) {
+               ch->send->fDSR = 1;
+               ch->send->fCTS = 1;
+               ch->send->fCD = 1;
+       } else {
+               ch->send->fDSR = 0;
+               ch->send->fCTS = 0;
+               ch->send->fCD = 0;
+       }
+       ch->send->state = n;
+       ch->send->fSTATE = 1;
+       ch->notify_other_cpu();
+}
+
+static void do_smd_probe(void)
+{
+       struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+       if (shared->heap_info.free_offset != last_heap_free) {
+               last_heap_free = shared->heap_info.free_offset;
+               schedule_work(&probe_work);
+       }
+}
+
+static void smd_state_change(struct smd_channel *ch,
+                            unsigned last, unsigned next)
+{
+       ch->last_state = next;
+
+       pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next);
+
+       switch (next) {
+       case SMD_SS_OPENING:
+               ch->recv->tail = 0;
+       case SMD_SS_OPENED:
+               if (ch->send->state != SMD_SS_OPENED)
+                       ch_set_state(ch, SMD_SS_OPENED);
+               ch->notify(ch->priv, SMD_EVENT_OPEN);
+               break;
+       case SMD_SS_FLUSHING:
+       case SMD_SS_RESET:
+               /* we should force them to close? */
+       default:
+               ch->notify(ch->priv, SMD_EVENT_CLOSE);
+       }
+}
+
+static void handle_smd_irq(struct list_head *list, void (*notify)(void))
+{
+       unsigned long flags;
+       struct smd_channel *ch;
+       int do_notify = 0;
+       unsigned ch_flags;
+       unsigned tmp;
+
+       spin_lock_irqsave(&smd_lock, flags);
+       list_for_each_entry(ch, list, ch_list) {
+               ch_flags = 0;
+               if (ch_is_open(ch)) {
+                       if (ch->recv->fHEAD) {
+                               ch->recv->fHEAD = 0;
+                               ch_flags |= 1;
+                               do_notify |= 1;
+                       }
+                       if (ch->recv->fTAIL) {
+                               ch->recv->fTAIL = 0;
+                               ch_flags |= 2;
+                               do_notify |= 1;
+                       }
+                       if (ch->recv->fSTATE) {
+                               ch->recv->fSTATE = 0;
+                               ch_flags |= 4;
+                               do_notify |= 1;
+                       }
+               }
+               tmp = ch->recv->state;
+               if (tmp != ch->last_state)
+                       smd_state_change(ch, ch->last_state, tmp);
+               if (ch_flags) {
+                       ch->update_state(ch);
+                       ch->notify(ch->priv, SMD_EVENT_DATA);
+               }
+       }
+       if (do_notify)
+               notify();
+       spin_unlock_irqrestore(&smd_lock, flags);
+       do_smd_probe();
+}
+
+static irqreturn_t smd_modem_irq_handler(int irq, void *data)
+{
+       handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+       return IRQ_HANDLED;
+}
+
+#if defined(CONFIG_QDSP6)
+static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
+{
+       handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+       return IRQ_HANDLED;
+}
+#endif
+
+static void smd_fake_irq_handler(unsigned long arg)
+{
+       handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+       handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+}
+
+static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
+
+static inline int smd_need_int(struct smd_channel *ch)
+{
+       if (ch_is_open(ch)) {
+               if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
+                       return 1;
+               if (ch->recv->state != ch->last_state)
+                       return 1;
+       }
+       return 0;
+}
+
+void smd_sleep_exit(void)
+{
+       unsigned long flags;
+       struct smd_channel *ch;
+       int need_int = 0;
+
+       spin_lock_irqsave(&smd_lock, flags);
+       list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
+               if (smd_need_int(ch)) {
+                       need_int = 1;
+                       break;
+               }
+       }
+       list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
+               if (smd_need_int(ch)) {
+                       need_int = 1;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&smd_lock, flags);
+       do_smd_probe();
+
+       if (need_int) {
+               if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+                       pr_info("smd_sleep_exit need interrupt\n");
+               tasklet_schedule(&smd_fake_irq_tasklet);
+       }
+}
+
+
+void smd_kick(smd_channel_t *ch)
+{
+       unsigned long flags;
+       unsigned tmp;
+
+       spin_lock_irqsave(&smd_lock, flags);
+       ch->update_state(ch);
+       tmp = ch->recv->state;
+       if (tmp != ch->last_state) {
+               ch->last_state = tmp;
+               if (tmp == SMD_SS_OPENED)
+                       ch->notify(ch->priv, SMD_EVENT_OPEN);
+               else
+                       ch->notify(ch->priv, SMD_EVENT_CLOSE);
+       }
+       ch->notify(ch->priv, SMD_EVENT_DATA);
+       ch->notify_other_cpu();
+       spin_unlock_irqrestore(&smd_lock, flags);
+}
+
+static int smd_is_packet(int chn, unsigned type)
+{
+       type &= SMD_KIND_MASK;
+       if (type == SMD_KIND_PACKET)
+               return 1;
+       if (type == SMD_KIND_STREAM)
+               return 0;
+
+       /* older AMSS reports SMD_KIND_UNKNOWN always */
+       if ((chn > 4) || (chn == 1))
+               return 1;
+       else
+               return 0;
+}
+
+static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
+{
+       void *ptr;
+       const unsigned char *buf = _data;
+       unsigned xfer;
+       int orig_len = len;
+
+       if (len < 0)
+               return -EINVAL;
+
+       while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
+               if (!ch_is_open(ch))
+                       break;
+               if (xfer > len)
+                       xfer = len;
+               memcpy(ptr, buf, xfer);
+               ch_write_done(ch, xfer);
+               len -= xfer;
+               buf += xfer;
+               if (len == 0)
+                       break;
+       }
+
+       ch->notify_other_cpu();
+
+       return orig_len - len;
+}
+
+static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
+{
+       unsigned hdr[5];
+
+       if (len < 0)
+               return -EINVAL;
+
+       if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
+               return -ENOMEM;
+
+       hdr[0] = len;
+       hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
+
+       smd_stream_write(ch, hdr, sizeof(hdr));
+       smd_stream_write(ch, _data, len);
+
+       return len;
+}
+
+static int smd_stream_read(smd_channel_t *ch, void *data, int len)
+{
+       int r;
+
+       if (len < 0)
+               return -EINVAL;
+
+       r = ch_read(ch, data, len);
+       if (r > 0)
+               ch->notify_other_cpu();
+
+       return r;
+}
+
+static int smd_packet_read(smd_channel_t *ch, void *data, int len)
+{
+       unsigned long flags;
+       int r;
+
+       if (len < 0)
+               return -EINVAL;
+
+       if (len > ch->current_packet)
+               len = ch->current_packet;
+
+       r = ch_read(ch, data, len);
+       if (r > 0)
+               ch->notify_other_cpu();
+
+       spin_lock_irqsave(&smd_lock, flags);
+       ch->current_packet -= r;
+       update_packet_state(ch);
+       spin_unlock_irqrestore(&smd_lock, flags);
+
+       return r;
+}
+
+static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
+{
+       struct smd_channel *ch;
+
+       ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
+       if (ch == 0) {
+               pr_err("smd_alloc_channel() out of memory\n");
+               return -1;
+       }
+       ch->n = cid;
+
+       if (_smd_alloc_channel(ch)) {
+               kfree(ch);
+               return -1;
+       }
+
+       ch->fifo_mask = ch->fifo_size - 1;
+       ch->type = type;
+
+       if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
+               ch->notify_other_cpu = notify_modem_smd;
+       else
+               ch->notify_other_cpu = notify_dsp_smd;
+
+       if (smd_is_packet(cid, type)) {
+               ch->read = smd_packet_read;
+               ch->write = smd_packet_write;
+               ch->read_avail = smd_packet_read_avail;
+               ch->write_avail = smd_packet_write_avail;
+               ch->update_state = update_packet_state;
+       } else {
+               ch->read = smd_stream_read;
+               ch->write = smd_stream_write;
+               ch->read_avail = smd_stream_read_avail;
+               ch->write_avail = smd_stream_write_avail;
+               ch->update_state = update_stream_state;
+       }
+
+       if ((type & 0xff) == 0)
+               memcpy(ch->name, "SMD_", 4);
+       else
+               memcpy(ch->name, "DSP_", 4);
+       memcpy(ch->name + 4, name, 20);
+       ch->name[23] = 0;
+       ch->pdev.name = ch->name;
+       ch->pdev.id = -1;
+
+       pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
+               ch->n, ch->fifo_size, ch->name);
+
+       mutex_lock(&smd_creation_mutex);
+       list_add(&ch->ch_list, &smd_ch_closed_list);
+       mutex_unlock(&smd_creation_mutex);
+
+       platform_device_register(&ch->pdev);
+       return 0;
+}
+
+static void smd_channel_probe_worker(struct work_struct *work)
+{
+       struct smd_alloc_elm *shared;
+       unsigned ctype;
+       unsigned type;
+       unsigned n;
+
+       shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+       if (!shared) {
+               pr_err("smd: cannot find allocation table\n");
+               return;
+       }
+       for (n = 0; n < 64; n++) {
+               if (smd_ch_allocated[n])
+                       continue;
+               if (!shared[n].ref_count)
+                       continue;
+               if (!shared[n].name[0])
+                       continue;
+               ctype = shared[n].ctype;
+               type = ctype & SMD_TYPE_MASK;
+
+               /* DAL channels are stream but neither the modem,
+                * nor the DSP correctly indicate this.  Fixup manually.
+                */
+               if (!memcmp(shared[n].name, "DAL", 3))
+                       ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
+
+               type = shared[n].ctype & SMD_TYPE_MASK;
+               if ((type == SMD_TYPE_APPS_MODEM) ||
+                   (type == SMD_TYPE_APPS_DSP))
+                       if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
+                               smd_ch_allocated[n] = 1;
+       }
+}
+
+static void do_nothing_notify(void *priv, unsigned flags)
+{
+}
+
+struct smd_channel *smd_get_channel(const char *name)
+{
+       struct smd_channel *ch;
+
+       mutex_lock(&smd_creation_mutex);
+       list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
+               if (!strcmp(name, ch->name)) {
+                       list_del(&ch->ch_list);
+                       mutex_unlock(&smd_creation_mutex);
+                       return ch;
+               }
+       }
+       mutex_unlock(&smd_creation_mutex);
+
+       return NULL;
+}
+
+int smd_open(const char *name, smd_channel_t **_ch,
+            void *priv, void (*notify)(void *, unsigned))
+{
+       struct smd_channel *ch;
+       unsigned long flags;
+
+       if (smd_initialized == 0) {
+               pr_info("smd_open() before smd_init()\n");
+               return -ENODEV;
+       }
+
+       ch = smd_get_channel(name);
+       if (!ch)
+               return -ENODEV;
+
+       if (notify == 0)
+               notify = do_nothing_notify;
+
+       ch->notify = notify;
+       ch->current_packet = 0;
+       ch->last_state = SMD_SS_CLOSED;
+       ch->priv = priv;
+
+       *_ch = ch;
+
+       spin_lock_irqsave(&smd_lock, flags);
+
+       if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
+               list_add(&ch->ch_list, &smd_ch_list_modem);
+       else
+               list_add(&ch->ch_list, &smd_ch_list_dsp);
+
+       /* If the remote side is CLOSING, we need to get it to
+        * move to OPENING (which we'll do by moving from CLOSED to
+        * OPENING) and then get it to move from OPENING to
+        * OPENED (by doing the same state change ourselves).
+        *
+        * Otherwise, it should be OPENING and we can move directly
+        * to OPENED so that it will follow.
+        */
+       if (ch->recv->state == SMD_SS_CLOSING) {
+               ch->send->head = 0;
+               ch_set_state(ch, SMD_SS_OPENING);
+       } else {
+               ch_set_state(ch, SMD_SS_OPENED);
+       }
+       spin_unlock_irqrestore(&smd_lock, flags);
+       smd_kick(ch);
+
+       return 0;
+}
+
+int smd_close(smd_channel_t *ch)
+{
+       unsigned long flags;
+
+       pr_info("smd_close(%p)\n", ch);
+
+       if (ch == 0)
+               return -1;
+
+       spin_lock_irqsave(&smd_lock, flags);
+       ch->notify = do_nothing_notify;
+       list_del(&ch->ch_list);
+       ch_set_state(ch, SMD_SS_CLOSED);
+       spin_unlock_irqrestore(&smd_lock, flags);
+
+       mutex_lock(&smd_creation_mutex);
+       list_add(&ch->ch_list, &smd_ch_closed_list);
+       mutex_unlock(&smd_creation_mutex);
+
+       return 0;
+}
+
+int smd_read(smd_channel_t *ch, void *data, int len)
+{
+       return ch->read(ch, data, len);
+}
+
+int smd_write(smd_channel_t *ch, const void *data, int len)
+{
+       return ch->write(ch, data, len);
+}
+
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
+{
+       unsigned long flags;
+       int res;
+       spin_lock_irqsave(&smd_lock, flags);
+       res = ch->write(ch, data, len);
+       spin_unlock_irqrestore(&smd_lock, flags);
+       return res;
+}
+
+int smd_read_avail(smd_channel_t *ch)
+{
+       return ch->read_avail(ch);
+}
+
+int smd_write_avail(smd_channel_t *ch)
+{
+       return ch->write_avail(ch);
+}
+
+int smd_wait_until_readable(smd_channel_t *ch, int bytes)
+{
+       return -1;
+}
+
+int smd_wait_until_writable(smd_channel_t *ch, int bytes)
+{
+       return -1;
+}
+
+int smd_cur_packet_size(smd_channel_t *ch)
+{
+       return ch->current_packet;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+void *smem_alloc(unsigned id, unsigned size)
+{
+       return smem_find(id, size);
+}
+
+void *smem_item(unsigned id, unsigned *size)
+{
+       struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+       struct smem_heap_entry *toc = shared->heap_toc;
+
+       if (id >= SMEM_NUM_ITEMS)
+               return 0;
+
+       if (toc[id].allocated) {
+               *size = toc[id].size;
+               return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
+       } else {
+               *size = 0;
+       }
+
+       return 0;
+}
+
+void *smem_find(unsigned id, unsigned size_in)
+{
+       unsigned size;
+       void *ptr;
+
+       ptr = smem_item(id, &size);
+       if (!ptr)
+               return 0;
+
+       size_in = ALIGN(size_in, 8);
+       if (size_in != size) {
+               pr_err("smem_find(%d, %d): wrong size %d\n",
+                      id, size_in, size);
+               return 0;
+       }
+
+       return ptr;
+}
+
+static irqreturn_t smsm_irq_handler(int irq, void *data)
+{
+       unsigned long flags;
+       unsigned apps, modm;
+
+       spin_lock_irqsave(&smem_lock, flags);
+
+       apps = raw_smsm_get_state(SMSM_STATE_APPS);
+       modm = raw_smsm_get_state(SMSM_STATE_MODEM);
+
+       if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+               pr_info("<SM %08x %08x>\n", apps, modm);
+       if (modm & SMSM_RESET)
+               handle_modem_crash();
+
+       do_smd_probe();
+
+       spin_unlock_irqrestore(&smem_lock, flags);
+       return IRQ_HANDLED;
+}
+
+int smsm_change_state(enum smsm_state_item item,
+                     uint32_t clear_mask, uint32_t set_mask)
+{
+       unsigned long addr = smd_info.state + item * 4;
+       unsigned long flags;
+       unsigned state;
+
+       if (!smd_info.ready)
+               return -EIO;
+
+       spin_lock_irqsave(&smem_lock, flags);
+
+       if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
+               handle_modem_crash();
+
+       state = (readl(addr) & ~clear_mask) | set_mask;
+       writel(state, addr);
+
+       if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+               pr_info("smsm_change_state %d %x\n", item, state);
+       notify_other_smsm();
+
+       spin_unlock_irqrestore(&smem_lock, flags);
+
+       return 0;
+}
+
+uint32_t smsm_get_state(enum smsm_state_item item)
+{
+       unsigned long flags;
+       uint32_t rv;
+
+       spin_lock_irqsave(&smem_lock, flags);
+
+       rv = readl(smd_info.state + item * 4);
+
+       if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
+               handle_modem_crash();
+
+       spin_unlock_irqrestore(&smem_lock, flags);
+
+       return rv;
+}
+
+#ifdef CONFIG_ARCH_MSM_SCORPION
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+       struct msm_dem_slave_data *ptr;
+
+       ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
+       if (ptr == NULL) {
+               pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
+               return -EIO;
+       }
+       if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+               pr_info("smsm_set_sleep_duration %d -> %d\n",
+                      ptr->sleep_time, delay);
+       ptr->sleep_time = delay;
+       return 0;
+}
+
+#else
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+       uint32_t *ptr;
+
+       ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+       if (ptr == NULL) {
+               pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
+               return -EIO;
+       }
+       if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+               pr_info("smsm_set_sleep_duration %d -> %d\n",
+                      *ptr, delay);
+       *ptr = delay;
+       return 0;
+}
+
+#endif
+
+int smd_core_init(void)
+{
+       int r;
+       pr_info("smd_core_init()\n");
+
+       /* wait for essential items to be initialized */
+       for (;;) {
+               unsigned size;
+               void *state;
+               state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
+               if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
+                       smd_info.state = (unsigned)state;
+                       break;
+               }
+       }
+
+       smd_info.ready = 1;
+
+       r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
+                       IRQF_TRIGGER_RISING, "smd_dev", 0);
+       if (r < 0)
+               return r;
+       r = enable_irq_wake(INT_A9_M2A_0);
+       if (r < 0)
+               pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
+
+       r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
+                       IRQF_TRIGGER_RISING, "smsm_dev", 0);
+       if (r < 0) {
+               free_irq(INT_A9_M2A_0, 0);
+               return r;
+       }
+       r = enable_irq_wake(INT_A9_M2A_5);
+       if (r < 0)
+               pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
+
+#if defined(CONFIG_QDSP6)
+       r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
+                       IRQF_TRIGGER_RISING, "smd_dsp", 0);
+       if (r < 0) {
+               free_irq(INT_A9_M2A_0, 0);
+               free_irq(INT_A9_M2A_5, 0);
+               return r;
+       }
+#endif
+
+       /* check for any SMD channels that may already exist */
+       do_smd_probe();
+
+       /* indicate that we're up and running */
+       smsm_change_state(SMSM_STATE_APPS,
+                         ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
+#ifdef CONFIG_ARCH_MSM_SCORPION
+       smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
+#endif
+
+       pr_info("smd_core_init() done\n");
+
+       return 0;
+}
+
+static int __init msm_smd_probe(struct platform_device *pdev)
+{
+       pr_info("smd_init()\n");
+
+       /*
+        * If we haven't waited for the ARM9 to boot up till now,
+        * then we need to wait here. Otherwise this should just
+        * return immediately.
+        */
+       proc_comm_boot_wait();
+
+       INIT_WORK(&probe_work, smd_channel_probe_worker);
+
+       if (smd_core_init()) {
+               pr_err("smd_core_init() failed\n");
+               return -1;
+       }
+
+       do_smd_probe();
+
+       msm_check_for_modem_crash = check_for_modem_crash;
+
+       msm_init_last_radio_log(THIS_MODULE);
+
+       smd_initialized = 1;
+
+       return 0;
+}
+
+static struct platform_driver msm_smd_driver = {
+       .probe = msm_smd_probe,
+       .driver = {
+               .name = MODULE_NAME,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init msm_smd_init(void)
+{
+       return platform_driver_register(&msm_smd_driver);
+}
+
+module_init(msm_smd_init);
+
+MODULE_DESCRIPTION("MSM Shared Memory Core");
+MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
new file mode 100644 (file)
index 0000000..3b2dd71
--- /dev/null
@@ -0,0 +1,315 @@
+/* arch/arm/mach-msm/smd_debug.c
+ *
+ * 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 <linux/debugfs.h>
+#include <linux/list.h>
+
+#include <mach/msm_iomap.h>
+
+#include "smd_private.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+static char *chstate(unsigned n)
+{
+       switch (n) {
+       case SMD_SS_CLOSED:
+               return "CLOSED";
+       case SMD_SS_OPENING:
+               return "OPENING";
+       case SMD_SS_OPENED:
+               return "OPENED";
+       case SMD_SS_FLUSHING:
+               return "FLUSHING";
+       case SMD_SS_CLOSING:
+               return "CLOSING";
+       case SMD_SS_RESET:
+               return "RESET";
+       case SMD_SS_RESET_OPENING:
+               return "ROPENING";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+
+static int dump_ch(char *buf, int max, struct smd_channel *ch)
+{
+       volatile struct smd_half_channel *s = ch->send;
+       volatile struct smd_half_channel *r = ch->recv;
+
+       return scnprintf(
+               buf, max,
+               "ch%02d:"
+               " %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
+               " %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n,
+               chstate(s->state), s->tail, s->head,
+               s->fDSR ? 'D' : 'd',
+               s->fCTS ? 'C' : 'c',
+               s->fCD ? 'C' : 'c',
+               s->fRI ? 'I' : 'i',
+               s->fHEAD ? 'W' : 'w',
+               s->fTAIL ? 'R' : 'r',
+               s->fSTATE ? 'S' : 's',
+               chstate(r->state), r->tail, r->head,
+               r->fDSR ? 'D' : 'd',
+               r->fCTS ? 'R' : 'r',
+               r->fCD ? 'C' : 'c',
+               r->fRI ? 'I' : 'i',
+               r->fHEAD ? 'W' : 'w',
+               r->fTAIL ? 'R' : 'r',
+               r->fSTATE ? 'S' : 's',
+               ch->name
+               );
+}
+
+static int debug_read_stat(char *buf, int max)
+{
+       char *msg;
+       int i = 0;
+
+       msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+
+       if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
+               i += scnprintf(buf + i, max - i,
+                              "smsm: ARM9 HAS CRASHED\n");
+
+       i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
+                      raw_smsm_get_state(SMSM_STATE_MODEM),
+                      raw_smsm_get_state(SMSM_STATE_APPS));
+#ifdef CONFIG_ARCH_MSM_SCORPION
+       i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x "
+                      "qdsp6: %08x power: %08x time: %08x\n",
+                      raw_smsm_get_state(SMSM_STATE_APPS_DEM),
+                      raw_smsm_get_state(SMSM_STATE_MODEM_DEM),
+                      raw_smsm_get_state(SMSM_STATE_QDSP6_DEM),
+                      raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM),
+                      raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM));
+#endif
+       if (msg) {
+               msg[SZ_DIAG_ERR_MSG - 1] = 0;
+               i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
+       }
+       return i;
+}
+
+static int debug_read_mem(char *buf, int max)
+{
+       unsigned n;
+       struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+       struct smem_heap_entry *toc = shared->heap_toc;
+       int i = 0;
+
+       i += scnprintf(buf + i, max - i,
+                      "heap: init=%d free=%d remain=%d\n",
+                      shared->heap_info.initialized,
+                      shared->heap_info.free_offset,
+                      shared->heap_info.heap_remaining);
+
+       for (n = 0; n < SMEM_NUM_ITEMS; n++) {
+               if (toc[n].allocated == 0)
+                       continue;
+               i += scnprintf(buf + i, max - i,
+                              "%04d: offset %08x size %08x\n",
+                              n, toc[n].offset, toc[n].size);
+       }
+       return i;
+}
+
+static int debug_read_ch(char *buf, int max)
+{
+       struct smd_channel *ch;
+       unsigned long flags;
+       int i = 0;
+
+       spin_lock_irqsave(&smd_lock, flags);
+       list_for_each_entry(ch, &smd_ch_list_dsp, ch_list)
+               i += dump_ch(buf + i, max - i, ch);
+       list_for_each_entry(ch, &smd_ch_list_modem, ch_list)
+               i += dump_ch(buf + i, max - i, ch);
+       list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
+               i += dump_ch(buf + i, max - i, ch);
+       spin_unlock_irqrestore(&smd_lock, flags);
+
+       return i;
+}
+
+static int debug_read_version(char *buf, int max)
+{
+       struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+       unsigned version = shared->version[VERSION_MODEM];
+       return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
+}
+
+static int debug_read_build_id(char *buf, int max)
+{
+       unsigned size;
+       void *data;
+
+       data = smem_item(SMEM_HW_SW_BUILD_ID, &size);
+       if (!data)
+               return 0;
+
+       if (size >= max)
+               size = max;
+       memcpy(buf, data, size);
+
+       return size;
+}
+
+static int debug_read_alloc_tbl(char *buf, int max)
+{
+       struct smd_alloc_elm *shared;
+       int n, i = 0;
+
+       shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+
+       for (n = 0; n < 64; n++) {
+               if (shared[n].ref_count == 0)
+                       continue;
+               i += scnprintf(buf + i, max - i,
+                              "%03d: %-20s cid=%02d type=%03d "
+                              "kind=%02d ref_count=%d\n",
+                              n, shared[n].name, shared[n].cid,
+                              shared[n].ctype & 0xff,
+                              (shared[n].ctype >> 8) & 0xf,
+                              shared[n].ref_count);
+       }
+
+       return i;
+}
+
+#define DEBUG_BUFMAX 4096
+static char debug_buffer[DEBUG_BUFMAX];
+
+static ssize_t debug_read(struct file *file, char __user *buf,
+                         size_t count, loff_t *ppos)
+{
+       int (*fill)(char *buf, int max) = file->private_data;
+       int bsize = fill(debug_buffer, DEBUG_BUFMAX);
+       return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
+}
+
+static int debug_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static const struct file_operations debug_ops = {
+       .read = debug_read,
+       .open = debug_open,
+};
+
+static void debug_create(const char *name, mode_t mode,
+                        struct dentry *dent,
+                        int (*fill)(char *buf, int max))
+{
+       debugfs_create_file(name, mode, dent, fill, &debug_ops);
+}
+
+static int smd_debugfs_init(void)
+{
+       struct dentry *dent;
+
+       dent = debugfs_create_dir("smd", 0);
+       if (IS_ERR(dent))
+               return 1;
+
+       debug_create("ch", 0444, dent, debug_read_ch);
+       debug_create("stat", 0444, dent, debug_read_stat);
+       debug_create("mem", 0444, dent, debug_read_mem);
+       debug_create("version", 0444, dent, debug_read_version);
+       debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
+       debug_create("build", 0444, dent, debug_read_build_id);
+
+       return 0;
+}
+
+late_initcall(smd_debugfs_init);
+#endif
+
+
+#define MAX_NUM_SLEEP_CLIENTS          64
+#define MAX_SLEEP_NAME_LEN             8
+
+#define NUM_GPIO_INT_REGISTERS         6
+#define GPIO_SMEM_NUM_GROUPS           2
+#define GPIO_SMEM_MAX_PC_INTERRUPTS    8
+
+struct tramp_gpio_save {
+       unsigned int enable;
+       unsigned int detect;
+       unsigned int polarity;
+};
+
+struct tramp_gpio_smem {
+       uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
+       uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
+       uint32_t enabled[NUM_GPIO_INT_REGISTERS];
+       uint32_t detection[NUM_GPIO_INT_REGISTERS];
+       uint32_t polarity[NUM_GPIO_INT_REGISTERS];
+};
+
+
+void smsm_print_sleep_info(void)
+{
+       unsigned long flags;
+       uint32_t *ptr;
+       struct tramp_gpio_smem *gpio;
+       struct smsm_interrupt_info *int_info;
+
+
+       spin_lock_irqsave(&smem_lock, flags);
+
+       ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+       if (ptr)
+               pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
+
+       ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
+       if (ptr)
+               pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
+
+       ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
+       if (ptr)
+               pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
+
+#ifndef CONFIG_ARCH_MSM_SCORPION
+       int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
+       if (int_info)
+               pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
+                       int_info->interrupt_mask,
+                       int_info->pending_interrupts,
+                       int_info->wakeup_reason);
+
+       gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
+       if (gpio) {
+               int i;
+               for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
+                       pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
+                               i, gpio->enabled[i], gpio->detection[i],
+                               gpio->polarity[i]);
+
+               for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
+                       pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
+                               i, gpio->num_fired[i], gpio->fired[i][0],
+                               gpio->fired[i][1]);
+       }
+#else
+#endif
+       spin_unlock_irqrestore(&smem_lock, flags);
+}
+
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
new file mode 100644 (file)
index 0000000..727bfe6
--- /dev/null
@@ -0,0 +1,403 @@
+/* arch/arm/mach-msm/smd_private.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * 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_MSM_SMD_PRIVATE_H_
+#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
+
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <mach/msm_iomap.h>
+
+struct smem_heap_info {
+       unsigned initialized;
+       unsigned free_offset;
+       unsigned heap_remaining;
+       unsigned reserved;
+};
+
+struct smem_heap_entry {
+       unsigned allocated;
+       unsigned offset;
+       unsigned size;
+       unsigned reserved;
+};
+
+struct smem_proc_comm {
+       unsigned command;
+       unsigned status;
+       unsigned data1;
+       unsigned data2;
+};
+
+#define PC_APPS  0
+#define PC_MODEM 1
+
+#define VERSION_SMD       0
+#define VERSION_QDSP6     4
+#define VERSION_APPS_SBL  6
+#define VERSION_MODEM_SBL 7
+#define VERSION_APPS      8
+#define VERSION_MODEM     9
+
+struct smem_shared {
+       struct smem_proc_comm proc_comm[4];
+       unsigned version[32];
+       struct smem_heap_info heap_info;
+       struct smem_heap_entry heap_toc[512];
+};
+
+#define SMSM_V1_SIZE           (sizeof(unsigned) * 8)
+#define SMSM_V2_SIZE           (sizeof(unsigned) * 4)
+
+#ifdef CONFIG_MSM_SMD_PKG3
+struct smsm_interrupt_info {
+       uint32_t interrupt_mask;
+       uint32_t pending_interrupts;
+       uint32_t wakeup_reason;
+};
+#else
+#define DEM_MAX_PORT_NAME_LEN (20)
+struct msm_dem_slave_data {
+       uint32_t sleep_time;
+       uint32_t interrupt_mask;
+       uint32_t resources_used;
+       uint32_t reserved1;
+
+       uint32_t wakeup_reason;
+       uint32_t pending_interrupts;
+       uint32_t rpc_prog;
+       uint32_t rpc_proc;
+       char     smd_port_name[DEM_MAX_PORT_NAME_LEN];
+       uint32_t reserved2;
+};
+#endif
+
+#define SZ_DIAG_ERR_MSG 0xC8
+#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
+#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
+#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE
+#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL
+
+#define SMSM_INIT              0x00000001
+#define SMSM_SMDINIT           0x00000008
+#define SMSM_RPCINIT           0x00000020
+#define SMSM_RESET             0x00000040
+#define SMSM_RSA               0x00000080
+#define SMSM_RUN               0x00000100
+#define SMSM_PWRC              0x00000200
+#define SMSM_TIMEWAIT          0x00000400
+#define SMSM_TIMEINIT          0x00000800
+#define SMSM_PWRC_EARLY_EXIT   0x00001000
+#define SMSM_WFPI              0x00002000
+#define SMSM_SLEEP             0x00004000
+#define SMSM_SLEEPEXIT         0x00008000
+#define SMSM_APPS_REBOOT       0x00020000
+#define SMSM_SYSTEM_POWER_DOWN 0x00040000
+#define SMSM_SYSTEM_REBOOT     0x00080000
+#define SMSM_SYSTEM_DOWNLOAD   0x00100000
+#define SMSM_PWRC_SUSPEND      0x00200000
+#define SMSM_APPS_SHUTDOWN     0x00400000
+#define SMSM_SMD_LOOPBACK      0x00800000
+#define SMSM_RUN_QUIET         0x01000000
+#define SMSM_MODEM_WAIT                0x02000000
+#define SMSM_MODEM_BREAK       0x04000000
+#define SMSM_MODEM_CONTINUE    0x08000000
+#define SMSM_UNKNOWN           0x80000000
+
+#define SMSM_WKUP_REASON_RPC   0x00000001
+#define SMSM_WKUP_REASON_INT   0x00000002
+#define SMSM_WKUP_REASON_GPIO  0x00000004
+#define SMSM_WKUP_REASON_TIMER 0x00000008
+#define SMSM_WKUP_REASON_ALARM 0x00000010
+#define SMSM_WKUP_REASON_RESET 0x00000020
+
+#ifdef CONFIG_ARCH_MSM7X00A
+enum smsm_state_item {
+       SMSM_STATE_APPS = 1,
+       SMSM_STATE_MODEM = 3,
+       SMSM_STATE_COUNT,
+};
+#else
+enum smsm_state_item {
+       SMSM_STATE_APPS,
+       SMSM_STATE_MODEM,
+       SMSM_STATE_HEXAGON,
+       SMSM_STATE_APPS_DEM,
+       SMSM_STATE_MODEM_DEM,
+       SMSM_STATE_QDSP6_DEM,
+       SMSM_STATE_POWER_MASTER_DEM,
+       SMSM_STATE_TIME_MASTER_DEM,
+       SMSM_STATE_COUNT,
+};
+#endif
+
+void *smem_alloc(unsigned id, unsigned size);
+int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask);
+uint32_t smsm_get_state(enum smsm_state_item item);
+int smsm_set_sleep_duration(uint32_t delay);
+void smsm_print_sleep_info(void);
+
+#define SMEM_NUM_SMD_CHANNELS        64
+
+typedef enum {
+       /* fixed items */
+       SMEM_PROC_COMM = 0,
+       SMEM_HEAP_INFO,
+       SMEM_ALLOCATION_TABLE,
+       SMEM_VERSION_INFO,
+       SMEM_HW_RESET_DETECT,
+       SMEM_AARM_WARM_BOOT,
+       SMEM_DIAG_ERR_MESSAGE,
+       SMEM_SPINLOCK_ARRAY,
+       SMEM_MEMORY_BARRIER_LOCATION,
+
+       /* dynamic items */
+       SMEM_AARM_PARTITION_TABLE,
+       SMEM_AARM_BAD_BLOCK_TABLE,
+       SMEM_RESERVE_BAD_BLOCKS,
+       SMEM_WM_UUID,
+       SMEM_CHANNEL_ALLOC_TBL,
+       SMEM_SMD_BASE_ID,
+       SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+       SMEM_SMEM_LOG_EVENTS,
+       SMEM_SMEM_STATIC_LOG_IDX,
+       SMEM_SMEM_STATIC_LOG_EVENTS,
+       SMEM_SMEM_SLOW_CLOCK_SYNC,
+       SMEM_SMEM_SLOW_CLOCK_VALUE,
+       SMEM_BIO_LED_BUF,
+       SMEM_SMSM_SHARED_STATE,
+       SMEM_SMSM_INT_INFO,
+       SMEM_SMSM_SLEEP_DELAY,
+       SMEM_SMSM_LIMIT_SLEEP,
+       SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
+       SMEM_KEYPAD_KEYS_PRESSED,
+       SMEM_KEYPAD_STATE_UPDATED,
+       SMEM_KEYPAD_STATE_IDX,
+       SMEM_GPIO_INT,
+       SMEM_MDDI_LCD_IDX,
+       SMEM_MDDI_HOST_DRIVER_STATE,
+       SMEM_MDDI_LCD_DISP_STATE,
+       SMEM_LCD_CUR_PANEL,
+       SMEM_MARM_BOOT_SEGMENT_INFO,
+       SMEM_AARM_BOOT_SEGMENT_INFO,
+       SMEM_SLEEP_STATIC,
+       SMEM_SCORPION_FREQUENCY,
+       SMEM_SMD_PROFILES,
+       SMEM_TSSC_BUSY,
+       SMEM_HS_SUSPEND_FILTER_INFO,
+       SMEM_BATT_INFO,
+       SMEM_APPS_BOOT_MODE,
+       SMEM_VERSION_FIRST,
+       SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
+       SMEM_OSS_RRCASN1_BUF1,
+       SMEM_OSS_RRCASN1_BUF2,
+       SMEM_ID_VENDOR0,
+       SMEM_ID_VENDOR1,
+       SMEM_ID_VENDOR2,
+       SMEM_HW_SW_BUILD_ID,
+       SMEM_SMD_BLOCK_PORT_BASE_ID,
+       SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+       SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS,
+       SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS,
+       SMEM_SCLK_CONVERSION,
+       SMEM_SMD_SMSM_INTR_MUX,
+       SMEM_SMSM_CPU_INTR_MASK,
+       SMEM_APPS_DEM_SLAVE_DATA,
+       SMEM_QDSP6_DEM_SLAVE_DATA,
+       SMEM_CLKREGIM_BSP,
+       SMEM_CLKREGIM_SOURCES,
+       SMEM_SMD_FIFO_BASE_ID,
+       SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+       SMEM_POWER_ON_STATUS_INFO,
+       SMEM_DAL_AREA,
+       SMEM_SMEM_LOG_POWER_IDX,
+       SMEM_SMEM_LOG_POWER_WRAP,
+       SMEM_SMEM_LOG_POWER_EVENTS,
+       SMEM_ERR_CRASH_LOG,
+       SMEM_ERR_F3_TRACE_LOG,
+       SMEM_NUM_ITEMS,
+} smem_mem_type;
+
+
+#define SMD_SS_CLOSED          0x00000000
+#define SMD_SS_OPENING         0x00000001
+#define SMD_SS_OPENED          0x00000002
+#define SMD_SS_FLUSHING                0x00000003
+#define SMD_SS_CLOSING         0x00000004
+#define SMD_SS_RESET           0x00000005
+#define SMD_SS_RESET_OPENING   0x00000006
+
+#define SMD_BUF_SIZE           8192
+#define SMD_CHANNELS           64
+
+#define SMD_HEADER_SIZE                20
+
+struct smd_alloc_elm {
+       char name[20];
+       uint32_t cid;
+       uint32_t ctype;
+       uint32_t ref_count;
+};
+
+struct smd_half_channel {
+       unsigned state;
+       unsigned char fDSR;
+       unsigned char fCTS;
+       unsigned char fCD;
+       unsigned char fRI;
+       unsigned char fHEAD;
+       unsigned char fTAIL;
+       unsigned char fSTATE;
+       unsigned char fUNUSED;
+       unsigned tail;
+       unsigned head;
+} __attribute__(( aligned(4), packed ));
+
+/* Only used on SMD package v3 on msm7201a */
+struct smd_shared_v1 {
+       struct smd_half_channel ch0;
+       unsigned char data0[SMD_BUF_SIZE];
+       struct smd_half_channel ch1;
+       unsigned char data1[SMD_BUF_SIZE];
+};
+
+/* Used on SMD package v4 */
+struct smd_shared_v2 {
+       struct smd_half_channel ch0;
+       struct smd_half_channel ch1;
+};
+
+struct smd_channel {
+       volatile struct smd_half_channel *send;
+       volatile struct smd_half_channel *recv;
+       unsigned char *send_data;
+       unsigned char *recv_data;
+
+       unsigned fifo_mask;
+       unsigned fifo_size;
+       unsigned current_packet;
+       unsigned n;
+
+       struct list_head ch_list;
+
+       void *priv;
+       void (*notify)(void *priv, unsigned flags);
+
+       int (*read)(struct smd_channel *ch, void *data, int len);
+       int (*write)(struct smd_channel *ch, const void *data, int len);
+       int (*read_avail)(struct smd_channel *ch);
+       int (*write_avail)(struct smd_channel *ch);
+
+       void (*update_state)(struct smd_channel *ch);
+       unsigned last_state;
+       void (*notify_other_cpu)(void);
+       unsigned type;
+
+       char name[32];
+       struct platform_device pdev;
+};
+
+#define SMD_TYPE_MASK          0x0FF
+#define SMD_TYPE_APPS_MODEM    0x000
+#define SMD_TYPE_APPS_DSP      0x001
+#define SMD_TYPE_MODEM_DSP     0x002
+
+#define SMD_KIND_MASK          0xF00
+#define SMD_KIND_UNKNOWN       0x000
+#define SMD_KIND_STREAM                0x100
+#define SMD_KIND_PACKET                0x200
+
+extern struct list_head smd_ch_closed_list;
+extern struct list_head smd_ch_list_modem;
+extern struct list_head smd_ch_list_dsp;
+
+extern spinlock_t smd_lock;
+extern spinlock_t smem_lock;
+
+void *smem_find(unsigned id, unsigned size);
+void *smem_item(unsigned id, unsigned *size);
+uint32_t raw_smsm_get_state(enum smsm_state_item item);
+
+extern void msm_init_last_radio_log(struct module *);
+
+#ifdef CONFIG_MSM_SMD_PKG3
+/*
+ * This allocator assumes an SMD Package v3 which only exists on
+ * MSM7x00 SoC's.
+ */
+static inline int _smd_alloc_channel(struct smd_channel *ch)
+{
+       struct smd_shared_v1 *shared1;
+
+       shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
+       if (!shared1) {
+               pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
+               return -1;
+       }
+       ch->send = &shared1->ch0;
+       ch->recv = &shared1->ch1;
+       ch->send_data = shared1->data0;
+       ch->recv_data = shared1->data1;
+       ch->fifo_size = SMD_BUF_SIZE;
+       return 0;
+}
+#else
+/*
+ * This allocator assumes an SMD Package v4, the most common
+ * and the default.
+ */
+static inline int _smd_alloc_channel(struct smd_channel *ch)
+{
+       struct smd_shared_v2 *shared2;
+       void *buffer;
+       unsigned buffer_sz;
+
+       shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2));
+       buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz);
+
+       if (!buffer)
+               return -1;
+
+       /* buffer must be a power-of-two size */
+       if (buffer_sz & (buffer_sz - 1))
+               return -1;
+
+       buffer_sz /= 2;
+       ch->send = &shared2->ch0;
+       ch->recv = &shared2->ch1;
+       ch->send_data = buffer;
+       ch->recv_data = buffer + buffer_sz;
+       ch->fifo_size = buffer_sz;
+       return 0;
+}
+#endif /* CONFIG_MSM_SMD_PKG3 */
+
+#if defined(CONFIG_ARCH_MSM7X30)
+static inline void msm_a2m_int(uint32_t irq)
+{
+       writel(1 << irq, MSM_GCC_BASE + 0x8);
+}
+#else
+static inline void msm_a2m_int(uint32_t irq)
+{
+       writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
+}
+#endif /* CONFIG_ARCH_MSM7X30 */
+
+
+#endif
index 4855b8c..dec5ca6 100644 (file)
@@ -25,7 +25,9 @@
 #include <asm/mach/time.h>
 #include <mach/msm_iomap.h>
 
+#ifndef MSM_DGT_BASE
 #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10)
+#endif
 #define MSM_DGT_SHIFT (5)
 
 #define TIMER_MATCH_VAL         0x0000
index fcb0b9f..a9103bc 100644 (file)
@@ -1,6 +1,7 @@
 /* arch/arm/mach-msm/vreg.c
  *
  * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  *
  * This software is licensed under the terms of the GNU General Public
@@ -18,6 +19,7 @@
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/debugfs.h>
+#include <linux/string.h>
 #include <mach/vreg.h>
 
 #include "proc_comm.h"
 struct vreg {
        const char *name;
        unsigned id;
+       int status;
+       unsigned refcnt;
 };
 
-#define VREG(_name, _id) { .name = _name, .id = _id, }
+#define VREG(_name, _id, _status, _refcnt) \
+       { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
 
 static struct vreg vregs[] = {
-       VREG("msma",    0),
-       VREG("msmp",    1),
-       VREG("msme1",   2),
-       VREG("msmc1",   3),
-       VREG("msmc2",   4),
-       VREG("gp3",     5),
-       VREG("msme2",   6),
-       VREG("gp4",     7),
-       VREG("gp1",     8),
-       VREG("tcxo",    9),
-       VREG("pa",      10),
-       VREG("rftx",    11),
-       VREG("rfrx1",   12),
-       VREG("rfrx2",   13),
-       VREG("synt",    14),
-       VREG("wlan",    15),
-       VREG("usb",     16),
-       VREG("boost",   17),
-       VREG("mmc",     18),
-       VREG("ruim",    19),
-       VREG("msmc0",   20),
-       VREG("gp2",     21),
-       VREG("gp5",     22),
-       VREG("gp6",     23),
-       VREG("rf",      24),
-       VREG("rf_vco",  26),
-       VREG("mpll",    27),
-       VREG("s2",      28),
-       VREG("s3",      29),
-       VREG("rfubm",   30),
-       VREG("ncp",     31),
+       VREG("msma",    0, 0, 0),
+       VREG("msmp",    1, 0, 0),
+       VREG("msme1",   2, 0, 0),
+       VREG("msmc1",   3, 0, 0),
+       VREG("msmc2",   4, 0, 0),
+       VREG("gp3",     5, 0, 0),
+       VREG("msme2",   6, 0, 0),
+       VREG("gp4",     7, 0, 0),
+       VREG("gp1",     8, 0, 0),
+       VREG("tcxo",    9, 0, 0),
+       VREG("pa",      10, 0, 0),
+       VREG("rftx",    11, 0, 0),
+       VREG("rfrx1",   12, 0, 0),
+       VREG("rfrx2",   13, 0, 0),
+       VREG("synt",    14, 0, 0),
+       VREG("wlan",    15, 0, 0),
+       VREG("usb",     16, 0, 0),
+       VREG("boost",   17, 0, 0),
+       VREG("mmc",     18, 0, 0),
+       VREG("ruim",    19, 0, 0),
+       VREG("msmc0",   20, 0, 0),
+       VREG("gp2",     21, 0, 0),
+       VREG("gp5",     22, 0, 0),
+       VREG("gp6",     23, 0, 0),
+       VREG("rf",      24, 0, 0),
+       VREG("rf_vco",  26, 0, 0),
+       VREG("mpll",    27, 0, 0),
+       VREG("s2",      28, 0, 0),
+       VREG("s3",      29, 0, 0),
+       VREG("rfubm",   30, 0, 0),
+       VREG("ncp",     31, 0, 0),
+       VREG("gp7",     32, 0, 0),
+       VREG("gp8",     33, 0, 0),
+       VREG("gp9",     34, 0, 0),
+       VREG("gp10",    35, 0, 0),
+       VREG("gp11",    36, 0, 0),
+       VREG("gp12",    37, 0, 0),
+       VREG("gp13",    38, 0, 0),
+       VREG("gp14",    39, 0, 0),
+       VREG("gp15",    40, 0, 0),
+       VREG("gp16",    41, 0, 0),
+       VREG("gp17",    42, 0, 0),
+       VREG("s4",      43, 0, 0),
+       VREG("usb2",    44, 0, 0),
+       VREG("wlan2",   45, 0, 0),
+       VREG("xo_out",  46, 0, 0),
+       VREG("lvsw0",   47, 0, 0),
+       VREG("lvsw1",   48, 0, 0),
 };
 
 struct vreg *vreg_get(struct device *dev, const char *id)
@@ -70,7 +92,7 @@ struct vreg *vreg_get(struct device *dev, const char *id)
                if (!strcmp(vregs[n].name, id))
                        return vregs + n;
        }
-       return 0;
+       return ERR_PTR(-ENOENT);
 }
 
 void vreg_put(struct vreg *vreg)
@@ -81,20 +103,39 @@ int vreg_enable(struct vreg *vreg)
 {
        unsigned id = vreg->id;
        unsigned enable = 1;
-       return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+       if (vreg->refcnt == 0)
+               vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+       if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
+               vreg->refcnt++;
+
+       return vreg->status;
 }
 
-void vreg_disable(struct vreg *vreg)
+int vreg_disable(struct vreg *vreg)
 {
        unsigned id = vreg->id;
        unsigned enable = 0;
-       msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+       if (!vreg->refcnt)
+               return 0;
+
+       if (vreg->refcnt == 1)
+               vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+       if (!vreg->status)
+               vreg->refcnt--;
+
+       return vreg->status;
 }
 
 int vreg_set_level(struct vreg *vreg, unsigned mv)
 {
        unsigned id = vreg->id;
-       return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+
+       vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+       return vreg->status;
 }
 
 #if defined(CONFIG_DEBUG_FS)
@@ -118,24 +159,59 @@ static int vreg_debug_set(void *data, u64 val)
 
 static int vreg_debug_get(void *data, u64 *val)
 {
-       return -ENOSYS;
+       struct vreg *vreg = data;
+
+       if (!vreg->status)
+               *val = 0;
+       else
+               *val = 1;
+
+       return 0;
+}
+
+static int vreg_debug_count_set(void *data, u64 val)
+{
+       struct vreg *vreg = data;
+       if (val > UINT_MAX)
+               val = UINT_MAX;
+       vreg->refcnt = val;
+       return 0;
+}
+
+static int vreg_debug_count_get(void *data, u64 *val)
+{
+       struct vreg *vreg = data;
+
+       *val = vreg->refcnt;
+
+       return 0;
 }
 
 DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
+                       vreg_debug_count_set, "%llu\n");
 
 static int __init vreg_debug_init(void)
 {
        struct dentry *dent;
        int n;
+       char name[32];
+       const char *refcnt_name = "_refcnt";
 
        dent = debugfs_create_dir("vreg", 0);
        if (IS_ERR(dent))
                return 0;
 
-       for (n = 0; n < ARRAY_SIZE(vregs); n++)
+       for (n = 0; n < ARRAY_SIZE(vregs); n++) {
                (void) debugfs_create_file(vregs[n].name, 0644,
                                           dent, vregs + n, &vreg_fops);
 
+               strlcpy(name, vregs[n].name, sizeof(name));
+               strlcat(name, refcnt_name, sizeof(name));
+               (void) debugfs_create_file(name, 0644,
+                                          dent, vregs + n, &vreg_count_fops);
+       }
+
        return 0;
 }
 
index 3872af1..170f68e 100644 (file)
@@ -62,6 +62,15 @@ config MACH_MX31_3DS
          Include support for MX31PDK (3DS) platform. This includes specific
          configurations for the board and its peripherals.
 
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+       bool "Make the MXC NAND driver use the in flash Bad Block Table"
+       depends on MACH_MX31_3DS
+       depends on MTD_NAND_MXC
+       help
+         Enable this if you want that the MXC NAND driver uses the in flash
+         Bad Block Table to know what blocks are bad instead of scanning the
+         entire flash looking for bad block markers.
+
 config MACH_MX31MOBOARD
        bool "Support mx31moboard platforms (EPFL Mobots group)"
        select ARCH_MX31
@@ -95,6 +104,7 @@ config MACH_PCM043
 config MACH_ARMADILLO5X0
        bool "Support Atmark Armadillo-500 Development Base Board"
        select ARCH_MX31
+       select MXC_ULPI if USB_ULPI
        help
          Include support for Atmark Armadillo-500 platform. This includes
          specific configurations for the board and its peripherals.
index 80dba99..9a9eb6d 100644 (file)
@@ -468,6 +468,7 @@ static struct clk ahb_clk = {
        }
 
 DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 DEFINE_CLOCK(sdhc1_clk,   0, MXC_CCM_CGR0,  0, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(sdhc2_clk,   1, MXC_CCM_CGR0,  2, NULL, NULL, &perclk_clk);
@@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk,   0, MXC_CCM_CGR1,  0, NULL, NULL, &ahb_clk);
 DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1,  2, mstick1_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1,  4, mstick2_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK1(csi_clk,    0, MXC_CCM_CGR1,  6, csi, NULL, &serial_pll_clk);
-DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ckil_clk);
 DEFINE_CLOCK(wdog_clk,    0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(pwm_clk,     0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(usb_clk2,    0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
@@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1,    0, NULL,          0, usb_get_rate, NULL, &usb_pll_clk)
 DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 #define _REGISTER_CLOCK(d, n, c) \
        { \
@@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "iim", iim_clk)
        _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
        _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
-       _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
 };
 
 int __init mx31_clocks_init(unsigned long fref)
index 6adb586..f891115 100644 (file)
@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = {
        .resource = imx_ssi_resources1,
 };
 
-static int mx3_devices_init(void)
+static struct resource imx_wdt_resources[] = {
+       {
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device imx_wdt_device0 = {
+       .name           = "imx-wdt",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(imx_wdt_resources),
+       .resource       = imx_wdt_resources,
+};
+
+static int __init mx3_devices_init(void)
 {
        if (cpu_is_mx31()) {
                mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
                mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+               imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
+               imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
                mxc_register_device(&mxc_rnga_device, NULL);
        }
        if (cpu_is_mx35()) {
@@ -597,6 +612,8 @@ static int mx3_devices_init(void)
                imx_ssi_resources0[1].end = MX35_INT_SSI1;
                imx_ssi_resources1[1].start = MX35_INT_SSI2;
                imx_ssi_resources1[1].end = MX35_INT_SSI2;
+               imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
+               imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
        }
 
        return 0;
index 42cf175..4f77eb5 100644 (file)
@@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1;
 extern struct platform_device mxc_spi_device2;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
-
+extern struct platform_device imx_ssi_device1;
+extern struct platform_device imx_wdt_device0;
index 3d72b0b..5f72ec9 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -52,6 +55,8 @@
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
 #include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 #include "devices.h"
 #include "crm_regs.h"
@@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = {
        /* I2C2 */
        MX31_PIN_CSPI2_MOSI__SCL,
        MX31_PIN_CSPI2_MISO__SDA,
+       /* OTG */
+       MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+       MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+       MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+       MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+       MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+       MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+       MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+       MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+       MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+       MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+       MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+       MX31_PIN_USBOTG_STP__USBOTG_STP,
+       /* USB host 2 */
+       IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
 };
 
+/* USB */
+#if defined(CONFIG_USB_ULPI)
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+                       PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+       int err;
+
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+       /* Chip already enabled by hardware */
+       /* OTG phy reset*/
+       err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+       if (err) {
+               pr_err("Failed to request the usb otg reset gpio\n");
+               return err;
+       }
+
+       err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+       if (err) {
+               pr_err("Failed to reset the usb otg phy\n");
+               goto otg_free_reset;
+       }
+
+       gpio_set_value(OTG_RESET, 0/*LOW*/);
+       mdelay(5);
+       gpio_set_value(OTG_RESET, 1/*HIGH*/);
+
+       return 0;
+
+otg_free_reset:
+       gpio_free(OTG_RESET);
+       return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+       int err;
+
+       mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+       mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+       /* Enable the chip */
+       err = gpio_request(USBH2_CS, "USB-H2-CS");
+       if (err) {
+               pr_err("Failed to request the usb host 2 CS gpio\n");
+               return err;
+       }
+
+       err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+       if (err) {
+               pr_err("Failed to drive the usb host 2 CS gpio\n");
+               goto h2_free_cs;
+       }
+
+       /* H2 phy reset*/
+       err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+       if (err) {
+               pr_err("Failed to request the usb host 2 reset gpio\n");
+               goto h2_free_cs;
+       }
+
+       err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+       if (err) {
+               pr_err("Failed to reset the usb host 2 phy\n");
+               goto h2_free_reset;
+       }
+
+       gpio_set_value(USBH2_RESET, 0/*LOW*/);
+       mdelay(5);
+       gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+
+       return 0;
+
+h2_free_reset:
+       gpio_free(USBH2_RESET);
+h2_free_cs:
+       gpio_free(USBH2_CS);
+       return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+       .init   = usbotg_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+       .init   = usbh2_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif /* CONFIG_USB_ULPI */
+
 /* RTC over I2C*/
 #define ARMADILLO5X0_RTC_GPIO  IOMUX_TO_GPIO(MX31_PIN_SRXD4)
 
@@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void)
        if (armadillo5x0_i2c_rtc.irq == 0)
                pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
        i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+       /* USB */
+#if defined(CONFIG_USB_ULPI)
+       usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+       usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+       mxc_register_device(&mxc_otg_host, &usbotg_pdata);
+       mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
 }
 
 static void __init armadillo5x0_timer_init(void)
index b88c18a..f54af1e 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/gpio.h>
 #include <linux/smsc911x.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <mach/common.h>
-#include <mach/board-mx31pdk.h>
+#include <mach/board-mx31_3ds.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
 #include "devices.h"
 
 /*!
- * @file mx31pdk.c
+ * @file mx31_3ds.c
  *
  * @brief This file contains the board-specific initialization routines.
  *
  * @ingroup System
  */
 
-static int mx31pdk_pins[] = {
+static int mx31_3ds_pins[] = {
        /* UART1 */
        MX31_PIN_CTS1__CTS1,
        MX31_PIN_RTS1__RTS1,
        MX31_PIN_TXD1__TXD1,
        MX31_PIN_RXD1__RXD1,
        IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+       /* SPI 1 */
+       MX31_PIN_CSPI2_SCLK__SCLK,
+       MX31_PIN_CSPI2_MOSI__MOSI,
+       MX31_PIN_CSPI2_MISO__MISO,
+       MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+       MX31_PIN_CSPI2_SS0__SS0,
+       MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+       /* MC13783 IRQ */
+       IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+       .constraints = {
+               .boot_on        = 1,
+               .always_on      = 1,
+       },
+};
+
+static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
+       {
+               .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
+               .init_data = &pwgtx_init,
+       }, {
+               .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
+               .init_data = &pwgtx_init,
+       },
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+       .regulators = mx31_3ds_regulators,
+       .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+       .flags  = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi1_internal_chipselect[] = {
+       MXC_SPI_CS(0),
+       MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi1_pdata = {
+       .chipselect     = spi1_internal_chipselect,
+       .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+       {
+               .modalias       = "mc13783",
+               .max_speed_hz   = 1000000,
+               .bus_num        = 1,
+               .chip_select    = 1, /* SS2 */
+               .platform_data  = &mc13783_pdata,
+               .irq            = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+               .mode = SPI_CS_HIGH,
+       },
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+       .width          = 1,
+       .hw_ecc         = 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+       .flash_bbt      = 1,
+#endif
 };
 
 static struct imxuart_platform_data uart_pdata = {
@@ -95,7 +168,7 @@ static struct platform_device smsc911x_device = {
  * LEDs, switches, interrupts for Ethernet.
  */
 
-static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
+static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
 {
        uint32_t imr_val;
        uint32_t int_valid;
@@ -163,7 +236,7 @@ static struct irq_chip expio_irq_chip = {
        .unmask = expio_unmask_irq,
 };
 
-static int __init mx31pdk_init_expio(void)
+static int __init mx31_3ds_init_expio(void)
 {
        int i;
        int ret;
@@ -176,7 +249,7 @@ static int __init mx31pdk_init_expio(void)
                return -ENODEV;
        }
 
-       pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
+       pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
                __raw_readw(CPLD_CODE_VER_REG));
 
        /*
@@ -201,7 +274,7 @@ static int __init mx31pdk_init_expio(void)
                set_irq_flags(i, IRQF_VALID);
        }
        set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
-       set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
+       set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
 
        return 0;
 }
@@ -209,7 +282,7 @@ static int __init mx31pdk_init_expio(void)
 /*
  * This structure defines the MX31 memory map.
  */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
+static struct map_desc mx31_3ds_io_desc[] __initdata = {
        {
                .virtual = MX31_CS5_BASE_ADDR_VIRT,
                .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
@@ -221,10 +294,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = {
 /*
  * Set up static virtual mappings.
  */
-static void __init mx31pdk_map_io(void)
+static void __init mx31_3ds_map_io(void)
 {
        mx31_map_io();
-       iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+       iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
 }
 
 /*!
@@ -232,35 +305,40 @@ static void __init mx31pdk_map_io(void)
  */
 static void __init mxc_board_init(void)
 {
-       mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
-                                     "mx31pdk");
+       mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+                                     "mx31_3ds");
 
        mxc_register_device(&mxc_uart_device0, &uart_pdata);
+       mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
+
+       mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+       spi_register_board_info(mx31_3ds_spi_devs,
+                                               ARRAY_SIZE(mx31_3ds_spi_devs));
 
-       if (!mx31pdk_init_expio())
+       if (!mx31_3ds_init_expio())
                platform_device_register(&smsc911x_device);
 }
 
-static void __init mx31pdk_timer_init(void)
+static void __init mx31_3ds_timer_init(void)
 {
        mx31_clocks_init(26000000);
 }
 
-static struct sys_timer mx31pdk_timer = {
-       .init   = mx31pdk_timer_init,
+static struct sys_timer mx31_3ds_timer = {
+       .init   = mx31_3ds_timer_init,
 };
 
 /*
  * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31PDK data structure.
+ * initialize __mach_desc_MX31_3DS data structure.
  */
 MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
        /* Maintainer: Freescale Semiconductor, Inc. */
        .phys_io        = MX31_AIPS1_BASE_ADDR,
        .io_pg_offst    = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
        .boot_params    = MX3x_PHYS_OFFSET + 0x100,
-       .map_io         = mx31pdk_map_io,
+       .map_io         = mx31_3ds_map_io,
        .init_irq       = mx31_init_irq,
        .init_machine   = mxc_board_init,
-       .timer          = &mx31pdk_timer,
+       .timer          = &mx31_3ds_timer,
 MACHINE_END
index 034ec81..2df1ec5 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/can/platform/sja1000.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
 #include <linux/gfp.h>
 
 #include <media/soc_camera.h>
index ccd8742..093c595 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 
@@ -206,5 +205,6 @@ void __init mx31lite_db_init(void)
        mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
        mxc_register_device(&mxc_spi_device0, &spi0_pdata);
        platform_device_register(&litekit_led_device);
+       mxc_register_device(&imx_wdt_device0, NULL);
 }
 
index be90c03..1ee6ce4 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 
 #include <asm/clkdev.h>
+#include <asm/div64.h>
 
 #include <mach/hardware.h>
 #include <mach/common.h>
@@ -757,7 +758,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
 
 /* GPT */
 DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
-       NULL,  NULL, &ipg_perclk, NULL);
+       NULL,  NULL, &ipg_clk, NULL);
 DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
        NULL,  NULL, &ipg_clk, NULL);
 
index 41c769f..2d37785 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
 
+static int cpu_silicon_rev = -1;
+
+#define SI_REV 0x48
+
+static void query_silicon_parameter(void)
+{
+       void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
+       u32 rev;
+
+       if (!rom) {
+               cpu_silicon_rev = -EINVAL;
+               return;
+       }
+
+       rev = readl(rom + SI_REV);
+       switch (rev) {
+       case 0x1:
+               cpu_silicon_rev = MX51_CHIP_REV_1_0;
+               break;
+       case 0x2:
+               cpu_silicon_rev = MX51_CHIP_REV_1_1;
+               break;
+       case 0x10:
+               cpu_silicon_rev = MX51_CHIP_REV_2_0;
+               break;
+       case 0x20:
+               cpu_silicon_rev = MX51_CHIP_REV_3_0;
+               break;
+       default:
+               cpu_silicon_rev = 0;
+       }
+
+       iounmap(rom);
+}
+
+/*
+ * Returns:
+ *     the silicon revision of the cpu
+ *     -EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+       if (!cpu_is_mx51())
+               return -EINVAL;
+
+       if (cpu_silicon_rev == -1)
+               query_silicon_parameter();
+
+       return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
 static int __init post_cpu_init(void)
 {
        unsigned int reg;
index c21e18b..b7677ef 100644 (file)
@@ -34,11 +34,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
                .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
                .length = MX51_DEBUG_SIZE,
                .type = MT_DEVICE
-       }, {
-               .virtual = MX51_TZIC_BASE_ADDR_VIRT,
-               .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
-               .length = MX51_TZIC_SIZE,
-               .type = MT_DEVICE
        }, {
                .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
                .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
@@ -54,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
                .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
                .length = MX51_AIPS2_SIZE,
                .type = MT_DEVICE
-       }, {
-               .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
-               .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
-               .length = MX51_NFC_AXI_SIZE,
-               .type = MT_DEVICE
        },
 };
 
@@ -69,14 +59,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
  */
 void __init mx51_map_io(void)
 {
-       u32 tzic_addr;
-
-       if (mx51_revision() < MX51_CHIP_REV_2_0)
-               tzic_addr = 0x8FFFC000;
-       else
-               tzic_addr = 0xE0003000;
-       mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
-
        mxc_set_cpu_type(MXC_CPU_MX51);
        mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
        mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
@@ -85,5 +67,17 @@ void __init mx51_map_io(void)
 
 void __init mx51_init_irq(void)
 {
-       tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
+       unsigned long tzic_addr;
+       void __iomem *tzic_virt;
+
+       if (mx51_revision() < MX51_CHIP_REV_2_0)
+               tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+       else
+               tzic_addr = MX51_TZIC_BASE_ADDR;
+
+       tzic_virt = ioremap(tzic_addr, SZ_16K);
+       if (!tzic_virt)
+               panic("unable to map TZIC interrupt controller\n");
+
+       tzic_init_irq(tzic_virt);
 }
index 3c5e0f5..71f3ea6 100644 (file)
@@ -6,6 +6,7 @@ config MACH_NOMADIK_8815NHK
        bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
        select NOMADIK_8815
        select HAS_MTU
+       select NOMADIK_GPIO
 
 endmenu
 
index 36f67fb..a6bbd1a 100644 (file)
@@ -7,7 +7,7 @@
 
 # Object file lists.
 
-obj-y                  += clock.o gpio.o
+obj-y                  += clock.o
 
 # Cpu revision
 obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
index ab3712c..841d459 100644 (file)
@@ -32,7 +32,6 @@
 #include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
-#include "clock.h"
 
 /* Initial value for SRC control register: all timers use MXTAL/8 source */
 #define SRC_CR_INIT_MASK       0x00007fff
@@ -202,11 +201,6 @@ static struct amba_device *amba_devs[] __initdata = {
        &uart1_device,
 };
 
-/* We have a fixed clock alone, by now */
-static struct clk nhk8815_clk_48 = {
-       .rate = 48*1000*1000,
-};
-
 static struct resource nhk8815_eth_resources[] = {
        {
                .name = "smc91x-regs",
@@ -276,10 +270,8 @@ static void __init nhk8815_platform_init(void)
        platform_add_devices(nhk8815_platform_devices,
                             ARRAY_SIZE(nhk8815_platform_devices));
 
-       for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-               nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name);
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
                amba_device_register(amba_devs[i], &iomem_resource);
-       }
 }
 
 MACHINE_START(NOMADIK, "NHK8815")
index 9f92502..60f5bee 100644 (file)
@@ -32,14 +32,36 @@ void clk_disable(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_disable);
 
-/* Create a clock structure with the given name */
-int nmdk_clk_create(struct clk *clk, const char *dev_id)
-{
-       struct clk_lookup *clkdev;
+/* We have a fixed clock alone, for now */
+static struct clk clk_48 = {
+       .rate = 48 * 1000 * 1000,
+};
+
+/*
+ * Catch-all default clock to satisfy drivers using the clk API.  We don't
+ * model the actual hardware clocks yet.
+ */
+static struct clk clk_default;
 
-       clkdev = clkdev_alloc(clk, NULL, dev_id);
-       if (!clkdev)
-               return -ENOMEM;
-       clkdev_add(clkdev);
+#define CLK(_clk, dev)                         \
+       {                                       \
+               .clk            = _clk,         \
+               .dev_id         = dev,          \
+       }
+
+static struct clk_lookup lookups[] = {
+       CLK(&clk_48, "uart0"),
+       CLK(&clk_48, "uart1"),
+       CLK(&clk_default, "gpio.0"),
+       CLK(&clk_default, "gpio.1"),
+       CLK(&clk_default, "gpio.2"),
+       CLK(&clk_default, "gpio.3"),
+};
+
+static int __init clk_init(void)
+{
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
        return 0;
 }
+
+arch_initcall(clk_init);
index 235faec..5563985 100644 (file)
@@ -11,4 +11,3 @@
 struct clk {
        unsigned long           rate;
 };
-extern int nmdk_clk_create(struct clk *clk, const char *dev_id);
index 9bf33b3..91c3c90 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/amba/bus.h>
+#include <linux/platform_device.h>
 #include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
 
+#define __MEM_4K_RESOURCE(x) \
+       .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
 /* The 8815 has 4 GPIO blocks, let's register them immediately */
+
+#define GPIO_RESOURCE(block)                                           \
+       {                                                               \
+               .start  = NOMADIK_GPIO##block##_BASE,                   \
+               .end    = NOMADIK_GPIO##block##_BASE + SZ_4K - 1,       \
+               .flags  = IORESOURCE_MEM,                               \
+       },                                                              \
+       {                                                               \
+               .start  = IRQ_GPIO##block,                              \
+               .end    = IRQ_GPIO##block,                              \
+               .flags  = IORESOURCE_IRQ,                               \
+       }
+
+#define GPIO_DEVICE(block)                                             \
+       {                                                               \
+               .name           = "gpio",                               \
+               .id             = block,                                \
+               .num_resources  = 2,                                    \
+               .resource       = &cpu8815_gpio_resources[block * 2],   \
+               .dev = {                                                \
+                       .platform_data = &cpu8815_gpio[block],          \
+               },                                                      \
+       }
+
 static struct nmk_gpio_platform_data cpu8815_gpio[] = {
        {
                .name = "GPIO-0-31",
                .first_gpio = 0,
                .first_irq = NOMADIK_GPIO_TO_IRQ(0),
-               .parent_irq = IRQ_GPIO0,
        }, {
                .name = "GPIO-32-63",
                .first_gpio = 32,
                .first_irq = NOMADIK_GPIO_TO_IRQ(32),
-               .parent_irq = IRQ_GPIO1,
        }, {
                .name = "GPIO-64-95",
                .first_gpio = 64,
                .first_irq = NOMADIK_GPIO_TO_IRQ(64),
-               .parent_irq = IRQ_GPIO2,
        }, {
                .name = "GPIO-96-127", /* 124..127 not routed to pin */
                .first_gpio = 96,
                .first_irq = NOMADIK_GPIO_TO_IRQ(96),
-               .parent_irq = IRQ_GPIO3,
        }
 };
 
-#define __MEM_4K_RESOURCE(x) \
-       .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+static struct resource cpu8815_gpio_resources[] = {
+       GPIO_RESOURCE(0),
+       GPIO_RESOURCE(1),
+       GPIO_RESOURCE(2),
+       GPIO_RESOURCE(3),
+};
 
-static struct amba_device cpu8815_amba_gpio[] = {
-       {
-               .dev = {
-                       .init_name = "gpio0",
-                       .platform_data = cpu8815_gpio + 0,
-               },
-               __MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE),
-       }, {
-               .dev = {
-                       .init_name = "gpio1",
-                       .platform_data = cpu8815_gpio + 1,
-               },
-               __MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE),
-       }, {
-               .dev = {
-                       .init_name = "gpio2",
-                       .platform_data = cpu8815_gpio + 2,
-               },
-               __MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE),
-       }, {
-               .dev = {
-                       .init_name = "gpio3",
-                       .platform_data = cpu8815_gpio + 3,
-               },
-               __MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE),
-       },
+static struct platform_device cpu8815_platform_gpio[] = {
+       GPIO_DEVICE(0),
+       GPIO_DEVICE(1),
+       GPIO_DEVICE(2),
+       GPIO_DEVICE(3),
 };
 
 static struct amba_device cpu8815_amba_rng = {
@@ -93,11 +100,14 @@ static struct amba_device cpu8815_amba_rng = {
        __MEM_4K_RESOURCE(NOMADIK_RNG_BASE),
 };
 
+static struct platform_device *platform_devs[] __initdata = {
+       cpu8815_platform_gpio + 0,
+       cpu8815_platform_gpio + 1,
+       cpu8815_platform_gpio + 2,
+       cpu8815_platform_gpio + 3,
+};
+
 static struct amba_device *amba_devs[] __initdata = {
-       cpu8815_amba_gpio + 0,
-       cpu8815_amba_gpio + 1,
-       cpu8815_amba_gpio + 2,
-       cpu8815_amba_gpio + 3,
        &cpu8815_amba_rng
 };
 
@@ -105,6 +115,7 @@ static int __init cpu8815_init(void)
 {
        int i;
 
+       platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
                amba_device_register(amba_devs[i], &iomem_resource);
        return 0;
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
deleted file mode 100644 (file)
index 66b1c91..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Generic GPIO driver for logic cells found in the Nomadik SoC
- *
- * Copyright (C) 2008,2009 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.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/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-
-/*
- * The GPIO module in the Nomadik family of Systems-on-Chip is an
- * AMBA device, managing 32 pins and alternate functions.  The logic block
- * is currently only used in the Nomadik.
- *
- * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
- */
-
-#define NMK_GPIO_PER_CHIP 32
-struct nmk_gpio_chip {
-       struct gpio_chip chip;
-       void __iomem *addr;
-       unsigned int parent_irq;
-       spinlock_t *lock;
-       /* Keep track of configured edges */
-       u32 edge_rising;
-       u32 edge_falling;
-};
-
-/* Mode functions */
-int nmk_gpio_set_mode(int gpio, int gpio_mode)
-{
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 afunc, bfunc, bit;
-
-       nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-       if (!nmk_chip)
-               return -EINVAL;
-
-       bit = 1 << (gpio - nmk_chip->chip.base);
-
-       spin_lock_irqsave(&nmk_chip->lock, flags);
-       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
-       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
-       if (gpio_mode & NMK_GPIO_ALT_A)
-               afunc |= bit;
-       if (gpio_mode & NMK_GPIO_ALT_B)
-               bfunc |= bit;
-       writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
-       writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
-       spin_unlock_irqrestore(&nmk_chip->lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(nmk_gpio_set_mode);
-
-int nmk_gpio_get_mode(int gpio)
-{
-       struct nmk_gpio_chip *nmk_chip;
-       u32 afunc, bfunc, bit;
-
-       nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-       if (!nmk_chip)
-               return -EINVAL;
-
-       bit = 1 << (gpio - nmk_chip->chip.base);
-
-       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
-       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
-
-       return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
-}
-EXPORT_SYMBOL(nmk_gpio_get_mode);
-
-
-/* IRQ functions */
-static inline int nmk_gpio_get_bitmask(int gpio)
-{
-       return 1 << (gpio % 32);
-}
-
-static void nmk_gpio_irq_ack(unsigned int irq)
-{
-       int gpio;
-       struct nmk_gpio_chip *nmk_chip;
-
-       gpio = NOMADIK_IRQ_TO_GPIO(irq);
-       nmk_chip = get_irq_chip_data(irq);
-       if (!nmk_chip)
-               return;
-       writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
-}
-
-static void nmk_gpio_irq_mask(unsigned int irq)
-{
-       int gpio;
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 bitmask, reg;
-
-       gpio = NOMADIK_IRQ_TO_GPIO(irq);
-       nmk_chip = get_irq_chip_data(irq);
-       bitmask = nmk_gpio_get_bitmask(gpio);
-       if (!nmk_chip)
-               return;
-
-       /* we must individually clear the two edges */
-       spin_lock_irqsave(&nmk_chip->lock, flags);
-       if (nmk_chip->edge_rising & bitmask) {
-               reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
-               reg &= ~bitmask;
-               writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
-       }
-       if (nmk_chip->edge_falling & bitmask) {
-               reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
-               reg &= ~bitmask;
-               writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
-       }
-       spin_unlock_irqrestore(&nmk_chip->lock, flags);
-};
-
-static void nmk_gpio_irq_unmask(unsigned int irq)
-{
-       int gpio;
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 bitmask, reg;
-
-       gpio = NOMADIK_IRQ_TO_GPIO(irq);
-       nmk_chip = get_irq_chip_data(irq);
-       bitmask = nmk_gpio_get_bitmask(gpio);
-       if (!nmk_chip)
-               return;
-
-       /* we must individually set the two edges */
-       spin_lock_irqsave(&nmk_chip->lock, flags);
-       if (nmk_chip->edge_rising & bitmask) {
-               reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
-               reg |= bitmask;
-               writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
-       }
-       if (nmk_chip->edge_falling & bitmask) {
-               reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
-               reg |= bitmask;
-               writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
-       }
-       spin_unlock_irqrestore(&nmk_chip->lock, flags);
-}
-
-static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
-{
-       int gpio;
-       struct nmk_gpio_chip *nmk_chip;
-       unsigned long flags;
-       u32 bitmask;
-
-       gpio = NOMADIK_IRQ_TO_GPIO(irq);
-       nmk_chip = get_irq_chip_data(irq);
-       bitmask = nmk_gpio_get_bitmask(gpio);
-       if (!nmk_chip)
-               return -EINVAL;
-
-       if (type & IRQ_TYPE_LEVEL_HIGH)
-               return -EINVAL;
-       if (type & IRQ_TYPE_LEVEL_LOW)
-               return -EINVAL;
-
-       spin_lock_irqsave(&nmk_chip->lock, flags);
-
-       nmk_chip->edge_rising &= ~bitmask;
-       if (type & IRQ_TYPE_EDGE_RISING)
-               nmk_chip->edge_rising |= bitmask;
-       writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC);
-
-       nmk_chip->edge_falling &= ~bitmask;
-       if (type & IRQ_TYPE_EDGE_FALLING)
-               nmk_chip->edge_falling |= bitmask;
-       writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC);
-
-       spin_unlock_irqrestore(&nmk_chip->lock, flags);
-
-       nmk_gpio_irq_unmask(irq);
-
-       return 0;
-}
-
-static struct irq_chip nmk_gpio_irq_chip = {
-       .name           = "Nomadik-GPIO",
-       .ack            = nmk_gpio_irq_ack,
-       .mask           = nmk_gpio_irq_mask,
-       .unmask         = nmk_gpio_irq_unmask,
-       .set_type       = nmk_gpio_irq_set_type,
-};
-
-static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-       struct nmk_gpio_chip *nmk_chip;
-       struct irq_chip *host_chip;
-       unsigned int gpio_irq;
-       u32 pending;
-       unsigned int first_irq;
-
-       nmk_chip = get_irq_data(irq);
-       first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
-       while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
-               gpio_irq = first_irq + __ffs(pending);
-               generic_handle_irq(gpio_irq);
-       }
-       if (0) {/* don't ack parent irq, as ack == disable */
-               host_chip = get_irq_chip(irq);
-               host_chip->ack(irq);
-       }
-}
-
-static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
-{
-       unsigned int first_irq;
-       int i;
-
-       first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
-       for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
-               set_irq_chip(i, &nmk_gpio_irq_chip);
-               set_irq_handler(i, handle_edge_irq);
-               set_irq_flags(i, IRQF_VALID);
-               set_irq_chip_data(i, nmk_chip);
-       }
-       set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
-       set_irq_data(nmk_chip->parent_irq, nmk_chip);
-       return 0;
-}
-
-/* I/O Functions */
-static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-
-       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
-       return 0;
-}
-
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
-                               int val)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-
-       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
-       return 0;
-}
-
-static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-       u32 bit = 1 << offset;
-
-       return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
-}
-
-static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
-                               int val)
-{
-       struct nmk_gpio_chip *nmk_chip =
-               container_of(chip, struct nmk_gpio_chip, chip);
-       u32 bit = 1 << offset;
-
-       if (val)
-               writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
-       else
-               writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
-}
-
-/* This structure is replicated for each GPIO block allocated at probe time */
-static struct gpio_chip nmk_gpio_template = {
-       .direction_input        = nmk_gpio_make_input,
-       .get                    = nmk_gpio_get_input,
-       .direction_output       = nmk_gpio_make_output,
-       .set                    = nmk_gpio_set_output,
-       .ngpio                  = NMK_GPIO_PER_CHIP,
-       .can_sleep              = 0,
-};
-
-static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
-{
-       struct nmk_gpio_platform_data *pdata;
-       struct nmk_gpio_chip *nmk_chip;
-       struct gpio_chip *chip;
-       int ret;
-
-       pdata = dev->dev.platform_data;
-       ret = amba_request_regions(dev, pdata->name);
-       if (ret)
-               return ret;
-
-       nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
-       if (!nmk_chip) {
-               ret = -ENOMEM;
-               goto out_amba;
-       }
-       /*
-        * The virt address in nmk_chip->addr is in the nomadik register space,
-        * so we can simply convert the resource address, without remapping
-        */
-       nmk_chip->addr = io_p2v(dev->res.start);
-       nmk_chip->chip = nmk_gpio_template;
-       nmk_chip->parent_irq = pdata->parent_irq;
-
-       chip = &nmk_chip->chip;
-       chip->base = pdata->first_gpio;
-       chip->label = pdata->name;
-       chip->dev = &dev->dev;
-       chip->owner = THIS_MODULE;
-
-       ret = gpiochip_add(&nmk_chip->chip);
-       if (ret)
-               goto out_free;
-
-       amba_set_drvdata(dev, nmk_chip);
-
-       nmk_gpio_init_irq(nmk_chip);
-
-       dev_info(&dev->dev, "Bits %i-%i at address %p\n",
-                nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
-       return 0;
-
- out_free:
-       kfree(nmk_chip);
- out_amba:
-       amba_release_regions(dev);
-       dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
-                 pdata->first_gpio, pdata->first_gpio+31);
-       return ret;
-}
-
-static int nmk_gpio_remove(struct amba_device *dev)
-{
-       struct nmk_gpio_chip *nmk_chip;
-
-       nmk_chip = amba_get_drvdata(dev);
-       gpiochip_remove(&nmk_chip->chip);
-       kfree(nmk_chip);
-       amba_release_regions(dev);
-       return 0;
-}
-
-
-/* We have 0x1f080060 and 0x1f180060, accept both using the mask */
-static struct amba_id nmk_gpio_ids[] = {
-       {
-               .id     = 0x1f080060,
-               .mask   = 0xffefffff,
-       },
-       {0, 0},
-};
-
-static struct amba_driver nmk_gpio_driver = {
-       .drv = {
-               .owner = THIS_MODULE,
-               .name = "gpio",
-               },
-       .probe = nmk_gpio_probe,
-       .remove = nmk_gpio_remove,
-       .suspend = NULL, /* to be done */
-       .resume = NULL,
-       .id_table = nmk_gpio_ids,
-};
-
-static int __init nmk_gpio_init(void)
-{
-       return amba_driver_register(&nmk_gpio_driver);
-}
-
-arch_initcall(nmk_gpio_init);
-
-MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
-MODULE_DESCRIPTION("Nomadik GPIO Driver");
-MODULE_LICENSE("GPL");
-
-
index 61577c9..7a81a04 100644 (file)
@@ -1,71 +1,6 @@
-/*
- * Structures and registers for GPIO access in the Nomadik SoC
- *
- * Copyright (C) 2008 STMicroelectronics
- *     Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *
- * 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
 
-#include <asm-generic/gpio.h>
-
-/*
- * These currently cause a function call to happen, they may be optimized
- * if needed by adding cpu-specific defines to identify blocks
- * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
- */
-#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
-
-/*
- * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
- * the "gpio" namespace for generic and cross-machine functions
- */
-
-/* Register in the logic block */
-#define NMK_GPIO_DAT   0x00
-#define NMK_GPIO_DATS  0x04
-#define NMK_GPIO_DATC  0x08
-#define NMK_GPIO_PDIS  0x0c
-#define NMK_GPIO_DIR   0x10
-#define NMK_GPIO_DIRS  0x14
-#define NMK_GPIO_DIRC  0x18
-#define NMK_GPIO_SLPC  0x1c
-#define NMK_GPIO_AFSLA 0x20
-#define NMK_GPIO_AFSLB 0x24
-
-#define NMK_GPIO_RIMSC 0x40
-#define NMK_GPIO_FIMSC 0x44
-#define NMK_GPIO_IS    0x48
-#define NMK_GPIO_IC    0x4c
-#define NMK_GPIO_RWIMSC        0x50
-#define NMK_GPIO_FWIMSC        0x54
-#define NMK_GPIO_WKS   0x58
-
-/* Alternate functions: function C is set in hw by setting both A and B */
-#define NMK_GPIO_ALT_GPIO      0
-#define NMK_GPIO_ALT_A 1
-#define NMK_GPIO_ALT_B 2
-#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
-
-extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
-extern int nmk_gpio_get_mode(int gpio);
-
-/*
- * Platform data to register a block: only the initial gpio/irq number.
- */
-struct nmk_gpio_platform_data {
-       char *name;
-       int first_gpio;
-       int first_irq;
-       int parent_irq;
-};
+#include <plat/gpio.h>
 
 #endif /* __ASM_ARCH_GPIO_H */
index e36639f..8e313b4 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
-#include <linux/bootmem.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 
index 9ad1185..20cfbcc 100644 (file)
@@ -68,12 +68,6 @@ struct sys_timer omap_timer;
  * ---------------------------------------------------------------------------
  */
 
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED         0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
 /* 16xx specific defines */
 #define OMAP1_32K_TIMER_BASE           0xfffb9000
 #define OMAP1_32K_TIMER_CR             0x08
@@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
        .set_mode       = omap_32k_timer_set_mode,
 };
 
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-       return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
        struct clock_event_device *evt = &clockevent_32k_timer;
index a8a3d1e..2455dcc 100644 (file)
@@ -59,8 +59,10 @@ config MACH_OMAP3_BEAGLE
        select OMAP_PACKAGE_CBB
 
 config MACH_DEVKIT8000
-        bool "DEVKIT8000 board"
-        depends on ARCH_OMAP3
+       bool "DEVKIT8000 board"
+       depends on ARCH_OMAP3
+       select OMAP_PACKAGE_CUS
+       select OMAP_MUX
 
 config MACH_OMAP_LDP
        bool "OMAP3 LDP board"
index a0a2a11..504d2bd 100644 (file)
@@ -96,6 +96,7 @@ static struct omap_board_mux board_mux[] __initdata = {
 static void __init omap_sdp_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+       omap_serial_init();
        zoom_peripherals_init();
        board_smc91x_init();
        enable_board_wakeup_source();
index 6ae8805..c1c4389 100644 (file)
@@ -294,9 +294,9 @@ static struct omap_board_mux board_mux[] __initdata = {
 
 static void __init am3517_evm_init(void)
 {
-       am3517_evm_i2c_init();
-
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+       am3517_evm_i2c_init();
        platform_add_devices(am3517_evm_devices,
                                ARRAY_SIZE(am3517_evm_devices));
 
index 5bfc13b..47e3af2 100644 (file)
@@ -50,7 +50,6 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
-#include <linux/usb/otg.h>
 #include <linux/dm9000.h>
 #include <linux/interrupt.h>
 
@@ -269,20 +268,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
        devkit8000_vmmc1_supply.dev = mmc[0].dev;
        devkit8000_vsim_supply.dev = mmc[0].dev;
 
-       /* REVISIT: need ehci-omap hooks for external VBUS
-        * power switch and overcurrent detect
-        */
-
-       gpio_request(gpio + 1, "EHCI_nOC");
-       gpio_direction_input(gpio + 1);
-
-       /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
-       gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
-       gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
-
-       /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
-       gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
        return 0;
 }
 
@@ -303,7 +288,7 @@ static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = {
        .dev            = &devkit8000_lcd_device.dev,
        },
        {
-       .supply         = "vdss_dsi",
+       .supply         = "vdds_dsi",
        .dev            = &devkit8000_dss_device.dev,
        }
 };
@@ -639,17 +624,21 @@ static struct omap_musb_board_data musb_board_data = {
 static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
-       .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
 
        .phy_reset  = true,
        .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = 147,
+       .reset_gpio_port[1]  = -EINVAL,
        .reset_gpio_port[2]  = -EINVAL
 };
 
 static void __init devkit8000_init(void)
 {
+       omap_serial_init();
+
+       omap_dm9000_init();
+
        devkit8000_i2c_init();
        platform_add_devices(devkit8000_devices,
                        ARRAY_SIZE(devkit8000_devices));
@@ -659,25 +648,15 @@ static void __init devkit8000_init(void)
        spi_register_board_info(devkit8000_spi_board_info,
        ARRAY_SIZE(devkit8000_spi_board_info));
 
-       omap_serial_init();
-
-       omap_dm9000_init();
-
        devkit8000_ads7846_init();
 
-       omap_mux_init_gpio(170, OMAP_PIN_INPUT);
-
-       gpio_request(170, "DVI_nPD");
-       /* REVISIT leave DVI powered down until it's needed ... */
-       gpio_direction_output(170, true);
-
        usb_musb_init(&musb_board_data);
        usb_ehci_init(&ehci_pdata);
        devkit8000_flash_init();
 
        /* Ensure SDRC pins are mux'd for self-refresh */
-       omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
-       omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
+       omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+       omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 }
 
 static void __init devkit8000_map_io(void)
index 3c7789d..d55c57b 100644 (file)
@@ -458,13 +458,13 @@ static struct omap_musb_board_data musb_board_data = {
 };
 
 static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
-       .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
-       .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
        .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
 
        .phy_reset = true,
-       .reset_gpio_port[0] = -EINVAL,
-       .reset_gpio_port[1] = IGEP2_GPIO_USBH_NRESET,
+       .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
+       .reset_gpio_port[1] = -EINVAL,
        .reset_gpio_port[2] = -EINVAL,
 };
 
index da9bcb8..3ccc34e 100644 (file)
@@ -216,7 +216,7 @@ static void __init n8x0_onenand_init(void) {}
  */
 #define N8X0_SLOT_SWITCH_GPIO  96
 #define N810_EMMC_VSD_GPIO     23
-#define NN810_EMMC_VIO_GPIO    9
+#define N810_EMMC_VIO_GPIO     9
 
 static int n8x0_mmc_switch_slot(struct device *dev, int slot)
 {
@@ -304,10 +304,10 @@ static void n810_set_power_emmc(struct device *dev,
        if (power_on) {
                gpio_set_value(N810_EMMC_VSD_GPIO, 1);
                msleep(1);
-               gpio_set_value(NN810_EMMC_VIO_GPIO, 1);
+               gpio_set_value(N810_EMMC_VIO_GPIO, 1);
                msleep(1);
        } else {
-               gpio_set_value(NN810_EMMC_VIO_GPIO, 0);
+               gpio_set_value(N810_EMMC_VIO_GPIO, 0);
                msleep(50);
                gpio_set_value(N810_EMMC_VSD_GPIO, 0);
                msleep(50);
@@ -468,7 +468,7 @@ static void n8x0_mmc_cleanup(struct device *dev)
 
        if (machine_is_nokia_n810()) {
                gpio_free(N810_EMMC_VSD_GPIO);
-               gpio_free(NN810_EMMC_VIO_GPIO);
+               gpio_free(N810_EMMC_VIO_GPIO);
        }
 }
 
@@ -529,7 +529,7 @@ void __init n8x0_mmc_init(void)
 
        err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch");
        if (err)
-               return err;
+               return;
 
        gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0);
 
@@ -537,17 +537,17 @@ void __init n8x0_mmc_init(void)
                err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf");
                if (err) {
                        gpio_free(N8X0_SLOT_SWITCH_GPIO);
-                       return err;
+                       return;
                }
                gpio_direction_output(N810_EMMC_VSD_GPIO, 0);
 
-               err = gpio_request(NN810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
+               err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
                if (err) {
                        gpio_free(N8X0_SLOT_SWITCH_GPIO);
                        gpio_free(N810_EMMC_VSD_GPIO);
-                       return err;
+                       return;
                }
-               gpio_direction_output(NN810_EMMC_VIO_GPIO, 0);
+               gpio_direction_output(N810_EMMC_VIO_GPIO, 0);
        }
 
        mmc_data[0] = &mmc1_data;
index b1b88de..2d02632 100644 (file)
@@ -253,20 +253,20 @@ void __init sdp_flash_init(struct flash_partitions sdp_partition_info[])
        }
 
        if (norcs > GPMC_CS_NUM)
-               printk(KERN_INFO "OneNAND: Unable to find configuration "
-                               " in GPMC\n ");
+               printk(KERN_INFO "NOR: Unable to find configuration "
+                               "in GPMC\n");
        else
                board_nor_init(sdp_partition_info[0], norcs);
 
        if (onenandcs > GPMC_CS_NUM)
                printk(KERN_INFO "OneNAND: Unable to find configuration "
-                               " in GPMC\n ");
+                               "in GPMC\n");
        else
                board_onenand_init(sdp_partition_info[1], onenandcs);
 
        if (nandcs > GPMC_CS_NUM)
                printk(KERN_INFO "NAND: Unable to find configuration "
-                               " in GPMC\n ");
+                               "in GPMC\n");
        else
                board_nand_init(sdp_partition_info[2], nandcs);
 }
index bb4018b..e15d2e8 100644 (file)
@@ -96,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device zoom_debugboard_serial_device = {
        .name                   = "serial8250",
-       .id                     = 3,
+       .id                     = PLAT8250_DEV_PLATFORM,
        .dev                    = {
                .platform_data  = serial_platform_data,
        },
index ca95d8d..6b39849 100644 (file)
@@ -280,7 +280,6 @@ static void enable_board_wakeup_source(void)
 void __init zoom_peripherals_init(void)
 {
        omap_i2c_init();
-       omap_serial_init();
        usb_musb_init(&musb_board_data);
        enable_board_wakeup_source();
 }
index d5153b6..9cba556 100644 (file)
@@ -895,7 +895,7 @@ static struct clk dpll4_m4x2_ck = {
        .ops            = &clkops_omap2_dflt_wait,
        .parent         = &dpll4_m4_ck,
        .enable_reg     = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
-       .enable_bit     = OMAP3430_PWRDN_CAM_SHIFT,
+       .enable_bit     = OMAP3430_PWRDN_DSS1_SHIFT,
        .flags          = INVERT_ENABLE,
        .clkdm_name     = "dpll4_clkdm",
        .recalc         = &omap3_clkoutx2_recalc,
index 28b1079..a5c0c9c 100644 (file)
@@ -2671,10 +2671,10 @@ static struct omap_clk omap44xx_clks[] = {
        CLK("omap-mcbsp.2",     "ick",                          &dummy_ck,      CK_443X),
        CLK("omap-mcbsp.3",     "ick",                          &dummy_ck,      CK_443X),
        CLK("omap-mcbsp.4",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.1",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.2",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.3",     "ick",                          &dummy_ck,      CK_443X),
-       CLK("omap-mcspi.4",     "ick",                          &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.1",    "ick",                  &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.2",    "ick",                  &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.3",    "ick",                  &dummy_ck,      CK_443X),
+       CLK("omap2_mcspi.4",    "ick",                  &dummy_ck,      CK_443X),
        CLK(NULL,       "uart1_ick",                    &dummy_ck,      CK_443X),
        CLK(NULL,       "uart2_ick",                    &dummy_ck,      CK_443X),
        CLK(NULL,       "uart3_ick",                    &dummy_ck,      CK_443X),
index b87ad66..6e568ec 100644 (file)
@@ -240,7 +240,7 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
                        bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
                else
                        bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
-       } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
                if (enable)
                        bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
                else
@@ -812,7 +812,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
                cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
                            clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
 
-       } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 
                u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
                         __ffs(clkdm->clktrctrl_mask));
@@ -856,7 +856,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
                cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
                              clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
 
-       } else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
+       } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
 
                u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
                         __ffs(clkdm->clktrctrl_mask));
index 23e4d77..12154d1 100644 (file)
 #include <linux/clk.h>
 
 #include <mach/hardware.h>
+#include <mach/irqs.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
+#include <asm/pmu.h>
 
 #include <plat/control.h>
 #include <plat/tc.h>
@@ -453,6 +455,37 @@ static void omap_init_mcspi(void)
 static inline void omap_init_mcspi(void) {}
 #endif
 
+static struct resource omap2_pmu_resource = {
+       .start  = 3,
+       .end    = 3,
+       .flags  = IORESOURCE_IRQ,
+};
+
+static struct resource omap3_pmu_resource = {
+       .start  = INT_34XX_BENCH_MPU_EMUL,
+       .end    = INT_34XX_BENCH_MPU_EMUL,
+       .flags  = IORESOURCE_IRQ,
+};
+
+static struct platform_device omap_pmu_device = {
+       .name           = "arm-pmu",
+       .id             = ARM_PMU_DEVICE_CPU,
+       .num_resources  = 1,
+};
+
+static void omap_init_pmu(void)
+{
+       if (cpu_is_omap24xx())
+               omap_pmu_device.resource = &omap2_pmu_resource;
+       else if (cpu_is_omap34xx())
+               omap_pmu_device.resource = &omap3_pmu_resource;
+       else
+               return;
+
+       platform_device_register(&omap_pmu_device);
+}
+
+
 #ifdef CONFIG_OMAP_SHA1_MD5
 static struct resource sha1_md5_resources[] = {
        {
@@ -726,7 +759,7 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
                        if (!cpu_is_omap44xx())
                                return;
                        base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
-                       irq = OMAP44XX_IRQ_MMC4;
+                       irq = OMAP44XX_IRQ_MMC5;
                        break;
                default:
                        continue;
@@ -797,6 +830,7 @@ static int __init omap2_init_devices(void)
        omap_init_camera();
        omap_init_mbox();
        omap_init_mcspi();
+       omap_init_pmu();
        omap_hdq_init();
        omap_init_sti();
        omap_init_sha1_md5();
index 64d74f0..e57fb29 100644 (file)
@@ -39,6 +39,9 @@ static int omap2_nand_gpmc_retime(void)
        struct gpmc_timings t;
        int err;
 
+       if (!gpmc_nand_data->gpmc_t)
+               return 0;
+
        memset(&t, 0, sizeof(t));
        t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk);
        t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
index ff25c7e..50fd749 100644 (file)
@@ -52,7 +52,7 @@ omap_irq_base:        .word   0
 
                mrc     p15, 0, \tmp, c0, c0, 0 @ get processor revision
                and     \tmp, \tmp, #0x000f0000 @ only check architecture
-               cmp     \tmp, #0x00060000       @ is v6?
+               cmp     \tmp, #0x00070000       @ is v6?
                beq     2400f                   @ found v6 so it's omap24xx
                mrc     p15, 0, \tmp, c0, c0, 0 @ get processor revision
                and     \tmp, \tmp, #0x000000f0 @ check cortex 8 or 9
index aa3f65c..ef0e7a0 100644 (file)
@@ -33,7 +33,7 @@
 ENTRY(omap_secondary_startup)
 hold:  ldr     r12,=0x103
        dsb
-       smc                             @ read from AuxCoreBoot0
+       smc     #0                      @ read from AuxCoreBoot0
        mov     r0, r0, lsr #9
        mrc     p15, 0, r4, c0, c0, 5
        and     r4, r4, #0x0f
@@ -52,7 +52,7 @@ ENTRY(omap_modify_auxcoreboot0)
        stmfd   sp!, {r1-r12, lr}
        ldr     r12, =0x104
        dsb
-       smc
+       smc     #0
        ldmfd   sp!, {r1-r12, pc}
 END(omap_modify_auxcoreboot0)
 
@@ -60,6 +60,6 @@ ENTRY(omap_auxcoreboot_addr)
        stmfd   sp!, {r2-r12, lr}
        ldr     r12, =0x105
        dsb
-       smc
+       smc     #0
        ldmfd   sp!, {r2-r12, pc}
 END(omap_auxcoreboot_addr)
index 89bb2b1..f61c777 100644 (file)
@@ -27,6 +27,6 @@ ENTRY(omap_smc1)
        mov     r12, r0
        mov     r0, r1
        dsb
-       smc
+       smc     #0
        ldmfd   sp!, {r2-r12, pc}
 END(omap_smc1)
index c664947..2c12e8c 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/bootmem.h>
 
 #include <plat/common.h>
 #include <plat/cpu.h>
@@ -1511,6 +1510,9 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
                c = oh->slaves[oh->_mpu_port_index]->_clk;
        }
 
+       if (!c->clkdm)
+               return NULL;
+
        return c->clkdm->pwrdm.ptr;
 
 }
index 9a0fb38..ebfce7d 100644 (file)
@@ -222,7 +222,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
 {
        struct powerdomain **p = NULL;
 
-       if (cpu_is_omap24xx() | cpu_is_omap34xx()) {
+       if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
                pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL;
                pwrstst_reg_offs = OMAP2_PM_PWSTST;
        } else if (cpu_is_omap44xx()) {
index 9537f6f..07a60f1 100644 (file)
@@ -123,7 +123,7 @@ struct omap3_prcm_regs prcm_context;
 u32 omap_prcm_get_reset_sources(void)
 {
        /* XXX This presumably needs modification for 34XX */
-       if (cpu_is_omap24xx() | cpu_is_omap34xx())
+       if (cpu_is_omap24xx() || cpu_is_omap34xx())
                return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
        if (cpu_is_omap44xx())
                return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
@@ -157,7 +157,7 @@ void omap_prcm_arch_reset(char mode, const char *cmd)
        else
                WARN_ON(1);
 
-       if (cpu_is_omap24xx() | cpu_is_omap34xx())
+       if (cpu_is_omap24xx() || cpu_is_omap34xx())
                prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
                                                 OMAP2_RM_RSTCTRL);
        if (cpu_is_omap44xx())
index da77930..3771254 100644 (file)
@@ -115,7 +115,6 @@ static struct plat_serial8250_port serial_platform_data2[] = {
        }
 };
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 static struct plat_serial8250_port serial_platform_data3[] = {
        {
                .irq            = 70,
@@ -128,23 +127,12 @@ static struct plat_serial8250_port serial_platform_data3[] = {
        }
 };
 
-static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
-{
-       serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
-}
-#else
-static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
-{
-}
-#endif
-
 void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
 {
        serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
        serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
        serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
-       if (cpu_is_omap3630() || cpu_is_omap44xx())
-               omap2_set_globals_uart4(omap2_globals);
+       serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
 }
 
 static inline unsigned int __serial_read_reg(struct uart_port *up,
@@ -550,7 +538,7 @@ static ssize_t sleep_timeout_store(struct device *dev,
        unsigned int value;
 
        if (sscanf(buf, "%u", &value) != 1) {
-               printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
+               dev_err(dev, "sleep_timeout_store: Invalid value\n");
                return -EINVAL;
        }
 
@@ -664,27 +652,33 @@ void __init omap_serial_early_init(void)
                struct device *dev = &pdev->dev;
                struct plat_serial8250_port *p = dev->platform_data;
 
+               /* Don't map zero-based physical address */
+               if (p->mapbase == 0) {
+                       dev_warn(dev, "no physical address for uart#%d,"
+                                " so skipping early_init...\n", i);
+                       continue;
+               }
                /*
                 * Module 4KB + L4 interconnect 4KB
                 * Static mapping, never released
                 */
                p->membase = ioremap(p->mapbase, SZ_8K);
                if (!p->membase) {
-                       printk(KERN_ERR "ioremap failed for uart%i\n", i + 1);
+                       dev_err(dev, "ioremap failed for uart%i\n", i + 1);
                        continue;
                }
 
                sprintf(name, "uart%d_ick", i + 1);
                uart->ick = clk_get(NULL, name);
                if (IS_ERR(uart->ick)) {
-                       printk(KERN_ERR "Could not get uart%d_ick\n", i + 1);
+                       dev_err(dev, "Could not get uart%d_ick\n", i + 1);
                        uart->ick = NULL;
                }
 
                sprintf(name, "uart%d_fck", i+1);
                uart->fck = clk_get(NULL, name);
                if (IS_ERR(uart->fck)) {
-                       printk(KERN_ERR "Could not get uart%d_fck\n", i + 1);
+                       dev_err(dev, "Could not get uart%d_fck\n", i + 1);
                        uart->fck = NULL;
                }
 
@@ -727,6 +721,13 @@ void __init omap_serial_init_port(int port)
        pdev = &uart->pdev;
        dev = &pdev->dev;
 
+       /* Don't proceed if there's no clocks available */
+       if (unlikely(!uart->ick || !uart->fck)) {
+               WARN(1, "%s: can't init uart%d, no clocks available\n",
+                    kobject_name(&dev->kobj), port);
+               return;
+       }
+
        omap_uart_enable_clocks(uart);
 
        omap_uart_reset(uart);
index 421b82f..685f34a 100644 (file)
@@ -439,6 +439,7 @@ static void __init dns323_init(void)
         */
        if (dns323_dev_id() == MV88F5181_DEV_ID) {
                dns323_leds[0].active_low = 1;
+               gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
                gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
        }
 
index 5b6ee46..3b51741 100644 (file)
@@ -19,7 +19,6 @@ config MACH_MAINSTONE
 config MACH_ZYLONITE
        bool
        select PXA3xx
-       select PXA_SSP
        select HAVE_PWM
        select PXA_HAVE_BOARD_IRQS
 
@@ -39,7 +38,6 @@ config MACH_LITTLETON
        select PXA3xx
        select CPU_PXA300
        select CPU_PXA310
-       select PXA_SSP
 
 config MACH_TAVOREVB
        bool "PXA930 Evaluation Board (aka TavorEVB)"
@@ -98,7 +96,6 @@ config MACH_ARMCORE
        select PXA27x
        select IWMMXT
        select PXA25x
-       select PXA_SSP
 
 config MACH_EM_X270
        bool "CompuLab EM-x270 platform"
@@ -161,7 +158,6 @@ config MACH_XCEP
        select MTD_CFI
        select MTD_CHAR
        select SMC91X
-       select PXA_SSP
        help
          PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
          Tuned for usage in Libera instruments for particle accelerators.
@@ -180,7 +176,6 @@ config MACH_TRIZEPS4WL
        depends on TRIZEPS_PXA
        select TRIZEPS_PCMCIA
        select PXA27x
-       select PXA_SSP
 
 choice
        prompt "Select base board for Trizeps module"
@@ -217,7 +212,6 @@ config MACH_PCM027
        bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
        select PXA27x
        select IWMMXT
-       select PXA_SSP
        select PXA_HAVE_BOARD_IRQS
 
 config MACH_PCM990_BASEBOARD
@@ -255,13 +249,19 @@ config MACH_COLIBRI320
        select PXA3xx
        select CPU_PXA320
 
+config MACH_VPAC270
+       bool "Voipac PXA270"
+       select PXA27x
+       select HAVE_PATA_PLATFORM
+       help
+         PXA270 based Single Board Computer.
+
 comment "End-user Products (sorted by vendor name)"
 
 config MACH_H4700
        bool "HP iPAQ hx4700"
        select PXA27x
        select IWMMXT
-       select PXA_SSP
        select HAVE_PWM
        select PXA_HAVE_BOARD_IRQS
 
@@ -277,7 +277,6 @@ config MACH_MAGICIAN
        bool "Enable HTC Magician Support"
        select PXA27x
        select IWMMXT
-       select PXA_SSP
        select HAVE_PWM
        select PXA_HAVE_BOARD_IRQS
 
@@ -431,13 +430,11 @@ config MACH_RAUMFELD_CONNECTOR
        bool "Raumfeld Connector"
        select PXA3xx
        select CPU_PXA300
-       select PXA_SSP
 
 config MACH_RAUMFELD_SPEAKER
        bool "Raumfeld Speaker"
        select PXA3xx
        select CPU_PXA300
-       select PXA_SSP
 
 config PXA_SHARPSL
        bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
@@ -461,21 +458,11 @@ config SHARPSL_PM_MAX1111
        select HWMON
        select SENSORS_MAX1111
 
-config CORGI_SSP_DEPRECATED
-       bool
-       select PXA_SSP
-       select PXA_SSP_LEGACY
-       help
-         This option will include corgi_ssp.c and corgi_lcd.c
-         that corgi_ts.c and other legacy drivers (corgi_bl.c
-         and sharpsl_pm.c) may depend on.
-
 config MACH_POODLE
        bool "Enable Sharp SL-5600 (Poodle) Support"
        depends on PXA_SHARPSL
        select PXA25x
        select SHARP_LOCOMO
-       select PXA_SSP
        select PXA_HAVE_BOARD_IRQS
 
 config MACH_CORGI
@@ -581,6 +568,12 @@ config MACH_E800
          Say Y here if you intend to run this kernel on a Toshiba
          e800 family PDA.
 
+config MACH_ZIPIT2
+       bool "Zipit Z2 Handheld"
+       select PXA27x
+       select HAVE_PWM
+       select PXA_HAVE_BOARD_IRQS
+
 endmenu
 
 config PXA25x
@@ -645,28 +638,16 @@ config CPU_PXA950
 
 config PXA_SHARP_C7xx
        bool
-       select PXA_SSP
        select SHARPSL_PM
        help
          Enable support for all Sharp C7xx models
 
 config PXA_SHARP_Cxx00
        bool
-       select PXA_SSP
        select SHARPSL_PM
        help
          Enable common support for Sharp Cxx00 models
 
-config PXA_SSP
-       tristate
-       help
-         Enable support for PXA2xx SSP ports
-
-config PXA_SSP_LEGACY
-       bool
-       help
-         Support of legacy SSP API
-
 config TOSA_BT
        tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
        depends on MACH_TOSA
@@ -675,6 +656,18 @@ config TOSA_BT
          This is a simple driver that is able to control
          the state of built in bluetooth chip on tosa.
 
+config TOSA_USE_EXT_KEYCODES
+       bool "Tosa keyboard: use extended keycodes"
+       depends on MACH_TOSA
+       default n
+       help
+         Say Y here to enable the tosa keyboard driver to generate extended
+         (>= 127) keycodes. Be aware, that they can't be correctly interpreted
+         by either console keyboard driver or by Kdrive keybd driver.
+
+         Say Y only if you know, what you are doing!
+
+
 config PXA_HAVE_BOARD_IRQS
        bool
 
index 86bc87b..b8f1f4b 100644 (file)
@@ -14,7 +14,6 @@ obj-$(CONFIG_PXA3xx)          += cpufreq-pxa3xx.o
 endif
 
 # Generic drivers that other drivers may depend upon
-obj-$(CONFIG_PXA_SSP)          += ssp.o
 
 # SoC-specific code
 obj-$(CONFIG_PXA25x)           += mfp-pxa2xx.o pxa2xx.o pxa25x.o
@@ -62,6 +61,7 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD)   += pcm990-baseboard.o
 obj-$(CONFIG_MACH_COLIBRI)     += colibri-pxa270.o
 obj-$(CONFIG_MACH_COLIBRI300)  += colibri-pxa3xx.o colibri-pxa300.o
 obj-$(CONFIG_MACH_COLIBRI320)  += colibri-pxa3xx.o colibri-pxa320.o
+obj-$(CONFIG_MACH_VPAC270)     += vpac270.o
 
 # End-user Products
 obj-$(CONFIG_MACH_H4700)       += hx4700.o
@@ -80,7 +80,6 @@ obj-$(CONFIG_MACH_PALMLD)     += palmld.o
 obj-$(CONFIG_PALM_TREO)                += palmtreo.o
 obj-$(CONFIG_PXA_SHARP_C7xx)   += corgi.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)  += spitz.o sharpsl_pm.o spitz_pm.o
-obj-$(CONFIG_CORGI_SSP_DEPRECATED)     += corgi_ssp.o corgi_lcd.o
 obj-$(CONFIG_MACH_POODLE)      += poodle.o
 obj-$(CONFIG_MACH_TOSA)                += tosa.o
 obj-$(CONFIG_MACH_ICONTROL)     += icontrol.o mxm8x10.o
@@ -94,6 +93,7 @@ obj-$(CONFIG_MACH_E800)               += e800.o
 obj-$(CONFIG_MACH_RAUMFELD_RC)         += raumfeld.o
 obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR)  += raumfeld.o
 obj-$(CONFIG_MACH_RAUMFELD_SPEAKER)    += raumfeld.o
+obj-$(CONFIG_MACH_ZIPIT2)      += z2.o
 
 # Support for blinky lights
 led-y := leds.o
index d37cfa1..fdda6be 100644 (file)
@@ -30,6 +30,9 @@
 #include <linux/i2c/pca953x.h>
 
 #include <linux/mfd/da903x.h>
+#include <linux/regulator/machine.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
@@ -430,7 +433,7 @@ static inline void cm_x300_init_nand(void) {}
 
 #if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
 static struct pxamci_platform_data cm_x300_mci_platform_data = {
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
        .gpio_card_detect       = GPIO82_MMC_IRQ,
        .gpio_card_ro           = GPIO85_MMC_WP,
@@ -451,7 +454,7 @@ static void cm_x300_mci2_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data cm_x300_mci2_platform_data = {
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
        .init                   = cm_x300_mci2_init,
        .exit                   = cm_x300_mci2_exit,
@@ -584,12 +587,87 @@ static void __init cm_x300_init_rtc(void)
 static inline void cm_x300_init_rtc(void) {}
 #endif
 
+/* Battery */
+struct power_supply_info cm_x300_psy_info = {
+       .name = "battery",
+       .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+       .voltage_max_design = 4200000,
+       .voltage_min_design = 3000000,
+       .use_for_apm = 1,
+};
+
+static void cm_x300_battery_low(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+       apm_queue_event(APM_LOW_BATTERY);
+#endif
+}
+
+static void cm_x300_battery_critical(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+       apm_queue_event(APM_CRITICAL_SUSPEND);
+#endif
+}
+
+struct da9030_battery_info cm_x300_battery_info = {
+       .battery_info = &cm_x300_psy_info,
+
+       .charge_milliamp = 1000,
+       .charge_millivolt = 4200,
+
+       .vbat_low = 3600,
+       .vbat_crit = 3400,
+       .vbat_charge_start = 4100,
+       .vbat_charge_stop = 4200,
+       .vbat_charge_restart = 4000,
+
+       .vcharge_min = 3200,
+       .vcharge_max = 5500,
+
+       .tbat_low = 197,
+       .tbat_high = 78,
+       .tbat_restart = 100,
+
+       .batmon_interval = 0,
+
+       .battery_low = cm_x300_battery_low,
+       .battery_critical = cm_x300_battery_critical,
+};
+
+static struct regulator_consumer_supply buck2_consumers[] = {
+       {
+               .dev = NULL,
+               .supply = "vcc_core",
+       },
+};
+
+static struct regulator_init_data buck2_data = {
+       .constraints = {
+               .min_uV = 1375000,
+               .max_uV = 1375000,
+               .state_mem = {
+                       .enabled = 0,
+               },
+               .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+               .apply_uV = 1,
+       },
+       .num_consumer_supplies = ARRAY_SIZE(buck2_consumers),
+       .consumer_supplies = buck2_consumers,
+};
+
 /* DA9030 */
 struct da903x_subdev_info cm_x300_da9030_subdevs[] = {
        {
-               .name = "da903x-backlight",
-               .id = DA9030_ID_WLED,
-       }
+               .name = "da903x-battery",
+               .id = DA9030_ID_BAT,
+               .platform_data = &cm_x300_battery_info,
+       },
+       {
+               .name = "da903x-regulator",
+               .id = DA9030_ID_BUCK2,
+               .platform_data = &buck2_data,
+       },
 };
 
 static struct da903x_platform_data cm_x300_da9030_info = {
@@ -599,7 +677,7 @@ static struct da903x_platform_data cm_x300_da9030_info = {
 
 static struct i2c_board_info cm_x300_pmic_info = {
        I2C_BOARD_INFO("da9030", 0x49),
-       .irq = IRQ_GPIO(0),
+       .irq = IRQ_WAKEUP0,
        .platform_data = &cm_x300_da9030_info,
 };
 
@@ -689,13 +767,13 @@ static void __init cm_x300_init(void)
 static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
                                 char **cmdline, struct meminfo *mi)
 {
-       mi->nr_banks = 2;
-       mi->bank[0].start = 0xa0000000;
-       mi->bank[0].node = 0;
-       mi->bank[0].size = (64*1024*1024);
-       mi->bank[1].start = 0xc0000000;
-       mi->bank[1].node = 0;
-       mi->bank[1].size = (64*1024*1024);
+       /* Make sure that mi->bank[0].start = PHYS_ADDR */
+       for (; tags->hdr.size; tags = tag_next(tags))
+               if (tags->hdr.tag == ATAG_MEM &&
+                       tags->u.mem.start == 0x80000000) {
+                       tags->u.mem.start = 0xa0000000;
+                       break;
+               }
 }
 
 MACHINE_START(CM_X300, "CM-X300 module")
index e6c0a22..199afa2 100644 (file)
@@ -96,7 +96,7 @@ static void colibri_pxa3xx_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = {
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
        .init                   = colibri_pxa3xx_mci_init,
        .exit                   = colibri_pxa3xx_mci_exit,
index da3156d..3d1dcb9 100644 (file)
@@ -106,18 +106,18 @@ static unsigned long corgi_pin_config[] __initdata = {
        GPIO8_MMC_CS0,
 
        /* GPIO Matrix Keypad */
-       GPIO66_GPIO,    /* column 0 */
-       GPIO67_GPIO,    /* column 1 */
-       GPIO68_GPIO,    /* column 2 */
-       GPIO69_GPIO,    /* column 3 */
-       GPIO70_GPIO,    /* column 4 */
-       GPIO71_GPIO,    /* column 5 */
-       GPIO72_GPIO,    /* column 6 */
-       GPIO73_GPIO,    /* column 7 */
-       GPIO74_GPIO,    /* column 8 */
-       GPIO75_GPIO,    /* column 9 */
-       GPIO76_GPIO,    /* column 10 */
-       GPIO77_GPIO,    /* column 11 */
+       GPIO66_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 0 */
+       GPIO67_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 1 */
+       GPIO68_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 2 */
+       GPIO69_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 3 */
+       GPIO70_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 4 */
+       GPIO71_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 5 */
+       GPIO72_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 6 */
+       GPIO73_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 7 */
+       GPIO74_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 8 */
+       GPIO75_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 9 */
+       GPIO76_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 10 */
+       GPIO77_GPIO | MFP_LPM_DRIVE_HIGH,       /* column 11 */
        GPIO58_GPIO,    /* row 0 */
        GPIO59_GPIO,    /* row 1 */
        GPIO60_GPIO,    /* row 2 */
@@ -128,13 +128,20 @@ static unsigned long corgi_pin_config[] __initdata = {
        GPIO65_GPIO,    /* row 7 */
 
        /* GPIO */
-       GPIO9_GPIO,     /* CORGI_GPIO_nSD_DETECT */
-       GPIO7_GPIO,     /* CORGI_GPIO_nSD_WP */
-       GPIO33_GPIO,    /* CORGI_GPIO_SD_PWR */
-       GPIO22_GPIO,    /* CORGI_GPIO_IR_ON */
-       GPIO44_GPIO,    /* CORGI_GPIO_HSYNC */
-
-       GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+       GPIO9_GPIO,                             /* CORGI_GPIO_nSD_DETECT */
+       GPIO7_GPIO,                             /* CORGI_GPIO_nSD_WP */
+       GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH,      /* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */
+       GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT,      /* CORGI_GPIO_LED_ORANGE */
+       GPIO21_GPIO,                            /* CORGI_GPIO_ADC_TEMP */
+       GPIO22_GPIO,                            /* CORGI_GPIO_IR_ON */
+       GPIO33_GPIO,                            /* CORGI_GPIO_SD_PWR */
+       GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT,      /* CORGI_GPIO_CHRG_ON */
+       GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT,      /* CORGI_GPIO_CHRG_UKN */
+       GPIO44_GPIO,                            /* CORGI_GPIO_HSYNC */
+
+       GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,       /* CORGI_GPIO_KEY_INT */
+       GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,       /* CORGI_GPIO_AC_IN */
+       GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH,       /* CORGI_GPIO_WAKEUP */
 };
 
 /*
@@ -437,6 +444,7 @@ static struct platform_device corgiled_device = {
  * to give the card a chance to fully insert/eject.
  */
 static struct pxamci_platform_data corgi_mci_platform_data = {
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
        .gpio_card_detect       = -1,
        .gpio_card_ro           = CORGI_GPIO_nSD_WP,
@@ -672,6 +680,15 @@ static void __init corgi_init(void)
 
        pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config));
 
+       /* allow wakeup from various GPIOs */
+       gpio_set_wake(CORGI_GPIO_KEY_INT, 1);
+       gpio_set_wake(CORGI_GPIO_WAKEUP, 1);
+       gpio_set_wake(CORGI_GPIO_AC_IN, 1);
+       gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1);
+
+       if (!machine_is_corgi())
+               gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1);
+
        pxa_set_ffuart_info(NULL);
        pxa_set_btuart_info(NULL);
        pxa_set_stuart_info(NULL);
@@ -679,7 +696,6 @@ static void __init corgi_init(void)
        corgi_init_spi();
 
        pxa_set_udc_info(&udc_info);
-       corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
        pxa_set_mci_info(&corgi_mci_platform_data);
        pxa_set_ficp_info(&corgi_ficp_platform_data);
        pxa_set_i2c_info(NULL);
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
deleted file mode 100644 (file)
index d9b9631..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/corgi_lcd.c
- *
- * Corgi/Spitz LCD Specific Code
- *
- * Copyright (C) 2005 Richard Purdie
- *
- * Connectivity:
- *   Corgi - LCD to ATI Imageon w100 (Wallaby)
- *   Spitz - LCD to PXA Framebuffer
- *
- * 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/delay.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/sharpsl.h>
-#include <mach/spitz.h>
-#include <asm/hardware/scoop.h>
-#include <asm/mach/sharpsl_param.h>
-#include "generic.h"
-
-/* Register Addresses */
-#define RESCTL_ADRS     0x00
-#define PHACTRL_ADRS    0x01
-#define DUTYCTRL_ADRS   0x02
-#define POWERREG0_ADRS  0x03
-#define POWERREG1_ADRS  0x04
-#define GPOR3_ADRS      0x05
-#define PICTRL_ADRS     0x06
-#define POLCTRL_ADRS    0x07
-
-/* Register Bit Definitions */
-#define RESCTL_QVGA     0x01
-#define RESCTL_VGA      0x00
-
-#define POWER1_VW_ON    0x01  /* VW Supply FET ON */
-#define POWER1_GVSS_ON  0x02  /* GVSS(-8V) Power Supply ON */
-#define POWER1_VDD_ON   0x04  /* VDD(8V),SVSS(-4V) Power Supply ON */
-
-#define POWER1_VW_OFF   0x00  /* VW Supply FET OFF */
-#define POWER1_GVSS_OFF 0x00  /* GVSS(-8V) Power Supply OFF */
-#define POWER1_VDD_OFF  0x00  /* VDD(8V),SVSS(-4V) Power Supply OFF */
-
-#define POWER0_COM_DCLK 0x01  /* COM Voltage DC Bias DAC Serial Data Clock */
-#define POWER0_COM_DOUT 0x02  /* COM Voltage DC Bias DAC Serial Data Out */
-#define POWER0_DAC_ON   0x04  /* DAC Power Supply ON */
-#define POWER0_COM_ON   0x08  /* COM Power Supply ON */
-#define POWER0_VCC5_ON  0x10  /* VCC5 Power Supply ON */
-
-#define POWER0_DAC_OFF  0x00  /* DAC Power Supply OFF */
-#define POWER0_COM_OFF  0x00  /* COM Power Supply OFF */
-#define POWER0_VCC5_OFF 0x00  /* VCC5 Power Supply OFF */
-
-#define PICTRL_INIT_STATE      0x01
-#define PICTRL_INIOFF          0x02
-#define PICTRL_POWER_DOWN      0x04
-#define PICTRL_COM_SIGNAL_OFF  0x08
-#define PICTRL_DAC_SIGNAL_OFF  0x10
-
-#define POLCTRL_SYNC_POL_FALL  0x01
-#define POLCTRL_EN_POL_FALL    0x02
-#define POLCTRL_DATA_POL_FALL  0x04
-#define POLCTRL_SYNC_ACT_H     0x08
-#define POLCTRL_EN_ACT_L       0x10
-
-#define POLCTRL_SYNC_POL_RISE  0x00
-#define POLCTRL_EN_POL_RISE    0x00
-#define POLCTRL_DATA_POL_RISE  0x00
-#define POLCTRL_SYNC_ACT_L     0x00
-#define POLCTRL_EN_ACT_H       0x00
-
-#define PHACTRL_PHASE_MANUAL   0x01
-#define DEFAULT_PHAD_QVGA     (9)
-#define DEFAULT_COMADJ        (125)
-
-/*
- * This is only a psuedo I2C interface. We can't use the standard kernel
- * routines as the interface is write only. We just assume the data is acked...
- */
-static void lcdtg_ssp_i2c_send(u8 data)
-{
-       corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
-       udelay(10);
-}
-
-static void lcdtg_i2c_send_bit(u8 data)
-{
-       lcdtg_ssp_i2c_send(data);
-       lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
-       lcdtg_ssp_i2c_send(data);
-}
-
-static void lcdtg_i2c_send_start(u8 base)
-{
-       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
-       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
-       lcdtg_ssp_i2c_send(base);
-}
-
-static void lcdtg_i2c_send_stop(u8 base)
-{
-       lcdtg_ssp_i2c_send(base);
-       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
-       lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
-}
-
-static void lcdtg_i2c_send_byte(u8 base, u8 data)
-{
-       int i;
-       for (i = 0; i < 8; i++) {
-               if (data & 0x80)
-                       lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
-               else
-                       lcdtg_i2c_send_bit(base);
-               data <<= 1;
-       }
-}
-
-static void lcdtg_i2c_wait_ack(u8 base)
-{
-       lcdtg_i2c_send_bit(base);
-}
-
-static void lcdtg_set_common_voltage(u8 base_data, u8 data)
-{
-       /* Set Common Voltage to M62332FP via I2C */
-       lcdtg_i2c_send_start(base_data);
-       lcdtg_i2c_send_byte(base_data, 0x9c);
-       lcdtg_i2c_wait_ack(base_data);
-       lcdtg_i2c_send_byte(base_data, 0x00);
-       lcdtg_i2c_wait_ack(base_data);
-       lcdtg_i2c_send_byte(base_data, data);
-       lcdtg_i2c_wait_ack(base_data);
-       lcdtg_i2c_send_stop(base_data);
-}
-
-/* Set Phase Adjust */
-static void lcdtg_set_phadadj(int mode)
-{
-       int adj;
-       switch(mode) {
-               case 480:
-               case 640:
-                       /* Setting for VGA */
-                       adj = sharpsl_param.phadadj;
-                       if (adj < 0) {
-                               adj = PHACTRL_PHASE_MANUAL;
-                       } else {
-                               adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
-                       }
-                       break;
-               case 240:
-               case 320:
-               default:
-                       /* Setting for QVGA */
-                       adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
-                       break;
-       }
-
-       corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
-}
-
-static int lcd_inited;
-
-void corgi_lcdtg_hw_init(int mode)
-{
-       if (!lcd_inited) {
-               int comadj;
-
-               /* Initialize Internal Logic & Port */
-               corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
-                               | PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
-
-               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
-                               | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
-
-               /* VDD(+8V), SVSS(-4V) ON */
-               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
-               mdelay(3);
-
-               /* DAC ON */
-               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
-                               | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-               /* INIB = H, INI = L  */
-               /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
-               corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
-
-               /* Set Common Voltage */
-               comadj = sharpsl_param.comadj;
-               if (comadj < 0)
-                       comadj = DEFAULT_COMADJ;
-               lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
-
-               /* VCC5 ON, DAC ON */
-               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
-                               POWER0_COM_OFF | POWER0_VCC5_ON);
-
-               /* GVSS(-8V) ON, VDD ON */
-               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
-               mdelay(2);
-
-               /* COM SIGNAL ON (PICTL[3] = L) */
-               corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
-
-               /* COM ON, DAC ON, VCC5_ON */
-               corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
-                               | POWER0_COM_ON | POWER0_VCC5_ON);
-
-               /* VW ON, GVSS ON, VDD ON */
-               corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
-
-               /* Signals output enable */
-               corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
-
-               /* Set Phase Adjust */
-               lcdtg_set_phadadj(mode);
-
-               /* Initialize for Input Signals from ATI */
-               corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
-                               | POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
-               udelay(1000);
-
-               lcd_inited=1;
-       } else {
-               lcdtg_set_phadadj(mode);
-       }
-
-       switch(mode) {
-               case 480:
-               case 640:
-                       /* Set Lcd Resolution (VGA) */
-                       corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
-                       break;
-               case 240:
-               case 320:
-               default:
-                       /* Set Lcd Resolution (QVGA) */
-                       corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
-                       break;
-       }
-}
-
-void corgi_lcdtg_suspend(void)
-{
-       /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
-       mdelay(34);
-
-       /* (1)VW OFF */
-       corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
-
-       /* (2)COM OFF */
-       corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
-       corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
-
-       /* (3)Set Common Voltage Bias 0V */
-       lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
-
-       /* (4)GVSS OFF */
-       corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
-
-       /* (5)VCC5 OFF */
-       corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-       /* (6)Set PDWN, INIOFF, DACOFF */
-       corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
-                       PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
-
-       /* (7)DAC OFF */
-       corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
-
-       /* (8)VDD OFF */
-       corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
-
-       lcd_inited = 0;
-}
-
index d4a0733..3f1dc74 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/apm-emulation.h>
@@ -25,7 +26,8 @@
 #include <mach/sharpsl.h>
 #include <mach/corgi.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+
+#include "generic.h"
 #include "sharpsl.h"
 
 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
 #define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
 #define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
 
+static struct gpio charger_gpios[] = {
+       { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
+       { CORGI_GPIO_CHRG_ON,     GPIOF_OUT_INIT_LOW, "Charger On" },
+       { CORGI_GPIO_CHRG_UKN,    GPIOF_OUT_INIT_LOW, "Charger Unknown" },
+       { CORGI_GPIO_KEY_INT,     GPIOF_IN, "Key Interrupt" },
+};
+
 static void corgi_charger_init(void)
 {
-       pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
-       pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
-       pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
-       pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
+       gpio_request_array(ARRAY_AND_SIZE(charger_gpios));
 }
 
 static void corgi_measure_temp(int on)
 {
-       if (on)
-               GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
-       else
-               GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+       gpio_set_value(CORGI_GPIO_ADC_TEMP_ON, on);
 }
 
 static void corgi_charge(int on)
 {
        if (on) {
                if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
-                       GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
-                       GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+                       gpio_set_value(CORGI_GPIO_CHRG_ON, 0);
+                       gpio_set_value(CORGI_GPIO_CHRG_UKN, 1);
                } else {
-                       GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
-                       GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+                       gpio_set_value(CORGI_GPIO_CHRG_ON, 1);
+                       gpio_set_value(CORGI_GPIO_CHRG_UKN, 0);
                }
        } else {
-               GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
-               GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+               gpio_set_value(CORGI_GPIO_CHRG_ON, 0);
+               gpio_set_value(CORGI_GPIO_CHRG_UKN, 0);
        }
 }
 
 static void corgi_discharge(int on)
 {
-       if (on)
-               GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
-       else
-               GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
+       gpio_set_value(CORGI_GPIO_DISCHARGE_ON, on);
 }
 
 static void corgi_presuspend(void)
 {
-       int i;
-       unsigned long wakeup_mask;
-
-       /* charging , so CHARGE_ON bit is HIGH during OFF. */
-       if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON))
-               PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
-       else
-               PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
-
-       if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE))
-               PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
-       else
-               PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
-
-       if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
-               PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
-       else
-               PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
-
-       /* Resume on keyboard power key */
-       PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
-
-       wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL);
-
-       if (!machine_is_corgi())
-               wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
-
-       PWER = wakeup_mask | PWER_RTC;
-       PRER = wakeup_mask;
-       PFER = wakeup_mask;
-
-       for (i = 0; i <=15; i++) {
-               if (PRER & PFER & GPIO_bit(i)) {
-                       if (GPLR0 & GPIO_bit(i) )
-                               PRER &= ~GPIO_bit(i);
-                       else
-                               PFER &= ~GPIO_bit(i);
-               }
-       }
 }
 
 static void corgi_postsuspend(void)
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
deleted file mode 100644 (file)
index 9347254..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- *  SSP control code for Sharp Corgi devices
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#include <mach/ssp.h>
-#include <mach/pxa2xx-gpio.h>
-#include <mach/regs-ssp.h>
-#include "sharpsl.h"
-
-static DEFINE_SPINLOCK(corgi_ssp_lock);
-static struct ssp_dev corgi_ssp_dev;
-static struct ssp_state corgi_ssp_state;
-static struct corgissp_machinfo *ssp_machinfo;
-
-/*
- * There are three devices connected to the SSP interface:
- *   1. A touchscreen controller (TI ADS7846 compatible)
- *   2. An LCD controller (with some Backlight functionality)
- *   3. A battery monitoring IC (Maxim MAX1111)
- *
- * Each device uses a different speed/mode of communication.
- *
- * The touchscreen is very sensitive and the most frequently used
- * so the port is left configured for this.
- *
- * Devices are selected using Chip Selects on GPIOs.
- */
-
-/*
- *  ADS7846 Routines
- */
-unsigned long corgi_ssp_ads7846_putget(ulong data)
-{
-       unsigned long flag;
-       u32 ret = 0;
-
-       spin_lock_irqsave(&corgi_ssp_lock, flag);
-       if (ssp_machinfo->cs_ads7846 >= 0)
-               GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-
-       ssp_write_word(&corgi_ssp_dev,data);
-       ssp_read_word(&corgi_ssp_dev, &ret);
-
-       if (ssp_machinfo->cs_ads7846 >= 0)
-               GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-       spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-       return ret;
-}
-
-/*
- * NOTE: These functions should always be called in interrupt context
- * and use the _lock and _unlock functions. They are very time sensitive.
- */
-void corgi_ssp_ads7846_lock(void)
-{
-       spin_lock(&corgi_ssp_lock);
-       if (ssp_machinfo->cs_ads7846 >= 0)
-               GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-}
-
-void corgi_ssp_ads7846_unlock(void)
-{
-       if (ssp_machinfo->cs_ads7846 >= 0)
-               GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
-       spin_unlock(&corgi_ssp_lock);
-}
-
-void corgi_ssp_ads7846_put(ulong data)
-{
-       ssp_write_word(&corgi_ssp_dev,data);
-}
-
-unsigned long corgi_ssp_ads7846_get(void)
-{
-       u32 ret = 0;
-       ssp_read_word(&corgi_ssp_dev, &ret);
-       return ret;
-}
-
-EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
-EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
-EXPORT_SYMBOL(corgi_ssp_ads7846_put);
-EXPORT_SYMBOL(corgi_ssp_ads7846_get);
-
-
-/*
- *  LCD/Backlight Routines
- */
-unsigned long corgi_ssp_dac_put(ulong data)
-{
-       unsigned long flag, sscr1 = SSCR1_SPH;
-       u32 tmp;
-
-       spin_lock_irqsave(&corgi_ssp_lock, flag);
-
-       if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
-               sscr1 = 0;
-
-       ssp_disable(&corgi_ssp_dev);
-       ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
-       ssp_enable(&corgi_ssp_dev);
-
-       if (ssp_machinfo->cs_lcdcon >= 0)
-               GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
-       ssp_write_word(&corgi_ssp_dev,data);
-       /* Read null data back from device to prevent SSP overflow */
-       ssp_read_word(&corgi_ssp_dev, &tmp);
-       if (ssp_machinfo->cs_lcdcon >= 0)
-               GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
-
-       ssp_disable(&corgi_ssp_dev);
-       ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-       ssp_enable(&corgi_ssp_dev);
-
-       spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-       return 0;
-}
-
-void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
-{
-       corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
-}
-
-void corgi_ssp_blduty_set(int duty)
-{
-       corgi_ssp_lcdtg_send(0x02,duty);
-}
-
-EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
-EXPORT_SYMBOL(corgi_ssp_blduty_set);
-
-/*
- *  Max1111 Routines
- */
-int corgi_ssp_max1111_get(ulong data)
-{
-       unsigned long flag;
-       long voltage = 0, voltage1 = 0, voltage2 = 0;
-
-       spin_lock_irqsave(&corgi_ssp_lock, flag);
-       if (ssp_machinfo->cs_max1111 >= 0)
-               GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
-       ssp_disable(&corgi_ssp_dev);
-       ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
-       ssp_enable(&corgi_ssp_dev);
-
-       udelay(1);
-
-       /* TB1/RB1 */
-       ssp_write_word(&corgi_ssp_dev,data);
-       ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
-
-       /* TB12/RB2 */
-       ssp_write_word(&corgi_ssp_dev,0);
-       ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
-
-       /* TB13/RB3*/
-       ssp_write_word(&corgi_ssp_dev,0);
-       ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
-
-       ssp_disable(&corgi_ssp_dev);
-       ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-       ssp_enable(&corgi_ssp_dev);
-       if (ssp_machinfo->cs_max1111 >= 0)
-               GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
-       spin_unlock_irqrestore(&corgi_ssp_lock, flag);
-
-       if (voltage1 & 0xc0 || voltage2 & 0x3f)
-               voltage = -1;
-       else
-               voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
-
-       return voltage;
-}
-
-EXPORT_SYMBOL(corgi_ssp_max1111_get);
-
-/*
- *  Support Routines
- */
-
-void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
-{
-       ssp_machinfo = machinfo;
-}
-
-static int __devinit corgi_ssp_probe(struct platform_device *dev)
-{
-       int ret;
-
-       /* Chip Select - Disable All */
-       if (ssp_machinfo->cs_lcdcon >= 0)
-               pxa_gpio_mode(ssp_machinfo->cs_lcdcon  | GPIO_OUT | GPIO_DFLT_HIGH);
-       if (ssp_machinfo->cs_max1111 >= 0)
-               pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
-       if (ssp_machinfo->cs_ads7846 >= 0)
-               pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
-
-       ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
-
-       if (ret)
-               printk(KERN_ERR "Unable to register SSP handler!\n");
-       else {
-               ssp_disable(&corgi_ssp_dev);
-               ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
-               ssp_enable(&corgi_ssp_dev);
-       }
-
-       return ret;
-}
-
-static int corgi_ssp_remove(struct platform_device *dev)
-{
-       ssp_exit(&corgi_ssp_dev);
-       return 0;
-}
-
-static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
-{
-       ssp_flush(&corgi_ssp_dev);
-       ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
-
-       return 0;
-}
-
-static int corgi_ssp_resume(struct platform_device *dev)
-{
-       if (ssp_machinfo->cs_lcdcon >= 0)
-               GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
-       if (ssp_machinfo->cs_max1111 >= 0)
-               GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
-       if (ssp_machinfo->cs_ads7846 >= 0)
-               GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
-       ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
-       ssp_enable(&corgi_ssp_dev);
-
-       return 0;
-}
-
-static struct platform_driver corgissp_driver = {
-       .probe          = corgi_ssp_probe,
-       .remove         = corgi_ssp_remove,
-       .suspend        = corgi_ssp_suspend,
-       .resume         = corgi_ssp_resume,
-       .driver         = {
-               .name   = "corgi-ssp",
-       },
-};
-
-int __init corgi_ssp_init(void)
-{
-       return platform_driver_register(&corgissp_driver);
-}
-
-arch_initcall(corgi_ssp_init);
index 88575b8..91fd4fe 100644 (file)
@@ -125,18 +125,9 @@ static unsigned long csb726_pin_config[] = {
        GPIO118_I2C_SDA,
 };
 
-static struct pxamci_platform_data csb726_mci_data;
-
-static int csb726_mci_init(struct device *dev,
-               irq_handler_t detect, void *data)
-{
-       csb726_mci_data.detect_delay = msecs_to_jiffies(500);
-       return 0;
-}
-
 static struct pxamci_platform_data csb726_mci = {
+       .detect_delay_ms        = 500,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
-       .init                   = csb726_mci_init,
        /* FIXME setpower */
        .gpio_card_detect       = CSB726_GPIO_MMC_DETECT,
        .gpio_card_ro           = CSB726_GPIO_MMC_RO,
index aab04f3..0517c17 100644 (file)
@@ -626,6 +626,7 @@ static int em_x270_mci_get_ro(struct device *dev)
 }
 
 static struct pxamci_platform_data em_x270_mci_platform_data = {
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
                                  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
                                  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
@@ -643,7 +644,6 @@ static void __init em_x270_init_mmc(void)
        if (machine_is_em_x270())
                em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro;
 
-       em_x270_mci_platform_data.detect_delay  = msecs_to_jiffies(250);
        pxa_set_mci_info(&em_x270_mci_platform_data);
 }
 #else
index 3126a35..baabb3c 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <mach/reset.h>
 #include <mach/gpio.h>
-#include <mach/pxa2xx-gpio.h>
 
 #include "generic.h"
 
@@ -128,33 +127,3 @@ void __init pxa_map_io(void)
        iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
        get_clk_frequency_khz(1);
 }
-
-/*
- * Configure pins for GPIO or other functions
- */
-int pxa_gpio_mode(int gpio_mode)
-{
-       unsigned long flags;
-       int gpio = gpio_mode & GPIO_MD_MASK_NR;
-       int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
-       int gafr;
-
-       if (gpio > pxa_last_gpio)
-               return -EINVAL;
-
-       local_irq_save(flags);
-       if (gpio_mode & GPIO_DFLT_LOW)
-               GPCR(gpio) = GPIO_bit(gpio);
-       else if (gpio_mode & GPIO_DFLT_HIGH)
-               GPSR(gpio) = GPIO_bit(gpio);
-       if (gpio_mode & GPIO_MD_MASK_DIR)
-               GPDR(gpio) |= GPIO_bit(gpio);
-       else
-               GPDR(gpio) &= ~GPIO_bit(gpio);
-       gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
-       GAFR(gpio) = gafr |  (fn  << (((gpio) & 0xf)*2));
-       local_irq_restore(flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(pxa_gpio_mode);
index 811743c..5f2ba8d 100644 (file)
@@ -2,6 +2,7 @@
 #define _COLIBRI_H_
 
 #include <net/ax88796.h>
+#include <mach/mfp.h>
 
 /*
  * common settings for all modules
index 7239281..585970e 100644 (file)
  * Shared data structures
  */
 extern struct platform_device corgiscoop_device;
-extern struct platform_device corgissp_device;
 
 #endif /* __ASM_ARCH_CORGI_H  */
 
index 7515757..3d8d8cb 100644 (file)
 #define __cpu_is_pxa950(id)                             \
        ({                                              \
                unsigned int _id = (id) >> 4 & 0xfff;   \
-               id == 0x697;                            \
+               _id == 0x697;                           \
         })
 #else
 #define __cpu_is_pxa950(id)    (0)
index 658b28e..c54cef2 100644 (file)
@@ -25,6 +25,8 @@
 #define MFP_DIR(x)             (((x) >> 23) & 0x1)
 
 #define MFP_LPM_CAN_WAKEUP     (0x1 << 24)
+#define MFP_LPM_KEEP_OUTPUT    (0x1 << 25)
+
 #define WAKEUP_ON_EDGE_RISE    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
 #define WAKEUP_ON_EDGE_FALL    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL)
 #define WAKEUP_ON_EDGE_BOTH    (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH)
index 02a69dc..9eb515b 100644 (file)
@@ -9,7 +9,7 @@ struct mmc_host;
 
 struct pxamci_platform_data {
        unsigned int ocr_mask;                  /* available voltages */
-       unsigned long detect_delay;             /* delay in jiffies before detecting cards after interrupt */
+       unsigned long detect_delay_ms;          /* delay in millisecond before detecting cards after interrupt */
        int (*init)(struct device *, irq_handler_t , void *);
        int (*get_ro)(struct device *);
        void (*setpower)(struct device *, unsigned int);
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h b/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
deleted file mode 100644 (file)
index 1209c44..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-#ifndef __ASM_ARCH_PXA2XX_GPIO_H
-#define __ASM_ARCH_PXA2XX_GPIO_H
-
-#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h
-
-#include <mach/gpio.h>
-
-/* GPIO alternate function assignments */
-
-#define GPIO1_RST              1       /* reset */
-#define GPIO6_MMCCLK           6       /* MMC Clock */
-#define GPIO7_48MHz            7       /* 48 MHz clock output */
-#define GPIO8_MMCCS0           8       /* MMC Chip Select 0 */
-#define GPIO9_MMCCS1           9       /* MMC Chip Select 1 */
-#define GPIO10_RTCCLK          10      /* real time clock (1 Hz) */
-#define GPIO11_3_6MHz          11      /* 3.6 MHz oscillator out */
-#define GPIO12_32KHz           12      /* 32 kHz out */
-#define GPIO12_CIF_DD_7                12      /* Camera data pin 7 */
-#define GPIO13_MBGNT           13      /* memory controller grant */
-#define GPIO14_MBREQ           14      /* alternate bus master request */
-#define GPIO15_nCS_1           15      /* chip select 1 */
-#define GPIO16_PWM0            16      /* PWM0 output */
-#define GPIO17_PWM1            17      /* PWM1 output */
-#define GPIO17_CIF_DD_6                17      /* Camera data pin 6 */
-#define GPIO18_RDY             18      /* Ext. Bus Ready */
-#define GPIO19_DREQ1           19      /* External DMA Request */
-#define GPIO20_DREQ0           20      /* External DMA Request */
-#define GPIO23_SCLK            23      /* SSP clock */
-#define GPIO23_CIF_MCLK                23      /* Camera Master Clock */
-#define GPIO24_SFRM            24      /* SSP Frame */
-#define GPIO24_CIF_FV          24      /* Camera frame start signal */
-#define GPIO25_STXD            25      /* SSP transmit */
-#define GPIO25_CIF_LV          25      /* Camera line start signal */
-#define GPIO26_SRXD            26      /* SSP receive */
-#define GPIO26_CIF_PCLK                26      /* Camera Pixel Clock */
-#define GPIO27_SEXTCLK         27      /* SSP ext_clk */
-#define GPIO27_CIF_DD_0                27      /* Camera data pin 0 */
-#define GPIO28_BITCLK          28      /* AC97/I2S bit_clk */
-#define GPIO29_SDATA_IN                29      /* AC97 Sdata_in0 / I2S Sdata_in */
-#define GPIO30_SDATA_OUT       30      /* AC97/I2S Sdata_out */
-#define GPIO31_SYNC            31      /* AC97/I2S sync */
-#define GPIO32_SDATA_IN1       32      /* AC97 Sdata_in1 */
-#define GPIO32_SYSCLK          32      /* I2S System Clock */
-#define GPIO32_MMCCLK          32      /* MMC Clock (PXA270) */
-#define GPIO33_nCS_5           33      /* chip select 5 */
-#define GPIO34_FFRXD           34      /* FFUART receive */
-#define GPIO34_MMCCS0          34      /* MMC Chip Select 0 */
-#define GPIO35_FFCTS           35      /* FFUART Clear to send */
-#define GPIO36_FFDCD           36      /* FFUART Data carrier detect */
-#define GPIO37_FFDSR           37      /* FFUART data set ready */
-#define GPIO38_FFRI            38      /* FFUART Ring Indicator */
-#define GPIO39_MMCCS1          39      /* MMC Chip Select 1 */
-#define GPIO39_FFTXD           39      /* FFUART transmit data */
-#define GPIO40_FFDTR           40      /* FFUART data terminal Ready */
-#define GPIO41_FFRTS           41      /* FFUART request to send */
-#define GPIO42_BTRXD           42      /* BTUART receive data */
-#define GPIO42_HWRXD           42      /* HWUART receive data */
-#define GPIO42_CIF_MCLK                42      /* Camera Master Clock */
-#define GPIO43_BTTXD           43      /* BTUART transmit data */
-#define GPIO43_HWTXD           43      /* HWUART transmit data */
-#define GPIO43_CIF_FV          43      /* Camera frame start signal */
-#define GPIO44_BTCTS           44      /* BTUART clear to send */
-#define GPIO44_HWCTS           44      /* HWUART clear to send */
-#define GPIO44_CIF_LV          44      /* Camera line start signal */
-#define GPIO45_BTRTS           45      /* BTUART request to send */
-#define GPIO45_HWRTS           45      /* HWUART request to send */
-#define GPIO45_AC97_SYSCLK     45      /* AC97 System Clock */
-#define GPIO45_CIF_PCLK                45      /* Camera Pixel Clock */
-#define GPIO46_ICPRXD          46      /* ICP receive data */
-#define GPIO46_STRXD           46      /* STD_UART receive data */
-#define GPIO47_ICPTXD          47      /* ICP transmit data */
-#define GPIO47_STTXD           47      /* STD_UART transmit data */
-#define GPIO47_CIF_DD_0                47      /* Camera data pin 0 */
-#define GPIO48_nPOE            48      /* Output Enable for Card Space */
-#define GPIO48_CIF_DD_5                48      /* Camera data pin 5 */
-#define GPIO49_nPWE            49      /* Write Enable for Card Space */
-#define GPIO50_nPIOR           50      /* I/O Read for Card Space */
-#define GPIO50_CIF_DD_3                50      /* Camera data pin 3 */
-#define GPIO51_nPIOW           51      /* I/O Write for Card Space */
-#define GPIO51_CIF_DD_2                51      /* Camera data pin 2 */
-#define GPIO52_nPCE_1          52      /* Card Enable for Card Space */
-#define GPIO52_CIF_DD_4                52      /* Camera data pin 4 */
-#define GPIO53_nPCE_2          53      /* Card Enable for Card Space */
-#define GPIO53_MMCCLK          53      /* MMC Clock */
-#define GPIO53_CIF_MCLK                53      /* Camera Master Clock */
-#define GPIO54_MMCCLK          54      /* MMC Clock */
-#define GPIO54_pSKTSEL         54      /* Socket Select for Card Space */
-#define GPIO54_nPCE_2          54      /* Card Enable for Card Space (PXA27x) */
-#define GPIO54_CIF_PCLK                54      /* Camera Pixel Clock */
-#define GPIO55_nPREG           55      /* Card Address bit 26 */
-#define GPIO55_CIF_DD_1                55      /* Camera data pin 1 */
-#define GPIO56_nPWAIT          56      /* Wait signal for Card Space */
-#define GPIO57_nIOIS16         57      /* Bus Width select for I/O Card Space */
-#define GPIO58_LDD_0           58      /* LCD data pin 0 */
-#define GPIO59_LDD_1           59      /* LCD data pin 1 */
-#define GPIO60_LDD_2           60      /* LCD data pin 2 */
-#define GPIO61_LDD_3           61      /* LCD data pin 3 */
-#define GPIO62_LDD_4           62      /* LCD data pin 4 */
-#define GPIO63_LDD_5           63      /* LCD data pin 5 */
-#define GPIO64_LDD_6           64      /* LCD data pin 6 */
-#define GPIO65_LDD_7           65      /* LCD data pin 7 */
-#define GPIO66_LDD_8           66      /* LCD data pin 8 */
-#define GPIO66_MBREQ           66      /* alternate bus master req */
-#define GPIO67_LDD_9           67      /* LCD data pin 9 */
-#define GPIO67_MMCCS0          67      /* MMC Chip Select 0 */
-#define GPIO68_LDD_10          68      /* LCD data pin 10 */
-#define GPIO68_MMCCS1          68      /* MMC Chip Select 1 */
-#define GPIO69_LDD_11          69      /* LCD data pin 11 */
-#define GPIO69_MMCCLK          69      /* MMC_CLK */
-#define GPIO70_LDD_12          70      /* LCD data pin 12 */
-#define GPIO70_RTCCLK          70      /* Real Time clock (1 Hz) */
-#define GPIO71_LDD_13          71      /* LCD data pin 13 */
-#define GPIO71_3_6MHz          71      /* 3.6 MHz Oscillator clock */
-#define GPIO72_LDD_14          72      /* LCD data pin 14 */
-#define GPIO72_32kHz           72      /* 32 kHz clock */
-#define GPIO73_LDD_15          73      /* LCD data pin 15 */
-#define GPIO73_MBGNT           73      /* Memory controller grant */
-#define GPIO74_LCD_FCLK                74      /* LCD Frame clock */
-#define GPIO75_LCD_LCLK                75      /* LCD line clock */
-#define GPIO76_LCD_PCLK                76      /* LCD Pixel clock */
-#define GPIO77_LCD_ACBIAS      77      /* LCD AC Bias */
-#define GPIO78_nCS_2           78      /* chip select 2 */
-#define GPIO79_nCS_3           79      /* chip select 3 */
-#define GPIO80_nCS_4           80      /* chip select 4 */
-#define GPIO81_NSCLK           81      /* NSSP clock */
-#define GPIO81_CIF_DD_0                81      /* Camera data pin 0 */
-#define GPIO82_NSFRM           82      /* NSSP Frame */
-#define GPIO82_CIF_DD_5                82      /* Camera data pin 5 */
-#define GPIO83_NSTXD           83      /* NSSP transmit */
-#define GPIO83_CIF_DD_4                83      /* Camera data pin 4 */
-#define GPIO84_NSRXD           84      /* NSSP receive */
-#define GPIO84_CIF_FV          84      /* Camera frame start signal */
-#define GPIO85_nPCE_1          85      /* Card Enable for Card Space (PXA27x) */
-#define GPIO85_CIF_LV          85      /* Camera line start signal */
-#define GPIO90_CIF_DD_4                90      /* Camera data pin 4 */
-#define GPIO91_CIF_DD_5                91      /* Camera data pin 5 */
-#define GPIO92_MMCDAT0         92      /* MMC DAT0 (PXA27x) */
-#define GPIO93_CIF_DD_6                93      /* Camera data pin 6 */
-#define GPIO94_CIF_DD_5                94      /* Camera data pin 5 */
-#define GPIO95_CIF_DD_4                95      /* Camera data pin 4 */
-#define GPIO96_FFRXD           96      /* FFUART recieve */
-#define GPIO98_FFRTS           98      /* FFUART request to send */
-#define GPIO98_CIF_DD_0                98      /* Camera data pin 0 */
-#define GPIO99_FFTXD           99      /* FFUART transmit data */
-#define GPIO100_FFCTS          100     /* FFUART Clear to send */
-#define GPIO102_nPCE_1         102     /* PCMCIA (PXA27x) */
-#define GPIO103_CIF_DD_3       103     /* Camera data pin 3 */
-#define GPIO104_CIF_DD_2       104     /* Camera data pin 2 */
-#define GPIO105_CIF_DD_1       105     /* Camera data pin 1 */
-#define GPIO106_CIF_DD_9       106     /* Camera data pin 9 */
-#define GPIO107_CIF_DD_8       107     /* Camera data pin 8 */
-#define GPIO108_CIF_DD_7       108     /* Camera data pin 7 */
-#define GPIO109_MMCDAT1                109     /* MMC DAT1 (PXA27x) */
-#define GPIO110_MMCDAT2                110     /* MMC DAT2 (PXA27x) */
-#define GPIO110_MMCCS0         110     /* MMC Chip Select 0 (PXA27x) */
-#define GPIO111_MMCDAT3                111     /* MMC DAT3 (PXA27x) */
-#define GPIO111_MMCCS1         111     /* MMC Chip Select 1 (PXA27x) */
-#define GPIO112_MMCCMD         112     /* MMC CMD (PXA27x) */
-#define GPIO113_I2S_SYSCLK     113     /* I2S System Clock (PXA27x) */
-#define GPIO113_AC97_RESET_N   113     /* AC97 NRESET on (PXA27x) */
-#define GPIO114_CIF_DD_1       114     /* Camera data pin 1 */
-#define GPIO115_CIF_DD_3       115     /* Camera data pin 3 */
-#define GPIO116_CIF_DD_2       116     /* Camera data pin 2 */
-
-/* GPIO alternate function mode & direction */
-
-#define GPIO_IN                        0x000
-#define GPIO_OUT               0x080
-#define GPIO_ALT_FN_1_IN       0x100
-#define GPIO_ALT_FN_1_OUT      0x180
-#define GPIO_ALT_FN_2_IN       0x200
-#define GPIO_ALT_FN_2_OUT      0x280
-#define GPIO_ALT_FN_3_IN       0x300
-#define GPIO_ALT_FN_3_OUT      0x380
-#define GPIO_MD_MASK_NR                0x07f
-#define GPIO_MD_MASK_DIR       0x080
-#define GPIO_MD_MASK_FN                0x300
-#define GPIO_DFLT_LOW          0x400
-#define GPIO_DFLT_HIGH         0x800
-
-#define GPIO1_RTS_MD           ( 1 | GPIO_ALT_FN_1_IN)
-#define GPIO6_MMCCLK_MD                ( 6 | GPIO_ALT_FN_1_OUT)
-#define GPIO7_48MHz_MD         ( 7 | GPIO_ALT_FN_1_OUT)
-#define GPIO8_MMCCS0_MD                ( 8 | GPIO_ALT_FN_1_OUT)
-#define GPIO9_MMCCS1_MD                ( 9 | GPIO_ALT_FN_1_OUT)
-#define GPIO10_RTCCLK_MD       (10 | GPIO_ALT_FN_1_OUT)
-#define GPIO11_3_6MHz_MD       (11 | GPIO_ALT_FN_1_OUT)
-#define GPIO12_32KHz_MD                (12 | GPIO_ALT_FN_1_OUT)
-#define GPIO12_CIF_DD_7_MD     (12 | GPIO_ALT_FN_2_IN)
-#define GPIO13_MBGNT_MD                (13 | GPIO_ALT_FN_2_OUT)
-#define GPIO14_MBREQ_MD                (14 | GPIO_ALT_FN_1_IN)
-#define GPIO15_nCS_1_MD                (15 | GPIO_ALT_FN_2_OUT)
-#define GPIO16_PWM0_MD         (16 | GPIO_ALT_FN_2_OUT)
-#define GPIO17_PWM1_MD         (17 | GPIO_ALT_FN_2_OUT)
-#define GPIO17_CIF_DD_6_MD     (17 | GPIO_ALT_FN_2_IN)
-#define GPIO18_RDY_MD          (18 | GPIO_ALT_FN_1_IN)
-#define GPIO19_DREQ1_MD                (19 | GPIO_ALT_FN_1_IN)
-#define GPIO20_DREQ0_MD                (20 | GPIO_ALT_FN_1_IN)
-#define GPIO23_CIF_MCLK_MD     (23 | GPIO_ALT_FN_1_OUT)
-#define GPIO23_SCLK_MD         (23 | GPIO_ALT_FN_2_OUT)
-#define GPIO24_CIF_FV_MD       (24 | GPIO_ALT_FN_1_OUT)
-#define GPIO24_SFRM_MD         (24 | GPIO_ALT_FN_2_OUT)
-#define GPIO25_CIF_LV_MD       (25 | GPIO_ALT_FN_1_OUT)
-#define GPIO25_STXD_MD         (25 | GPIO_ALT_FN_2_OUT)
-#define GPIO26_SRXD_MD         (26 | GPIO_ALT_FN_1_IN)
-#define GPIO26_CIF_PCLK_MD     (26 | GPIO_ALT_FN_2_IN)
-#define GPIO27_SEXTCLK_MD      (27 | GPIO_ALT_FN_1_IN)
-#define GPIO27_CIF_DD_0_MD     (27 | GPIO_ALT_FN_3_IN)
-#define GPIO28_BITCLK_AC97_MD  (28 | GPIO_ALT_FN_1_IN)
-#define GPIO28_BITCLK_IN_I2S_MD        (28 | GPIO_ALT_FN_2_IN)
-#define GPIO28_BITCLK_OUT_I2S_MD       (28 | GPIO_ALT_FN_1_OUT)
-#define GPIO29_SDATA_IN_AC97_MD        (29 | GPIO_ALT_FN_1_IN)
-#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN)
-#define GPIO30_SDATA_OUT_AC97_MD       (30 | GPIO_ALT_FN_2_OUT)
-#define GPIO30_SDATA_OUT_I2S_MD        (30 | GPIO_ALT_FN_1_OUT)
-#define GPIO31_SYNC_I2S_MD     (31 | GPIO_ALT_FN_1_OUT)
-#define GPIO31_SYNC_AC97_MD    (31 | GPIO_ALT_FN_2_OUT)
-#define GPIO32_SDATA_IN1_AC97_MD       (32 | GPIO_ALT_FN_1_IN)
-#define GPIO32_SYSCLK_I2S_MD   (32 | GPIO_ALT_FN_1_OUT)
-#define GPIO32_MMCCLK_MD       (32 | GPIO_ALT_FN_2_OUT)
-#define GPIO33_nCS_5_MD                (33 | GPIO_ALT_FN_2_OUT)
-#define GPIO34_FFRXD_MD                (34 | GPIO_ALT_FN_1_IN)
-#define GPIO34_MMCCS0_MD       (34 | GPIO_ALT_FN_2_OUT)
-#define GPIO35_FFCTS_MD                (35 | GPIO_ALT_FN_1_IN)
-#define GPIO35_KP_MKOUT6_MD    (35 | GPIO_ALT_FN_2_OUT)
-#define GPIO36_FFDCD_MD                (36 | GPIO_ALT_FN_1_IN)
-#define GPIO37_FFDSR_MD                (37 | GPIO_ALT_FN_1_IN)
-#define GPIO38_FFRI_MD         (38 | GPIO_ALT_FN_1_IN)
-#define GPIO39_MMCCS1_MD       (39 | GPIO_ALT_FN_1_OUT)
-#define GPIO39_FFTXD_MD                (39 | GPIO_ALT_FN_2_OUT)
-#define GPIO40_FFDTR_MD                (40 | GPIO_ALT_FN_2_OUT)
-#define GPIO41_FFRTS_MD                (41 | GPIO_ALT_FN_2_OUT)
-#define GPIO41_KP_MKOUT7_MD    (41 | GPIO_ALT_FN_1_OUT)
-#define GPIO42_BTRXD_MD                (42 | GPIO_ALT_FN_1_IN)
-#define GPIO42_HWRXD_MD                (42 | GPIO_ALT_FN_3_IN)
-#define GPIO42_CIF_MCLK_MD     (42 | GPIO_ALT_FN_3_OUT)
-#define GPIO43_BTTXD_MD                (43 | GPIO_ALT_FN_2_OUT)
-#define GPIO43_HWTXD_MD                (43 | GPIO_ALT_FN_3_OUT)
-#define GPIO43_CIF_FV_MD       (43 | GPIO_ALT_FN_3_OUT)
-#define GPIO44_BTCTS_MD                (44 | GPIO_ALT_FN_1_IN)
-#define GPIO44_HWCTS_MD                (44 | GPIO_ALT_FN_3_IN)
-#define GPIO44_CIF_LV_MD       (44 | GPIO_ALT_FN_3_OUT)
-#define GPIO45_CIF_PCLK_MD     (45 | GPIO_ALT_FN_3_IN)
-#define GPIO45_BTRTS_MD                (45 | GPIO_ALT_FN_2_OUT)
-#define GPIO45_HWRTS_MD                (45 | GPIO_ALT_FN_3_OUT)
-#define GPIO45_SYSCLK_AC97_MD  (45 | GPIO_ALT_FN_1_OUT)
-#define GPIO46_ICPRXD_MD       (46 | GPIO_ALT_FN_1_IN)
-#define GPIO46_STRXD_MD                (46 | GPIO_ALT_FN_2_IN)
-#define GPIO47_CIF_DD_0_MD     (47 | GPIO_ALT_FN_1_IN)
-#define GPIO47_ICPTXD_MD       (47 | GPIO_ALT_FN_2_OUT)
-#define GPIO47_STTXD_MD                (47 | GPIO_ALT_FN_1_OUT)
-#define GPIO48_CIF_DD_5_MD     (48 | GPIO_ALT_FN_1_IN)
-#define GPIO48_nPOE_MD         (48 | GPIO_ALT_FN_2_OUT)
-#define GPIO48_HWTXD_MD                (48 | GPIO_ALT_FN_1_OUT)
-#define GPIO48_nPOE_MD         (48 | GPIO_ALT_FN_2_OUT)
-#define GPIO49_HWRXD_MD                (49 | GPIO_ALT_FN_1_IN)
-#define GPIO49_nPWE_MD         (49 | GPIO_ALT_FN_2_OUT)
-#define GPIO50_CIF_DD_3_MD     (50 | GPIO_ALT_FN_1_IN)
-#define GPIO50_nPIOR_MD                (50 | GPIO_ALT_FN_2_OUT)
-#define GPIO50_HWCTS_MD                (50 | GPIO_ALT_FN_1_IN)
-#define GPIO50_CIF_DD_3_MD     (50 | GPIO_ALT_FN_1_IN)
-#define GPIO51_CIF_DD_2_MD     (51 | GPIO_ALT_FN_1_IN)
-#define GPIO51_nPIOW_MD                (51 | GPIO_ALT_FN_2_OUT)
-#define GPIO51_HWRTS_MD                (51 | GPIO_ALT_FN_1_OUT)
-#define GPIO51_CIF_DD_2_MD     (51 | GPIO_ALT_FN_1_IN)
-#define GPIO52_nPCE_1_MD       (52 | GPIO_ALT_FN_2_OUT)
-#define GPIO52_CIF_DD_4_MD     (52 | GPIO_ALT_FN_1_IN)
-#define GPIO53_nPCE_2_MD       (53 | GPIO_ALT_FN_2_OUT)
-#define GPIO53_MMCCLK_MD       (53 | GPIO_ALT_FN_1_OUT)
-#define GPIO53_CIF_MCLK_MD     (53 | GPIO_ALT_FN_2_OUT)
-#define GPIO54_MMCCLK_MD       (54 | GPIO_ALT_FN_1_OUT)
-#define GPIO54_nPCE_2_MD       (54 | GPIO_ALT_FN_2_OUT)
-#define GPIO54_pSKTSEL_MD      (54 | GPIO_ALT_FN_2_OUT)
-#define GPIO54_CIF_PCLK_MD     (54 | GPIO_ALT_FN_3_IN)
-#define GPIO55_nPREG_MD                (55 | GPIO_ALT_FN_2_OUT)
-#define GPIO55_CIF_DD_1_MD     (55 | GPIO_ALT_FN_1_IN)
-#define GPIO56_nPWAIT_MD       (56 | GPIO_ALT_FN_1_IN)
-#define GPIO57_nIOIS16_MD      (57 | GPIO_ALT_FN_1_IN)
-#define GPIO58_LDD_0_MD                (58 | GPIO_ALT_FN_2_OUT)
-#define GPIO59_LDD_1_MD                (59 | GPIO_ALT_FN_2_OUT)
-#define GPIO60_LDD_2_MD                (60 | GPIO_ALT_FN_2_OUT)
-#define GPIO61_LDD_3_MD                (61 | GPIO_ALT_FN_2_OUT)
-#define GPIO62_LDD_4_MD                (62 | GPIO_ALT_FN_2_OUT)
-#define GPIO63_LDD_5_MD                (63 | GPIO_ALT_FN_2_OUT)
-#define GPIO64_LDD_6_MD                (64 | GPIO_ALT_FN_2_OUT)
-#define GPIO65_LDD_7_MD                (65 | GPIO_ALT_FN_2_OUT)
-#define GPIO66_LDD_8_MD                (66 | GPIO_ALT_FN_2_OUT)
-#define GPIO66_MBREQ_MD                (66 | GPIO_ALT_FN_1_IN)
-#define GPIO67_LDD_9_MD                (67 | GPIO_ALT_FN_2_OUT)
-#define GPIO67_MMCCS0_MD       (67 | GPIO_ALT_FN_1_OUT)
-#define GPIO68_LDD_10_MD       (68 | GPIO_ALT_FN_2_OUT)
-#define GPIO68_MMCCS1_MD       (68 | GPIO_ALT_FN_1_OUT)
-#define GPIO69_LDD_11_MD       (69 | GPIO_ALT_FN_2_OUT)
-#define GPIO69_MMCCLK_MD       (69 | GPIO_ALT_FN_1_OUT)
-#define GPIO70_LDD_12_MD       (70 | GPIO_ALT_FN_2_OUT)
-#define GPIO70_RTCCLK_MD       (70 | GPIO_ALT_FN_1_OUT)
-#define GPIO71_LDD_13_MD       (71 | GPIO_ALT_FN_2_OUT)
-#define GPIO71_3_6MHz_MD       (71 | GPIO_ALT_FN_1_OUT)
-#define GPIO72_LDD_14_MD       (72 | GPIO_ALT_FN_2_OUT)
-#define GPIO72_32kHz_MD                (72 | GPIO_ALT_FN_1_OUT)
-#define GPIO73_LDD_15_MD       (73 | GPIO_ALT_FN_2_OUT)
-#define GPIO73_MBGNT_MD                (73 | GPIO_ALT_FN_1_OUT)
-#define GPIO74_LCD_FCLK_MD     (74 | GPIO_ALT_FN_2_OUT)
-#define GPIO75_LCD_LCLK_MD     (75 | GPIO_ALT_FN_2_OUT)
-#define GPIO76_LCD_PCLK_MD     (76 | GPIO_ALT_FN_2_OUT)
-#define GPIO77_LCD_ACBIAS_MD   (77 | GPIO_ALT_FN_2_OUT)
-#define GPIO78_nCS_2_MD                (78 | GPIO_ALT_FN_2_OUT)
-#define GPIO78_nPCE_2_MD       (78 | GPIO_ALT_FN_1_OUT)
-#define GPIO79_nCS_3_MD                (79 | GPIO_ALT_FN_2_OUT)
-#define GPIO79_pSKTSEL_MD      (79 | GPIO_ALT_FN_1_OUT)
-#define GPIO80_nCS_4_MD                (80 | GPIO_ALT_FN_2_OUT)
-#define GPIO81_NSSP_CLK_OUT    (81 | GPIO_ALT_FN_1_OUT)
-#define GPIO81_NSSP_CLK_IN     (81 | GPIO_ALT_FN_1_IN)
-#define GPIO81_CIF_DD_0_MD     (81 | GPIO_ALT_FN_2_IN)
-#define GPIO82_NSSP_FRM_OUT    (82 | GPIO_ALT_FN_1_OUT)
-#define GPIO82_NSSP_FRM_IN     (82 | GPIO_ALT_FN_1_IN)
-#define GPIO82_CIF_DD_5_MD     (82 | GPIO_ALT_FN_3_IN)
-#define GPIO83_NSSP_TX         (83 | GPIO_ALT_FN_1_OUT)
-#define GPIO83_NSSP_RX         (83 | GPIO_ALT_FN_2_IN)
-#define GPIO83_CIF_DD_4_MD     (83 | GPIO_ALT_FN_3_IN)
-#define GPIO84_NSSP_TX         (84 | GPIO_ALT_FN_1_OUT)
-#define GPIO84_NSSP_RX         (84 | GPIO_ALT_FN_2_IN)
-#define GPIO84_CIF_FV_MD       (84 | GPIO_ALT_FN_3_IN)
-#define GPIO85_nPCE_1_MD       (85 | GPIO_ALT_FN_1_OUT)
-#define GPIO85_CIF_LV_MD       (85 | GPIO_ALT_FN_3_IN)
-#define GPIO86_nPCE_1_MD       (86 | GPIO_ALT_FN_1_OUT)
-#define GPIO88_USBH1_PWR_MD    (88 | GPIO_ALT_FN_1_IN)
-#define GPIO89_USBH1_PEN_MD    (89 | GPIO_ALT_FN_2_OUT)
-#define GPIO90_CIF_DD_4_MD     (90 | GPIO_ALT_FN_3_IN)
-#define GPIO91_CIF_DD_5_MD     (91 | GPIO_ALT_FN_3_IN)
-#define GPIO92_MMCDAT0_MD      (92 | GPIO_ALT_FN_1_OUT)
-#define GPIO93_CIF_DD_6_MD     (93 | GPIO_ALT_FN_2_IN)
-#define GPIO94_CIF_DD_5_MD     (94 | GPIO_ALT_FN_2_IN)
-#define GPIO95_CIF_DD_4_MD     (95 | GPIO_ALT_FN_2_IN)
-#define GPIO95_KP_MKIN6_MD     (95 | GPIO_ALT_FN_3_IN)
-#define GPIO96_KP_DKIN3_MD     (96 | GPIO_ALT_FN_1_IN)
-#define GPIO96_FFRXD_MD                (96 | GPIO_ALT_FN_3_IN)
-#define GPIO97_KP_MKIN3_MD     (97 | GPIO_ALT_FN_3_IN)
-#define GPIO98_CIF_DD_0_MD     (98 | GPIO_ALT_FN_2_IN)
-#define GPIO98_FFRTS_MD                (98 | GPIO_ALT_FN_3_OUT)
-#define GPIO99_FFTXD_MD                (99 | GPIO_ALT_FN_3_OUT)
-#define GPIO100_KP_MKIN0_MD    (100 | GPIO_ALT_FN_1_IN)
-#define GPIO101_KP_MKIN1_MD    (101 | GPIO_ALT_FN_1_IN)
-#define GPIO102_nPCE_1_MD      (102 | GPIO_ALT_FN_1_OUT)
-#define GPIO102_KP_MKIN2_MD    (102 | GPIO_ALT_FN_1_IN)
-#define GPIO103_CIF_DD_3_MD    (103 | GPIO_ALT_FN_1_IN)
-#define GPIO103_KP_MKOUT0_MD   (103 | GPIO_ALT_FN_2_OUT)
-#define GPIO104_CIF_DD_2_MD    (104 | GPIO_ALT_FN_1_IN)
-#define GPIO104_pSKTSEL_MD     (104 | GPIO_ALT_FN_1_OUT)
-#define GPIO104_KP_MKOUT1_MD   (104 | GPIO_ALT_FN_2_OUT)
-#define GPIO105_CIF_DD_1_MD    (105 | GPIO_ALT_FN_1_IN)
-#define GPIO105_KP_MKOUT2_MD   (105 | GPIO_ALT_FN_2_OUT)
-#define GPIO106_CIF_DD_9_MD    (106 | GPIO_ALT_FN_1_IN)
-#define GPIO106_KP_MKOUT3_MD   (106 | GPIO_ALT_FN_2_OUT)
-#define GPIO107_CIF_DD_8_MD    (107 | GPIO_ALT_FN_1_IN)
-#define GPIO107_KP_MKOUT4_MD   (107 | GPIO_ALT_FN_2_OUT)
-#define GPIO108_CIF_DD_7_MD    (108 | GPIO_ALT_FN_1_IN)
-#define GPIO108_KP_MKOUT5_MD   (108 | GPIO_ALT_FN_2_OUT)
-#define GPIO109_MMCDAT1_MD     (109 | GPIO_ALT_FN_1_OUT)
-#define GPIO110_MMCDAT2_MD     (110 | GPIO_ALT_FN_1_OUT)
-#define GPIO110_MMCCS0_MD      (110 | GPIO_ALT_FN_1_OUT)
-#define GPIO111_MMCDAT3_MD     (111 | GPIO_ALT_FN_1_OUT)
-#define GPIO110_MMCCS1_MD      (111 | GPIO_ALT_FN_1_OUT)
-#define GPIO112_MMCCMD_MD      (112 | GPIO_ALT_FN_1_OUT)
-#define GPIO113_I2S_SYSCLK_MD  (113 | GPIO_ALT_FN_1_OUT)
-#define GPIO113_AC97_RESET_N_MD        (113 | GPIO_ALT_FN_2_OUT)
-#define GPIO117_I2CSCL_MD      (117 | GPIO_ALT_FN_1_IN)
-#define GPIO118_I2CSDA_MD      (118 | GPIO_ALT_FN_1_IN)
-
-/*
- * Handy routine to set GPIO alternate functions
- */
-extern int pxa_gpio_mode( int gpio_mode );
-
-#endif /* __ASM_ARCH_PXA2XX_GPIO_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h
deleted file mode 100644 (file)
index 6a2ed35..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef __ASM_ARCH_REGS_SSP_H
-#define __ASM_ARCH_REGS_SSP_H
-
-/*
- * SSP Serial Port Registers
- * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different.
- * PXA255, PXA26x and PXA27x have extra ports, registers and bits.
- */
-
-#define SSCR0          (0x00)  /* SSP Control Register 0 */
-#define SSCR1          (0x04)  /* SSP Control Register 1 */
-#define SSSR           (0x08)  /* SSP Status Register */
-#define SSITR          (0x0C)  /* SSP Interrupt Test Register */
-#define SSDR           (0x10)  /* SSP Data Write/Data Read Register */
-
-#define SSTO           (0x28)  /* SSP Time Out Register */
-#define SSPSP          (0x2C)  /* SSP Programmable Serial Protocol */
-#define SSTSA          (0x30)  /* SSP Tx Timeslot Active */
-#define SSRSA          (0x34)  /* SSP Rx Timeslot Active */
-#define SSTSS          (0x38)  /* SSP Timeslot Status */
-#define SSACD          (0x3C)  /* SSP Audio Clock Divider */
-
-#if defined(CONFIG_PXA3xx)
-#define SSACDD         (0x40)  /* SSP Audio Clock Dither Divider */
-#endif
-
-/* Common PXA2xx bits first */
-#define SSCR0_DSS      (0x0000000f)    /* Data Size Select (mask) */
-#define SSCR0_DataSize(x)  ((x) - 1)   /* Data Size Select [4..16] */
-#define SSCR0_FRF      (0x00000030)    /* FRame Format (mask) */
-#define SSCR0_Motorola (0x0 << 4)      /* Motorola's Serial Peripheral Interface (SPI) */
-#define SSCR0_TI       (0x1 << 4)      /* Texas Instruments' Synchronous Serial Protocol (SSP) */
-#define SSCR0_National (0x2 << 4)      /* National Microwire */
-#define SSCR0_ECS      (1 << 6)        /* External clock select */
-#define SSCR0_SSE      (1 << 7)        /* Synchronous Serial Port Enable */
-
-#if defined(CONFIG_PXA25x)
-#define SSCR0_SCR      (0x0000ff00)    /* Serial Clock Rate (mask) */
-#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
-#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#define SSCR0_SCR      (0x000fff00)    /* Serial Clock Rate (mask) */
-#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
-#endif
-
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#define SSCR0_EDSS     (1 << 20)       /* Extended data size select */
-#define SSCR0_NCS      (1 << 21)       /* Network clock select */
-#define SSCR0_RIM      (1 << 22)       /* Receive FIFO overrrun interrupt mask */
-#define SSCR0_TUM      (1 << 23)       /* Transmit FIFO underrun interrupt mask */
-#define SSCR0_FRDC     (0x07000000)    /* Frame rate divider control (mask) */
-#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */
-#define SSCR0_ACS      (1 << 30)       /* Audio clock select */
-#define SSCR0_MOD      (1 << 31)       /* Mode (normal or network) */
-#endif
-
-#if defined(CONFIG_PXA3xx)
-#define SSCR0_FPCKE    (1 << 29)       /* FIFO packing enable */
-#endif
-
-#define SSCR1_RIE      (1 << 0)        /* Receive FIFO Interrupt Enable */
-#define SSCR1_TIE      (1 << 1)        /* Transmit FIFO Interrupt Enable */
-#define SSCR1_LBM      (1 << 2)        /* Loop-Back Mode */
-#define SSCR1_SPO      (1 << 3)        /* Motorola SPI SSPSCLK polarity setting */
-#define SSCR1_SPH      (1 << 4)        /* Motorola SPI SSPSCLK phase setting */
-#define SSCR1_MWDS     (1 << 5)        /* Microwire Transmit Data Size */
-#define SSCR1_TFT      (0x000003c0)    /* Transmit FIFO Threshold (mask) */
-#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
-#define SSCR1_RFT      (0x00003c00)    /* Receive FIFO Threshold (mask) */
-#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
-
-#define SSSR_TNF       (1 << 2)        /* Transmit FIFO Not Full */
-#define SSSR_RNE       (1 << 3)        /* Receive FIFO Not Empty */
-#define SSSR_BSY       (1 << 4)        /* SSP Busy */
-#define SSSR_TFS       (1 << 5)        /* Transmit FIFO Service Request */
-#define SSSR_RFS       (1 << 6)        /* Receive FIFO Service Request */
-#define SSSR_ROR       (1 << 7)        /* Receive FIFO Overrun */
-
-#define SSCR0_TIM              (1 << 23)       /* Transmit FIFO Under Run Interrupt Mask */
-#define SSCR0_RIM              (1 << 22)       /* Receive FIFO Over Run interrupt Mask */
-#define SSCR0_NCS              (1 << 21)       /* Network Clock Select */
-#define SSCR0_EDSS             (1 << 20)       /* Extended Data Size Select */
-
-/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
-#define SSCR0_TISSP            (1 << 4)        /* TI Sync Serial Protocol */
-#define SSCR0_PSP              (3 << 4)        /* PSP - Programmable Serial Protocol */
-#define SSCR1_TTELP            (1 << 31)       /* TXD Tristate Enable Last Phase */
-#define SSCR1_TTE              (1 << 30)       /* TXD Tristate Enable */
-#define SSCR1_EBCEI            (1 << 29)       /* Enable Bit Count Error interrupt */
-#define SSCR1_SCFR             (1 << 28)       /* Slave Clock free Running */
-#define SSCR1_ECRA             (1 << 27)       /* Enable Clock Request A */
-#define SSCR1_ECRB             (1 << 26)       /* Enable Clock request B */
-#define SSCR1_SCLKDIR          (1 << 25)       /* Serial Bit Rate Clock Direction */
-#define SSCR1_SFRMDIR          (1 << 24)       /* Frame Direction */
-#define SSCR1_RWOT             (1 << 23)       /* Receive Without Transmit */
-#define SSCR1_TRAIL            (1 << 22)       /* Trailing Byte */
-#define SSCR1_TSRE             (1 << 21)       /* Transmit Service Request Enable */
-#define SSCR1_RSRE             (1 << 20)       /* Receive Service Request Enable */
-#define SSCR1_TINTE            (1 << 19)       /* Receiver Time-out Interrupt enable */
-#define SSCR1_PINTE            (1 << 18)       /* Peripheral Trailing Byte Interupt Enable */
-#define SSCR1_IFS              (1 << 16)       /* Invert Frame Signal */
-#define SSCR1_STRF             (1 << 15)       /* Select FIFO or EFWR */
-#define SSCR1_EFWR             (1 << 14)       /* Enable FIFO Write/Read */
-
-#define SSSR_BCE               (1 << 23)       /* Bit Count Error */
-#define SSSR_CSS               (1 << 22)       /* Clock Synchronisation Status */
-#define SSSR_TUR               (1 << 21)       /* Transmit FIFO Under Run */
-#define SSSR_EOC               (1 << 20)       /* End Of Chain */
-#define SSSR_TINT              (1 << 19)       /* Receiver Time-out Interrupt */
-#define SSSR_PINT              (1 << 18)       /* Peripheral Trailing Byte Interrupt */
-
-#if defined(CONFIG_PXA3xx)
-#define SSPSP_EDMYSTOP(x)      ((x) << 28)     /* Extended Dummy Stop */
-#define SSPSP_EDMYSTRT(x)      ((x) << 26)     /* Extended Dummy Start */
-#endif
-
-#define SSPSP_FSRT             (1 << 25)       /* Frame Sync Relative Timing */
-#define SSPSP_DMYSTOP(x)       ((x) << 23)     /* Dummy Stop */
-#define SSPSP_SFRMWDTH(x)      ((x) << 16)     /* Serial Frame Width */
-#define SSPSP_SFRMDLY(x)       ((x) << 9)      /* Serial Frame Delay */
-#define SSPSP_DMYSTRT(x)       ((x) << 7)      /* Dummy Start */
-#define SSPSP_STRTDLY(x)       ((x) << 4)      /* Start Delay */
-#define SSPSP_ETDS             (1 << 3)        /* End of Transfer data State */
-#define SSPSP_SFRMP            (1 << 2)        /* Serial Frame Polarity */
-#define SSPSP_SCMODE(x)                ((x) << 0)      /* Serial Bit Rate Clock Mode */
-
-#define SSACD_SCDB             (1 << 3)        /* SSPSYSCLK Divider Bypass */
-#define SSACD_ACPS(x)          ((x) << 4)      /* Audio clock PLL select */
-#define SSACD_ACDS(x)          ((x) << 0)      /* Audio clock divider select */
-#if defined(CONFIG_PXA3xx)
-#define SSACD_SCDX8            (1 << 7)        /* SYSCLK division ratio select */
-#endif
-
-
-#endif /* __ASM_ARCH_REGS_SSP_H */
index 44b0b20..c15c0c5 100644 (file)
 #define U2DMACSR_BUSERRTYPE    (7 << 10)       /* PX Bus Error Type */
 #define U2DMACSR_EORINTR       (1 << 9)        /* End Of Receive */
 #define U2DMACSR_REQPEND       (1 << 8)        /* Request Pending */
-#define U2DMACSR_RASINTR       (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */#define U2DMACSR_STOPINTR     (1 << 3)        /* Stop Interrupt (read only) */
+#define U2DMACSR_RASINTR       (1 << 4)        /* Request After Channel Stopped (read / write 1 clear) */
+#define U2DMACSR_STOPINTR      (1 << 3)        /* Stop Interrupt (read only) */
 #define U2DMACSR_ENDINTR       (1 << 2)        /* End Interrupt (read / write 1 clear) */
 #define U2DMACSR_STARTINTR     (1 << 1)        /* Start Interrupt (read / write 1 clear) */
 #define U2DMACSR_BUSERRINTR    (1 << 0)        /* Bus Error Interrupt (read / write 1 clear) */
diff --git a/arch/arm/mach-pxa/include/mach/ssp.h b/arch/arm/mach-pxa/include/mach/ssp.h
deleted file mode 100644 (file)
index be1be5b..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  ssp.h
- *
- *  Copyright (C) 2003 Russell King, 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 as
- * published by the Free Software Foundation.
- *
- * This driver supports the following PXA CPU/SSP ports:-
- *
- *       PXA250     SSP
- *       PXA255     SSP, NSSP
- *       PXA26x     SSP, NSSP, ASSP
- *       PXA27x     SSP1, SSP2, SSP3
- *       PXA3xx     SSP1, SSP2, SSP3, SSP4
- */
-
-#ifndef __ASM_ARCH_SSP_H
-#define __ASM_ARCH_SSP_H
-
-#include <linux/list.h>
-#include <linux/io.h>
-
-enum pxa_ssp_type {
-       SSP_UNDEFINED = 0,
-       PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
-       PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
-       PXA27x_SSP,
-};
-
-struct ssp_device {
-       struct platform_device *pdev;
-       struct list_head        node;
-
-       struct clk      *clk;
-       void __iomem    *mmio_base;
-       unsigned long   phys_base;
-
-       const char      *label;
-       int             port_id;
-       int             type;
-       int             use_count;
-       int             irq;
-       int             drcmr_rx;
-       int             drcmr_tx;
-};
-
-#ifdef CONFIG_PXA_SSP_LEGACY
-/*
- * SSP initialisation flags
- */
-#define SSP_NO_IRQ     0x1             /* don't register an irq handler in SSP driver */
-
-struct ssp_state {
-       u32     cr0;
-       u32 cr1;
-       u32 to;
-       u32 psp;
-};
-
-struct ssp_dev {
-       struct ssp_device *ssp;
-       u32 port;
-       u32 mode;
-       u32 flags;
-       u32 psp_flags;
-       u32 speed;
-       int irq;
-};
-
-int ssp_write_word(struct ssp_dev *dev, u32 data);
-int ssp_read_word(struct ssp_dev *dev, u32 *data);
-int ssp_flush(struct ssp_dev *dev);
-void ssp_enable(struct ssp_dev *dev);
-void ssp_disable(struct ssp_dev *dev);
-void ssp_save_state(struct ssp_dev *dev, struct ssp_state *ssp);
-void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *ssp);
-int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags);
-int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed);
-void ssp_exit(struct ssp_dev *dev);
-#endif /* CONFIG_PXA_SSP_LEGACY */
-
-/**
- * ssp_write_reg - Write to a SSP register
- *
- * @dev: SSP device to access
- * @reg: Register to write to
- * @val: Value to be written.
- */
-static inline void ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
-{
-       __raw_writel(val, dev->mmio_base + reg);
-}
-
-/**
- * ssp_read_reg - Read from a SSP register
- *
- * @dev: SSP device to access
- * @reg: Register to read from
- */
-static inline u32 ssp_read_reg(struct ssp_device *dev, u32 reg)
-{
-       return __raw_readl(dev->mmio_base + reg);
-}
-
-struct ssp_device *ssp_request(int port, const char *label);
-void ssp_free(struct ssp_device *);
-#endif /* __ASM_ARCH_SSP_H */
index 4df2d38..1bbd1f2 100644 (file)
 
 #define TOSA_KEY_SYNC          KEY_102ND /* ??? */
 
-#ifndef CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES
+#ifndef CONFIG_TOSA_USE_EXT_KEYCODES
 #define TOSA_KEY_RECORD                KEY_YEN
 #define TOSA_KEY_ADDRESSBOOK   KEY_KATAKANA
 #define TOSA_KEY_CANCEL                KEY_ESC
diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h
new file mode 100644 (file)
index 0000000..7bfa3dd
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * GPIOs and interrupts for Voipac PXA270
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_VPAC270_H_
+#define _INCLUDE_VPAC270_H_
+
+#define        GPIO1_VPAC270_USER_BTN          1
+
+#define        GPIO15_VPAC270_LED_ORANGE       15
+
+#define        GPIO81_VPAC270_BKL_ON           81
+#define        GPIO83_VPAC270_NL_ON            83
+
+#define        GPIO52_VPAC270_SD_READONLY      52
+#define        GPIO53_VPAC270_SD_DETECT_N      53
+
+#define        GPIO84_VPAC270_PCMCIA_CD        84
+#define        GPIO35_VPAC270_PCMCIA_RDY       35
+#define        GPIO107_VPAC270_PCMCIA_PPEN     107
+#define        GPIO11_VPAC270_PCMCIA_RESET     11
+#define        GPIO17_VPAC270_CF_CD            17
+#define        GPIO12_VPAC270_CF_RDY           12
+#define        GPIO16_VPAC270_CF_RESET         16
+
+#define        GPIO41_VPAC270_UDC_DETECT       41
+
+#define        GPIO114_VPAC270_ETH_IRQ         114
+
+#define        GPIO36_VPAC270_IDE_IRQ          36
+
+#define        GPIO113_VPAC270_TS_IRQ          113
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h
new file mode 100644 (file)
index 0000000..8835c16
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  arch/arm/mach-pxa/include/mach/z2.h
+ *
+ *  Author: Ken McGuire
+ *  Created: Feb 6, 2009
+ *
+ * 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_ZIPIT2_H
+#define ASM_ARCH_ZIPIT2_H
+
+/* LEDs */
+#define        GPIO10_ZIPITZ2_LED_WIFI         10
+#define        GPIO85_ZIPITZ2_LED_CHARGED      85
+#define        GPIO83_ZIPITZ2_LED_CHARGING     83
+
+/* SD/MMC */
+#define        GPIO96_ZIPITZ2_SD_DETECT        96
+
+/* GPIO Buttons */
+#define        GPIO1_ZIPITZ2_POWER_BUTTON      1
+#define        GPIO98_ZIPITZ2_LID_BUTTON       98
+
+/* Libertas GSPI8686 WiFi */
+#define        GPIO14_ZIPITZ2_WIFI_RESET       14
+#define        GPIO15_ZIPITZ2_WIFI_POWER       15
+#define        GPIO24_ZIPITZ2_WIFI_CS          24
+#define        GPIO36_ZIPITZ2_WIFI_IRQ         36
+
+/* LCD */
+#define        GPIO19_ZIPITZ2_LCD_RESET        19
+#define        GPIO88_ZIPITZ2_LCD_CS           88
+
+/* MISC GPIOs */
+#define        GPIO0_ZIPITZ2_AC_DETECT         0
+#define GPIO37_ZIPITZ2_HEADSET_DETECT  37
+
+#endif
index fa527b2..9b90461 100644 (file)
@@ -41,7 +41,6 @@
 
 #include <mach/pxa300.h>
 #include <mach/pxafb.h>
-#include <mach/ssp.h>
 #include <mach/mmc.h>
 #include <mach/pxa2xx_spi.h>
 #include <mach/pxa27x_keypad.h>
@@ -272,7 +271,7 @@ static inline void littleton_init_keypad(void) {}
 
 #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
 static struct pxamci_platform_data littleton_mci_platform_data = {
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
        .gpio_card_detect       = GPIO_MMC1_CARD_DETECT,
        .gpio_card_ro           = -1,
index 63d65a2..330c328 100644 (file)
@@ -478,7 +478,7 @@ static void lubbock_mci_exit(struct device *dev, void *data)
 
 static struct pxamci_platform_data lubbock_mci_platform_data = {
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
-       .detect_delay           = 1,
+       .detect_delay_ms        = 10,
        .init                   = lubbock_mci_init,
        .get_ro                 = lubbock_mci_get_ro,
        .exit                   = lubbock_mci_exit,
index cf6b720..1d1419b 100644 (file)
@@ -81,6 +81,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c)
                PGSR(bank) &= ~mask;
                is_out = 1;
                break;
+       case MFP_LPM_INPUT:
        case MFP_LPM_DEFAULT:
                break;
        default:
@@ -178,8 +179,17 @@ int gpio_set_wake(unsigned int gpio, unsigned int on)
        if (!d->valid)
                return -EINVAL;
 
-       if (d->keypad_gpio)
-               return -EINVAL;
+       /* Allow keypad GPIOs to wakeup system when
+        * configured as generic GPIOs.
+        */
+       if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&
+           (d->config & MFP_LPM_CAN_WAKEUP)) {
+               if (on)
+                       PKWR |= d->mask;
+               else
+                       PKWR &= ~d->mask;
+               return 0;
+       }
 
        mux_taken = (PWER & d->mux_mask) & (~d->mask);
        if (on && mux_taken)
@@ -239,21 +249,25 @@ static int pxa27x_pkwr_gpio[] = {
 int keypad_set_wake(unsigned int on)
 {
        unsigned int i, gpio, mask = 0;
-
-       if (!on) {
-               PKWR = 0;
-               return 0;
-       }
+       struct gpio_desc *d;
 
        for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
 
                gpio = pxa27x_pkwr_gpio[i];
+               d = &gpio_desc[gpio];
 
-               if (gpio_desc[gpio].config & MFP_LPM_CAN_WAKEUP)
+               /* skip if configured as generic GPIO */
+               if (MFP_AF(d->config) == 0)
+                       continue;
+
+               if (d->config & MFP_LPM_CAN_WAKEUP)
                        mask |= gpio_desc[gpio].mask;
        }
 
-       PKWR = mask;
+       if (on)
+               PKWR |= mask;
+       else
+               PKWR &= ~mask;
        return 0;
 }
 
@@ -328,6 +342,17 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
 {
        int i;
 
+       /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
+       for (i = 0; i < pxa_last_gpio; i++) {
+               if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
+                   (GPDR(i) & GPIO_bit(i))) {
+                       if (GPLR(i) & GPIO_bit(i))
+                               PGSR(i) |= GPIO_bit(i);
+                       else
+                               PGSR(i) &= ~GPIO_bit(i);
+               }
+       }
+
        for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
 
                saved_gafr[0][i] = GAFR_L(i);
index 7a50ed8..d60db87 100644 (file)
@@ -426,6 +426,7 @@ struct gpio_vbus_mach_info gpio_vbus_data = {
  * to give the card a chance to fully insert/eject.
  */
 static struct pxamci_platform_data mioa701_mci_info = {
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
        .gpio_card_detect       = GPIO15_SDIO_INSERT,
        .gpio_card_ro           = GPIO78_SDIO_RO,
@@ -791,7 +792,6 @@ static void __init mioa701_machine_init(void)
        mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
        bootstrap_init();
        set_pxa_fb_info(&mioa701_pxafb_info);
-       mioa701_mci_info.detect_delay = msecs_to_jiffies(250);
        pxa_set_mci_info(&mioa701_mci_info);
        pxa_set_keypad_info(&mioa701_keypad_info);
        wm97xx_bat_set_pdata(&mioa701_battery_data);
index 8c9c6f0..462167a 100644 (file)
@@ -325,7 +325,7 @@ static mfp_cfg_t mfp_cfg[] __initdata = {
 #if defined(CONFIG_MMC)
 static struct pxamci_platform_data mxm_8x10_mci_platform_data = {
        .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
-       .detect_delay = 1,
+       .detect_delay_ms = 10,
        .gpio_card_detect = MXM_8X10_SD_nCD,
        .gpio_card_ro = MXM_8X10_SD_WP,
        .gpio_power = -1
index f70c75b..1963819 100644 (file)
@@ -168,7 +168,7 @@ static struct pxamci_platform_data palmld_mci_platform_data = {
        .gpio_card_detect       = GPIO_NR_PALMLD_SD_DETECT_N,
        .gpio_card_ro           = GPIO_NR_PALMLD_SD_READONLY,
        .gpio_power             = GPIO_NR_PALMLD_SD_POWER,
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
 };
 
 /******************************************************************************
index d902a81..5305a39 100644 (file)
@@ -110,7 +110,7 @@ static struct pxamci_platform_data palmt5_mci_platform_data = {
        .gpio_card_detect       = GPIO_NR_PALMT5_SD_DETECT_N,
        .gpio_card_ro           = GPIO_NR_PALMT5_SD_READONLY,
        .gpio_power             = GPIO_NR_PALMT5_SD_POWER,
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
 };
 
 /******************************************************************************
index 717d7a6..033b567 100644 (file)
@@ -121,7 +121,7 @@ static struct pxamci_platform_data palmtc_mci_platform_data = {
        .gpio_power             = GPIO_NR_PALMTC_SD_POWER,
        .gpio_card_ro           = GPIO_NR_PALMTC_SD_READONLY,
        .gpio_card_detect       = GPIO_NR_PALMTC_SD_DETECT_N,
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
 };
 
 /******************************************************************************
index 007b58c..ecc1a40 100644 (file)
@@ -170,7 +170,7 @@ static struct pxamci_platform_data palmtx_mci_platform_data = {
        .gpio_card_detect       = GPIO_NR_PALMTX_SD_DETECT_N,
        .gpio_card_ro           = GPIO_NR_PALMTX_SD_READONLY,
        .gpio_power             = GPIO_NR_PALMTX_SD_POWER,
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
 };
 
 /******************************************************************************
index 9d0ecea..f56ae10 100644 (file)
@@ -326,7 +326,7 @@ static void pcm990_mci_exit(struct device *dev, void *data)
 #define MSECS_PER_JIFFY (1000/HZ)
 
 static struct pxamci_platform_data pcm990_mci_platform_data = {
-       .detect_delay           = 250 / MSECS_PER_JIFFY,
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
        .init                   = pcm990_mci_init,
        .setpower               = pcm990_mci_setpower,
index d58a524..f4abdaa 100644 (file)
 #include <mach/pxa25x.h>
 #include <mach/mmc.h>
 #include <mach/udc.h>
-#include <plat/i2c.h>
 #include <mach/irda.h>
 #include <mach/poodle.h>
 #include <mach/pxafb.h>
 #include <mach/sharpsl.h>
-#include <mach/ssp.h>
 #include <mach/pxa2xx_spi.h>
+#include <plat/i2c.h>
 
 #include <asm/hardware/scoop.h>
 #include <asm/hardware/locomo.h>
@@ -277,6 +276,7 @@ static void poodle_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data poodle_mci_platform_data = {
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
        .init                   = poodle_mci_init,
        .setpower               = poodle_mci_setpower,
@@ -450,7 +450,6 @@ static void __init poodle_init(void)
        set_pxa_fb_parent(&poodle_locomo_device.dev);
        set_pxa_fb_info(&poodle_fb_info);
        pxa_set_udc_info(&udc_info);
-       poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
        pxa_set_mci_info(&poodle_mci_platform_data);
        pxa_set_ficp_info(&poodle_ficp_platform_data);
        pxa_set_i2c_info(NULL);
index 4d7c03e..f544e58 100644 (file)
@@ -29,7 +29,6 @@
 #include <mach/ohci.h>
 #include <mach/pm.h>
 #include <mach/dma.h>
-#include <mach/ssp.h>
 #include <mach/regs-intc.h>
 #include <plat/i2c.h>
 
index 44bb675..d4b61b3 100644 (file)
@@ -714,7 +714,7 @@ static void raumfeld_mci_exit(struct device *dev, void *data)
 static struct pxamci_platform_data raumfeld_mci_platform_data = {
        .init                   = raumfeld_mci_init,
        .exit                   = raumfeld_mci_exit,
-       .detect_delay           = 20,
+       .detect_delay_ms        = 200,
        .gpio_card_detect       = -1,
        .gpio_card_ro           = -1,
        .gpio_power             = -1,
@@ -983,7 +983,7 @@ static void __init raumfeld_common_init(void)
                int i;
 
                for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++)
-                       if (!strcmp(gpio_keys_button[i].desc, "on/off button"))
+                       if (!strcmp(gpio_keys_button[i].desc, "on_off button"))
                                gpio_keys_button[i].active_low = 1;
        }
 
@@ -1009,8 +1009,7 @@ static void __init raumfeld_common_init(void)
                gpio_direction_output(GPIO_W2W_PDN, 0);
 
        /* this can be used to switch off the device */
-       ret = gpio_request(GPIO_SHUTDOWN_SUPPLY,
-                               "supply shutdown");
+       ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown");
        if (ret < 0)
                pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
        else
index 1439785..0cc1203 100644 (file)
@@ -9,29 +9,6 @@
 
 #include <mach/sharpsl_pm.h>
 
-/*
- * SharpSL SSP Driver
- */
-struct corgissp_machinfo {
-       int port;
-       int cs_lcdcon;
-       int cs_ads7846;
-       int cs_max1111;
-       int clk_lcdcon;
-       int clk_ads7846;
-       int clk_max1111;
-};
-
-void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
-
-
-/*
- * SharpSL/Corgi LCD Driver
- */
-void corgi_lcdtg_suspend(void);
-void corgi_lcdtg_hw_init(int mode);
-
-
 /*
  * SharpSL Battery/PM Driver
  */
index 463d874..cb47672 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/mach-types.h>
 #include <mach/pm.h>
 #include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
 #include <mach/regs-rtc.h>
 #include <mach/sharpsl.h>
 #include <mach/sharpsl_pm.h>
index 19b5109..4d2413e 100644 (file)
@@ -86,6 +86,7 @@ static unsigned long spitz_pin_config[] __initdata = {
 
        /* GPIOs */
        GPIO9_GPIO,     /* SPITZ_GPIO_nSD_DETECT */
+       GPIO16_GPIO,    /* SPITZ_GPIO_SYNC */
        GPIO81_GPIO,    /* SPITZ_GPIO_nSD_WP */
        GPIO41_GPIO,    /* SPITZ_GPIO_USB_CONNECT */
        GPIO37_GPIO,    /* SPITZ_GPIO_USB_HOST */
@@ -119,7 +120,8 @@ static unsigned long spitz_pin_config[] __initdata = {
        GPIO117_I2C_SCL,
        GPIO118_I2C_SDA,
 
-       GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+       GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,       /* SPITZ_GPIO_KEY_INT */
+       GPIO1_GPIO | WAKEUP_ON_EDGE_FALL,       /* SPITZ_GPIO_RESET */
 };
 
 /*
@@ -363,7 +365,7 @@ static struct gpio_keys_button spitz_gpio_keys[] = {
                .type   = EV_PWR,
                .code   = KEY_SUSPEND,
                .gpio   = SPITZ_GPIO_ON_KEY,
-               .desc   = "On/Off",
+               .desc   = "On Off",
                .wakeup = 1,
        },
        /* Two buttons detecting the lid state */
@@ -537,6 +539,7 @@ static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
 }
 
 static struct pxamci_platform_data spitz_mci_platform_data = {
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
        .setpower               = spitz_mci_setpower,
        .gpio_card_detect       = SPITZ_GPIO_nSD_DETECT,
@@ -757,7 +760,6 @@ static void __init common_init(void)
        spitz_init_spi();
 
        platform_add_devices(devices, ARRAY_SIZE(devices));
-       spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
        pxa_set_mci_info(&spitz_mci_platform_data);
        pxa_set_ohci_info(&spitz_ohci_platform_data);
        pxa_set_ficp_info(&spitz_ficp_platform_data);
index fc5a70c..4209ddf 100644 (file)
 
 #include <mach/sharpsl.h>
 #include <mach/spitz.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/pxa2xx-gpio.h>
+#include <mach/pxa27x.h>
+
 #include "sharpsl.h"
+#include "generic.h"
 
 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
 #define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
 
 static int spitz_last_ac_status;
 
+static struct gpio spitz_charger_gpios[] = {
+       { SPITZ_GPIO_KEY_INT,   GPIOF_IN, "Keyboard Interrupt" },
+       { SPITZ_GPIO_SYNC,      GPIOF_IN, "Sync" },
+       { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
+       { SPITZ_GPIO_JK_B,        GPIOF_OUT_INIT_LOW, "JK B" },
+       { SPITZ_GPIO_CHRG_ON,     GPIOF_OUT_INIT_LOW, "Charger On" },
+};
+
 static void spitz_charger_init(void)
 {
-       pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
-       pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
+       gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
 }
 
 static void spitz_measure_temp(int on)
@@ -76,6 +84,11 @@ static void spitz_discharge1(int on)
        gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
 }
 
+static unsigned long gpio18_config[] = {
+       GPIO18_RDY,
+       GPIO18_GPIO,
+};
+
 static void spitz_presuspend(void)
 {
        spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
@@ -97,7 +110,9 @@ static void spitz_presuspend(void)
        PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
        PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
 
-       pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH);
+       pxa2xx_mfp_config(&gpio18_config[0], 1);
+       gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
+       gpio_free(18);
 
        PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
        PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
@@ -114,8 +129,7 @@ static void spitz_presuspend(void)
 
 static void spitz_postsuspend(void)
 {
-       pxa_gpio_mode(GPIO18_RDY_MD);
-       pxa_gpio_mode(10 | GPIO_IN);
+       pxa2xx_mfp_config(&gpio18_config[1], 1);
 }
 
 static int spitz_should_wakeup(unsigned int resume_on_alarm)
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
deleted file mode 100644 (file)
index a81d6db..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- *  linux/arch/arm/mach-pxa/ssp.c
- *
- *  based on linux/arch/arm/mach-sa1100/ssp.c by Russell King
- *
- *  Copyright (C) 2003 Russell King.
- *  Copyright (C) 2003 Wolfson Microelectronics PLC
- *
- * 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.
- *
- *  PXA2xx SSP driver.  This provides the generic core for simple
- *  IO-based SSP applications and allows easy port setup for DMA access.
- *
- *  Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/ssp.h>
-#include <mach/regs-ssp.h>
-
-#ifdef CONFIG_PXA_SSP_LEGACY
-
-#define TIMEOUT 100000
-
-static irqreturn_t ssp_interrupt(int irq, void *dev_id)
-{
-       struct ssp_dev *dev = dev_id;
-       struct ssp_device *ssp = dev->ssp;
-       unsigned int status;
-
-       status = __raw_readl(ssp->mmio_base + SSSR);
-       __raw_writel(status, ssp->mmio_base + SSSR);
-
-       if (status & SSSR_ROR)
-               printk(KERN_WARNING "SSP(%d): receiver overrun\n", dev->port);
-
-       if (status & SSSR_TUR)
-               printk(KERN_WARNING "SSP(%d): transmitter underrun\n", dev->port);
-
-       if (status & SSSR_BCE)
-               printk(KERN_WARNING "SSP(%d): bit count error\n", dev->port);
-
-       return IRQ_HANDLED;
-}
-
-/**
- * ssp_write_word - write a word to the SSP port
- * @data: 32-bit, MSB justified data to write.
- *
- * Wait for a free entry in the SSP transmit FIFO, and write a data
- * word to the SSP port.
- *
- * The caller is expected to perform the necessary locking.
- *
- * Returns:
- *   %-ETIMEDOUT       timeout occurred
- *   0                 success
- */
-int ssp_write_word(struct ssp_dev *dev, u32 data)
-{
-       struct ssp_device *ssp = dev->ssp;
-       int timeout = TIMEOUT;
-
-       while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_TNF)) {
-               if (!--timeout)
-                       return -ETIMEDOUT;
-               cpu_relax();
-       }
-
-       __raw_writel(data, ssp->mmio_base + SSDR);
-
-       return 0;
-}
-
-/**
- * ssp_read_word - read a word from the SSP port
- *
- * Wait for a data word in the SSP receive FIFO, and return the
- * received data.  Data is LSB justified.
- *
- * Note: Currently, if data is not expected to be received, this
- * function will wait for ever.
- *
- * The caller is expected to perform the necessary locking.
- *
- * Returns:
- *   %-ETIMEDOUT       timeout occurred
- *   32-bit data       success
- */
-int ssp_read_word(struct ssp_dev *dev, u32 *data)
-{
-       struct ssp_device *ssp = dev->ssp;
-       int timeout = TIMEOUT;
-
-       while (!(__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE)) {
-               if (!--timeout)
-                       return -ETIMEDOUT;
-               cpu_relax();
-       }
-
-       *data = __raw_readl(ssp->mmio_base + SSDR);
-       return 0;
-}
-
-/**
- * ssp_flush - flush the transmit and receive FIFOs
- *
- * Wait for the SSP to idle, and ensure that the receive FIFO
- * is empty.
- *
- * The caller is expected to perform the necessary locking.
- */
-int ssp_flush(struct ssp_dev *dev)
-{
-       struct ssp_device *ssp = dev->ssp;
-       int timeout = TIMEOUT * 2;
-
-       /* ensure TX FIFO is empty instead of not full */
-       if (cpu_is_pxa3xx()) {
-               while (__raw_readl(ssp->mmio_base + SSSR) & 0xf00) {
-                       if (!--timeout)
-                               return -ETIMEDOUT;
-                       cpu_relax();
-               }
-               timeout = TIMEOUT * 2;
-       }
-
-       do {
-               while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_RNE) {
-                       if (!--timeout)
-                               return -ETIMEDOUT;
-                       (void)__raw_readl(ssp->mmio_base + SSDR);
-               }
-               if (!--timeout)
-                       return -ETIMEDOUT;
-       } while (__raw_readl(ssp->mmio_base + SSSR) & SSSR_BSY);
-
-       return 0;
-}
-
-/**
- * ssp_enable - enable the SSP port
- *
- * Turn on the SSP port.
- */
-void ssp_enable(struct ssp_dev *dev)
-{
-       struct ssp_device *ssp = dev->ssp;
-       uint32_t sscr0;
-
-       sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
-       sscr0 |= SSCR0_SSE;
-       __raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-/**
- * ssp_disable - shut down the SSP port
- *
- * Turn off the SSP port, optionally powering it down.
- */
-void ssp_disable(struct ssp_dev *dev)
-{
-       struct ssp_device *ssp = dev->ssp;
-       uint32_t sscr0;
-
-       sscr0 = __raw_readl(ssp->mmio_base + SSCR0);
-       sscr0 &= ~SSCR0_SSE;
-       __raw_writel(sscr0, ssp->mmio_base + SSCR0);
-}
-
-/**
- * ssp_save_state - save the SSP configuration
- * @ssp: pointer to structure to save SSP configuration
- *
- * Save the configured SSP state for suspend.
- */
-void ssp_save_state(struct ssp_dev *dev, struct ssp_state *state)
-{
-       struct ssp_device *ssp = dev->ssp;
-
-       state->cr0 = __raw_readl(ssp->mmio_base + SSCR0);
-       state->cr1 = __raw_readl(ssp->mmio_base + SSCR1);
-       state->to  = __raw_readl(ssp->mmio_base + SSTO);
-       state->psp = __raw_readl(ssp->mmio_base + SSPSP);
-
-       ssp_disable(dev);
-}
-
-/**
- * ssp_restore_state - restore a previously saved SSP configuration
- * @ssp: pointer to configuration saved by ssp_save_state
- *
- * Restore the SSP configuration saved previously by ssp_save_state.
- */
-void ssp_restore_state(struct ssp_dev *dev, struct ssp_state *state)
-{
-       struct ssp_device *ssp = dev->ssp;
-       uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE;
-
-       __raw_writel(sssr, ssp->mmio_base + SSSR);
-
-       __raw_writel(state->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0);
-       __raw_writel(state->cr1, ssp->mmio_base + SSCR1);
-       __raw_writel(state->to,  ssp->mmio_base + SSTO);
-       __raw_writel(state->psp, ssp->mmio_base + SSPSP);
-       __raw_writel(state->cr0, ssp->mmio_base + SSCR0);
-}
-
-/**
- * ssp_config - configure SSP port settings
- * @mode: port operating mode
- * @flags: port config flags
- * @psp_flags: port PSP config flags
- * @speed: port speed
- *
- * Port MUST be disabled by ssp_disable before making any config changes.
- */
-int ssp_config(struct ssp_dev *dev, u32 mode, u32 flags, u32 psp_flags, u32 speed)
-{
-       struct ssp_device *ssp = dev->ssp;
-
-       dev->mode = mode;
-       dev->flags = flags;
-       dev->psp_flags = psp_flags;
-       dev->speed = speed;
-
-       /* set up port type, speed, port settings */
-       __raw_writel((dev->speed | dev->mode), ssp->mmio_base + SSCR0);
-       __raw_writel(dev->flags, ssp->mmio_base + SSCR1);
-       __raw_writel(dev->psp_flags, ssp->mmio_base + SSPSP);
-
-       return 0;
-}
-
-/**
- * ssp_init - setup the SSP port
- *
- * initialise and claim resources for the SSP port.
- *
- * Returns:
- *   %-ENODEV  if the SSP port is unavailable
- *   %-EBUSY   if the resources are already in use
- *   %0                on success
- */
-int ssp_init(struct ssp_dev *dev, u32 port, u32 init_flags)
-{
-       struct ssp_device *ssp;
-       int ret;
-
-       ssp = ssp_request(port, "SSP");
-       if (ssp == NULL)
-               return -ENODEV;
-
-       dev->ssp = ssp;
-       dev->port = port;
-
-       /* do we need to get irq */
-       if (!(init_flags & SSP_NO_IRQ)) {
-               ret = request_irq(ssp->irq, ssp_interrupt,
-                               0, "SSP", dev);
-               if (ret)
-                       goto out_region;
-               dev->irq = ssp->irq;
-       } else
-               dev->irq = NO_IRQ;
-
-       /* turn on SSP port clock */
-       clk_enable(ssp->clk);
-       return 0;
-
-out_region:
-       ssp_free(ssp);
-       return ret;
-}
-
-/**
- * ssp_exit - undo the effects of ssp_init
- *
- * release and free resources for the SSP port.
- */
-void ssp_exit(struct ssp_dev *dev)
-{
-       struct ssp_device *ssp = dev->ssp;
-
-       ssp_disable(dev);
-       if (dev->irq != NO_IRQ)
-               free_irq(dev->irq, dev);
-       clk_disable(ssp->clk);
-       ssp_free(ssp);
-}
-#endif /* CONFIG_PXA_SSP_LEGACY */
-
-static DEFINE_MUTEX(ssp_lock);
-static LIST_HEAD(ssp_list);
-
-struct ssp_device *ssp_request(int port, const char *label)
-{
-       struct ssp_device *ssp = NULL;
-
-       mutex_lock(&ssp_lock);
-
-       list_for_each_entry(ssp, &ssp_list, node) {
-               if (ssp->port_id == port && ssp->use_count == 0) {
-                       ssp->use_count++;
-                       ssp->label = label;
-                       break;
-               }
-       }
-
-       mutex_unlock(&ssp_lock);
-
-       if (&ssp->node == &ssp_list)
-               return NULL;
-
-       return ssp;
-}
-EXPORT_SYMBOL(ssp_request);
-
-void ssp_free(struct ssp_device *ssp)
-{
-       mutex_lock(&ssp_lock);
-       if (ssp->use_count) {
-               ssp->use_count--;
-               ssp->label = NULL;
-       } else
-               dev_err(&ssp->pdev->dev, "device already free\n");
-       mutex_unlock(&ssp_lock);
-}
-EXPORT_SYMBOL(ssp_free);
-
-static int __devinit ssp_probe(struct platform_device *pdev)
-{
-       const struct platform_device_id *id = platform_get_device_id(pdev);
-       struct resource *res;
-       struct ssp_device *ssp;
-       int ret = 0;
-
-       ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
-       if (ssp == NULL) {
-               dev_err(&pdev->dev, "failed to allocate memory");
-               return -ENOMEM;
-       }
-       ssp->pdev = pdev;
-
-       ssp->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(ssp->clk)) {
-               ret = PTR_ERR(ssp->clk);
-               goto err_free;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               ret = -ENODEV;
-               goto err_free_clk;
-       }
-
-       res = request_mem_region(res->start, res->end - res->start + 1,
-                       pdev->name);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "failed to request memory resource\n");
-               ret = -EBUSY;
-               goto err_free_clk;
-       }
-
-       ssp->phys_base = res->start;
-
-       ssp->mmio_base = ioremap(res->start, res->end - res->start + 1);
-       if (ssp->mmio_base == NULL) {
-               dev_err(&pdev->dev, "failed to ioremap() registers\n");
-               ret = -ENODEV;
-               goto err_free_mem;
-       }
-
-       ssp->irq = platform_get_irq(pdev, 0);
-       if (ssp->irq < 0) {
-               dev_err(&pdev->dev, "no IRQ resource defined\n");
-               ret = -ENODEV;
-               goto err_free_io;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
-               ret = -ENODEV;
-               goto err_free_io;
-       }
-       ssp->drcmr_rx = res->start;
-
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
-               ret = -ENODEV;
-               goto err_free_io;
-       }
-       ssp->drcmr_tx = res->start;
-
-       /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
-        * starts from 0, do a translation here
-        */
-       ssp->port_id = pdev->id + 1;
-       ssp->use_count = 0;
-       ssp->type = (int)id->driver_data;
-
-       mutex_lock(&ssp_lock);
-       list_add(&ssp->node, &ssp_list);
-       mutex_unlock(&ssp_lock);
-
-       platform_set_drvdata(pdev, ssp);
-       return 0;
-
-err_free_io:
-       iounmap(ssp->mmio_base);
-err_free_mem:
-       release_mem_region(res->start, res->end - res->start + 1);
-err_free_clk:
-       clk_put(ssp->clk);
-err_free:
-       kfree(ssp);
-       return ret;
-}
-
-static int __devexit ssp_remove(struct platform_device *pdev)
-{
-       struct resource *res;
-       struct ssp_device *ssp;
-
-       ssp = platform_get_drvdata(pdev);
-       if (ssp == NULL)
-               return -ENODEV;
-
-       iounmap(ssp->mmio_base);
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, res->end - res->start + 1);
-
-       clk_put(ssp->clk);
-
-       mutex_lock(&ssp_lock);
-       list_del(&ssp->node);
-       mutex_unlock(&ssp_lock);
-
-       kfree(ssp);
-       return 0;
-}
-
-static const struct platform_device_id ssp_id_table[] = {
-       { "pxa25x-ssp",         PXA25x_SSP },
-       { "pxa25x-nssp",        PXA25x_NSSP },
-       { "pxa27x-ssp",         PXA27x_SSP },
-       { },
-};
-
-static struct platform_driver ssp_driver = {
-       .probe          = ssp_probe,
-       .remove         = __devexit_p(ssp_remove),
-       .driver         = {
-               .owner  = THIS_MODULE,
-               .name   = "pxa2xx-ssp",
-       },
-       .id_table       = ssp_id_table,
-};
-
-static int __init pxa_ssp_init(void)
-{
-       return platform_driver_register(&ssp_driver);
-}
-
-static void __exit pxa_ssp_exit(void)
-{
-       platform_driver_unregister(&ssp_driver);
-}
-
-arch_initcall(pxa_ssp_init);
-module_exit(pxa_ssp_exit);
-
-#ifdef CONFIG_PXA_SSP_LEGACY
-EXPORT_SYMBOL(ssp_write_word);
-EXPORT_SYMBOL(ssp_read_word);
-EXPORT_SYMBOL(ssp_flush);
-EXPORT_SYMBOL(ssp_enable);
-EXPORT_SYMBOL(ssp_disable);
-EXPORT_SYMBOL(ssp_save_state);
-EXPORT_SYMBOL(ssp_restore_state);
-EXPORT_SYMBOL(ssp_init);
-EXPORT_SYMBOL(ssp_exit);
-EXPORT_SYMBOL(ssp_config);
-#endif
-
-MODULE_DESCRIPTION("PXA SSP driver");
-MODULE_AUTHOR("Liam Girdwood");
-MODULE_LICENSE("GPL");
-
index 2041eb1..af40d2a 100644 (file)
@@ -464,8 +464,6 @@ static struct platform_device smc91x_device = {
 
 
 
-static struct pxamci_platform_data stargate2_mci_platform_data;
-
 /*
  * The card detect interrupt isn't debounced so we delay it by 250ms
  * to give the card a chance to fully insert / eject.
@@ -489,8 +487,6 @@ static int stargate2_mci_init(struct device *dev,
                goto free_power_en;
        }
        gpio_direction_input(SG2_GPIO_nSD_DETECT);
-       /* Delay to allow for full insertion */
-       stargate2_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
        err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT),
                          stargate2_detect_int,
@@ -529,6 +525,7 @@ static void stargate2_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data stargate2_mci_platform_data = {
+       .detect_delay_ms = 250,
        .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
        .init = stargate2_mci_init,
        .setpower = stargate2_mci_setpower,
index ad55279..7512b82 100644 (file)
@@ -275,6 +275,7 @@ static void tosa_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data tosa_mci_platform_data = {
+       .detect_delay_ms        = 250,
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
        .init                   = tosa_mci_init,
        .exit                   = tosa_mci_exit,
@@ -926,7 +927,6 @@ static void __init tosa_init(void)
        dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
        dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
 
-       tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250);
        pxa_set_mci_info(&tosa_mci_platform_data);
        pxa_set_udc_info(&udc_info);
        pxa_set_ficp_info(&tosa_ficp_platform_data);
index 797f254..6968911 100644 (file)
@@ -349,7 +349,7 @@ static void trizeps4_mci_exit(struct device *dev, void *data)
 
 static struct pxamci_platform_data trizeps4_mci_platform_data = {
        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-       .detect_delay   = 1,
+       .detect_delay_ms= 10,
        .init           = trizeps4_mci_init,
        .exit           = trizeps4_mci_exit,
        .get_ro         = NULL, /* write-protection not supported */
index 9e0c5c3..e90114a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/pm.h>
 #include <linux/sched.h>
 #include <linux/gpio.h>
+#include <linux/jiffies.h>
 #include <linux/i2c-gpio.h>
 #include <linux/serial_8250.h>
 #include <linux/smc91x.h>
@@ -454,7 +455,7 @@ static struct i2c_gpio_platform_data i2c_bus_data = {
        .sda_pin = VIPER_RTC_I2C_SDA_GPIO,
        .scl_pin = VIPER_RTC_I2C_SCL_GPIO,
        .udelay  = 10,
-       .timeout = 100,
+       .timeout = HZ,
 };
 
 static struct platform_device i2c_bus_device = {
@@ -779,7 +780,7 @@ static void __init viper_tpm_init(void)
                .sda_pin = VIPER_TPM_I2C_SDA_GPIO,
                .scl_pin = VIPER_TPM_I2C_SCL_GPIO,
                .udelay  = 10,
-               .timeout = 100,
+               .timeout = HZ,
        };
        char *errstr;
 
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
new file mode 100644 (file)
index 0000000..9884fa9
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ * Hardware definitions for Voipac PXA270
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/sysdev.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/onenand.h>
+#include <linux/dm9000.h>
+#include <linux/ucb1400.h>
+#include <linux/ata_platform.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/vpac270.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long vpac270_pin_config[] __initdata = {
+       /* MMC */
+       GPIO32_MMC_CLK,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+       GPIO112_MMC_CMD,
+       GPIO53_GPIO,    /* SD detect */
+       GPIO52_GPIO,    /* SD r/o switch */
+
+       /* GPIO KEYS */
+       GPIO1_GPIO,     /* USER BTN */
+
+       /* LEDs */
+       GPIO15_GPIO,    /* orange led */
+
+       /* FFUART */
+       GPIO34_FFUART_RXD,
+       GPIO39_FFUART_TXD,
+       GPIO27_FFUART_RTS,
+       GPIO100_FFUART_CTS,
+       GPIO33_FFUART_DSR,
+       GPIO40_FFUART_DTR,
+       GPIO10_FFUART_DCD,
+       GPIO38_FFUART_RI,
+
+       /* LCD */
+       GPIO58_LCD_LDD_0,
+       GPIO59_LCD_LDD_1,
+       GPIO60_LCD_LDD_2,
+       GPIO61_LCD_LDD_3,
+       GPIO62_LCD_LDD_4,
+       GPIO63_LCD_LDD_5,
+       GPIO64_LCD_LDD_6,
+       GPIO65_LCD_LDD_7,
+       GPIO66_LCD_LDD_8,
+       GPIO67_LCD_LDD_9,
+       GPIO68_LCD_LDD_10,
+       GPIO69_LCD_LDD_11,
+       GPIO70_LCD_LDD_12,
+       GPIO71_LCD_LDD_13,
+       GPIO72_LCD_LDD_14,
+       GPIO73_LCD_LDD_15,
+       GPIO86_LCD_LDD_16,
+       GPIO87_LCD_LDD_17,
+       GPIO74_LCD_FCLK,
+       GPIO75_LCD_LCLK,
+       GPIO76_LCD_PCLK,
+       GPIO77_LCD_BIAS,
+
+       /* PCMCIA */
+       GPIO48_nPOE,
+       GPIO49_nPWE,
+       GPIO50_nPIOR,
+       GPIO51_nPIOW,
+       GPIO85_nPCE_1,
+       GPIO54_nPCE_2,
+       GPIO55_nPREG,
+       GPIO57_nIOIS16,
+       GPIO56_nPWAIT,
+       GPIO104_PSKTSEL,
+       GPIO84_GPIO,    /* PCMCIA CD */
+       GPIO35_GPIO,    /* PCMCIA RDY */
+       GPIO107_GPIO,   /* PCMCIA PPEN */
+       GPIO11_GPIO,    /* PCMCIA RESET */
+       GPIO17_GPIO,    /* CF CD */
+       GPIO12_GPIO,    /* CF RDY */
+       GPIO16_GPIO,    /* CF RESET */
+
+       /* UHC */
+       GPIO88_USBH1_PWR,
+       GPIO89_USBH1_PEN,
+       GPIO119_USBH2_PWR,
+       GPIO120_USBH2_PEN,
+
+       /* UDC */
+       GPIO41_GPIO,
+
+       /* Ethernet */
+       GPIO114_GPIO,   /* IRQ */
+
+       /* AC97 */
+       GPIO28_AC97_BITCLK,
+       GPIO29_AC97_SDATA_IN_0,
+       GPIO30_AC97_SDATA_OUT,
+       GPIO31_AC97_SYNC,
+       GPIO95_AC97_nRESET,
+       GPIO98_AC97_SYSCLK,
+       GPIO113_GPIO,   /* TS IRQ */
+
+       /* I2C */
+       GPIO117_I2C_SCL,
+       GPIO118_I2C_SDA,
+
+       /* IDE */
+       GPIO36_GPIO,    /* IDE IRQ */
+       GPIO80_DREQ_1,
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition vpac270_nor_partitions[] = {
+       {
+               .name           = "Flash",
+               .offset         = 0x00000000,
+               .size           = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct physmap_flash_data vpac270_flash_data[] = {
+       {
+               .width          = 2,    /* bankwidth in bytes */
+               .parts          = vpac270_nor_partitions,
+               .nr_parts       = ARRAY_SIZE(vpac270_nor_partitions)
+       }
+};
+
+static struct resource vpac270_flash_resource = {
+       .start  = PXA_CS0_PHYS,
+       .end    = PXA_CS0_PHYS + SZ_64M - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device vpac270_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .resource       = &vpac270_flash_resource,
+       .num_resources  = 1,
+       .dev            = {
+               .platform_data = vpac270_flash_data,
+       },
+};
+static void __init vpac270_nor_init(void)
+{
+       platform_device_register(&vpac270_flash);
+}
+#else
+static inline void vpac270_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * OneNAND Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
+static struct mtd_partition vpac270_onenand_partitions[] = {
+       {
+               .name           = "Flash",
+               .offset         = 0x00000000,
+               .size           = MTDPART_SIZ_FULL,
+       }
+};
+
+static struct onenand_platform_data vpac270_onenand_info = {
+       .parts          = vpac270_onenand_partitions,
+       .nr_parts       = ARRAY_SIZE(vpac270_onenand_partitions),
+};
+
+static struct resource vpac270_onenand_resources[] = {
+       [0] = {
+               .start  = PXA_CS0_PHYS,
+               .end    = PXA_CS0_PHYS + SZ_1M,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device vpac270_onenand = {
+       .name           = "onenand-flash",
+       .id             = -1,
+       .resource       = vpac270_onenand_resources,
+       .num_resources  = ARRAY_SIZE(vpac270_onenand_resources),
+       .dev            = {
+               .platform_data  = &vpac270_onenand_info,
+       },
+};
+
+static void __init vpac270_onenand_init(void)
+{
+       platform_device_register(&vpac270_onenand);
+}
+#else
+static void __init vpac270_onenand_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#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_card_detect       = GPIO53_VPAC270_SD_DETECT_N,
+       .gpio_card_ro           = GPIO52_VPAC270_SD_READONLY,
+       .detect_delay_ms        = 200,
+};
+
+static void __init vpac270_mmc_init(void)
+{
+       pxa_set_mci_info(&vpac270_mci_platform_data);
+}
+#else
+static inline void vpac270_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button vpac270_pxa_buttons[] = {
+       {KEY_POWER, GPIO1_VPAC270_USER_BTN, 0, "USER BTN"},
+};
+
+static struct gpio_keys_platform_data vpac270_pxa_keys_data = {
+       .buttons        = vpac270_pxa_buttons,
+       .nbuttons       = ARRAY_SIZE(vpac270_pxa_buttons),
+};
+
+static struct platform_device vpac270_pxa_keys = {
+       .name   = "gpio-keys",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &vpac270_pxa_keys_data,
+       },
+};
+
+static void __init vpac270_keys_init(void)
+{
+       platform_device_register(&vpac270_pxa_keys);
+}
+#else
+static inline void vpac270_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * LED
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led vpac270_gpio_leds[] = {
+{
+       .name                   = "vpac270:orange:user",
+       .default_trigger        = "none",
+       .gpio                   = GPIO15_VPAC270_LED_ORANGE,
+       .active_low             = 1,
+}
+};
+
+static struct gpio_led_platform_data vpac270_gpio_led_info = {
+       .leds           = vpac270_gpio_leds,
+       .num_leds       = ARRAY_SIZE(vpac270_gpio_leds),
+};
+
+static struct platform_device vpac270_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &vpac270_gpio_led_info,
+       }
+};
+
+static void __init vpac270_leds_init(void)
+{
+       platform_device_register(&vpac270_leds);
+}
+#else
+static inline void vpac270_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int vpac270_ohci_init(struct device *dev)
+{
+       UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
+       return 0;
+}
+
+static struct pxaohci_platform_data vpac270_ohci_info = {
+       .port_mode      = PMM_PERPORT_MODE,
+       .flags          = ENABLE_PORT1 | ENABLE_PORT2 |
+                       POWER_CONTROL_LOW | POWER_SENSE_LOW,
+       .init           = vpac270_ohci_init,
+};
+
+static void __init vpac270_uhc_init(void)
+{
+       pxa_set_ohci_info(&vpac270_ohci_info);
+}
+#else
+static inline void vpac270_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Gadget
+ ******************************************************************************/
+#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE)
+static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = {
+       .gpio_vbus              = GPIO41_VPAC270_UDC_DETECT,
+       .gpio_pullup            = -1,
+};
+
+static struct platform_device vpac270_gpio_vbus = {
+       .name   = "gpio-vbus",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &vpac270_gpio_vbus_info,
+       },
+};
+
+static void vpac270_udc_command(int cmd)
+{
+       if (cmd == PXA2XX_UDC_CMD_CONNECT)
+               UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+       else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+               UP2OCR = UP2OCR_HXOE;
+}
+
+static struct pxa2xx_udc_mach_info vpac270_udc_info __initdata = {
+       .udc_command            = vpac270_udc_command,
+       .gpio_pullup            = -1,
+};
+
+static void __init vpac270_udc_init(void)
+{
+       pxa_set_udc_info(&vpac270_udc_info);
+       platform_device_register(&vpac270_gpio_vbus);
+}
+#else
+static inline void vpac270_udc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Ethernet
+ ******************************************************************************/
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource vpac270_dm9000_resources[] = {
+       [0] = {
+               .start  = PXA_CS2_PHYS + 0x300,
+               .end    = PXA_CS2_PHYS + 0x303,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = PXA_CS2_PHYS + 0x304,
+               .end    = PXA_CS2_PHYS + 0x343,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ),
+               .end    = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ),
+               .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+       },
+};
+
+static struct dm9000_plat_data vpac270_dm9000_platdata = {
+       .flags          = DM9000_PLATF_32BITONLY,
+};
+
+static struct platform_device vpac270_dm9000_device = {
+       .name           = "dm9000",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(vpac270_dm9000_resources),
+       .resource       = vpac270_dm9000_resources,
+       .dev            = {
+               .platform_data = &vpac270_dm9000_platdata,
+       }
+};
+
+static void __init vpac270_eth_init(void)
+{
+       platform_device_register(&vpac270_dm9000_device);
+}
+#else
+static inline void vpac270_eth_init(void) {}
+#endif
+
+/******************************************************************************
+ * Audio and Touchscreen
+ ******************************************************************************/
+#if    defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+       defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static pxa2xx_audio_ops_t vpac270_ac97_pdata = {
+       .reset_gpio     = 95,
+};
+
+static struct ucb1400_pdata vpac270_ucb1400_pdata = {
+       .irq            = IRQ_GPIO(GPIO113_VPAC270_TS_IRQ),
+};
+
+static struct platform_device vpac270_ucb1400_device = {
+       .name           = "ucb1400_core",
+       .id             = -1,
+       .dev            = {
+               .platform_data = &vpac270_ucb1400_pdata,
+       },
+};
+
+static void __init vpac270_ts_init(void)
+{
+       pxa_set_ac97_info(&vpac270_ac97_pdata);
+       platform_device_register(&vpac270_ucb1400_device);
+}
+#else
+static inline void vpac270_ts_init(void) {}
+#endif
+
+/******************************************************************************
+ * RTC
+ ******************************************************************************/
+#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE)
+static struct i2c_board_info __initdata vpac270_i2c_devs[] = {
+       {
+               I2C_BOARD_INFO("ds1339", 0x68),
+       },
+};
+
+static void __init vpac270_rtc_init(void)
+{
+       pxa_set_i2c_info(NULL);
+       i2c_register_board_info(0, ARRAY_AND_SIZE(vpac270_i2c_devs));
+}
+#else
+static inline void vpac270_rtc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info vpac270_lcd_modes[] = {
+{
+       .pixclock       = 57692,
+       .xres           = 640,
+       .yres           = 480,
+       .bpp            = 32,
+       .depth          = 18,
+
+       .left_margin    = 144,
+       .right_margin   = 32,
+       .upper_margin   = 13,
+       .lower_margin   = 30,
+
+       .hsync_len      = 32,
+       .vsync_len      = 2,
+
+       .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+},
+};
+
+static struct pxafb_mach_info vpac270_lcd_screen = {
+       .modes          = vpac270_lcd_modes,
+       .num_modes      = ARRAY_SIZE(vpac270_lcd_modes),
+       .lcd_conn       = LCD_COLOR_TFT_18BPP,
+};
+
+static void vpac270_lcd_power(int on, struct fb_var_screeninfo *info)
+{
+       gpio_set_value(GPIO81_VPAC270_BKL_ON, on);
+}
+
+static void __init vpac270_lcd_init(void)
+{
+       int ret;
+
+       ret = gpio_request(GPIO81_VPAC270_BKL_ON, "BKL-ON");
+       if (ret) {
+               pr_err("Requesting BKL-ON GPIO failed!\n");
+               goto err;
+       }
+
+       ret = gpio_direction_output(GPIO81_VPAC270_BKL_ON, 1);
+       if (ret) {
+               pr_err("Setting BKL-ON GPIO direction failed!\n");
+               goto err2;
+       }
+
+       vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
+       set_pxa_fb_info(&vpac270_lcd_screen);
+       return;
+
+err2:
+       gpio_free(GPIO81_VPAC270_BKL_ON);
+err:
+       return;
+}
+#else
+static inline void vpac270_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * PATA IDE
+ ******************************************************************************/
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+static struct pata_platform_info vpac270_pata_pdata = {
+       .ioport_shift   = 1,
+       .irq_flags      = IRQF_TRIGGER_RISING,
+};
+
+static struct resource vpac270_ide_resources[] = {
+       [0] = { /* I/O Base address */
+              .start   = PXA_CS3_PHYS + 0x120,
+              .end     = PXA_CS3_PHYS + 0x13f,
+              .flags   = IORESOURCE_MEM
+       },
+       [1] = { /* CTL Base address */
+              .start   = PXA_CS3_PHYS + 0x15c,
+              .end     = PXA_CS3_PHYS + 0x15f,
+              .flags   = IORESOURCE_MEM
+       },
+       [2] = { /* IDE IRQ pin */
+              .start   = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ),
+              .end     = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ),
+              .flags   = IORESOURCE_IRQ
+       }
+};
+
+static struct platform_device vpac270_ide_device = {
+       .name           = "pata_platform",
+       .num_resources  = ARRAY_SIZE(vpac270_ide_resources),
+       .resource       = vpac270_ide_resources,
+       .dev            = {
+               .platform_data  = &vpac270_pata_pdata,
+       }
+};
+
+static void __init vpac270_ide_init(void)
+{
+       platform_device_register(&vpac270_ide_device);
+}
+#else
+static inline void vpac270_ide_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init vpac270_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(vpac270_pin_config));
+
+       pxa_set_ffuart_info(NULL);
+       pxa_set_btuart_info(NULL);
+       pxa_set_stuart_info(NULL);
+
+       vpac270_lcd_init();
+       vpac270_mmc_init();
+       vpac270_nor_init();
+       vpac270_onenand_init();
+       vpac270_leds_init();
+       vpac270_keys_init();
+       vpac270_uhc_init();
+       vpac270_udc_init();
+       vpac270_eth_init();
+       vpac270_ts_init();
+       vpac270_rtc_init();
+       vpac270_ide_init();
+}
+
+MACHINE_START(VPAC270, "Voipac PXA270")
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = vpac270_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
new file mode 100644 (file)
index 0000000..f5d1ae3
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ *  linux/arch/arm/mach-pxa/z2.c
+ *
+ *  Support for the Zipit Z2 Handheld device.
+ *
+ *  Author:    Ken McGuire
+ *  Created:   Jan 25, 2009
+ *  Based on mainstone.c as modified for the Zipit Z2.
+ *
+ *  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/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pwm_backlight.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/lms283gf05.h>
+#include <linux/power_supply.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/z2.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/pxa2xx_spi.h>
+
+#include <plat/i2c.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long z2_pin_config[] = {
+
+       /* LCD - 16bpp Active TFT */
+       GPIO58_LCD_LDD_0,
+       GPIO59_LCD_LDD_1,
+       GPIO60_LCD_LDD_2,
+       GPIO61_LCD_LDD_3,
+       GPIO62_LCD_LDD_4,
+       GPIO63_LCD_LDD_5,
+       GPIO64_LCD_LDD_6,
+       GPIO65_LCD_LDD_7,
+       GPIO66_LCD_LDD_8,
+       GPIO67_LCD_LDD_9,
+       GPIO68_LCD_LDD_10,
+       GPIO69_LCD_LDD_11,
+       GPIO70_LCD_LDD_12,
+       GPIO71_LCD_LDD_13,
+       GPIO72_LCD_LDD_14,
+       GPIO73_LCD_LDD_15,
+       GPIO74_LCD_FCLK,
+       GPIO75_LCD_LCLK,
+       GPIO76_LCD_PCLK,
+       GPIO77_LCD_BIAS,
+       GPIO19_GPIO,            /* LCD reset */
+       GPIO88_GPIO,            /* LCD chipselect */
+
+       /* PWM */
+       GPIO115_PWM1_OUT,       /* Keypad Backlight */
+       GPIO11_PWM2_OUT,        /* LCD Backlight */
+
+       /* MMC */
+       GPIO32_MMC_CLK,
+       GPIO112_MMC_CMD,
+       GPIO92_MMC_DAT_0,
+       GPIO109_MMC_DAT_1,
+       GPIO110_MMC_DAT_2,
+       GPIO111_MMC_DAT_3,
+       GPIO96_GPIO,            /* SD detect */
+
+       /* STUART */
+       GPIO46_STUART_RXD,
+       GPIO47_STUART_TXD,
+
+       /* Keypad */
+       GPIO100_KP_MKIN_0       | WAKEUP_ON_LEVEL_HIGH,
+       GPIO101_KP_MKIN_1       | WAKEUP_ON_LEVEL_HIGH,
+       GPIO102_KP_MKIN_2       | WAKEUP_ON_LEVEL_HIGH,
+       GPIO34_KP_MKIN_3        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO38_KP_MKIN_4        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO16_KP_MKIN_5        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO17_KP_MKIN_6        | WAKEUP_ON_LEVEL_HIGH,
+       GPIO103_KP_MKOUT_0,
+       GPIO104_KP_MKOUT_1,
+       GPIO105_KP_MKOUT_2,
+       GPIO106_KP_MKOUT_3,
+       GPIO107_KP_MKOUT_4,
+       GPIO108_KP_MKOUT_5,
+       GPIO35_KP_MKOUT_6,
+       GPIO41_KP_MKOUT_7,
+
+       /* I2C */
+       GPIO117_I2C_SCL,
+       GPIO118_I2C_SDA,
+
+       /* SSP1 */
+       GPIO23_SSP1_SCLK,       /* SSP1_SCK */
+       GPIO25_SSP1_TXD,        /* SSP1_TXD */
+       GPIO26_SSP1_RXD,        /* SSP1_RXD */
+
+       /* SSP2 */
+       GPIO22_SSP2_SCLK,       /* SSP2_SCK */
+       GPIO13_SSP2_TXD,        /* SSP2_TXD */
+       GPIO40_SSP2_RXD,        /* SSP2_RXD */
+
+       /* LEDs */
+       GPIO10_GPIO,            /* WiFi LED */
+       GPIO83_GPIO,            /* Charging LED */
+       GPIO85_GPIO,            /* Charged LED */
+
+       /* I2S */
+       GPIO28_I2S_BITCLK_OUT,
+       GPIO29_I2S_SDATA_IN,
+       GPIO30_I2S_SDATA_OUT,
+       GPIO31_I2S_SYNC,
+       GPIO113_I2S_SYSCLK,
+
+       /* MISC */
+       GPIO0_GPIO,             /* AC power detect */
+       GPIO1_GPIO,             /* Power button */
+       GPIO37_GPIO,            /* Headphone detect */
+       GPIO98_GPIO,            /* Lid switch */
+       GPIO14_GPIO,            /* WiFi Reset */
+       GPIO15_GPIO,            /* WiFi Power */
+       GPIO24_GPIO,            /* WiFi CS */
+       GPIO36_GPIO,            /* WiFi IRQ */
+       GPIO88_GPIO,            /* LCD CS */
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct resource z2_flash_resource = {
+       .start  = PXA_CS0_PHYS,
+       .end    = PXA_CS0_PHYS + SZ_8M - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct mtd_partition z2_flash_parts[] = {
+       {
+               .name   = "U-Boot Bootloader",
+               .offset = 0x0,
+               .size   = 0x20000,
+       },
+       {
+               .name   = "Linux Kernel",
+               .offset = 0x20000,
+               .size   = 0x220000,
+       },
+       {
+               .name   = "Filesystem",
+               .offset = 0x240000,
+               .size   = 0x5b0000,
+       },
+       {
+               .name   = "U-Boot Environment",
+               .offset = 0x7f0000,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct physmap_flash_data z2_flash_data = {
+       .width          = 2,
+       .parts          = z2_flash_parts,
+       .nr_parts       = ARRAY_SIZE(z2_flash_parts),
+};
+
+static struct platform_device z2_flash = {
+       .name           = "physmap-flash",
+       .id             = -1,
+       .resource       = &z2_flash_resource,
+       .num_resources  = 1,
+       .dev = {
+               .platform_data  = &z2_flash_data,
+       },
+};
+
+static void __init z2_nor_init(void)
+{
+       platform_device_register(&z2_flash);
+}
+#else
+static inline void z2_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct platform_pwm_backlight_data z2_backlight_data[] = {
+       [0] = {
+               /* Keypad Backlight */
+               .pwm_id         = 1,
+               .max_brightness = 1023,
+               .dft_brightness = 512,
+               .pwm_period_ns  = 1260320,
+       },
+       [1] = {
+               /* LCD Backlight */
+               .pwm_id         = 2,
+               .max_brightness = 1023,
+               .dft_brightness = 512,
+               .pwm_period_ns  = 1260320,
+       },
+};
+
+static struct platform_device z2_backlight_devices[2] = {
+       {
+               .name   = "pwm-backlight",
+               .id     = 0,
+               .dev    = {
+                       .platform_data  = &z2_backlight_data[1],
+               },
+       },
+       {
+               .name   = "pwm-backlight",
+               .id     = 1,
+               .dev    = {
+                       .platform_data  = &z2_backlight_data[0],
+               },
+       },
+};
+static void __init z2_pwm_init(void)
+{
+       platform_device_register(&z2_backlight_devices[0]);
+       platform_device_register(&z2_backlight_devices[1]);
+}
+#else
+static inline void z2_pwm_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info z2_lcd_modes[] = {
+{
+       .pixclock       = 192000,
+       .xres           = 240,
+       .yres           = 320,
+       .bpp            = 16,
+
+       .left_margin    = 4,
+       .right_margin   = 8,
+       .upper_margin   = 4,
+       .lower_margin   = 8,
+
+       .hsync_len      = 4,
+       .vsync_len      = 4,
+},
+};
+
+static struct pxafb_mach_info z2_lcd_screen = {
+       .modes          = z2_lcd_modes,
+       .num_modes      = ARRAY_SIZE(z2_lcd_modes),
+       .lcd_conn       = LCD_COLOR_TFT_16BPP | LCD_BIAS_ACTIVE_LOW |
+                         LCD_ALTERNATE_MAPPING,
+};
+
+static void __init z2_lcd_init(void)
+{
+       set_pxa_fb_info(&z2_lcd_screen);
+}
+#else
+static inline void z2_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data z2_mci_platform_data = {
+       .ocr_mask               = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .gpio_card_detect       = GPIO96_ZIPITZ2_SD_DETECT,
+       .gpio_power             = -1,
+       .gpio_card_ro           = -1,
+       .detect_delay_ms        = 200,
+};
+
+static void __init z2_mmc_init(void)
+{
+       pxa_set_mci_info(&z2_mci_platform_data);
+}
+#else
+static inline void z2_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led z2_gpio_leds[] = {
+{
+       .name                   = "z2:green:wifi",
+       .default_trigger        = "none",
+       .gpio                   = GPIO10_ZIPITZ2_LED_WIFI,
+       .active_low             = 1,
+}, {
+       .name                   = "z2:green:charged",
+       .default_trigger        = "none",
+       .gpio                   = GPIO85_ZIPITZ2_LED_CHARGED,
+       .active_low             = 1,
+}, {
+       .name                   = "z2:amber:charging",
+       .default_trigger        = "none",
+       .gpio                   = GPIO83_ZIPITZ2_LED_CHARGING,
+       .active_low             = 1,
+},
+};
+
+static struct gpio_led_platform_data z2_gpio_led_info = {
+       .leds           = z2_gpio_leds,
+       .num_leds       = ARRAY_SIZE(z2_gpio_leds),
+};
+
+static struct platform_device z2_leds = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &z2_gpio_led_info,
+       }
+};
+
+static void __init z2_leds_init(void)
+{
+       platform_device_register(&z2_leds);
+}
+#else
+static inline void z2_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int z2_matrix_keys[] = {
+       KEY(0, 0, KEY_OPTION),
+       KEY(1, 0, KEY_UP),
+       KEY(2, 0, KEY_DOWN),
+       KEY(3, 0, KEY_LEFT),
+       KEY(4, 0, KEY_RIGHT),
+       KEY(5, 0, KEY_END),
+       KEY(6, 0, KEY_KPPLUS),
+
+       KEY(0, 1, KEY_HOME),
+       KEY(1, 1, KEY_Q),
+       KEY(2, 1, KEY_I),
+       KEY(3, 1, KEY_G),
+       KEY(4, 1, KEY_X),
+       KEY(5, 1, KEY_ENTER),
+       KEY(6, 1, KEY_KPMINUS),
+
+       KEY(0, 2, KEY_PAGEUP),
+       KEY(1, 2, KEY_W),
+       KEY(2, 2, KEY_O),
+       KEY(3, 2, KEY_H),
+       KEY(4, 2, KEY_C),
+       KEY(5, 2, KEY_LEFTALT),
+
+       KEY(0, 3, KEY_PAGEDOWN),
+       KEY(1, 3, KEY_E),
+       KEY(2, 3, KEY_P),
+       KEY(3, 3, KEY_J),
+       KEY(4, 3, KEY_V),
+       KEY(5, 3, KEY_LEFTSHIFT),
+
+       KEY(0, 4, KEY_ESC),
+       KEY(1, 4, KEY_R),
+       KEY(2, 4, KEY_A),
+       KEY(3, 4, KEY_K),
+       KEY(4, 4, KEY_B),
+       KEY(5, 4, KEY_LEFTCTRL),
+
+       KEY(0, 5, KEY_TAB),
+       KEY(1, 5, KEY_T),
+       KEY(2, 5, KEY_S),
+       KEY(3, 5, KEY_L),
+       KEY(4, 5, KEY_N),
+       KEY(5, 5, KEY_SPACE),
+
+       KEY(0, 6, KEY_STOPCD),
+       KEY(1, 6, KEY_Y),
+       KEY(2, 6, KEY_D),
+       KEY(3, 6, KEY_BACKSPACE),
+       KEY(4, 6, KEY_M),
+       KEY(5, 6, KEY_COMMA),
+
+       KEY(0, 7, KEY_PLAYCD),
+       KEY(1, 7, KEY_U),
+       KEY(2, 7, KEY_F),
+       KEY(3, 7, KEY_Z),
+       KEY(4, 7, KEY_SEMICOLON),
+       KEY(5, 7, KEY_DOT),
+};
+
+static struct pxa27x_keypad_platform_data z2_keypad_platform_data = {
+       .matrix_key_rows        = 7,
+       .matrix_key_cols        = 8,
+       .matrix_key_map         = z2_matrix_keys,
+       .matrix_key_map_size    = ARRAY_SIZE(z2_matrix_keys),
+
+       .debounce_interval      = 30,
+};
+
+static void __init z2_mkp_init(void)
+{
+       pxa_set_keypad_info(&z2_keypad_platform_data);
+}
+#else
+static inline void z2_mkp_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button z2_pxa_buttons[] = {
+       {KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" },
+       {KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" },
+};
+
+static struct gpio_keys_platform_data z2_pxa_keys_data = {
+       .buttons        = z2_pxa_buttons,
+       .nbuttons       = ARRAY_SIZE(z2_pxa_buttons),
+};
+
+static struct platform_device z2_pxa_keys = {
+       .name   = "gpio-keys",
+       .id     = -1,
+       .dev    = {
+               .platform_data = &z2_pxa_keys_data,
+       },
+};
+
+static void __init z2_keys_init(void)
+{
+       platform_device_register(&z2_pxa_keys);
+}
+#else
+static inline void z2_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * SSP Devices - WiFi and LCD control
+ ******************************************************************************/
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+/* WiFi */
+static int z2_lbs_spi_setup(struct spi_device *spi)
+{
+       int ret = 0;
+
+       ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power");
+       if (ret)
+               goto err;
+
+       ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1);
+       if (ret)
+               goto err2;
+
+       ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset");
+       if (ret)
+               goto err2;
+
+       ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0);
+       if (ret)
+               goto err3;
+
+       /* Reset the card */
+       mdelay(180);
+       gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1);
+       mdelay(20);
+
+       spi->bits_per_word = 16;
+       spi->mode = SPI_MODE_2,
+
+       spi_setup(spi);
+
+       return 0;
+
+err3:
+       gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
+err2:
+       gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+err:
+       return ret;
+};
+
+static int z2_lbs_spi_teardown(struct spi_device *spi)
+{
+       gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0);
+       gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0);
+       gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
+       gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+       return 0;
+
+};
+
+static struct pxa2xx_spi_chip z2_lbs_chip_info = {
+       .rx_threshold   = 8,
+       .tx_threshold   = 8,
+       .timeout        = 1000,
+       .gpio_cs        = GPIO24_ZIPITZ2_WIFI_CS,
+};
+
+static struct libertas_spi_platform_data z2_lbs_pdata = {
+       .use_dummy_writes       = 1,
+       .setup                  = z2_lbs_spi_setup,
+       .teardown               = z2_lbs_spi_teardown,
+};
+
+/* LCD */
+static struct pxa2xx_spi_chip lms283_chip_info = {
+       .rx_threshold   = 1,
+       .tx_threshold   = 1,
+       .timeout        = 64,
+       .gpio_cs        = GPIO88_ZIPITZ2_LCD_CS,
+};
+
+static const struct lms283gf05_pdata lms283_pdata = {
+       .reset_gpio     = GPIO19_ZIPITZ2_LCD_RESET,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+{
+       .modalias               = "libertas_spi",
+       .platform_data          = &z2_lbs_pdata,
+       .controller_data        = &z2_lbs_chip_info,
+       .irq                    = gpio_to_irq(GPIO36_ZIPITZ2_WIFI_IRQ),
+       .max_speed_hz           = 13000000,
+       .bus_num                = 1,
+       .chip_select            = 0,
+},
+{
+       .modalias               = "lms283gf05",
+       .controller_data        = &lms283_chip_info,
+       .platform_data          = &lms283_pdata,
+       .max_speed_hz           = 400000,
+       .bus_num                = 2,
+       .chip_select            = 0,
+},
+};
+
+static struct pxa2xx_spi_master pxa_ssp1_master_info = {
+       .clock_enable   = CKEN_SSP,
+       .num_chipselect = 1,
+       .enable_dma     = 1,
+};
+
+static struct pxa2xx_spi_master pxa_ssp2_master_info = {
+       .clock_enable   = CKEN_SSP2,
+       .num_chipselect = 1,
+};
+
+static void __init z2_spi_init(void)
+{
+       pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
+       pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+#else
+static inline void z2_spi_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init z2_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(z2_pin_config));
+
+       z2_lcd_init();
+       z2_mmc_init();
+       z2_mkp_init();
+
+       pxa_set_i2c_info(NULL);
+
+       z2_spi_init();
+       z2_nor_init();
+       z2_pwm_init();
+       z2_leds_init();
+       z2_keys_init();
+}
+
+MACHINE_START(ZIPIT2, "Zipit Z2")
+       .phys_io        = 0x40000000,
+       .boot_params    = 0xa0000100,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = z2_init,
+MACHINE_END
index 39896d8..3680f6a 100644 (file)
@@ -644,7 +644,7 @@ static struct pxafb_mach_info zeus_fb_info = {
 
 static struct pxamci_platform_data zeus_mci_platform_data = {
        .ocr_mask               = MMC_VDD_32_33|MMC_VDD_33_34,
-       .detect_delay           = HZ/4,
+       .detect_delay_ms        = 250,
        .gpio_card_detect       = ZEUS_MMC_CD_GPIO,
        .gpio_card_ro           = ZEUS_MMC_WP_GPIO,
        .gpio_card_ro_invert    = 1,
index 2b4043c..c479cbe 100644 (file)
@@ -218,7 +218,7 @@ static inline void zylonite_init_lcd(void) {}
 
 #if defined(CONFIG_MMC)
 static struct pxamci_platform_data zylonite_mci_platform_data = {
-       .detect_delay   = 20,
+       .detect_delay_ms= 200,
        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
        .gpio_card_detect = EXT_GPIO(0),
        .gpio_card_ro   = EXT_GPIO(2),
@@ -226,7 +226,7 @@ static struct pxamci_platform_data zylonite_mci_platform_data = {
 };
 
 static struct pxamci_platform_data zylonite_mci2_platform_data = {
-       .detect_delay   = 20,
+       .detect_delay_ms= 200,
        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
        .gpio_card_detect = EXT_GPIO(1),
        .gpio_card_ro   = EXT_GPIO(3),
@@ -234,7 +234,7 @@ static struct pxamci_platform_data zylonite_mci2_platform_data = {
 };
 
 static struct pxamci_platform_data zylonite_mci3_platform_data = {
-       .detect_delay   = 20,
+       .detect_delay_ms= 200,
        .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
        .gpio_card_detect = EXT_GPIO(30),
        .gpio_card_ro   = EXT_GPIO(31),
index e704edb..a01b76b 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                                  := core.o clock.o
+obj-y                                  := core.o
 obj-$(CONFIG_MACH_REALVIEW_EB)         += realview_eb.o
 obj-$(CONFIG_MACH_REALVIEW_PB11MP)     += realview_pb11mp.o
 obj-$(CONFIG_MACH_REALVIEW_PB1176)     += realview_pb1176.o
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
deleted file mode 100644 (file)
index a704311..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/clock.c
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/hardware/icst307.h>
-
-#include "clock.h"
-
-int clk_enable(struct clk *clk)
-{
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       struct icst307_vco vco;
-       vco = icst307_khz_to_vco(clk->params, rate / 1000);
-       return icst307_khz(clk->params, vco) * 1000;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       int ret = -EIO;
-
-       if (clk->setvco) {
-               struct icst307_vco vco;
-
-               vco = icst307_khz_to_vco(clk->params, rate / 1000);
-               clk->rate = icst307_khz(clk->params, vco) * 1000;
-               clk->setvco(clk, vco);
-               ret = 0;
-       }
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
deleted file mode 100644 (file)
index ebbb0f0..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- *  linux/arch/arm/mach-realview/clock.h
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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.
- */
-struct module;
-struct icst307_params;
-
-struct clk {
-       unsigned long           rate;
-       const struct icst307_params *params;
-       void                    *data;
-       void                    (*setvco)(struct clk *, struct icst307_vco vco);
-};
index f2dbce5..595be19 100644 (file)
@@ -25,8 +25,6 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 #include <linux/ata_platform.h>
@@ -40,7 +38,7 @@
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst307.h>
+#include <asm/hardware/icst.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
 #include <asm/hardware/gic.h>
 
+#include <mach/clkdev.h>
 #include <mach/platform.h>
 #include <mach/irqs.h>
+#include <plat/timer-sp.h>
 
 #include "core.h"
-#include "clock.h"
-
-#define REALVIEW_REFCOUNTER    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
 
 /* used by entry-macro.S and platsmp.c */
 void __iomem *gic_cpu_base_addr;
@@ -79,20 +76,6 @@ void __init realview_adjust_zones(int node, unsigned long *size,
 }
 #endif
 
-/*
- * This is the RealView sched_clock implementation.  This has
- * a resolution of 41.7ns, and a maximum value of about 179s.
- */
-unsigned long long sched_clock(void)
-{
-       unsigned long long v;
-
-       v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
-       do_div(v, 3);
-
-       return v;
-}
-
 
 #define REALVIEW_FLASHCTRL    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
 
@@ -254,7 +237,7 @@ static unsigned int realview_mmc_status(struct device *dev)
        else
                mask = 2;
 
-       return readl(REALVIEW_SYSMCI) & mask;
+       return !(readl(REALVIEW_SYSMCI) & mask);
 }
 
 struct mmci_platform_data realview_mmc0_plat_data = {
@@ -274,37 +257,40 @@ struct mmci_platform_data realview_mmc1_plat_data = {
 /*
  * Clock handling
  */
-static const struct icst307_params realview_oscvco_params = {
-       .ref            = 24000,
-       .vco_max        = 200000,
+static const struct icst_params realview_oscvco_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST307_VCO_MAX,
+       .vco_min        = ICST307_VCO_MIN,
        .vd_min         = 4 + 8,
        .vd_max         = 511 + 8,
        .rd_min         = 1 + 2,
        .rd_max         = 127 + 2,
+       .s2div          = icst307_s2div,
+       .idx2s          = icst307_idx2s,
 };
 
-static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
+static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
 {
        void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
-       void __iomem *sys_osc;
        u32 val;
 
-       if (machine_is_realview_pb1176())
-               sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
-       else
-               sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
-
-       val = readl(sys_osc) & ~0x7ffff;
+       val = readl(clk->vcoreg) & ~0x7ffff;
        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
        writel(0xa05f, sys_lock);
-       writel(val, sys_osc);
+       writel(val, clk->vcoreg);
        writel(0, sys_lock);
 }
 
+static const struct clk_ops oscvco_clk_ops = {
+       .round  = icst_clk_round,
+       .set    = icst_clk_set,
+       .setvco = realview_oscvco_set,
+};
+
 static struct clk oscvco_clk = {
+       .ops    = &oscvco_clk_ops,
        .params = &realview_oscvco_params,
-       .setvco = realview_oscvco_set,
 };
 
 /*
@@ -347,7 +333,13 @@ static struct clk_lookup lookups[] = {
 
 static int __init clk_init(void)
 {
+       if (machine_is_realview_pb1176())
+               oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC0_OFFSET;
+       else
+               oscvco_clk.vcoreg = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
+
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        return 0;
 }
 arch_initcall(clk_init);
@@ -643,133 +635,6 @@ void __iomem *timer1_va_base;
 void __iomem *timer2_va_base;
 void __iomem *timer3_va_base;
 
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV256)
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 4)           /* Divide by 16 */
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV16)
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD   (TIMER_INTERVAL)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV1)
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *clk)
-{
-       unsigned long ctrl;
-
-       switch(mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               writel(TIMER_RELOAD, timer0_va_base + TIMER_LOAD);
-
-               ctrl = TIMER_CTRL_PERIODIC;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* period set, and timer enabled in 'next_event' hook */
-               ctrl = TIMER_CTRL_ONESHOT;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       default:
-               ctrl = 0;
-       }
-
-       writel(ctrl, timer0_va_base + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-                               struct clock_event_device *unused)
-{
-       unsigned long ctrl = readl(timer0_va_base + TIMER_CTRL);
-
-       writel(evt, timer0_va_base + TIMER_LOAD);
-       writel(ctrl | TIMER_CTRL_ENABLE, timer0_va_base + TIMER_CTRL);
-
-       return 0;
-}
-
-static struct clock_event_device timer0_clockevent =    {
-       .name           = "timer0",
-       .shift          = 32,
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = timer_set_mode,
-       .set_next_event = timer_set_next_event,
-       .rating         = 300,
-       .cpumask        = cpu_all_mask,
-};
-
-static void __init realview_clockevents_init(unsigned int timer_irq)
-{
-       timer0_clockevent.irq = timer_irq;
-       timer0_clockevent.mult =
-               div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-       timer0_clockevent.max_delta_ns =
-               clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-       timer0_clockevent.min_delta_ns =
-               clockevent_delta2ns(0xf, &timer0_clockevent);
-
-       clockevents_register_device(&timer0_clockevent);
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &timer0_clockevent;
-
-       /* clear the interrupt */
-       writel(1, timer0_va_base + TIMER_INTCLR);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction realview_timer_irq = {
-       .name           = "RealView Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = realview_timer_interrupt,
-};
-
-static cycle_t realview_get_cycles(struct clocksource *cs)
-{
-       return ~readl(timer3_va_base + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_realview = {
-       .name   = "timer3",
-       .rating = 200,
-       .read   = realview_get_cycles,
-       .mask   = CLOCKSOURCE_MASK(32),
-       .shift  = 20,
-       .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static void __init realview_clocksource_init(void)
-{
-       /* setup timer 0 as free-running clocksource */
-       writel(0, timer3_va_base + TIMER_CTRL);
-       writel(0xffffffff, timer3_va_base + TIMER_LOAD);
-       writel(0xffffffff, timer3_va_base + TIMER_VALUE);
-       writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-               timer3_va_base + TIMER_CTRL);
-
-       clocksource_realview.mult =
-               clocksource_khz2mult(1000, clocksource_realview.shift);
-       clocksource_register(&clocksource_realview);
-}
-
 /*
  * Set up the clock source and clock events devices
  */
@@ -797,13 +662,8 @@ void __init realview_timer_init(unsigned int timer_irq)
        writel(0, timer2_va_base + TIMER_CTRL);
        writel(0, timer3_va_base + TIMER_CTRL);
 
-       /* 
-        * Make irqs happen for the system timer
-        */
-       setup_irq(timer_irq, &realview_timer_irq);
-
-       realview_clocksource_init();
-       realview_clockevents_init(timer_irq);
+       sp804_clocksource_init(timer3_va_base);
+       sp804_clockevents_init(timer0_va_base, timer_irq);
 }
 
 /*
index be048e3..f95521a 100644 (file)
@@ -131,7 +131,7 @@ void platform_cpu_die(unsigned int cpu)
        cpu_leave_lowpower();
 }
 
-int mach_cpu_disable(unsigned int cpu)
+int platform_cpu_disable(unsigned int cpu)
 {
        /*
         * we don't allow CPU 0 to be shutdown (it is still too special
index 04b37a8..e58d077 100644 (file)
@@ -1,6 +1,15 @@
 #ifndef __ASM_MACH_CLKDEV_H
 #define __ASM_MACH_CLKDEV_H
 
+#include <plat/clock.h>
+
+struct clk {
+       unsigned long           rate;
+       const struct clk_ops    *ops;
+       const struct icst_params *params;
+       void __iomem            *vcoreg;
+};
+
 #define __clk_get(clk) ({ 1; })
 #define __clk_put(clk) do { } while (0)
 
index 2410d4f..830055b 100644 (file)
@@ -31,6 +31,7 @@
 #define IRQ_DC1176_SOFTINT     (IRQ_DC1176_GIC_START + 1)      /* Software interrupt */
 #define IRQ_DC1176_COMMRx      (IRQ_DC1176_GIC_START + 2)      /* Debug Comm Rx interrupt */
 #define IRQ_DC1176_COMMTx      (IRQ_DC1176_GIC_START + 3)      /* Debug Comm Tx interrupt */
+#define IRQ_DC1176_CORE_PMU    (IRQ_DC1176_GIC_START + 7)      /* Core PMU interrupt */
 #define IRQ_DC1176_TIMER0      (IRQ_DC1176_GIC_START + 8)      /* Timer 0 */
 #define IRQ_DC1176_TIMER1      (IRQ_DC1176_GIC_START + 9)      /* Timer 1 */
 #define IRQ_DC1176_TIMER2      (IRQ_DC1176_GIC_START + 10)     /* Timer 2 */
index 86792a9..4a88a4e 100644 (file)
 
 #define IRQ_PBA8_GIC_START                     32
 
-/* L220
-#define IRQ_PBA8_L220_EVENT    (IRQ_PBA8_GIC_START + 29)
-#define IRQ_PBA8_L220_SLAVE    (IRQ_PBA8_GIC_START + 30)
-#define IRQ_PBA8_L220_DECODE   (IRQ_PBA8_GIC_START + 31)
-*/
-
 /*
  * PB-A8 on-board gic irq sources
  */
@@ -65,6 +59,8 @@
 #define IRQ_PBA8_TSPEN         (IRQ_PBA8_GIC_START + 30)       /* Touchscreen pen */
 #define IRQ_PBA8_TSKPAD                (IRQ_PBA8_GIC_START + 31)       /* Touchscreen keypad */
 
+#define IRQ_PBA8_PMU           (IRQ_PBA8_GIC_START + 47)       /* Cortex-A8 PMU */
+
 /* ... */
 #define IRQ_PBA8_PCI0          (IRQ_PBA8_GIC_START + 50)
 #define IRQ_PBA8_PCI1          (IRQ_PBA8_GIC_START + 51)
index deaad43..206a300 100644 (file)
 
 #define IRQ_PBX_GIC_START                      32
 
-/* L220
-#define IRQ_PBX_L220_EVENT     (IRQ_PBX_GIC_START + 29)
-#define IRQ_PBX_L220_SLAVE     (IRQ_PBX_GIC_START + 30)
-#define IRQ_PBX_L220_DECODE    (IRQ_PBX_GIC_START + 31)
-*/
-
 /*
  * PBX on-board gic irq sources
  */
 #define IRQ_PBX_TIMER4_5        (IRQ_PBX_GIC_START + 41)        /* Timer 0/1 (default timer) */
 #define IRQ_PBX_TIMER6_7        (IRQ_PBX_GIC_START + 42)        /* Timer 2/3 */
 /* ... */
-#define IRQ_PBX_PMU_CPU3        (IRQ_PBX_GIC_START + 44)        /* CPU PMU Interrupts */
-#define IRQ_PBX_PMU_CPU2        (IRQ_PBX_GIC_START + 45)
-#define IRQ_PBX_PMU_CPU1        (IRQ_PBX_GIC_START + 46)
-#define IRQ_PBX_PMU_CPU0        (IRQ_PBX_GIC_START + 47)
+#define IRQ_PBX_PMU_CPU0        (IRQ_PBX_GIC_START + 44)        /* CPU PMU Interrupts */
+#define IRQ_PBX_PMU_CPU1        (IRQ_PBX_GIC_START + 45)
+#define IRQ_PBX_PMU_CPU2        (IRQ_PBX_GIC_START + 46)
+#define IRQ_PBX_PMU_CPU3        (IRQ_PBX_GIC_START + 47)
 
 /* ... */
 #define IRQ_PBX_PCI0           (IRQ_PBX_GIC_START + 50)
index 86c0c44..1b77a27 100644 (file)
 #define REALVIEW_INTREG_OFFSET         0x8     /* Interrupt control */
 #define REALVIEW_DECODE_OFFSET         0xC     /* Fitted logic modules */
 
-/* 
- *  Clean base - dummy
- * 
- */
-#define CLEAN_BASE                      REALVIEW_BOOT_ROM_HI
-
 /*
  * System controller bit assignment
  */
 #define REALVIEW_TIMER4_EnSel  21
 
 
-#define MAX_TIMER                       2
-#define MAX_PERIOD                      699050
-#define TICKS_PER_uSEC                  1
-
-/* 
- *  These are useconds NOT ticks.  
- * 
- */
-#define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
-#define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
-
 #define REALVIEW_CSR_BASE             0x10000000
 #define REALVIEW_CSR_SIZE             0x10000000
 
index 7d857d3..422ccd7 100644 (file)
@@ -31,8 +31,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/localtimer.h>
 
@@ -44,7 +44,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_eb_io_desc[] __initdata = {
        {
@@ -294,6 +293,36 @@ static struct resource realview_eb_isp1761_resources[] = {
        },
 };
 
+static struct resource pmu_resources[] = {
+       [0] = {
+               .start          = IRQ_EB11MP_PMU_CPU0,
+               .end            = IRQ_EB11MP_PMU_CPU0,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start          = IRQ_EB11MP_PMU_CPU1,
+               .end            = IRQ_EB11MP_PMU_CPU1,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start          = IRQ_EB11MP_PMU_CPU2,
+               .end            = IRQ_EB11MP_PMU_CPU2,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start          = IRQ_EB11MP_PMU_CPU3,
+               .end            = IRQ_EB11MP_PMU_CPU3,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device pmu_device = {
+       .name                   = "arm-pmu",
+       .id                     = ARM_PMU_DEVICE_CPU,
+       .num_resources          = ARRAY_SIZE(pmu_resources),
+       .resource               = pmu_resources,
+};
+
 static void __init gic_init_irq(void)
 {
        if (core_tile_eb11mp() || core_tile_a9mp()) {
@@ -407,6 +436,7 @@ static void __init realview_eb_init(void)
                 * Bits:  .... ...0 0111 1001 0000 .... .... .... */
                l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
 #endif
+               platform_device_register(&pmu_device);
        }
 
        realview_flash_register(&realview_eb_flash_resource, 1);
index 44392e5..96568eb 100644 (file)
@@ -31,8 +31,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 #include <asm/hardware/cache-l2x0.h>
 
 #include <asm/mach/arch.h>
@@ -44,7 +44,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_pb1176_io_desc[] __initdata = {
        {
@@ -263,6 +262,19 @@ static struct resource realview_pb1176_isp1761_resources[] = {
        },
 };
 
+static struct resource pmu_resource = {
+       .start          = IRQ_DC1176_CORE_PMU,
+       .end            = IRQ_DC1176_CORE_PMU,
+       .flags          = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+       .name                   = "arm-pmu",
+       .id                     = ARM_PMU_DEVICE_CPU,
+       .num_resources          = 1,
+       .resource               = &pmu_resource,
+};
+
 static void __init gic_init_irq(void)
 {
        /* ARM1176 DevChip GIC, primary */
@@ -324,6 +336,7 @@ static void __init realview_pb1176_init(void)
        realview_eth_register(NULL, realview_pb1176_smsc911x_resources);
        platform_device_register(&realview_i2c_device);
        realview_usb_register(realview_pb1176_isp1761_resources);
+       platform_device_register(&pmu_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index 3e02731..7fbefbb 100644 (file)
@@ -31,8 +31,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/localtimer.h>
 
@@ -45,7 +45,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_pb11mp_io_desc[] __initdata = {
        {
@@ -260,6 +259,36 @@ static struct resource realview_pb11mp_isp1761_resources[] = {
        },
 };
 
+static struct resource pmu_resources[] = {
+       [0] = {
+               .start          = IRQ_TC11MP_PMU_CPU0,
+               .end            = IRQ_TC11MP_PMU_CPU0,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start          = IRQ_TC11MP_PMU_CPU1,
+               .end            = IRQ_TC11MP_PMU_CPU1,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start          = IRQ_TC11MP_PMU_CPU2,
+               .end            = IRQ_TC11MP_PMU_CPU2,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start          = IRQ_TC11MP_PMU_CPU3,
+               .end            = IRQ_TC11MP_PMU_CPU3,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device pmu_device = {
+       .name                   = "arm-pmu",
+       .id                     = ARM_PMU_DEVICE_CPU,
+       .num_resources          = ARRAY_SIZE(pmu_resources),
+       .resource               = pmu_resources,
+};
+
 static void __init gic_init_irq(void)
 {
        unsigned int pldctrl;
@@ -329,6 +358,7 @@ static void __init realview_pb11mp_init(void)
        platform_device_register(&realview_i2c_device);
        platform_device_register(&realview_cf_device);
        realview_usb_register(realview_pb11mp_isp1761_resources);
+       platform_device_register(&pmu_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index fe4e25c..d3c113b 100644 (file)
@@ -30,8 +30,8 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/icst307.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -42,7 +42,6 @@
 #include <mach/irqs.h>
 
 #include "core.h"
-#include "clock.h"
 
 static struct map_desc realview_pba8_io_desc[] __initdata = {
        {
@@ -250,6 +249,19 @@ static struct resource realview_pba8_isp1761_resources[] = {
        },
 };
 
+static struct resource pmu_resource = {
+       .start          = IRQ_PBA8_PMU,
+       .end            = IRQ_PBA8_PMU,
+       .flags          = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+       .name                   = "arm-pmu",
+       .id                     = ARM_PMU_DEVICE_CPU,
+       .num_resources          = 1,
+       .resource               = &pmu_resource,
+};
+
 static void __init gic_init_irq(void)
 {
        /* ARM PB-A8 on-board GIC */
@@ -296,6 +308,7 @@ static void __init realview_pba8_init(void)
        platform_device_register(&realview_i2c_device);
        platform_device_register(&realview_cf_device);
        realview_usb_register(realview_pba8_isp1761_resources);
+       platform_device_register(&pmu_device);
 
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
                struct amba_device *d = amba_devs[i];
index d94857e..a235ba3 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/mach-types.h>
+#include <asm/pmu.h>
 #include <asm/smp_twd.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -270,6 +271,36 @@ static struct resource realview_pbx_isp1761_resources[] = {
        },
 };
 
+static struct resource pmu_resources[] = {
+       [0] = {
+               .start          = IRQ_PBX_PMU_CPU0,
+               .end            = IRQ_PBX_PMU_CPU0,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start          = IRQ_PBX_PMU_CPU1,
+               .end            = IRQ_PBX_PMU_CPU1,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start          = IRQ_PBX_PMU_CPU2,
+               .end            = IRQ_PBX_PMU_CPU2,
+               .flags          = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start          = IRQ_PBX_PMU_CPU3,
+               .end            = IRQ_PBX_PMU_CPU3,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device pmu_device = {
+       .name                   = "arm-pmu",
+       .id                     = ARM_PMU_DEVICE_CPU,
+       .num_resources          = ARRAY_SIZE(pmu_resources),
+       .resource               = pmu_resources,
+};
+
 static void __init gic_init_irq(void)
 {
        /* ARM PBX on-board GIC */
@@ -354,6 +385,7 @@ static void __init realview_pbx_init(void)
                /* 16KB way size, 8-way associativity, parity disabled
                 * Bits:  .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
                l2x0_init(l2x0_base, 0x02520000, 0xc0000fff);
+               platform_device_register(&pmu_device);
        }
 #endif
 
index 5547318..7245a55 100644 (file)
@@ -6,6 +6,7 @@ config CPU_S3C2410
        bool
        depends on ARCH_S3C2410
        select CPU_ARM920T
+       select S3C_GPIO_PULL_UP
        select S3C2410_CLOCK
        select S3C2410_GPIO
        select CPU_LLSERIAL_S3C2410
@@ -76,6 +77,7 @@ config ARCH_H1940
        select PM_H1940 if PM
        select S3C_DEV_USB_HOST
        select S3C_DEV_NAND
+       select S3C2410_SETUP_TS
        help
          Say Y here if you are using the HP IPAQ H1940
 
@@ -95,12 +97,19 @@ config PM_H1940
 config MACH_N30
        bool "Acer N30 family"
        select CPU_S3C2410
+       select MACH_N35
        select S3C_DEV_USB_HOST
        select S3C_DEV_NAND
        help
          Say Y here if you want suppt for the Acer N30, Acer N35,
          Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
 
+config MACH_N35
+       bool
+       help
+         Internal node in order to enable support for Acer N35 if Acer N30 is
+         selected.
+
 config ARCH_BAST
        bool "Simtec Electronics BAST (EB2410ITX)"
        select CPU_S3C2410
@@ -110,6 +119,7 @@ config ARCH_BAST
        select MACH_BAST_IDE
        select S3C24XX_DCLK
        select ISA
+       select S3C_DEV_HWMON
        select S3C_DEV_USB_HOST
        select S3C_DEV_NAND
        help
index 7dab2a0..58c1dd7 100644 (file)
@@ -1,3 +1,7 @@
-   zreladdr-y  := 0x30008000
-params_phys-y  := 0x30000100
-
+ifeq ($(CONFIG_PM_H1940),y)
+       zreladdr-y              := 0x30108000
+       params_phys-y   := 0x30100100
+else
+       zreladdr-y              := 0x30008000
+       params_phys-y   := 0x30000100
+endif
index a3f3c7b..8cdeb14 100644 (file)
@@ -33,14 +33,15 @@ static void h1940bt_enable(int on)
                h1940_latch_control(0, H1940_LATCH_BLUETOOTH_POWER);
                /* Reset the chip */
                mdelay(10);
-               s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
+
+               gpio_set_value(S3C2410_GPH(1), 1);
                mdelay(10);
-               s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
+               gpio_set_value(S3C2410_GPH(1), 0);
        }
        else {
-               s3c2410_gpio_setpin(S3C2410_GPH(1), 1);
+               gpio_set_value(S3C2410_GPH(1), 1);
                mdelay(10);
-               s3c2410_gpio_setpin(S3C2410_GPH(1), 0);
+               gpio_set_value(S3C2410_GPH(1), 0);
                mdelay(10);
                h1940_latch_control(H1940_LATCH_BLUETOOTH_POWER, 0);
        }
@@ -61,15 +62,21 @@ static int __devinit h1940bt_probe(struct platform_device *pdev)
        struct rfkill *rfk;
        int ret = 0;
 
+       ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
+       if (ret) {
+               dev_err(&pdev->dev, "could not get GPH1\n");\
+               return ret;
+       }
+
        /* Configures BT serial port GPIOs */
-       s3c2410_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
-       s3c2410_gpio_pullup(S3C2410_GPH(0), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_pullup(S3C2410_GPH(1), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
-       s3c2410_gpio_pullup(S3C2410_GPH(2), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
-       s3c2410_gpio_pullup(S3C2410_GPH(3), 1);
+       s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
+       s3c_gpio_cfgpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
+       s3c_gpio_cfgpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
+       s3c_gpio_cfgpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
 
 
        rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
@@ -100,6 +107,7 @@ static int h1940bt_remove(struct platform_device *pdev)
        struct rfkill *rfk = platform_get_drvdata(pdev);
 
        platform_set_drvdata(pdev, NULL);
+       gpio_free(S3C2410_GPH(1));
 
        if (rfk) {
                rfkill_unregister(rfk);
index 08ac5f9..cf68136 100644 (file)
@@ -54,7 +54,7 @@ enum dma_ch {
 #define DMACH_LOW_LEVEL        (1<<28) /* use this to specifiy hardware ch no */
 
 /* we have 4 dma channels */
-#ifndef CONFIG_CPU_S3C2443
+#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
 #define S3C_DMA_CHANNELS               (4)
 #else
 #define S3C_DMA_CHANNELS               (6)
index 035a493..f453c4f 100644 (file)
  * published by the Free Software Foundation.
 */
 
+#ifndef __MACH_GPIO_FNS_H
+#define __MACH_GPIO_FNS_H __FILE__
+
 /* These functions are in the to-be-removed category and it is strongly
  * encouraged not to use these in new code. They will be marked deprecated
  * very soon.
  *
  * Most of the functionality can be either replaced by the gpiocfg calls
  * for the s3c platform or by the generic GPIOlib API.
+ *
+ * As of 2.6.35-rc, these will be removed, with the few drivers using them
+ * either replaced or given a wrapper until the calls can be removed.
 */
 
+#include <plat/gpio-cfg.h>
+
+static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
+{
+       /* 1:1 mapping between cfgpin and setcfg calls at the moment */
+       s3c_gpio_cfgpin(pin, cfg);
+}
+
 /* external functions for GPIO support
  *
  * These allow various different clients to access the same GPIO
  * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
 */
 
-/* s3c2410_gpio_cfgpin
- *
- * set the configuration of the given pin to the value passed.
- *
- * eg:
- *    s3c2410_gpio_cfgpin(S3C2410_GPA(0), S3C2410_GPA0_ADDR0);
- *    s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
-*/
-
-extern void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);
-
 extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
 
 /* s3c2410_gpio_getirq
@@ -71,6 +74,14 @@ extern int s3c2400_gpio_getirq(unsigned int pin);
 extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
                                  unsigned int config);
 
+/* s3c2410_gpio_pullup
+ *
+ * This call should be replaced with s3c_gpio_setpull().
+ *
+ * As a note, there is currently no distinction between pull-up and pull-down
+ * in the s3c24xx series devices with only an on/off configuration.
+ */
+
 /* s3c2410_gpio_pullup
  *
  * configure the pull-up control on the given pin
@@ -86,18 +97,8 @@ extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
 
 extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
 
-/* s3c2410_gpio_getpull
- *
- * Read the state of the pull-up on a given pin
- *
- * return:
- *     < 0 => error code
- *       0 => enabled
- *       1 => disabled
-*/
-
-extern int s3c2410_gpio_getpull(unsigned int pin);
-
 extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
 
 extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
+
+#endif /* __MACH_GPIO_FNS_H */
index 2edbb9c..4f7bf32 100644 (file)
 
 #define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
 
-#define S3C2410_GPIO_BANKA   (32*0)
-#define S3C2410_GPIO_BANKB   (32*1)
-#define S3C2410_GPIO_BANKC   (32*2)
-#define S3C2410_GPIO_BANKD   (32*3)
-#define S3C2410_GPIO_BANKE   (32*4)
-#define S3C2410_GPIO_BANKF   (32*5)
 #define S3C2410_GPIO_BANKG   (32*6)
 #define S3C2410_GPIO_BANKH   (32*7)
 
+/* GPIO sizes for various SoCs:
+ *
+ *             2442
+ *   2410 2412 2440 2443 2416
+ *   ---- ---- ---- ---- ----
+ * A 23   22   25   16   25
+ * B 11   11   11   11   9
+ * C 16   15   16   16   16
+ * D 16   16   16   16   16
+ * E 16   16   16   16   16
+ * F 8    8    8    8    8
+ * G 16   16   16   16   8
+ * H 11   11   9    15   15
+ * J --   --   13   16   --
+ * K --   --   --   --   16
+ * L --   --   --   15   7
+ * M --   --   --   2    2
+ */
+
 /* GPIO bank sizes */
 #define S3C2410_GPIO_A_NR      (32)
 #define S3C2410_GPIO_B_NR      (32)
 #define S3C2410_GPIO_F_NR      (32)
 #define S3C2410_GPIO_G_NR      (32)
 #define S3C2410_GPIO_H_NR      (32)
+#define S3C2410_GPIO_J_NR      (32)    /* technically 16. */
+#define S3C2410_GPIO_K_NR      (32)    /* technically 16. */
+#define S3C2410_GPIO_L_NR      (32)    /* technically 15. */
+#define S3C2410_GPIO_M_NR      (32)    /* technically 2. */
 
 #if CONFIG_S3C_GPIO_SPACE != 0
 #error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
@@ -53,6 +70,10 @@ enum s3c_gpio_number {
        S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
        S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
        S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
+       S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
+       S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
+       S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
+       S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
 };
 
 #endif /* __ASSEMBLY__ */
@@ -67,6 +88,10 @@ enum s3c_gpio_number {
 #define S3C2410_GPF(_nr)       (S3C2410_GPIO_F_START + (_nr))
 #define S3C2410_GPG(_nr)       (S3C2410_GPIO_G_START + (_nr))
 #define S3C2410_GPH(_nr)       (S3C2410_GPIO_H_START + (_nr))
+#define S3C2410_GPJ(_nr)       (S3C2410_GPIO_J_START + (_nr))
+#define S3C2410_GPK(_nr)       (S3C2410_GPIO_K_START + (_nr))
+#define S3C2410_GPL(_nr)       (S3C2410_GPIO_L_START + (_nr))
+#define S3C2410_GPM(_nr)       (S3C2410_GPIO_M_START + (_nr))
 
 /* compatibility until drivers can be modified */
 
index acb2591..d67819d 100644 (file)
@@ -23,11 +23,11 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
 {
        struct s3c_gpio_chip *chip;
 
-       if (pin > S3C2410_GPG(10))
+       if (pin > S3C_GPIO_END)
                return NULL;
 
        chip = &s3c24xx_gpios[pin/32];
-       return (S3C2410_GPIO_OFFSET(pin) < chip->chip.ngpio) ? chip : NULL;
+       return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
 }
 
 #endif /* __ASM_ARCH_GPIO_CORE_H */
index 15f0b3e..b649bf2 100644 (file)
  * devices that need GPIO.
  */
 
+#ifdef CONFIG_CPU_S3C244X
+#define ARCH_NR_GPIOS  (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
+#else
 #define ARCH_NR_GPIOS  (256 + CONFIG_S3C24XX_GPIO_EXTRA)
+#endif
 
 #include <asm-generic/gpio.h>
 #include <mach/gpio-nrs.h>
 #include <mach/gpio-fns.h>
 
+#ifdef CONFIG_CPU_S3C24XX
+#define S3C_GPIO_END   (S3C2410_GPIO_BANKJ + 32)
+#else
 #define S3C_GPIO_END   (S3C2410_GPIO_BANKH + 32)
+#endif
index 6c12c63..11bb0f0 100644 (file)
 #define IRQ_S3C2412_SDI                S3C2410_IRQSUB(13)
 #define IRQ_S3C2412_CF         S3C2410_IRQSUB(14)
 
+
+#define IRQ_S3C2416_EINT8t15   S3C2410_IRQ(5)
+#define IRQ_S3C2416_DMA                S3C2410_IRQ(17)
+#define IRQ_S3C2416_UART3      S3C2410_IRQ(18)
+#define IRQ_S3C2416_SDI1       S3C2410_IRQ(20)
+#define IRQ_S3C2416_SDI0       S3C2410_IRQ(21)
+
+#define IRQ_S3C2416_LCD2       S3C2410_IRQSUB(15)
+#define IRQ_S3C2416_LCD3       S3C2410_IRQSUB(16)
+#define IRQ_S3C2416_LCD4       S3C2410_IRQSUB(17)
+#define IRQ_S3C2416_DMA0       S3C2410_IRQSUB(18)
+#define IRQ_S3C2416_DMA1       S3C2410_IRQSUB(19)
+#define IRQ_S3C2416_DMA2       S3C2410_IRQSUB(20)
+#define IRQ_S3C2416_DMA3       S3C2410_IRQSUB(21)
+#define IRQ_S3C2416_DMA4       S3C2410_IRQSUB(22)
+#define IRQ_S3C2416_DMA5       S3C2410_IRQSUB(23)
+#define IRQ_S32416_WDT         S3C2410_IRQSUB(27)
+#define IRQ_S32416_AC97                S3C2410_IRQSUB(28)
+
+
 /* extra irqs for s3c2440 */
 
 #define IRQ_S3C2440_CAM_C      S3C2410_IRQSUB(11)      /* S3C2443 too */
 #define IRQ_S3C2443_HSMMC      S3C2410_IRQ(20)         /* IRQ_SDI */
 #define IRQ_S3C2443_NAND       S3C2410_IRQ(24)         /* reserved */
 
+#define IRQ_S3C2416_HSMMC0     S3C2410_IRQ(21)         /* S3C2416/S3C2450 */
+
 #define IRQ_HSMMC0             IRQ_S3C2443_HSMMC
+#define IRQ_HSMMC1             IRQ_S3C2416_HSMMC0
 
 #define IRQ_S3C2443_LCD1       S3C2410_IRQSUB(14)
 #define IRQ_S3C2443_LCD2       S3C2410_IRQSUB(15)
 #define IRQ_S3C2443_WDT                S3C2410_IRQSUB(27)
 #define IRQ_S3C2443_AC97       S3C2410_IRQSUB(28)
 
-#ifdef CONFIG_CPU_S3C2443
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
 #define NR_IRQS (IRQ_S3C2443_AC97+1)
 #else
 #define NR_IRQS (IRQ_S3C2440_AC97+1)
 #define IRQ_S3CUART_TX3                IRQ_S3C2443_TX3
 #define IRQ_S3CUART_ERR3       IRQ_S3C2443_ERR3
 
+#define IRQ_LCD_VSYNC          IRQ_S3C2443_LCD3
+#define IRQ_LCD_SYSTEM         IRQ_S3C2443_LCD2
+
 #ifdef CONFIG_CPU_S3C2440
 #define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
 #else
index b049e61..091c98a 100644 (file)
 #define S3C2440_PA_AC97           (0x5B000000)
 #define S3C2440_SZ_AC97           SZ_1M
 
-/* S3C2443 High-speed SD/MMC */
+/* S3C2443/S3C2416 High-speed SD/MMC */
 #define S3C2443_PA_HSMMC   (0x4A800000)
-#define S3C2443_SZ_HSMMC   (256)
+#define S3C2416_PA_HSMMC0  (0x4AC00000)
+
+#define        S3C2443_PA_FB   (0x4C800000)
 
 /* S3C2412 memory and IO controls */
 #define S3C2412_PA_SSMC        (0x4F000000)
 #define S3C24XX_PA_SDI      S3C2410_PA_SDI
 #define S3C24XX_PA_NAND            S3C2410_PA_NAND
 
+#define S3C_PA_FB          S3C2443_PA_FB
 #define S3C_PA_IIC          S3C2410_PA_IIC
 #define S3C_PA_UART        S3C24XX_PA_UART
 #define S3C_PA_USBHOST S3C2410_PA_USBHOST
 #define S3C_PA_HSMMC0      S3C2443_PA_HSMMC
+#define S3C_PA_HSMMC1      S3C2416_PA_HSMMC0
 #define S3C_PA_NAND        S3C24XX_PA_NAND
 
 #endif /* __ASM_ARCH_MAP_H */
index 9a0d169..3415b60 100644 (file)
 
 #endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
 
+#define S3C2416_CLKDIV2                S3C2410_CLKREG(0x28)
+
 #endif /* __ASM_ARM_REGS_CLOCK */
index 3c3853c..98fd4a0 100644 (file)
 #define S3C2412_DSC1      S3C2410_GPIOREG(0xe0)
 #endif
 
+#if defined(CONFIG_CPU_S3C2416)
+#define S3C2416_DSC0      S3C2410_GPIOREG(0xc0)
+#define S3C2416_DSC1      S3C2410_GPIOREG(0xc4)
+#define S3C2416_DSC2      S3C2410_GPIOREG(0xc8)
+#define S3C2416_DSC3      S3C2410_GPIOREG(0x110)
+
+#define S3C2416_SELECT_DSC0    (0 << 30)
+#define S3C2416_SELECT_DSC1    (1 << 30)
+#define S3C2416_SELECT_DSC2    (2 << 30)
+#define S3C2416_SELECT_DSC3    (3 << 30)
+
+#define S3C2416_DSC_GETSHIFT(x)        (x & 30)
+
+#define S3C2416_DSC0_CF                (S3C2416_SELECT_DSC0 | 28)
+#define        S3C2416_DSC0_CF_5mA     (0 << 28)
+#define        S3C2416_DSC0_CF_10mA    (1 << 28)
+#define        S3C2416_DSC0_CF_15mA    (2 << 28)
+#define        S3C2416_DSC0_CF_21mA    (3 << 28)
+#define        S3C2416_DSC0_CF_MASK    (3 << 28)
+
+#define S3C2416_DSC0_nRBE      (S3C2416_SELECT_DSC0 | 26)
+#define        S3C2416_DSC0_nRBE_5mA   (0 << 26)
+#define        S3C2416_DSC0_nRBE_10mA  (1 << 26)
+#define        S3C2416_DSC0_nRBE_15mA  (2 << 26)
+#define        S3C2416_DSC0_nRBE_21mA  (3 << 26)
+#define        S3C2416_DSC0_nRBE_MASK  (3 << 26)
+
+#define S3C2416_DSC0_nROE      (S3C2416_SELECT_DSC0 | 24)
+#define        S3C2416_DSC0_nROE_5mA   (0 << 24)
+#define        S3C2416_DSC0_nROE_10mA  (1 << 24)
+#define        S3C2416_DSC0_nROE_15mA  (2 << 24)
+#define        S3C2416_DSC0_nROE_21mA  (3 << 24)
+#define        S3C2416_DSC0_nROE_MASK  (3 << 24)
+
+#endif
+
 #if defined(CONFIG_CPU_S3C244X)
 
 #define S3C2440_DSC0      S3C2410_GPIOREG(0xc4)
index fd672f3..a0a89d4 100644 (file)
 #include <mach/gpio-nrs.h>
 
 #ifdef CONFIG_CPU_S3C2400
-#define S3C24XX_GPIO_BASE(x)  S3C2400_GPIO_BASE(x)
-#define S3C24XX_MISCCR        S3C2400_MISCCR
+#define S3C24XX_MISCCR         S3C2400_MISCCR
 #else
-#define S3C24XX_GPIO_BASE(x)  S3C2410_GPIO_BASE(x)
-#define S3C24XX_MISCCR       S3C24XX_GPIOREG2(0x80)
+#define S3C24XX_MISCCR         S3C24XX_GPIOREG2(0x80)
 #endif /* CONFIG_CPU_S3C2400 */
 
-
-/* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */
-
-#define S3C2400_BANKNUM(pin)     (((pin) & ~31) / 32)
-#define S3C2400_BASEA2B(pin)     ((((pin) & ~31) >> 2))
-#define S3C2400_BASEC2H(pin)     ((S3C2400_BANKNUM(pin) * 10) + \
-                                 (2 * (S3C2400_BANKNUM(pin)-2)))
-
-#define S3C2400_GPIO_BASE(pin)   (pin < S3C2410_GPIO_BANKC ? \
-                                 S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \
-                                 S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO)
-
-
-#define S3C2410_GPIO_BASE(pin)   ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
-#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)
-
 /* general configuration options */
 
 #define S3C2410_GPIO_LEAVE   (0xFFFFFFFF)
 #define S3C2410_GPHUP     S3C2410_GPIOREG(0x78)
 
 #define S3C2410_GPH0_nCTS0  (0x02 << 0)
+#define S3C2416_GPH0_TXD0  (0x02 << 0)
 
 #define S3C2410_GPH1_nRTS0  (0x02 << 2)
+#define S3C2416_GPH1_RXD0  (0x02 << 2)
 
 #define S3C2410_GPH2_TXD0   (0x02 << 4)
+#define S3C2416_GPH2_TXD1   (0x02 << 4)
 
 #define S3C2410_GPH3_RXD0   (0x02 << 6)
+#define S3C2416_GPH3_RXD1   (0x02 << 6)
 
 #define S3C2410_GPH4_TXD1   (0x02 << 8)
+#define S3C2416_GPH4_TXD2   (0x02 << 8)
 
 #define S3C2410_GPH5_RXD1   (0x02 << 10)
+#define S3C2416_GPH5_RXD2   (0x02 << 10)
 
 #define S3C2410_GPH6_TXD2   (0x02 << 12)
+#define S3C2416_GPH6_TXD3   (0x02 << 12)
 #define S3C2410_GPH6_nRTS1  (0x03 << 12)
+#define S3C2416_GPH6_nRTS2  (0x03 << 12)
 
 #define S3C2410_GPH7_RXD2   (0x02 << 14)
+#define S3C2416_GPH7_RXD3   (0x02 << 14)
 #define S3C2410_GPH7_nCTS1  (0x03 << 14)
+#define S3C2416_GPH7_nCTS2  (0x03 << 14)
 
 #define S3C2410_GPH8_UCLK   (0x02 << 16)
+#define S3C2416_GPH8_nCTS0  (0x02 << 16)
 
 #define S3C2410_GPH9_CLKOUT0  (0x02 << 18)
 #define S3C2442_GPH9_nSPICS0  (0x03 << 18)
+#define S3C2416_GPH9_nRTS0    (0x02 << 18)
 
 #define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
+#define S3C2416_GPH10_nCTS1   (0x02 << 20)
+
+#define S3C2416_GPH11_nRTS1   (0x02 << 22)
+
+#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
+
+#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
+
+#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
 
 /* The S3C2412 and S3C2413 move the GPJ register set to after
  * GPH, which means all registers after 0x80 are now offset by 0x10
  * for the 2412/2413 from the 2410/2440/2442
 */
 
+/* S3C2443 and above */
+#define S3C2440_GPJCON    S3C2410_GPIOREG(0xD0)
+#define S3C2440_GPJDAT    S3C2410_GPIOREG(0xD4)
+#define S3C2440_GPJUP     S3C2410_GPIOREG(0xD8)
+
+#define S3C2443_GPKCON    S3C2410_GPIOREG(0xE0)
+#define S3C2443_GPKDAT    S3C2410_GPIOREG(0xE4)
+#define S3C2443_GPKUP     S3C2410_GPIOREG(0xE8)
+
+#define S3C2443_GPLCON    S3C2410_GPIOREG(0xF0)
+#define S3C2443_GPLDAT    S3C2410_GPIOREG(0xF4)
+#define S3C2443_GPLUP     S3C2410_GPIOREG(0xF8)
+
+#define S3C2443_GPMCON    S3C2410_GPIOREG(0x100)
+#define S3C2443_GPMDAT    S3C2410_GPIOREG(0x104)
+#define S3C2443_GPMUP     S3C2410_GPIOREG(0x108)
+
 /* miscellaneous control */
 #define S3C2400_MISCCR    S3C2410_GPIOREG(0x54)
 #define S3C2410_MISCCR    S3C2410_GPIOREG(0x80)
 #define S3C2412_MISCCR_CLK1_CLKsrc  (0<<8)
 
 #define S3C2410_MISCCR_USBSUSPND0   (1<<12)
+#define S3C2416_MISCCR_SEL_SUSPND   (1<<12)
 #define S3C2410_MISCCR_USBSUSPND1   (1<<13)
 
 #define S3C2410_MISCCR_nRSTCON     (1<<16)
 #define S3C2410_MISCCR_nEN_SCLKE    (1<<19)    /* not 2412 */
 #define S3C2410_MISCCR_SDSLEEP     (7<<17)
 
+#define S3C2416_MISCCR_FLT_I2C      (1<<24)
+#define S3C2416_MISCCR_HSSPI_EN2    (1<<31)
+
 /* external interrupt control... */
 /* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
  * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
 #define S3C2410_GSTATUS1_IDMASK           (0xffff0000)
 #define S3C2410_GSTATUS1_2410     (0x32410000)
 #define S3C2410_GSTATUS1_2412     (0x32412001)
+#define S3C2410_GSTATUS1_2416     (0x32416003)
 #define S3C2410_GSTATUS1_2440     (0x32440000)
 #define S3C2410_GSTATUS1_2442     (0x32440aaa)
+/* some 2416 CPUs report this value also */
+#define S3C2410_GSTATUS1_2450     (0x32450003)
 
 #define S3C2410_GSTATUS2_WTRESET   (1<<2)
 #define S3C2410_GSTATUS2_OFFRESET  (1<<1)
index 1202ca5..19575e0 100644 (file)
  * pull up works like all other ports.
 */
 
-#define S3C2440_GPIO_BANKJ  (416)
-
-#define S3C2440_GPJCON     S3C2410_GPIOREG(0xd0)
-#define S3C2440_GPJDAT     S3C2410_GPIOREG(0xd4)
-#define S3C2440_GPJUP      S3C2410_GPIOREG(0xd8)
-
 #define S3C2413_GPJCON         S3C2410_GPIOREG(0x80)
 #define S3C2413_GPJDAT         S3C2410_GPIOREG(0x84)
 #define S3C2413_GPJUP          S3C2410_GPIOREG(0x88)
 #define S3C2413_GPJSLPCON      S3C2410_GPIOREG(0x8C)
 
-#define S3C2440_GPJ0            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
-#define S3C2440_GPJ0_INP        (0x00 << 0)
 #define S3C2440_GPJ0_OUTP       (0x01 << 0)
 #define S3C2440_GPJ0_CAMDATA0   (0x02 << 0)
 
-#define S3C2440_GPJ1            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 1)
-#define S3C2440_GPJ1_INP        (0x00 << 2)
 #define S3C2440_GPJ1_OUTP       (0x01 << 2)
 #define S3C2440_GPJ1_CAMDATA1   (0x02 << 2)
 
-#define S3C2440_GPJ2            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 2)
-#define S3C2440_GPJ2_INP        (0x00 << 4)
 #define S3C2440_GPJ2_OUTP       (0x01 << 4)
 #define S3C2440_GPJ2_CAMDATA2   (0x02 << 4)
 
-#define S3C2440_GPJ3            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 3)
-#define S3C2440_GPJ3_INP        (0x00 << 6)
 #define S3C2440_GPJ3_OUTP       (0x01 << 6)
 #define S3C2440_GPJ3_CAMDATA3   (0x02 << 6)
 
-#define S3C2440_GPJ4            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 4)
-#define S3C2440_GPJ4_INP        (0x00 << 8)
 #define S3C2440_GPJ4_OUTP       (0x01 << 8)
 #define S3C2440_GPJ4_CAMDATA4   (0x02 << 8)
 
-#define S3C2440_GPJ5            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 5)
-#define S3C2440_GPJ5_INP        (0x00 << 10)
 #define S3C2440_GPJ5_OUTP       (0x01 << 10)
 #define S3C2440_GPJ5_CAMDATA5   (0x02 << 10)
 
-#define S3C2440_GPJ6            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 6)
-#define S3C2440_GPJ6_INP        (0x00 << 12)
 #define S3C2440_GPJ6_OUTP       (0x01 << 12)
 #define S3C2440_GPJ6_CAMDATA6   (0x02 << 12)
 
-#define S3C2440_GPJ7            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 7)
-#define S3C2440_GPJ7_INP        (0x00 << 14)
 #define S3C2440_GPJ7_OUTP       (0x01 << 14)
 #define S3C2440_GPJ7_CAMDATA7   (0x02 << 14)
 
-#define S3C2440_GPJ8            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 8)
-#define S3C2440_GPJ8_INP        (0x00 << 16)
 #define S3C2440_GPJ8_OUTP       (0x01 << 16)
 #define S3C2440_GPJ8_CAMPCLK    (0x02 << 16)
 
-#define S3C2440_GPJ9            S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 9)
-#define S3C2440_GPJ9_INP        (0x00 << 18)
 #define S3C2440_GPJ9_OUTP       (0x01 << 18)
 #define S3C2440_GPJ9_CAMVSYNC   (0x02 << 18)
 
-#define S3C2440_GPJ10           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 10)
-#define S3C2440_GPJ10_INP       (0x00 << 20)
 #define S3C2440_GPJ10_OUTP      (0x01 << 20)
 #define S3C2440_GPJ10_CAMHREF   (0x02 << 20)
 
-#define S3C2440_GPJ11           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 11)
-#define S3C2440_GPJ11_INP       (0x00 << 22)
 #define S3C2440_GPJ11_OUTP      (0x01 << 22)
 #define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
 
-#define S3C2440_GPJ12           S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 12)
-#define S3C2440_GPJ12_INP       (0x00 << 24)
 #define S3C2440_GPJ12_OUTP      (0x01 << 24)
 #define S3C2440_GPJ12_CAMRESET  (0x02 << 24)
 
-#define S3C2443_GPJ13          S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 13)
-#define S3C2443_GPJ14          S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 14)
-#define S3C2443_GPJ15          S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 15)
-
 #endif /* __ASM_ARCH_REGS_GPIOJ_H */
 
index de86ee8..0f07ba3 100644 (file)
 #define S3C2410_SUBSRCPND      S3C2410_IRQREG(0x018)
 #define S3C2410_INTSUBMSK      S3C2410_IRQREG(0x01C)
 
+#define S3C2416_PRIORITY_MODE1         S3C2410_IRQREG(0x030)
+#define S3C2416_PRIORITY_UPDATE1       S3C2410_IRQREG(0x034)
+#define S3C2416_SRCPND2                        S3C2410_IRQREG(0x040)
+#define S3C2416_INTMOD2                        S3C2410_IRQREG(0x044)
+#define S3C2416_INTMSK2                        S3C2410_IRQREG(0x048)
+#define S3C2416_INTPND2                        S3C2410_IRQREG(0x050)
+#define S3C2416_INTOFFSET2             S3C2410_IRQREG(0x054)
+#define S3C2416_PRIORITY_MODE2         S3C2410_IRQREG(0x070)
+#define S3C2416_PRIORITY_UPDATE2       S3C2410_IRQREG(0x074)
+
 /* mask: 0=enable, 1=disable
  * 1 bit EINT, 4=EINT4, 23=EINT23
  * EINT0,1,2,3 are not handled here.
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
new file mode 100644 (file)
index 0000000..2f31b74
--- /dev/null
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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.
+ *
+ * S3C2416 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2416_MEM
+#define __ASM_ARM_REGS_S3C2416_MEM
+
+#ifndef S3C2416_MEMREG
+#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+#define S3C2416_BANKCFG                        S3C2416_MEMREG(0x00)
+#define S3C2416_BANKCON1               S3C2416_MEMREG(0x04)
+#define S3C2416_BANKCON2               S3C2416_MEMREG(0x08)
+#define S3C2416_BANKCON3               S3C2416_MEMREG(0x0C)
+
+#define S3C2416_REFRESH                        S3C2416_MEMREG(0x10)
+#define S3C2416_TIMEOUT                        S3C2416_MEMREG(0x14)
+
+#endif /*  __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
new file mode 100644 (file)
index 0000000..e443167
--- /dev/null
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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.
+ *
+ * S3C2416 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2416_H
+#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
+
+#define S3C2416_SWRST          (S3C24XX_VA_CLKPWR + 0x44)
+#define S3C2416_SWRST_RESET    (0x533C2416)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif /* __ASM_ARCH_REGS_S3C2416_H */
+
index d87ebe0..08ab9df 100644 (file)
@@ -83,8 +83,7 @@
 #define S3C2443_HCLKCON_DMA4           (1<<4)
 #define S3C2443_HCLKCON_DMA5           (1<<5)
 #define S3C2443_HCLKCON_CAMIF          (1<<8)
-#define S3C2443_HCLKCON_DISP           (1<<9)
-#define S3C2443_HCLKCON_LCDC           (1<<10)
+#define S3C2443_HCLKCON_LCDC           (1<<9)
 #define S3C2443_HCLKCON_USBH           (1<<11)
 #define S3C2443_HCLKCON_USBD           (1<<12)
 #define S3C2443_HCLKCON_HSMMC          (1<<16)
diff --git a/arch/arm/mach-s3c2410/include/mach/ts.h b/arch/arm/mach-s3c2410/include/mach/ts.h
deleted file mode 100644 (file)
index dc36170..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* linux/include/asm/arch-s3c2410/ts.h
- *
- * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * 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_TS_H
-#define __ASM_ARM_TS_H
-
-struct s3c2410_ts_mach_info {
-       int             delay;
-       int             presc;
-       int             oversampling_shift;
-};
-
-extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
-
-#endif /* __ASM_ARM_TS_H */
index 72f756c..8b283f8 100644 (file)
@@ -40,7 +40,9 @@ static void arch_detect_cpu(void)
        cpuid &= S3C2410_GSTATUS1_IDMASK;
 
        if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
-           cpuid == S3C2410_GSTATUS1_2442) {
+           cpuid == S3C2410_GSTATUS1_2442 ||
+           cpuid == S3C2410_GSTATUS1_2416 ||
+           cpuid == S3C2410_GSTATUS1_2450) {
                fifo_mask = S3C2440_UFSTAT_TXMASK;
                fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
        } else {
index 7047317..34fc05a 100644 (file)
@@ -56,6 +56,7 @@
 #include <plat/iic.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
 
 #ifdef CONFIG_MTD_PARTITIONS
 
@@ -225,8 +226,8 @@ static void amlm5900_init_pm(void)
        } else {
                enable_irq_wake(IRQ_EINT9);
                /* configure the suspend/resume status pin */
-               s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
-               s3c2410_gpio_pullup(S3C2410_GPF(2), 0);
+               s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+               s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
        }
 }
 static void __init amlm5900_init(void)
index 02b1b62..c1f90f6 100644 (file)
@@ -61,6 +61,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
+#include <plat/gpio-cfg.h>
 #include <plat/audio-simtec.h>
 
 #include "usb-simtec.h"
@@ -216,15 +217,13 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
 static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
 {
        /* ensure that an nRESET is not generated on resume. */
-       s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
-
+       gpio_direction_output(S3C2410_GPA(21), 1);
        return 0;
 }
 
 static int bast_pm_resume(struct sys_device *sd)
 {
-       s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
        return 0;
 }
 
@@ -634,7 +633,7 @@ static void __init bast_map_io(void)
 
        s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
 
-       s3c_device_hwmon.dev.platform_data = &bast_hwmon_info;
+       s3c_hwmon_set_platdata(&bast_hwmon_info);
 
        s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
        s3c24xx_init_clocks(0);
@@ -658,6 +657,8 @@ static void __init bast_init(void)
        nor_simtec_init();
        simtec_audio_add(NULL, true, &bast_audio);
 
+       WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
+       
        s3c_cpufreq_setboard(&bast_cpufreq);
 }
 
index fbedd07..779b45b 100644 (file)
 #include <mach/h1940.h>
 #include <mach/h1940-latch.h>
 #include <mach/fb.h>
-#include <mach/ts.h>
 #include <plat/udc.h>
 #include <plat/iic.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/pll.h>
 #include <plat/pm.h>
 #include <plat/mci.h>
+#include <plat/ts.h>
 
 static struct map_desc h1940_iodesc[] __initdata = {
        [0] = {
@@ -145,6 +146,7 @@ static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
                .delay = 10000,
                .presc = 49,
                .oversampling_shift = 2,
+               .cfg_gpio = s3c24xx_ts_cfg_gpio,
 };
 
 /**
@@ -162,8 +164,8 @@ static struct s3c2410fb_display h1940_lcd __initdata = {
        .xres =         240,
        .yres =         320,
        .bpp =          16,
-       .left_margin =  20,
-       .right_margin = 8,
+       .left_margin =  8,
+       .right_margin = 20,
        .hsync_len =    4,
        .upper_margin = 8,
        .lower_margin = 7,
@@ -207,16 +209,16 @@ static int h1940_backlight_init(struct device *dev)
 {
        gpio_request(S3C2410_GPB(0), "Backlight");
 
-       s3c2410_gpio_setpin(S3C2410_GPB(0), 0);
-       s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       gpio_direction_output(S3C2410_GPB(0), 0);
+       s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
 
        return 0;
 }
 
 static void h1940_backlight_exit(struct device *dev)
 {
-       s3c2410_gpio_cfgpin(S3C2410_GPB(0), 1/*S3C2410_GPB0_OUTP*/);
+       gpio_direction_output(S3C2410_GPB(0), 1);
 }
 
 static struct platform_pwm_backlight_data backlight_data = {
@@ -245,18 +247,18 @@ static void h1940_lcd_power_set(struct plat_lcd_data *pd,
 
        if (!power) {
                /* set to 3ec */
-               s3c2410_gpio_setpin(S3C2410_GPC(0), 0);
+               gpio_direction_output(S3C2410_GPC(0), 0);
                /* wait for 3ac */
                do {
-                       value = s3c2410_gpio_getpin(S3C2410_GPC(6));
+                       value = gpio_get_value(S3C2410_GPC(6));
                } while (value);
                /* set to 38c */
-               s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+               gpio_direction_output(S3C2410_GPC(5), 0);
        } else {
                /* Set to 3ac */
-               s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+               gpio_direction_output(S3C2410_GPC(5), 1);
                /* Set to 3ad */
-               s3c2410_gpio_setpin(S3C2410_GPC(0), 1);
+               gpio_direction_output(S3C2410_GPC(0), 1);
        }
 }
 
@@ -271,7 +273,6 @@ static struct platform_device h1940_lcd_powerdev = {
 };
 
 static struct platform_device *h1940_devices[] __initdata = {
-       &s3c_device_ts,
        &s3c_device_ohci,
        &s3c_device_lcd,
        &s3c_device_wdt,
@@ -285,6 +286,8 @@ static struct platform_device *h1940_devices[] __initdata = {
        &s3c_device_timer[0],
        &h1940_backlight,
        &h1940_lcd_powerdev,
+       &s3c_device_adc,
+       &s3c_device_ts,
 };
 
 static void __init h1940_map_io(void)
@@ -332,12 +335,13 @@ static void __init h1940_init(void)
        gpio_request(S3C2410_GPC(5), "LCD power");
        gpio_request(S3C2410_GPC(6), "LCD power");
 
+       gpio_direction_input(S3C2410_GPC(6));
 
        platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 684710f..41f299d 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/serial_core.h>
 #include <linux/timer.h>
 #include <linux/io.h>
+#include <linux/mmc/host.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -46,6 +47,7 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/mci.h>
 #include <plat/s3c2410.h>
 #include <plat/udc.h>
 
@@ -86,10 +88,10 @@ static void n30_udc_pullup(enum s3c2410_udc_cmd_e cmd)
 {
        switch (cmd) {
        case S3C2410_UDC_P_ENABLE :
-               s3c2410_gpio_setpin(S3C2410_GPB(3), 1);
+               gpio_set_value(S3C2410_GPB(3), 1);
                break;
        case S3C2410_UDC_P_DISABLE :
-               s3c2410_gpio_setpin(S3C2410_GPB(3), 0);
+               gpio_set_value(S3C2410_GPB(3), 0);
                break;
        case S3C2410_UDC_P_RESET :
                break;
@@ -172,8 +174,10 @@ static struct gpio_keys_button n35_buttons[] = {
        {
                .gpio           = S3C2410_GPF(0),
                .code           = KEY_POWER,
+               .type           = EV_PWR,
                .desc           = "Power",
                .active_low     = 0,
+               .wakeup         = 1,
        },
        {
                .gpio           = S3C2410_GPG(9),
@@ -264,6 +268,14 @@ static struct s3c24xx_led_platdata n30_blue_led_pdata = {
        .def_trigger    = "",
 };
 
+/* This is the blue LED on the device. Originaly used to indicate GPS activity
+ * by flashing. */
+static struct s3c24xx_led_platdata n35_blue_led_pdata = {
+       .name           = "blue_led",
+       .gpio           = S3C2410_GPD(8),
+       .def_trigger    = "",
+};
+
 /* This LED is driven by the battery microcontroller, and is blinking
  * red, blinking green or solid green when the battery is low,
  * charging or full respectively.  By driving GPD9 low, it's possible
@@ -275,6 +287,13 @@ static struct s3c24xx_led_platdata n30_warning_led_pdata = {
        .def_trigger    = "",
 };
 
+static struct s3c24xx_led_platdata n35_warning_led_pdata = {
+       .name           = "warning_led",
+       .flags          = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+       .gpio           = S3C2410_GPD(9),
+       .def_trigger    = "",
+};
+
 static struct platform_device n30_blue_led = {
        .name           = "s3c24xx_led",
        .id             = 1,
@@ -283,6 +302,14 @@ static struct platform_device n30_blue_led = {
        },
 };
 
+static struct platform_device n35_blue_led = {
+       .name           = "s3c24xx_led",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &n35_blue_led_pdata,
+       },
+};
+
 static struct platform_device n30_warning_led = {
        .name           = "s3c24xx_led",
        .id             = 2,
@@ -291,6 +318,14 @@ static struct platform_device n30_warning_led = {
        },
 };
 
+static struct platform_device n35_warning_led = {
+       .name           = "s3c24xx_led",
+       .id             = 2,
+       .dev            = {
+               .platform_data  = &n35_warning_led_pdata,
+       },
+};
+
 static struct s3c2410fb_display n30_display __initdata = {
        .type           = S3C2410_LCDCON1_TFT,
        .width          = 240,
@@ -317,13 +352,36 @@ static struct s3c2410fb_mach_info n30_fb_info __initdata = {
        .lpcsel         = 0x06,
 };
 
+static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_ON:
+       case MMC_POWER_UP:
+               gpio_set_value(S3C2410_GPG(4), 1);
+               break;
+       case MMC_POWER_OFF:
+       default:
+               gpio_set_value(S3C2410_GPG(4), 0);
+               break;
+       }
+}
+
+static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
+       .gpio_detect    = S3C2410_GPF(1),
+       .gpio_wprotect  = S3C2410_GPG(10),
+       .ocr_avail      = MMC_VDD_32_33,
+       .set_power      = n30_sdi_set_power,
+};
+
 static struct platform_device *n30_devices[] __initdata = {
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
        &s3c_device_ohci,
+       &s3c_device_rtc,
        &s3c_device_usbgadget,
+       &s3c_device_sdi,
        &n30_button_device,
        &n30_blue_led,
        &n30_warning_led,
@@ -334,8 +392,12 @@ static struct platform_device *n35_devices[] __initdata = {
        &s3c_device_wdt,
        &s3c_device_i2c0,
        &s3c_device_iis,
+       &s3c_device_rtc,
        &s3c_device_usbgadget,
+       &s3c_device_sdi,
        &n35_button_device,
+       &n35_blue_led,
+       &n35_warning_led,
 };
 
 static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
@@ -490,17 +552,15 @@ static void __init n30_map_io(void)
        s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
 }
 
-static void __init n30_init_irq(void)
-{
-       s3c24xx_init_irq();
-}
-
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
 
 static void __init n30_init(void)
 {
+       WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
+
        s3c24xx_fb_set_platdata(&n30_fb_info);
        s3c24xx_udc_set_platdata(&n30_udc_cfg);
+       s3c24xx_mci_set_platdata(&n30_mci_cfg);
        s3c_i2c0_set_platdata(&n30_i2ccfg);
 
        /* Turn off suspend on both USB ports, and switch the
@@ -532,10 +592,13 @@ static void __init n30_init(void)
                s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
                                      S3C2410_MISCCR_USBSUSPND0 |
                                      S3C2410_MISCCR_USBSUSPND1,
-                                     S3C2410_MISCCR_USBSUSPND1);
+                                     S3C2410_MISCCR_USBSUSPND0);
 
                platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
        }
+
+       WARN_ON(gpio_request(S3C2410_GPB(3), "udc pup"));
+       gpio_direction_output(S3C2410_GPB(3), 0);
 }
 
 MACHINE_START(N30, "Acer-N30")
@@ -547,7 +610,7 @@ MACHINE_START(N30, "Acer-N30")
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
        .timer          = &s3c24xx_timer,
        .init_machine   = n30_init,
-       .init_irq       = n30_init_irq,
+       .init_irq       = s3c24xx_init_irq,
        .map_io         = n30_map_io,
 MACHINE_END
 
@@ -559,6 +622,6 @@ MACHINE_START(N35, "Acer-N35")
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
        .timer          = &s3c24xx_timer,
        .init_machine   = n30_init,
-       .init_irq       = n30_init_irq,
+       .init_irq       = s3c24xx_init_irq,
        .map_io         = n30_map_io,
 MACHINE_END
index 92a4ec3..d0e87b6 100644 (file)
@@ -58,6 +58,7 @@
 #include <plat/iic.h>
 
 #include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
@@ -219,10 +220,10 @@ static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
 {
        switch (cs) {
        case BITBANG_CS_ACTIVE:
-               s3c2410_gpio_setpin(S3C2410_GPB(5), 0);
+               gpio_set_value(S3C2410_GPB(5), 0);
                break;
        case BITBANG_CS_INACTIVE:
-               s3c2410_gpio_setpin(S3C2410_GPB(5), 1);
+               gpio_set_value(S3C2410_GPB(5), 1);
                break;
        }
 }
@@ -347,13 +348,14 @@ static void __init qt2410_machine_init(void)
        }
        s3c24xx_fb_set_platdata(&qt2410_fb_info);
 
-       s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
        s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
 
        s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
        s3c_i2c0_set_platdata(NULL);
 
-       s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);
+       WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
+       gpio_direction_output(S3C2410_GPB(5), 1);
 
        platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
        s3c_pm_init();
index 9051f0d..d540d79 100644 (file)
@@ -357,8 +357,7 @@ static struct clk *vr1000_clocks[] __initdata = {
 
 static void vr1000_power_off(void)
 {
-       s3c2410_gpio_cfgpin(S3C2410_GPB(9), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_setpin(S3C2410_GPB(9), 1);
+       gpio_direction_output(S3C2410_GPB(9), 1);
 }
 
 static void __init vr1000_map_io(void)
@@ -395,6 +394,8 @@ static void __init vr1000_init(void)
 
        nor_simtec_init();
        simtec_audio_add(NULL, true, NULL);
+
+       WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
 }
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
index 966119c..725636f 100644 (file)
@@ -60,10 +60,10 @@ static void s3c2410_pm_prepare(void)
                __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
        }
 
-       /* the RX3715 uses similar code and the same H1940 and the
+       /* RX3715 and RX1950 use similar to H1940 code and the
         * same offsets for resume and checksum pointers */
 
-       if (machine_is_rx3715()) {
+       if (machine_is_rx3715() || machine_is_rx1950()) {
                void *base = phys_to_virt(H1940_SUSPEND_CHECK);
                unsigned long ptr;
                unsigned long calc = 0;
@@ -79,6 +79,17 @@ static void s3c2410_pm_prepare(void)
        if ( machine_is_aml_m5900() )
                s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
 
+       if (machine_is_rx1950()) {
+               /* According to S3C2442 user's manual, page 7-17,
+                * when the system is operating in NAND boot mode,
+                * the hardware pin configuration - EINT[23:21] â€“
+                * must be set as input for starting up after
+                * wakeup from sleep mode
+                */
+               s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
+       }
 }
 
 static int s3c2410_pm_resume(struct sys_device *dev)
index 91ba42f..adc90a3 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/sysdev.h>
 #include <linux/serial_core.h>
 #include <plat/clock.h>
 #include <plat/pll.h>
 
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
 /* Initial IO mappings */
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
@@ -65,6 +70,9 @@ void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
 
 void __init s3c2410_map_io(void)
 {
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
        iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
 
index 9a8c065..cef6a65 100644 (file)
@@ -16,7 +16,8 @@ config CPU_S3C2412
 config CPU_S3C2412_ONLY
        bool
        depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
-                  !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412
+                  !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+                  !CPU_S3C2443 && CPU_S3C2412
        default y if CPU_S3C2412
 
 config S3C2412_DMA
index f7afece..3404a87 100644 (file)
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include <mach/regs-gpio.h>
-
 #include <mach/hardware.h>
 
+#include <plat/gpio-core.h>
+
 int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long offs = pin - chip->chip.base;
        unsigned long flags;
        unsigned long slpcon;
 
        offs *= 2;
 
-       if (pin < S3C2410_GPIO_BANKB)
+       if (pin < S3C2410_GPB(0))
                return -EINVAL;
 
-       if (pin >= S3C2410_GPIO_BANKF &&
-           pin <= S3C2410_GPIO_BANKG)
+       if (pin >= S3C2410_GPF(0) &&
+           pin <= S3C2410_GPG(16))
                return -EINVAL;
 
-       if (pin > (S3C2410_GPIO_BANKH + 32))
+       if (pin > S3C2410_GPH(16))
                return -EINVAL;
 
        local_irq_save(flags);
 
-       slpcon = __raw_readl(base + 0x0C);
+       slpcon = __raw_readl(chip->base + 0x0C);
 
        slpcon &= ~(3 << offs);
        slpcon |= state << offs;
 
-       __raw_writel(slpcon, base + 0x0C);
+       __raw_writel(slpcon, chip->base + 0x0C);
 
        local_irq_restore(flags);
 
index 14f4798..478f4b4 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -357,8 +358,7 @@ static void jive_lcm_reset(unsigned int set)
 {
        printk(KERN_DEBUG "%s(%d)\n", __func__, set);
 
-       s3c2410_gpio_setpin(S3C2410_GPG(13), set);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
+       gpio_set_value(S3C2410_GPG(13), set);
 }
 
 #undef LCD_UPPER_MARGIN
@@ -391,7 +391,7 @@ static struct ili9320_platdata jive_lcm_config = {
 
 static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
 {
-       s3c2410_gpio_setpin(S3C2410_GPB(7), cs ? 0 : 1);
+       gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
 }
 
 static struct s3c2410_spigpio_info jive_lcd_spi = {
@@ -413,7 +413,7 @@ static struct platform_device jive_device_lcdspi = {
 
 static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
 {
-       s3c2410_gpio_setpin(S3C2410_GPH(10), cs ? 0 : 1);
+       gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
 }
 
 static struct s3c2410_spigpio_info jive_wm8750_spi = {
@@ -531,7 +531,7 @@ static void jive_power_off(void)
        printk(KERN_INFO "powering system down...\n");
 
        s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
 }
 
 static void __init jive_machine_init(void)
@@ -636,22 +636,22 @@ static void __init jive_machine_init(void)
 
        /* initialise the spi */
 
-       s3c2410_gpio_setpin(S3C2410_GPG(13), 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_OUTPUT);
+       gpio_request(S3C2410_GPG(13), "lcm reset");
+       gpio_direction_output(S3C2410_GPG(13), 0);
 
-       s3c2410_gpio_setpin(S3C2410_GPB(7), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT);
+       gpio_request(S3C2410_GPB(7), "jive spi");
+       gpio_direction_output(S3C2410_GPB(7), 1);
 
        s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
 
        s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
 
        /* initialise the WM8750 spi */
 
-       s3c2410_gpio_setpin(S3C2410_GPH(10), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPH(10), S3C2410_GPIO_OUTPUT);
+       gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
+       gpio_direction_output(S3C2410_GPH(10), 1);
 
        /* Turn off suspend on both USB ports, and switch the
         * selectable USB port to USB device mode. */
@@ -674,7 +674,7 @@ static void __init jive_machine_init(void)
 }
 
 MACHINE_START(JIVE, "JIVE")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 0392065..ba93a35 100644 (file)
@@ -85,10 +85,10 @@ static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
        switch (cmd)
        {
                case S3C2410_UDC_P_ENABLE :
-                       s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
+                       gpio_set_value(S3C2410_GPF(2), 1);
                        break;
                case S3C2410_UDC_P_DISABLE :
-                       s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+                       gpio_set_value(S3C2410_GPF(2), 0);
                        break;
                case S3C2410_UDC_P_RESET :
                        break;
@@ -134,8 +134,8 @@ static void __init smdk2413_machine_init(void)
 {      /* Turn off suspend on both USB ports, and switch the
         * selectable USB port to USB device mode. */
 
-       s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+       WARN_ON(gpio_request(S3C2410_GPF(2), "udc pull"));
+       gpio_direction_output(S3C2410_GPF(2), 0);
 
        s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
                              S3C2410_MISCCR_USBSUSPND0 |
@@ -150,7 +150,7 @@ static void __init smdk2413_machine_init(void)
 }
 
 MACHINE_START(S3C2413, "S3C2413")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
@@ -163,7 +163,7 @@ MACHINE_START(S3C2413, "S3C2413")
 MACHINE_END
 
 MACHINE_START(SMDK2412, "SMDK2412")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
@@ -176,7 +176,7 @@ MACHINE_START(SMDK2412, "SMDK2412")
 MACHINE_END
 
 MACHINE_START(SMDK2413, "SMDK2413")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
new file mode 100644 (file)
index 0000000..657e4fe
--- /dev/null
@@ -0,0 +1,39 @@
+# arch/arm/mach-s3c2416/Kconfig
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+# note, this also supports the S3C2450 which is so similar it has the same
+# ID code as the S3C2416.
+
+config CPU_S3C2416
+       bool
+       depends on ARCH_S3C2410
+       select CPU_ARM926T
+       select S3C2416_DMA if S3C2410_DMA
+       select CPU_LLSERIAL_S3C2440
+       select S3C_GPIO_PULL_UPDOWN
+       select SAMSUNG_CLKSRC
+       select S3C2443_CLOCK
+       help
+         Support for the S3C2416 SoC from the S3C24XX line
+
+config S3C2416_DMA
+       bool
+       depends on CPU_S3C2416
+       help
+         Internal config node for S3C2416 DMA support
+
+menu "S3C2416 Machines"
+
+config MACH_SMDK2416
+       bool "SMDK2416"
+       select CPU_S3C2416
+       select S3C_DEV_FB
+       select S3C_DEV_HSMMC
+       select S3C_DEV_HSMMC1
+       help
+         Say Y here if you are using an SMDK2416
+
+endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
new file mode 100644 (file)
index 0000000..6c12c7b
--- /dev/null
@@ -0,0 +1,19 @@
+# arch/arm/mach-s3c2416/Makefile
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+obj-y                          :=
+obj-m                          :=
+obj-n                          :=
+obj-                           :=
+
+obj-$(CONFIG_CPU_S3C2416)      += s3c2416.o clock.o
+obj-$(CONFIG_CPU_S3C2416)      += irq.o
+
+#obj-$(CONFIG_S3C2416_DMA)     += dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2416)    += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
new file mode 100644 (file)
index 0000000..7ccf5a2
--- /dev/null
@@ -0,0 +1,135 @@
+/* linux/arch/arm/mach-s3c2416/clock.c
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S3C2416 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <plat/s3c2416.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/pll6553x.h>
+#include <plat/pll.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2443-clock.h>
+
+static unsigned int armdiv[8] = {
+       [0] = 1,
+       [1] = 2,
+       [2] = 3,
+       [3] = 4,
+       [5] = 6,
+       [7] = 8,
+};
+
+/* ID to hardware numbering, 0 is HSMMC1, 1 is HSMMC0 */
+static struct clksrc_clk hsmmc_div[] = {
+       [0] = {
+               .clk = {
+                       .name   = "hsmmc-div",
+                       .id     = 1,
+                       .parent = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
+       },
+       [1] = {
+               .clk = {
+                       .name   = "hsmmc-div",
+                       .id     = 0,
+                       .parent = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+       },
+};
+
+static struct clksrc_clk hsmmc_mux[] = {
+       [0] = {
+               .clk    = {
+                       .id     = 1,
+                       .name   = "hsmmc-if",
+                       .ctrlbit = (1 << 6),
+                       .enable = s3c2443_clkcon_enable_s,
+               },
+               .sources = &(struct clksrc_sources) {
+                       .nr_sources = 2,
+                       .sources = (struct clk *[]) {
+                               [0] = &hsmmc_div[0].clk,
+                               [1] = NULL, /* to fix */
+                       },
+               },
+               .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
+       },
+       [1] = {
+               .clk    = {
+                       .id     = 0,
+                       .name   = "hsmmc-if",
+                       .ctrlbit = (1 << 12),
+                       .enable = s3c2443_clkcon_enable_s,
+               },
+               .sources = &(struct clksrc_sources) {
+                       .nr_sources = 2,
+                       .sources = (struct clk *[]) {
+                               [0] = &hsmmc_div[1].clk,
+                               [1] = NULL, /* to fix */
+                       },
+               },
+               .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
+       },
+};
+
+
+static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
+{
+       clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+       return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+void __init_or_cpufreq s3c2416_setup_clocks(void)
+{
+       s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
+}
+
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+       &hsmmc_div[0],
+       &hsmmc_div[1],
+       &hsmmc_mux[0],
+       &hsmmc_mux[1],
+};
+
+void __init s3c2416_init_clocks(int xtal)
+{
+       u32 epllcon = __raw_readl(S3C2443_EPLLCON);
+       u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
+       int ptr;
+
+       /* s3c2416 EPLL compatible with s3c64xx */
+       clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
+
+       clk_epll.parent = &clk_epllref.clk;
+
+       s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+
+       s3c_pwmclk_init();
+
+}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
new file mode 100644 (file)
index 0000000..89f521d
--- /dev/null
@@ -0,0 +1,254 @@
+/* linux/arch/arm/mach-s3c2416/irq.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+       unsigned int subsrc, submsk;
+       unsigned int end;
+
+       /* read the current pending interrupts, and the mask
+        * for what it is available */
+
+       subsrc = __raw_readl(S3C2410_SUBSRCPND);
+       submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+       subsrc  &= ~submsk;
+       subsrc >>= (irq - S3C2410_IRQSUB(0));
+       subsrc  &= (1 << len)-1;
+
+       end = len + irq;
+
+       for (; irq < end && subsrc; irq++) {
+               if (subsrc & 1)
+                       generic_handle_irq(irq);
+
+               subsrc >>= 1;
+       }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+       .mask       = s3c2416_irq_wdtac97_mask,
+       .unmask     = s3c2416_irq_wdtac97_unmask,
+       .ack        = s3c2416_irq_wdtac97_ack,
+};
+
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD     (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD     INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+       .mask       = s3c2416_irq_lcd_mask,
+       .unmask     = s3c2416_irq_lcd_unmask,
+       .ack        = s3c2416_irq_lcd_ack,
+};
+
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA     (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA     INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+       .mask       = s3c2416_irq_dma_mask,
+       .unmask     = s3c2416_irq_dma_unmask,
+       .ack        = s3c2416_irq_dma_ack,
+};
+
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+       s3c2416_irq_demux(IRQ_S3C2443_UART3, 3);
+}
+
+#define INTMSK_UART3   (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3   (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+
+static void s3c2416_irq_uart3_mask(unsigned int irqno)
+{
+       s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(unsigned int irqno)
+{
+       s3c_irqsub_unmask(irqno, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(unsigned int irqno)
+{
+       s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+       .mask       = s3c2416_irq_uart3_mask,
+       .unmask     = s3c2416_irq_uart3_unmask,
+       .ack        = s3c2416_irq_uart3_ack,
+};
+
+
+/* IRQ initialisation code */
+
+static int __init s3c2416_add_sub(unsigned int base,
+                                  void (*demux)(unsigned int,
+                                                struct irq_desc *),
+                                  struct irq_chip *chip,
+                                  unsigned int start, unsigned int end)
+{
+       unsigned int irqno;
+
+       set_irq_chip(base, &s3c_irq_level_chip);
+       set_irq_handler(base, handle_level_irq);
+       set_irq_chained_handler(base, demux);
+
+       for (irqno = start; irqno <= end; irqno++) {
+               set_irq_chip(irqno, chip);
+               set_irq_handler(irqno, handle_level_irq);
+               set_irq_flags(irqno, IRQF_VALID);
+       }
+
+       return 0;
+}
+
+static int __init s3c2416_irq_add(struct sys_device *sysdev)
+{
+       printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+       s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+                       IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+       s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+                       &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+       s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+                       &s3c2416_irq_uart3,
+                       IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+       s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+                       &s3c2416_irq_wdtac97,
+                       IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+       return 0;
+}
+
+static struct sysdev_driver s3c2416_irq_driver = {
+       .add            = s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+       return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver);
+}
+
+arch_initcall(s3c2416_irq_init);
+
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
new file mode 100644 (file)
index 0000000..5fc3f67
--- /dev/null
@@ -0,0 +1,206 @@
+/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/leds-gpio.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2416.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/nand.h>
+
+#include <plat/regs-fb-v4.h>
+#include <plat/fb.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2416_iodesc[] __initdata = {
+       /* ISA IO Space map (memory space selected by A24) */
+
+       {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
+               .pfn            = __phys_to_pfn(S3C2410_CS2),
+               .length         = 0x10000,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+               .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+               .length         = SZ_4M,
+               .type           = MT_DEVICE,
+       }
+};
+
+#define UCON (S3C2410_UCON_DEFAULT     | \
+               S3C2440_UCON_PCLK       | \
+               S3C2443_UCON_RXERR_IRQEN)
+
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+
+#define UFCON (S3C2410_UFCON_RXTRIG8   | \
+               S3C2410_UFCON_FIFOMODE  | \
+               S3C2440_UFCON_TXTRIG16)
+
+static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
+       [0] = {
+               .hwport      = 0,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       [1] = {
+               .hwport      = 1,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON,
+               .ufcon       = UFCON,
+       },
+       /* IR port */
+       [2] = {
+               .hwport      = 2,
+               .flags       = 0,
+               .ucon        = UCON,
+               .ulcon       = ULCON | 0x50,
+               .ufcon       = UFCON,
+       }
+};
+
+struct s3c_fb_pd_win smdk2416_fb_win[] = {
+       [0] = {
+               /* think this is the same as the smdk6410 */
+               .win_mode       = {
+                       .pixclock       = 41094,
+                       .left_margin    = 8,
+                       .right_margin   = 13,
+                       .upper_margin   = 7,
+                       .lower_margin   = 5,
+                       .hsync_len      = 3,
+                       .vsync_len      = 1,
+                       .xres           = 800,
+                       .yres           = 480,
+               },
+               .default_bpp    = 16,
+               .max_bpp        = 32,
+       },
+};
+
+static void s3c2416_fb_gpio_setup_24bpp(void)
+{
+       unsigned int gpio;
+
+       for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+}
+
+static struct s3c_fb_platdata smdk2416_fb_platdata = {
+       .win[0]         = &smdk2416_fb_win[0],
+       .setup_gpio     = s3c2416_fb_gpio_setup_24bpp,
+       .vidcon0        = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+       .vidcon1        = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct platform_device *smdk2416_devices[] __initdata = {
+       &s3c_device_fb,
+       &s3c_device_wdt,
+       &s3c_device_ohci,
+       &s3c_device_i2c0,
+       &s3c_device_hsmmc0,
+       &s3c_device_hsmmc1,
+};
+
+static void __init smdk2416_map_io(void)
+{
+       s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+       s3c24xx_init_clocks(12000000);
+       s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+}
+
+static void __init smdk2416_machine_init(void)
+{
+       s3c_i2c0_set_platdata(NULL);
+       s3c_fb_set_platdata(&smdk2416_fb_platdata);
+
+       gpio_request(S3C2410_GPB(4), "USBHost Power");
+       gpio_direction_output(S3C2410_GPB(4), 1);
+
+       gpio_request(S3C2410_GPB(3), "Display Power");
+       gpio_direction_output(S3C2410_GPB(3), 1);
+
+       gpio_request(S3C2410_GPB(1), "Display Reset");
+       gpio_direction_output(S3C2410_GPB(1), 1);
+
+       platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
+       smdk_machine_init();
+}
+
+MACHINE_START(SMDK2416, "SMDK2416")
+       /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
+       .phys_io        = S3C2410_PA_UART,
+       .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params    = S3C2410_SDRAM_PA + 0x100,
+
+       .init_irq       = s3c24xx_init_irq,
+       .map_io         = smdk2416_map_io,
+       .init_machine   = smdk2416_machine_init,
+       .timer          = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
new file mode 100644 (file)
index 0000000..35dabcc
--- /dev/null
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-s3c2416/s3c2416.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ *     as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ *     Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * Samsung S3C2416 Mobile CPU support
+ *
+ * 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/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/reset.h>
+#include <mach/idle.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2416.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/iic-core.h>
+
+static struct map_desc s3c2416_iodesc[] __initdata = {
+       IODESC_ENT(WATCHDOG),
+       IODESC_ENT(CLKPWR),
+       IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2416_sysclass = {
+       .name = "s3c2416-core",
+};
+
+static struct sys_device s3c2416_sysdev = {
+       .cls            = &s3c2416_sysclass,
+};
+
+static void s3c2416_hard_reset(void)
+{
+       __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2416_init(void)
+{
+       printk(KERN_INFO "S3C2416: Initializing architecture\n");
+
+       s3c24xx_reset_hook = s3c2416_hard_reset;
+       /* s3c24xx_idle = s3c2416_idle; */
+
+       /* change WDT IRQ number */
+       s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+       s3c_device_wdt.resource[1].end   = IRQ_S3C2443_WDT;
+
+       /* the i2c devices are directly compatible with s3c2440 */
+       s3c_i2c0_setname("s3c2440-i2c");
+       s3c_i2c1_setname("s3c2440-i2c");
+
+       s3c_device_fb.name = "s3c2443-fb";
+
+       return sysdev_register(&s3c2416_sysdev);
+}
+
+void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+       s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+
+       s3c_device_nand.name = "s3c2416-nand";
+}
+
+/* s3c2416_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2416_map_io(void)
+{
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
+
+       iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2416 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2416_core_init(void)
+{
+       return sysdev_class_register(&s3c2416_sysclass);
+}
+
+core_initcall(s3c2416_core_init);
index 7f46526..cd8e7de 100644 (file)
@@ -6,6 +6,7 @@ config CPU_S3C2440
        bool
        depends on ARCH_S3C2410
        select CPU_ARM920T
+       select S3C_GPIO_PULL_UP
        select S3C2410_CLOCK
        select S3C2410_PM if PM
        select S3C2410_GPIO
@@ -187,4 +188,17 @@ config MACH_MINI2440
          Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
          available via various sources. It can come with a 3.5" or 7" touch LCD.
 
+config MACH_RX1950
+       bool "HP iPAQ rx1950"
+       select CPU_S3C2442
+       select S3C24XX_DCLK
+       select PM_H1940 if PM
+       select I2C
+       select S3C2410_PWM
+       select S3C_DEV_NAND
+       select S3C2410_IOTIMING if S3C2440_CPUFREQ
+       select S3C2440_XTAL_16934400
+       help
+          Say Y here if you're using HP iPAQ rx1950
+
 endmenu
index c85ba32..d5440fa 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
 obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
 obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
 obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
+obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o
 
 # extra machine support
 
index 571b176..a76bcda 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -102,10 +103,10 @@ static void mini2440_udc_pullup(enum s3c2410_udc_cmd_e cmd)
 
        switch (cmd) {
                case S3C2410_UDC_P_ENABLE :
-                       s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+                       gpio_set_value(S3C2410_GPC(5), 1);
                        break;
                case S3C2410_UDC_P_DISABLE :
-                       s3c2410_gpio_setpin(S3C2410_GPC(5), 0);
+                       gpio_set_value(S3C2410_GPC(5), 0);
                        break;
                case S3C2410_UDC_P_RESET :
                        break;
@@ -632,25 +633,25 @@ static void __init mini2440_init(void)
        mini2440_parse_features(&features, mini2440_features_str);
 
        /* turn LCD on */
-       s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
+       s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
 
        /* Turn the backlight early on */
-       s3c2410_gpio_setpin(S3C2410_GPG(4), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(4), S3C2410_GPIO_OUTPUT);
+       WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
+       gpio_direction_output(S3C2410_GPG(4), 1);
 
        /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
-       s3c2410_gpio_pullup(S3C2410_GPB(1), 0);
+       s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
        s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
+       s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
 
        /* Make sure the D+ pullup pin is output */
-       s3c2410_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+       WARN_ON(gpio_request(S3C2410_GPC(5), "udc pup"));
+       gpio_direction_output(S3C2410_GPC(5), 0);
 
        /* mark the key as input, without pullups (there is one on the board) */
        for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
-               s3c2410_gpio_pullup(mini2440_buttons[i].gpio, 0);
-               s3c2410_gpio_cfgpin(mini2440_buttons[i].gpio,
-                                       S3C2410_GPIO_INPUT);
+               s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
+               s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
        }
        if (features.lcd_index != -1) {
                int li;
index 3420415..3ff62de 100644 (file)
@@ -40,6 +40,7 @@
 #include <plat/regs-serial.h>
 #include <plat/iic.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/s3c2410.h>
 #include <plat/s3c244x.h>
 #include <plat/clock.h>
@@ -122,15 +123,15 @@ static void __init nexcoder_sensorboard_init(void)
 {
        // Initialize SCCB bus
        s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
-       s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
        s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
-       s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
 
        // Power up the sensor board
        s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
+       s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
        s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-       s3c2410_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
+       s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
 }
 
 static void __init nexcoder_map_io(void)
index f35371d..319458d 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
@@ -298,7 +299,7 @@ static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
 
        /* ensure that an nRESET is not generated on resume. */
        s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
-       s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
 
        return 0;
 }
@@ -310,7 +311,7 @@ static int osiris_pm_resume(struct sys_device *sd)
 
        __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
 
-       s3c2410_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+       s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
 
        return 0;
 }
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
new file mode 100644 (file)
index 0000000..8603b57
--- /dev/null
@@ -0,0 +1,582 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx1950.c
+ *
+ * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
+ * Copyright (c) 2007-2010 Vasily Khoruzhick
+ *
+ * based on smdk2440 written by Ben Dooks
+ *
+ * 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/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/sysdev.h>
+#include <linux/pwm_backlight.h>
+#include <linux/pwm.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/h1940.h>
+#include <mach/fb.h>
+
+#include <plat/clock.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-iic.h>
+#include <plat/mci.h>
+#include <plat/udc.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+#include <plat/ts.h>
+
+#define LCD_PWM_PERIOD 192960
+#define LCD_PWM_DUTY 127353
+
+static struct map_desc rx1950_iodesc[] __initdata = {
+};
+
+static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
+       [0] = {
+              .name = "fclk",
+              .divisor = 0x0a,
+              .min_baud = 0,
+              .max_baud = 0,
+       },
+};
+
+static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
+       [0] = {
+              .hwport = 0,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+              .clocks = rx1950_serial_clocks,
+              .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+       },
+       [1] = {
+              .hwport = 1,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x03,
+              .ufcon = 0x51,
+              .clocks = rx1950_serial_clocks,
+              .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+       },
+       /* IR port */
+       [2] = {
+              .hwport = 2,
+              .flags = 0,
+              .ucon = 0x3c5,
+              .ulcon = 0x43,
+              .ufcon = 0xf1,
+              .clocks = rx1950_serial_clocks,
+              .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+       },
+};
+
+static struct s3c2410fb_display rx1950_display = {
+       .type = S3C2410_LCDCON1_TFT,
+       .width = 240,
+       .height = 320,
+       .xres = 240,
+       .yres = 320,
+       .bpp = 16,
+
+       .pixclock = 260000,
+       .left_margin = 10,
+       .right_margin = 20,
+       .hsync_len = 10,
+       .upper_margin = 2,
+       .lower_margin = 2,
+       .vsync_len = 2,
+
+       .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+                          S3C2410_LCDCON5_INVVCLK |
+                          S3C2410_LCDCON5_INVVLINE |
+                          S3C2410_LCDCON5_INVVFRAME |
+                          S3C2410_LCDCON5_HWSWP |
+                          (0x02 << 13) |
+                          (0x02 << 15),
+
+};
+
+static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
+       .displays = &rx1950_display,
+       .num_displays = 1,
+       .default_display = 0,
+
+       .lpcsel = 0x02,
+       .gpccon = 0xaa9556a9,
+       .gpccon_mask = 0xffc003fc,
+       .gpcup = 0x0000ffff,
+       .gpcup_mask = 0xffffffff,
+
+       .gpdcon = 0xaa90aaa1,
+       .gpdcon_mask = 0xffc0fff0,
+       .gpdup = 0x0000fcfd,
+       .gpdup_mask = 0xffffffff,
+
+};
+
+static struct pwm_device *lcd_pwm;
+
+void rx1950_lcd_power(int enable)
+{
+       int i;
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+
+               /* GPC11-GPC15->OUTPUT */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 1);
+
+               /* Wait a bit here... */
+               mdelay(100);
+
+               /* GPD2-GPD7->OUTPUT */
+               /* GPD11-GPD15->OUTPUT */
+               /* GPD2-GPD7->1, GPD11-GPD15->1 */
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 1);
+
+               /* Wait a bit here...*/
+               mdelay(100);
+
+               /* GPB0->OUTPUT, GPB0->0 */
+               gpio_direction_output(S3C2410_GPB(0), 0);
+
+               /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
+               for (i = 1; i < 5; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+
+               /* GPC15-GPC11->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPC(i), 0);
+
+               /* GPD15-GPD11->0, GPD2->GPD7->0 */
+               for (i = 11; i < 16; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+
+               for (i = 2; i < 8; i++)
+                       gpio_direction_output(S3C2410_GPD(i), 0);
+
+               /* GPC6->0, GPC7->0, GPC5->0 */
+               gpio_direction_output(S3C2410_GPC(6), 0);
+               gpio_direction_output(S3C2410_GPC(7), 0);
+               gpio_direction_output(S3C2410_GPC(5), 0);
+
+               /* GPB1->OUTPUT, GPB1->0 */
+               gpio_direction_output(S3C2410_GPB(1), 0);
+               pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
+               pwm_disable(lcd_pwm);
+
+               /* GPC0->0, GPC10->0 */
+               gpio_direction_output(S3C2410_GPC(0), 0);
+               gpio_direction_output(S3C2410_GPC(10), 0);
+       } else {
+               pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
+               pwm_enable(lcd_pwm);
+
+               gpio_direction_output(S3C2410_GPC(0), 1);
+               gpio_direction_output(S3C2410_GPC(5), 1);
+
+               s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
+               gpio_direction_output(S3C2410_GPC(7), 1);
+
+               for (i = 1; i < 5; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+               for (i = 2; i < 8; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+               for (i = 11; i < 16; i++)
+                       s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+               gpio_direction_output(S3C2410_GPC(10), 1);
+               gpio_direction_output(S3C2410_GPC(6), 1);
+       }
+       enabled = enable;
+}
+
+static void rx1950_bl_power(int enable)
+{
+       static int enabled;
+       if (enabled == enable)
+               return;
+       if (!enable) {
+                       gpio_direction_output(S3C2410_GPB(0), 0);
+       } else {
+                       /* LED driver need a "push" to power on */
+                       gpio_direction_output(S3C2410_GPB(0), 1);
+                       /* Warm up backlight for one period of PWM.
+                        * Without this trick its almost impossible to
+                        * enable backlight with low brightness value
+                        */
+                       ndelay(48000);
+                       s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+       }
+       enabled = enable;
+}
+
+static int rx1950_backlight_init(struct device *dev)
+{
+       WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
+       lcd_pwm = pwm_request(1, "RX1950 LCD");
+       if (IS_ERR(lcd_pwm)) {
+               dev_err(dev, "Unable to request PWM for LCD power!\n");
+               return PTR_ERR(lcd_pwm);
+       }
+
+       rx1950_lcd_power(1);
+       rx1950_bl_power(1);
+
+       return 0;
+}
+
+static void rx1950_backlight_exit(struct device *dev)
+{
+       rx1950_bl_power(0);
+       rx1950_lcd_power(0);
+
+       pwm_free(lcd_pwm);
+       gpio_free(S3C2410_GPB(0));
+}
+
+
+static int rx1950_backlight_notify(struct device *dev, int brightness)
+{
+       if (!brightness) {
+               rx1950_bl_power(0);
+               rx1950_lcd_power(0);
+       } else {
+               rx1950_lcd_power(1);
+               rx1950_bl_power(1);
+       }
+       return brightness;
+}
+
+static struct platform_pwm_backlight_data rx1950_backlight_data = {
+       .pwm_id = 0,
+       .max_brightness = 24,
+       .dft_brightness = 4,
+       .pwm_period_ns = 48000,
+       .init = rx1950_backlight_init,
+       .notify = rx1950_backlight_notify,
+       .exit = rx1950_backlight_exit,
+};
+
+static struct platform_device rx1950_backlight = {
+       .name = "pwm-backlight",
+       .dev = {
+               .parent = &s3c_device_timer[0].dev,
+               .platform_data = &rx1950_backlight_data,
+       },
+};
+
+static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+       switch (power_mode) {
+       case MMC_POWER_OFF:
+               gpio_direction_output(S3C2410_GPJ(1), 0);
+               break;
+       case MMC_POWER_UP:
+       case MMC_POWER_ON:
+               gpio_direction_output(S3C2410_GPJ(1), 1);
+               break;
+       default:
+               break;
+       }
+}
+
+static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
+       .gpio_detect = S3C2410_GPF(5),
+       .gpio_wprotect = S3C2410_GPH(8),
+       .set_power = rx1950_set_mmc_power,
+       .ocr_avail = MMC_VDD_32_33,
+};
+
+static struct mtd_partition rx1950_nand_part[] = {
+       [0] = {
+                       .name = "Boot0",
+                       .offset = 0,
+                       .size = 0x4000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [1] = {
+                       .name = "Boot1",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x40000,
+                       .mask_flags = MTD_WRITEABLE,
+       },
+       [2] = {
+                       .name = "Kernel",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = 0x300000,
+                       .mask_flags = 0,
+       },
+       [3] = {
+                       .name = "Filesystem",
+                       .offset = MTDPART_OFS_APPEND,
+                       .size = MTDPART_SIZ_FULL,
+                       .mask_flags = 0,
+       },
+};
+
+static struct s3c2410_nand_set rx1950_nand_sets[] = {
+       [0] = {
+                       .name = "Internal",
+                       .nr_chips = 1,
+                       .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
+                       .partitions = rx1950_nand_part,
+       },
+};
+
+static struct s3c2410_platform_nand rx1950_nand_info = {
+       .tacls = 25,
+       .twrph0 = 50,
+       .twrph1 = 15,
+       .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
+       .sets = rx1950_nand_sets,
+};
+
+static void rx1950_udc_pullup(enum s3c2410_udc_cmd_e cmd)
+{
+       switch (cmd) {
+       case S3C2410_UDC_P_ENABLE:
+               gpio_direction_output(S3C2410_GPJ(5), 1);
+               break;
+       case S3C2410_UDC_P_DISABLE:
+               gpio_direction_output(S3C2410_GPJ(5), 0);
+               break;
+       case S3C2410_UDC_P_RESET:
+               break;
+       default:
+               break;
+       }
+}
+
+static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
+       .udc_command = rx1950_udc_pullup,
+       .vbus_pin = S3C2410_GPG(5),
+       .vbus_pin_inverted = 1,
+};
+
+static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
+       .delay = 10000,
+       .presc = 49,
+       .oversampling_shift = 3,
+};
+
+static struct gpio_keys_button rx1950_gpio_keys_table[] = {
+       {
+               .code           = KEY_POWER,
+               .gpio           = S3C2410_GPF(0),
+               .active_low     = 1,
+               .desc           = "Power button",
+               .wakeup         = 1,
+       },
+       {
+               .code           = KEY_F5,
+               .gpio           = S3C2410_GPF(7),
+               .active_low     = 1,
+               .desc           = "Record button",
+       },
+       {
+               .code           = KEY_F1,
+               .gpio           = S3C2410_GPG(0),
+               .active_low     = 1,
+               .desc           = "Calendar button",
+       },
+       {
+               .code           = KEY_F2,
+               .gpio           = S3C2410_GPG(2),
+               .active_low     = 1,
+               .desc           = "Contacts button",
+       },
+       {
+               .code           = KEY_F3,
+               .gpio           = S3C2410_GPG(3),
+               .active_low     = 1,
+               .desc           = "Mail button",
+       },
+       {
+               .code           = KEY_F4,
+               .gpio           = S3C2410_GPG(7),
+               .active_low     = 1,
+               .desc           = "WLAN button",
+       },
+       {
+               .code           = KEY_LEFT,
+               .gpio           = S3C2410_GPG(10),
+               .active_low     = 1,
+               .desc           = "Left button",
+       },
+       {
+               .code           = KEY_RIGHT,
+               .gpio           = S3C2410_GPG(11),
+               .active_low     = 1,
+               .desc           = "Right button",
+       },
+       {
+               .code           = KEY_UP,
+               .gpio           = S3C2410_GPG(4),
+               .active_low     = 1,
+               .desc           = "Up button",
+       },
+       {
+               .code           = KEY_DOWN,
+               .gpio           = S3C2410_GPG(6),
+               .active_low     = 1,
+               .desc           = "Down button",
+       },
+       {
+               .code           = KEY_ENTER,
+               .gpio           = S3C2410_GPG(9),
+               .active_low     = 1,
+               .desc           = "Ok button"
+       },
+};
+
+static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
+       .buttons = rx1950_gpio_keys_table,
+       .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
+};
+
+static struct platform_device rx1950_device_gpiokeys = {
+       .name = "gpio-keys",
+       .dev.platform_data = &rx1950_gpio_keys_data,
+};
+
+static struct s3c2410_platform_i2c rx1950_i2c_data = {
+       .flags = 0,
+       .slave_addr = 0x42,
+       .frequency = 400 * 1000,
+       .sda_delay = S3C2410_IICLC_SDA_DELAY5 | S3C2410_IICLC_FILTER_ON,
+};
+
+static struct platform_device *rx1950_devices[] __initdata = {
+       &s3c_device_lcd,
+       &s3c_device_wdt,
+       &s3c_device_i2c0,
+       &s3c_device_iis,
+       &s3c_device_usbgadget,
+       &s3c_device_rtc,
+       &s3c_device_nand,
+       &s3c_device_sdi,
+       &s3c_device_adc,
+       &s3c_device_ts,
+       &s3c_device_timer[0],
+       &s3c_device_timer[1],
+       &rx1950_backlight,
+       &rx1950_device_gpiokeys,
+};
+
+static struct clk *rx1950_clocks[] __initdata = {
+       &s3c24xx_clkout0,
+       &s3c24xx_clkout1,
+};
+
+static void __init rx1950_map_io(void)
+{
+       s3c24xx_clkout0.parent  = &clk_h;
+       s3c24xx_clkout1.parent  = &clk_f;
+
+       s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+
+       s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+       s3c24xx_init_clocks(16934000);
+       s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+
+       /* setup PM */
+
+#ifdef CONFIG_PM_H1940
+       memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
+#endif
+
+       s3c_pm_init();
+}
+
+static void __init rx1950_init_machine(void)
+{
+       int i;
+
+       s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
+       s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
+       s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
+       s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
+       s3c_i2c0_set_platdata(&rx1950_i2c_data);
+       s3c_nand_set_platdata(&rx1950_nand_info);
+
+       /* Turn off suspend on both USB ports, and switch the
+        * selectable USB port to USB device mode. */
+       s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+                                               S3C2410_MISCCR_USBSUSPND0 |
+                                               S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+       WARN_ON(gpio_request(S3C2410_GPJ(5), "UDC pullup"));
+       gpio_direction_output(S3C2410_GPJ(5), 0);
+
+       /* mmc power is disabled by default */
+       WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
+       gpio_direction_output(S3C2410_GPJ(1), 0);
+
+       for (i = 0; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+       for (i = 10; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+       for (i = 2; i < 8; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+       for (i = 11; i < 16; i++)
+               WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+       WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
+
+       platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+}
+
+MACHINE_START(RX1950, "HP iPAQ RX1950")
+    /* Maintainers: Vasily Khoruzhick */
+    .phys_io = S3C2410_PA_UART,
+       .io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc,
+       .boot_params = S3C2410_SDRAM_PA + 0x100,
+       .map_io = rx1950_map_io,
+       .init_irq = s3c24xx_init_irq,
+       .init_machine = rx1950_init_machine,
+       .timer = &s3c24xx_timer,
+MACHINE_END
index 1e836e5..d2946de 100644 (file)
@@ -209,7 +209,7 @@ static void __init rx3715_init_machine(void)
 }
 
 MACHINE_START(RX3715, "IPAQ-RX3715")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 3ac3d63..df83276 100644 (file)
@@ -174,7 +174,7 @@ static void __init smdk2440_machine_init(void)
 }
 
 MACHINE_START(S3C2440, "SMDK2440")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 2b68f7e..d50f3ae 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
+#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
 #include <plat/cpu.h>
 #include <plat/s3c244x.h>
 
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
 static struct sys_device s3c2440_sysdev = {
        .cls            = &s3c2440_sysclass,
 };
@@ -41,6 +46,9 @@ int __init s3c2440_init(void)
 {
        printk("S3C2440: Initialising architecture\n");
 
+       s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+       s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
        /* change irq for watchdog */
 
        s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
index 698140a..4fef723 100644 (file)
@@ -8,6 +8,7 @@ config CPU_S3C2443
        select S3C2443_DMA if S3C2410_DMA
        select CPU_LLSERIAL_S3C2440
        select SAMSUNG_CLKSRC
+       select S3C2443_CLOCK
        help
          Support for the S3C2443 SoC from the S3C24XX line
 
index 62cd4ea..83b1aa6 100644 (file)
@@ -21,6 +21,7 @@
 */
 
 #include <linux/init.h>
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
  * set the correct muxing at initialisation
 */
 
-static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
-{
-       u32 ctrlbit = clk->ctrlbit;
-       u32 con = __raw_readl(reg);
-
-       if (enable)
-               con |= ctrlbit;
-       else
-               con &= ~ctrlbit;
-
-       __raw_writel(con, reg);
-       return 0;
-}
-
-static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
-{
-       return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
-}
-
-static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
-{
-       return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
-}
-
-static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
-{
-       return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
-}
-
 /* clock selections */
 
-/* mpllref is a direct descendant of clk_xtal by default, but it is not
- * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
- * such directly equating the two source clocks is impossible.
- */
-static struct clk clk_mpllref = {
-       .name           = "mpllref",
-       .parent         = &clk_xtal,
-       .id             = -1,
-};
-
 static struct clk clk_i2s_ext = {
        .name           = "i2s-ext",
        .id             = -1,
 };
 
-static struct clk *clk_epllref_sources[] = {
-       [0] = &clk_mpllref,
-       [1] = &clk_mpllref,
-       [2] = &clk_xtal,
-       [3] = &clk_ext,
-};
-
-static struct clksrc_clk clk_epllref = {
-       .clk    = {
-               .name           = "epllref",
-               .id             = -1,
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_epllref_sources,
-               .nr_sources = ARRAY_SIZE(clk_epllref_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
-};
-
-static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
-{
-       unsigned long parent_rate = clk_get_rate(clk->parent);
-       unsigned long div = __raw_readl(S3C2443_CLKDIV0);
-
-       div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
-       div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
-
-       return parent_rate / (div + 1);
-}
-
-static struct clk clk_mdivclk = {
-       .name           = "mdivclk",
-       .parent         = &clk_mpllref,
-       .id             = -1,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2443_getrate_mdivclk,
-       },
-};
-
-static struct clk *clk_msysclk_sources[] = {
-       [0] = &clk_mpllref,
-       [1] = &clk_mpll,
-       [2] = &clk_mdivclk,
-       [3] = &clk_mpllref,
-};
-
-static struct clksrc_clk clk_msysclk = {
-       .clk    = {
-               .name           = "msysclk",
-               .parent         = &clk_xtal,
-               .id             = -1,
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_msysclk_sources,
-               .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
-};
-
 /* armdiv
  *
  * this clock is sourced from msysclk and can have a number of
@@ -266,44 +169,6 @@ static struct clksrc_clk clk_arm = {
        .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
 };
 
-/* esysclk
- *
- * this is sourced from either the EPLL or the EPLLref clock
-*/
-
-static struct clk *clk_sysclk_sources[] = {
-       [0] = &clk_epllref.clk,
-       [1] = &clk_epll,
-};
-
-static struct clksrc_clk clk_esysclk = {
-       .clk    = {
-               .name           = "esysclk",
-               .parent         = &clk_epll,
-               .id             = -1,
-       },
-       .sources = &(struct clksrc_sources) {
-               .sources = clk_sysclk_sources,
-               .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
-       },
-       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
-};
-
-/* uartclk
- *
- * UART baud-rate clock sourced from esysclk via a divisor
-*/
-
-static struct clksrc_clk clk_uart = {
-       .clk    = {
-               .name           = "uartclk",
-               .id             = -1,
-               .parent         = &clk_esysclk.clk,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
-};
-
-
 /* hsspi
  *
  * high-speed spi clock, sourced from esysclk
@@ -320,21 +185,6 @@ static struct clksrc_clk clk_hsspi = {
        .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
 };
 
-/* usbhost
- *
- * usb host bus-clock, usually 48MHz to provide USB bus clock timing
-*/
-
-static struct clksrc_clk clk_usb_bus_host = {
-       .clk    = {
-               .name           = "usb-bus-host-parent",
-               .id             = -1,
-               .parent         = &clk_esysclk.clk,
-               .ctrlbit        = S3C2443_SCLKCON_USBHOST,
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
-};
 
 /* clk_hsmcc_div
  *
@@ -433,88 +283,15 @@ static struct clksrc_clk clk_i2s = {
        .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
 };
 
-/* cam-if
- *
- * camera interface bus-clock, divided down from esysclk
-*/
-
-static struct clksrc_clk clk_cam = {
-       .clk    = {
-               .name           = "camif-upll", /* same as 2440 name */
-               .id             = -1,
-               .parent         = &clk_esysclk.clk,
-               .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
-};
-
-/* display-if
- *
- * display interface clock, divided from esysclk
-*/
-
-static struct clksrc_clk clk_display = {
-       .clk    = {
-               .name           = "display-if",
-               .id             = -1,
-               .parent         = &clk_esysclk.clk,
-               .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
-               .enable         = s3c2443_clkcon_enable_s,
-       },
-       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
-};
-
-/* prediv
- *
- * this divides the msysclk down to pass to h/p/etc.
- */
-
-static unsigned long s3c2443_prediv_getrate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
-       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-
-       clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
-       clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
-
-       return rate / (clkdiv0 + 1);
-}
-
-static struct clk clk_prediv = {
-       .name           = "prediv",
-       .id             = -1,
-       .parent         = &clk_msysclk.clk,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s3c2443_prediv_getrate,
-       },
-};
-
 /* standard clock definitions */
 
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks_off[] = {
        {
-               .name           = "nand",
-               .id             = -1,
-               .parent         = &clk_h,
-       }, {
                .name           = "sdi",
                .id             = -1,
                .parent         = &clk_p,
                .enable         = s3c2443_clkcon_enable_p,
                .ctrlbit        = S3C2443_PCLKCON_SDI,
-       }, {
-               .name           = "adc",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_ADC,
-       }, {
-               .name           = "i2c",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_IIC,
        }, {
                .name           = "iis",
                .id             = -1,
@@ -537,179 +314,12 @@ static struct clk init_clocks_disable[] = {
 };
 
 static struct clk init_clocks[] = {
-       {
-               .name           = "dma",
-               .id             = 0,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA0,
-       }, {
-               .name           = "dma",
-               .id             = 1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA1,
-       }, {
-               .name           = "dma",
-               .id             = 2,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA2,
-       }, {
-               .name           = "dma",
-               .id             = 3,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA3,
-       }, {
-               .name           = "dma",
-               .id             = 4,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA4,
-       }, {
-               .name           = "dma",
-               .id             = 5,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_DMA5,
-       }, {
-               .name           = "lcd",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_LCDC,
-       }, {
-               .name           = "gpio",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_GPIO,
-       }, {
-               .name           = "usb-host",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_USBH,
-       }, {
-               .name           = "usb-device",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_USBD,
-       }, {
-               .name           = "hsmmc",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_HSMMC,
-       }, {
-               .name           = "cfc",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_CFC,
-       }, {
-               .name           = "ssmc",
-               .id             = -1,
-               .parent         = &clk_h,
-               .enable         = s3c2443_clkcon_enable_h,
-               .ctrlbit        = S3C2443_HCLKCON_SSMC,
-       }, {
-               .name           = "timers",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_PWMT,
-       }, {
-               .name           = "uart",
-               .id             = 0,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART0,
-       }, {
-               .name           = "uart",
-               .id             = 1,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART1,
-       }, {
-               .name           = "uart",
-               .id             = 2,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART2,
-       }, {
-               .name           = "uart",
-               .id             = 3,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_UART3,
-       }, {
-               .name           = "rtc",
-               .id             = -1,
-               .parent         = &clk_p,
-               .enable         = s3c2443_clkcon_enable_p,
-               .ctrlbit        = S3C2443_PCLKCON_RTC,
-       }, {
-               .name           = "watchdog",
-               .id             = -1,
-               .parent         = &clk_p,
-               .ctrlbit        = S3C2443_PCLKCON_WDT,
-       }, {
-               .name           = "usb-bus-host",
-               .id             = -1,
-               .parent         = &clk_usb_bus_host.clk,
-       }, {
-               .name           = "ac97",
-               .id             = -1,
-               .parent         = &clk_p,
-               .ctrlbit        = S3C2443_PCLKCON_AC97,
-       }
-};
-
-/* clocks to add where we need to check their parentage */
-
-static struct clksrc_clk __initdata *init_list[] = {
-       &clk_epllref, /* should be first */
-       &clk_esysclk,
-       &clk_msysclk,
-       &clk_arm,
-       &clk_i2s_eplldiv,
-       &clk_i2s,
-       &clk_cam,
-       &clk_uart,
-       &clk_display,
-       &clk_hsmmc_div,
-       &clk_usb_bus_host,
 };
 
-static void __init s3c2443_clk_initparents(void)
-{
-       int ptr;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
-               s3c_set_clksrc(init_list[ptr], true);
-}
-
-static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
-{
-       clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
-
-       return clkcon0 + 1;
-}
-
 /* clocks to add straight away */
 
 static struct clksrc_clk *clksrcs[] __initdata = {
-       &clk_usb_bus_host,
-       &clk_epllref,
-       &clk_esysclk,
-       &clk_msysclk,
        &clk_arm,
-       &clk_uart,
-       &clk_display,
-       &clk_cam,
        &clk_i2s_eplldiv,
        &clk_i2s,
        &clk_hsspi,
@@ -717,92 +327,32 @@ static struct clksrc_clk *clksrcs[] __initdata = {
 };
 
 static struct clk *clks[] __initdata = {
-       &clk_ext,
-       &clk_epll,
-       &clk_usb_bus,
-       &clk_mpllref,
        &clk_hsmmc,
        &clk_armdiv,
-       &clk_prediv,
 };
 
 void __init_or_cpufreq s3c2443_setup_clocks(void)
 {
-       unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
-       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
-       struct clk *xtal_clk;
-       unsigned long xtal;
-       unsigned long pll;
-       unsigned long fclk;
-       unsigned long hclk;
-       unsigned long pclk;
-
-       xtal_clk = clk_get(NULL, "xtal");
-       xtal = clk_get_rate(xtal_clk);
-       clk_put(xtal_clk);
-
-       pll = s3c2443_get_mpll(mpllcon, xtal);
-       clk_msysclk.clk.rate = pll;
-
-       fclk = pll / s3c2443_fclk_div(clkdiv0);
-       hclk = s3c2443_prediv_getrate(&clk_prediv);
-       hclk /= s3c2443_get_hdiv(clkdiv0);
-       pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
-
-       s3c24xx_setup_clocks(fclk, hclk, pclk);
-
-       printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
-              (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
-              print_mhz(pll), print_mhz(fclk),
-              print_mhz(hclk), print_mhz(pclk));
-
-       s3c24xx_setup_clocks(fclk, hclk, pclk);
+       s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
 }
 
 void __init s3c2443_init_clocks(int xtal)
 {
-       struct clk *clkp;
        unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
-       int ret;
        int ptr;
 
-       /* s3c2443 parents h and p clocks from prediv */
-       clk_h.parent = &clk_prediv;
-       clk_p.parent = &clk_prediv;
+       clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+       clk_epll.parent = &clk_epllref.clk;
+
+       s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
 
-       s3c24xx_register_baseclocks(xtal);
        s3c2443_setup_clocks();
-       s3c2443_clk_initparents();
-
-       for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
-               clkp = clks[ptr];
 
-               ret = s3c24xx_register_clock(clkp);
-               if (ret < 0) {
-                       printk(KERN_ERR "Failed to register clock %s (%d)\n",
-                              clkp->name, ret);
-               }
-       }
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_register_clksrc(clksrcs[ptr], 1);
 
-       clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
-       clk_epll.parent = &clk_epllref.clk;
-       clk_usb_bus.parent = &clk_usb_bus_host.clk;
-
-       /* ensure usb bus clock is within correct rate of 48MHz */
-
-       if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
-               printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
-               clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
-       }
-
-       printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
-              (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
-              print_mhz(clk_get_rate(&clk_epll)),
-              print_mhz(clk_get_rate(&clk_usb_bus)));
-
        /* register clocks from clock array */
 
        s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
@@ -819,17 +369,8 @@ void __init s3c2443_init_clocks(int xtal)
 
        /* install (and disable) the clocks we do not need immediately */
 
-       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_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
        s3c_pwmclk_init();
 }
index e2e362b..4c863d3 100644 (file)
@@ -131,7 +131,7 @@ static void __init smdk2443_machine_init(void)
 }
 
 MACHINE_START(SMDK2443, "SMDK2443")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C2410_PA_UART,
        .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C2410_SDRAM_PA + 0x100,
index 959df38..69e9fbf 100644 (file)
@@ -85,6 +85,7 @@ config MACH_ANW6410
 config MACH_SMDK6410
        bool "SMDK6410"
        select CPU_S3C6410
+       select SAMSUNG_DEV_ADC
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_I2C1
index 3758e15..a10f1fc 100644 (file)
@@ -56,7 +56,6 @@ obj-$(CONFIG_MACH_HMT)                += mach-hmt.o
 # device support
 
 obj-y                          += dev-uart.o
-obj-y                          += dev-rtc.o
 obj-y                          += dev-audio.o
-obj-$(CONFIG_S3C_ADC)          += dev-adc.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)  += dev-spi.o
+obj-$(CONFIG_S3C64XX_DEV_TS)   += dev-ts.o
index 2ac2e7d..7a4138b 100644 (file)
@@ -88,6 +88,12 @@ struct clk clk_48m = {
        .enable         = clk_48m_ctrl,
 };
 
+struct clk clk_xusbxti = {
+       .name           = "xusbxti",
+       .id             = -1,
+       .rate           = 48000000,
+};
+
 static int inline s3c64xx_gate(void __iomem *reg,
                                struct clk *clk,
                                int enable)
@@ -518,6 +524,11 @@ static struct clk clk_iis_cd1 = {
        .id             = -1,
 };
 
+static struct clk clk_iisv4_cd = {
+       .name           = "iis_cdclk_v4",
+       .id             = -1,
+};
+
 static struct clk clk_pcm_cd = {
        .name           = "pcm_cdclk",
        .id             = -1,
@@ -549,6 +560,19 @@ static struct clksrc_sources clkset_audio1 = {
        .nr_sources     = ARRAY_SIZE(clkset_audio1_list),
 };
 
+static struct clk *clkset_audio2_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_dout_mpll,
+       [2] = &clk_fin_epll,
+       [3] = &clk_iisv4_cd,
+       [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio2 = {
+       .sources        = clkset_audio2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_audio2_list),
+};
+
 static struct clk *clkset_camif_list[] = {
        &clk_h2,
 };
@@ -650,6 +674,16 @@ static struct clksrc_clk clksrcs[] = {
                .reg_src        = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3  },
                .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4  },
                .sources        = &clkset_audio1,
+       }, {
+               .clk    = {
+                       .name           = "audio-bus",
+                       .id             = -1,  /* There's only one IISv4 port */
+                       .ctrlbit        = S3C6410_CLKCON_SCLK_AUDIO2,
+                       .enable         = s3c64xx_sclk_ctrl,
+               },
+               .reg_src        = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3  },
+               .reg_div        = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4  },
+               .sources        = &clkset_audio2,
        }, {
                .clk    = {
                        .name           = "irda-bus",
@@ -749,6 +783,7 @@ static struct clk *clks1[] __initdata = {
        &clk_ext_xtal_mux,
        &clk_iis_cd0,
        &clk_iis_cd1,
+       &clk_iisv4_cd,
        &clk_pcm_cd,
        &clk_mout_epll.clk,
        &clk_mout_mpll.clk,
@@ -762,6 +797,7 @@ static struct clk *clks[] __initdata = {
        &clk_27m,
        &clk_48m,
        &clk_h2,
+       &clk_xusbxti,
 };
 
 /**
diff --git a/arch/arm/mach-s3c64xx/dev-adc.c b/arch/arm/mach-s3c64xx/dev-adc.c
deleted file mode 100644 (file)
index fafef9b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/dev-adc.c
- *
- * Copyright 2010 Maurus Cuelenaere
- *
- * S3C64xx series device definition for ADC device
- *
- * 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/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/adc.h>
-#include <plat/devs.h>
-#include <plat/cpu.h>
-
-static struct resource s3c_adc_resource[] = {
-       [0] = {
-               .start = S3C64XX_PA_ADC,
-               .end   = S3C64XX_PA_ADC + SZ_256 - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_TC,
-               .end   = IRQ_TC,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_ADC,
-               .end   = IRQ_ADC,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device s3c_device_adc = {
-       .name           = "s3c64xx-adc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(s3c_adc_resource),
-       .resource       = s3c_adc_resource,
-};
diff --git a/arch/arm/mach-s3c64xx/dev-rtc.c b/arch/arm/mach-s3c64xx/dev-rtc.c
deleted file mode 100644 (file)
index b9e7a05..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/dev-rtc.c
- *
- * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-static struct resource s3c_rtc_resource[] = {
-       [0] = {
-               .start = S3C64XX_PA_RTC,
-               .end   = S3C64XX_PA_RTC + 0xff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_RTC_ALARM,
-               .end   = IRQ_RTC_ALARM,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_RTC_TIC,
-               .end   = IRQ_RTC_TIC,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-struct platform_device s3c_device_rtc = {
-       .name             = "s3c64xx-rtc",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(s3c_rtc_resource),
-       .resource         = s3c_rtc_resource,
-};
-EXPORT_SYMBOL(s3c_device_rtc);
index 33ccf7b..5567e03 100644 (file)
@@ -414,7 +414,7 @@ err_buff:
 EXPORT_SYMBOL(s3c2410_dma_enqueue);
 
 
-int s3c2410_dma_devconfig(int channel,
+int s3c2410_dma_devconfig(unsigned int channel,
                          enum s3c2410_dmasrc source,
                          unsigned long devaddr)
 {
index 66e6794..60c929a 100644 (file)
@@ -51,6 +51,7 @@
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .get_config     = s3c_gpio_getcfg_s3c64xx_4bit,
        .set_pull       = s3c_gpio_setpull_updown,
        .get_pull       = s3c_gpio_getpull_updown,
 };
@@ -58,12 +59,14 @@ static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
        .cfg_eint       = 7,
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .get_config     = s3c_gpio_getcfg_s3c64xx_4bit,
        .set_pull       = s3c_gpio_setpull_updown,
        .get_pull       = s3c_gpio_getpull_updown,
 };
 
 static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
        .cfg_eint       = 3,
+       .get_config     = s3c_gpio_getcfg_s3c64xx_4bit,
        .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
        .set_pull       = s3c_gpio_setpull_updown,
        .get_pull       = s3c_gpio_getpull_updown,
@@ -171,6 +174,7 @@ static struct s3c_gpio_chip gpio_4bit2[] = {
 
 static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
        .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .get_config     = s3c_gpio_getcfg_s3c24xx,
        .set_pull       = s3c_gpio_setpull_updown,
        .get_pull       = s3c_gpio_getpull_updown,
 };
@@ -178,6 +182,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
 static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
        .cfg_eint       = 2,
        .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .get_config     = s3c_gpio_getcfg_s3c24xx,
        .set_pull       = s3c_gpio_setpull_updown,
        .get_pull       = s3c_gpio_getpull_updown,
 };
@@ -185,6 +190,7 @@ static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
 static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
        .cfg_eint       = 3,
        .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .get_config     = s3c_gpio_getcfg_s3c24xx,
        .set_pull       = s3c_gpio_setpull_updown,
        .get_pull       = s3c_gpio_getpull_updown,
 };
index 801c1c0..9fdd50c 100644 (file)
 #define S3C_PA_USBHOST         S3C64XX_PA_USBHOST
 #define S3C_PA_USB_HSOTG       S3C64XX_PA_USB_HSOTG
 #define S3C_VA_USB_HSPHY       S3C64XX_VA_USB_HSPHY
+#define S3C_PA_RTC             S3C64XX_PA_RTC
+
+#define SAMSUNG_PA_ADC         S3C64XX_PA_ADC
 
 #endif /* __ASM_ARCH_6400_MAP_H */
index 90bbd72..5ef0bb6 100644 (file)
@@ -20,6 +20,7 @@
 #define S3C6400_PLL_SDIV_SHIFT (0)
 
 #include <asm/div64.h>
+#include <plat/pll6553x.h>
 
 static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
                                            u32 pllcon)
@@ -37,38 +38,8 @@ static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
        return (unsigned long)fvco;
 }
 
-#define S3C6400_EPLL_MDIV_MASK ((1 << (23-16)) - 1)
-#define S3C6400_EPLL_PDIV_MASK ((1 << (13-8)) - 1)
-#define S3C6400_EPLL_SDIV_MASK ((1 << (2-0)) - 1)
-#define S3C6400_EPLL_MDIV_SHIFT        (16)
-#define S3C6400_EPLL_PDIV_SHIFT        (8)
-#define S3C6400_EPLL_SDIV_SHIFT        (0)
-#define S3C6400_EPLL_KDIV_MASK  (0xffff)
-
 static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
 {
-       unsigned long result;
-       u32 epll0 = __raw_readl(S3C_EPLL_CON0);
-       u32 epll1 = __raw_readl(S3C_EPLL_CON1);
-       u32 mdiv, pdiv, sdiv, kdiv;
-       u64 tmp;
-
-       mdiv = (epll0 >> S3C6400_EPLL_MDIV_SHIFT) & S3C6400_EPLL_MDIV_MASK;
-       pdiv = (epll0 >> S3C6400_EPLL_PDIV_SHIFT) & S3C6400_EPLL_PDIV_MASK;
-       sdiv = (epll0 >> S3C6400_EPLL_SDIV_SHIFT) & S3C6400_EPLL_SDIV_MASK;
-       kdiv = epll1 & S3C6400_EPLL_KDIV_MASK;
-
-       /* We need to multiple baseclk by mdiv (the integer part) and kdiv
-        * which is in 2^16ths, so shift mdiv up (does not overflow) and
-        * add kdiv before multiplying. The use of tmp is to avoid any
-        * overflows before shifting bac down into result when multipling
-        * by the mdiv and kdiv pair.
-        */
-
-       tmp = baseclk;
-       tmp *= (mdiv << 16) + kdiv;
-       do_div(tmp, (pdiv << sdiv));
-       result = tmp >> 16;
-
-       return result;
+       return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
+                               __raw_readl(S3C_EPLL_CON1));
 }
index 3ef6274..0114eb0 100644 (file)
@@ -33,6 +33,7 @@
 #define S3C_PCLK_GATE          S3C_CLKREG(0x34)
 #define S3C_SCLK_GATE          S3C_CLKREG(0x38)
 #define S3C_MEM0_GATE          S3C_CLKREG(0x3C)
+#define S3C6410_CLK_SRC2       S3C_CLKREG(0x10C)
 
 /* CLKDIV0 */
 #define S3C6400_CLKDIV0_PCLK_MASK      (0xf << 12)
index f7b1898..5991667 100644 (file)
@@ -84,7 +84,7 @@ static void __init smdk6400_machine_init(void)
 }
 
 MACHINE_START(SMDK6400, "SMDK6400")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C_PA_UART & 0xfff00000,
        .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C64XX_PA_SDRAM + 0x100,
index 2d5afd2..9d51455 100644 (file)
@@ -656,7 +656,7 @@ static void __init smdk6410_machine_init(void)
 }
 
 MACHINE_START(SMDK6410, "SMDK6410")
-       /* Maintainer: Ben Dooks <ben@fluff.org> */
+       /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
        .phys_io        = S3C_PA_UART & 0xfff00000,
        .io_pg_offst    = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
        .boot_params    = S3C64XX_PA_SDRAM + 0x100,
index 59635d1..3ab695c 100644 (file)
@@ -38,6 +38,7 @@
 #include <plat/clock.h>
 #include <plat/sdhci.h>
 #include <plat/iic-core.h>
+#include <plat/adc.h>
 #include <mach/s3c6400.h>
 #include <mach/s3c6410.h>
 
@@ -52,6 +53,7 @@ void __init s3c6410_map_io(void)
        s3c_i2c0_setname("s3c2440-i2c");
        s3c_i2c1_setname("s3c2440-i2c");
 
+       s3c_device_adc.name     = "s3c64xx-adc";
        s3c_device_nand.name = "s3c6400-nand";
 }
 
index 4c29ff8..77aeffd 100644 (file)
@@ -9,6 +9,7 @@ if ARCH_S5P6440
 
 config CPU_S5P6440
        bool
+       select S3C_PL330_DMA
        help
          Enable S5P6440 CPU support
 
index 1ad894b..44facf4 100644 (file)
@@ -12,8 +12,12 @@ obj-                         :=
 
 # Core support for S5P6440 system
 
-obj-$(CONFIG_CPU_S5P6440)      += cpu.o init.o clock.o gpio.o
+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
index b2672e1..ca6e48d 100644 (file)
@@ -134,24 +134,6 @@ static struct clksrc_clk clk_mout_mpll = {
        .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 1, .size = 1 },
 };
 
-static struct clk clk_h_low = {
-       .name           = "hclk_low",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-       .ops            = &clk_ops_def_setrate,
-};
-
-static struct clk clk_p_low = {
-       .name           = "pclk_low",
-       .id             = -1,
-       .rate           = 0,
-       .parent         = NULL,
-       .ctrlbit        = 0,
-       .ops            = &clk_ops_def_setrate,
-};
-
 enum perf_level {
        L0 = 532*1000,
        L1 = 266*1000,
@@ -247,23 +229,70 @@ static struct clk_ops s5p6440_clkarm_ops = {
        .round_rate     = s5p6440_armclk_round_rate,
 };
 
-static unsigned long s5p6440_clk_doutmpll_get_rate(struct clk *clk)
-{
-       unsigned long rate = clk_get_rate(clk->parent);
+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 },
+};
 
-       if (__raw_readl(S5P_CLK_DIV0) & S5P_CLKDIV0_MPLL_MASK)
-               rate /= 2;
+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 },
+};
 
-       return rate;
-}
+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 clk clk_dout_mpll = {
-       .name           = "dout_mpll",
-       .id             = -1,
-       .parent         = &clk_mout_mpll.clk,
-       .ops            = &(struct clk_ops) {
-               .get_rate       = s5p6440_clk_doutmpll_get_rate,
+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)
@@ -307,6 +336,11 @@ 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);
@@ -321,37 +355,37 @@ static struct clk init_clocks_disable[] = {
        {
                .name           = "nand",
                .id             = -1,
-               .parent         = &clk_h,
+               .parent         = &clk_hclk.clk,
                .enable         = s5p6440_mem_ctrl,
                .ctrlbit        = S5P_CLKCON_MEM0_HCLK_NFCON,
        }, {
                .name           = "adc",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_TSADC,
        }, {
                .name           = "i2c",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_IIC0,
        }, {
                .name           = "i2s_v40",
                .id             = 0,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_IIS2,
        }, {
                .name           = "spi",
                .id             = 0,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_SPI0,
        }, {
                .name           = "spi",
                .id             = 1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_SPI1,
        }, {
@@ -387,58 +421,124 @@ static struct clk init_clocks_disable[] = {
        }, {
                .name           = "otg",
                .id             = -1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_USB
        }, {
                .name           = "post",
                .id             = -1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_POST0
        }, {
                .name           = "lcd",
                .id             = -1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk1_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK1_DISPCON,
        }, {
                .name           = "hsmmc",
                .id             = 0,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC0,
        }, {
                .name           = "hsmmc",
                .id             = 1,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC1,
        }, {
                .name           = "hsmmc",
                .id             = 2,
-               .parent         = &clk_h_low,
+               .parent         = &clk_hclk_low.clk,
                .enable         = s5p6440_hclk0_ctrl,
                .ctrlbit        = S5P_CLKCON_HCLK0_HSMMC2,
        }, {
                .name           = "rtc",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_RTC,
        }, {
                .name           = "watchdog",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_WDT,
        }, {
                .name           = "timers",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .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),
+       },
 };
 
 /*
@@ -448,34 +548,46 @@ static struct clk init_clocks[] = {
        {
                .name           = "gpio",
                .id             = -1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_GPIO,
        }, {
                .name           = "uart",
                .id             = 0,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART0,
        }, {
                .name           = "uart",
                .id             = 1,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART1,
        }, {
                .name           = "uart",
                .id             = 2,
-               .parent         = &clk_p_low,
+               .parent         = &clk_pclk_low.clk,
                .enable         = s5p6440_pclk_ctrl,
                .ctrlbit        = S5P_CLKCON_PCLK_UART2,
        }, {
                .name           = "uart",
                .id             = 3,
-               .parent         = &clk_p_low,
+               .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 = {
@@ -488,20 +600,20 @@ static struct clk clk_pcm_cd = {
        .id             = -1,
 };
 
-static struct clk *clkset_spi_mmc_list[] = {
+static struct clk *clkset_group1_list[] = {
        &clk_mout_epll.clk,
-       &clk_dout_mpll,
+       &clk_dout_mpll.clk,
        &clk_fin_epll,
 };
 
-static struct clksrc_sources clkset_spi_mmc = {
-       .sources        = clkset_spi_mmc_list,
-       .nr_sources     = ARRAY_SIZE(clkset_spi_mmc_list),
+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_dout_mpll.clk,
 };
 
 static struct clksrc_sources clkset_uart = {
@@ -509,6 +621,19 @@ static struct clksrc_sources clkset_uart = {
        .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    = {
@@ -517,7 +642,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_MMC0,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 18, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4 },
        }, {
@@ -527,7 +652,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_MMC1,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 4 },
        }, {
@@ -537,7 +662,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_MMC2,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 22, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 4 },
        }, {
@@ -557,7 +682,7 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_SPI0,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .sources = &clkset_group1,
                .reg_src = { .reg = S5P_CLK_SRC0, .shift = 14, .size = 2 },
                .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
        }, {
@@ -567,17 +692,63 @@ static struct clksrc_clk clksrcs[] = {
                        .ctrlbit        = S5P_CLKCON_SCLK0_SPI1,
                        .enable         = s5p6440_sclk_ctrl,
                },
-               .sources = &clkset_spi_mmc,
+               .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 *init_parents[] = {
+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)
@@ -593,21 +764,13 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
        unsigned long apll;
        unsigned long mpll;
        unsigned int ptr;
-       u32 clkdiv0;
-       u32 clkdiv3;
 
        /* Set S5P6440 functions for clk_fout_epll */
        clk_fout_epll.enable = s5p6440_epll_enable;
        clk_fout_epll.ops = &s5p6440_epll_ops;
 
-       /* Set S5P6440 functions for arm clock */
-       clk_arm.parent = &clk_mout_apll.clk;
-       clk_arm.ops = &s5p6440_clkarm_ops;
        clk_48m.enable = s5p6440_clk48m_ctrl;
 
-       clkdiv0 = __raw_readl(S5P_CLK_DIV0);
-       clkdiv3 = __raw_readl(S5P_CLK_DIV3);
-
        xtal_clk = clk_get(NULL, "ext_xtal");
        BUG_ON(IS_ERR(xtal_clk));
 
@@ -619,41 +782,28 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
        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 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_ARM);
-       hclk = fclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK);
-       pclk = hclk / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK);
-
-       if (__raw_readl(S5P_OTHERS) & S5P_OTHERS_HCLK_LOW_SEL_MPLL) {
-               /* Asynchronous mode */
-               hclk_low = mpll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
-       } else {
-               /* Synchronous mode */
-               hclk_low = apll / GET_DIV(clkdiv3, S5P_CLKDIV3_HCLK_LOW);
-       }
-
-       pclk_low = hclk_low / GET_DIV(clkdiv3, S5P_CLKDIV3_PCLK_LOW);
+       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_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_apll.rate = apll;
-
        clk_f.rate = fclk;
        clk_h.rate = hclk;
        clk_p.rate = pclk;
-       clk_h_low.rate = hclk_low;
-       clk_p_low.rate = pclk_low;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-               s3c_set_clksrc(init_parents[ptr], true);
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_set_clksrc(&clksrcs[ptr], true);
@@ -661,13 +811,8 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
 
 static struct clk *clks[] __initdata = {
        &clk_ext,
-       &clk_mout_epll.clk,
-       &clk_mout_mpll.clk,
-       &clk_dout_mpll,
        &clk_iis_cd_v40,
        &clk_pcm_cd,
-       &clk_p_low,
-       &clk_h_low,
 };
 
 void __init s5p6440_register_clocks(void)
@@ -680,6 +825,9 @@ void __init s5p6440_register_clocks(void)
        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));
 
index 1794131..ca3b320 100644 (file)
@@ -88,7 +88,7 @@ void __init s5p6440_init_irq(void)
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
 
-static struct sysdev_class s5p6440_sysclass = {
+struct sysdev_class s5p6440_sysclass = {
        .name   = "s5p6440-core",
 };
 
diff --git a/arch/arm/mach-s5p6440/dev-audio.c b/arch/arm/mach-s5p6440/dev-audio.c
new file mode 100644 (file)
index 0000000..0c53679
--- /dev/null
@@ -0,0 +1,127 @@
+/* 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 <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/gpio.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/dma.c b/arch/arm/mach-s5p6440/dma.c
new file mode 100644 (file)
index 0000000..07606ad
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <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 <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5p6440_pdma_resource[] = {
+       [0] = {
+               .start  = S5P6440_PA_PDMA,
+               .end    = S5P6440_PA_PDMA + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_DMA0,
+               .end    = IRQ_DMA0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5p6440_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_MAX,
+               [9] = DMACH_MAX,
+               [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_MAX,
+               [17] = DMACH_MAX,
+               [18] = DMACH_MAX,
+               [19] = DMACH_MAX,
+               [20] = DMACH_SPI1_TX,
+               [21] = DMACH_SPI1_RX,
+               [22] = DMACH_MAX,
+               [23] = DMACH_MAX,
+               [24] = DMACH_MAX,
+               [25] = DMACH_MAX,
+               [26] = DMACH_MAX,
+               [27] = DMACH_MAX,
+               [28] = DMACH_MAX,
+               [29] = DMACH_PWM,
+               [30] = DMACH_MAX,
+               [31] = DMACH_MAX,
+       },
+};
+
+static struct platform_device s5p6440_device_pdma = {
+       .name           = "s3c-pl330",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p6440_pdma_resource),
+       .resource       = s5p6440_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)
+{
+       platform_add_devices(s5p6440_dmacs, ARRAY_SIZE(s5p6440_dmacs));
+
+       return 0;
+}
+arch_initcall(s5p6440_dma_init);
index b0ea741..262dc75 100644 (file)
@@ -161,12 +161,15 @@ static struct s3c_gpio_cfg s5p6440_gpio_cfgs[] = {
        }, {
                .cfg_eint       = 0,
                .set_config     = s3c_gpio_setcfg_s3c24xx,
+               .get_config     = s3c_gpio_getcfg_s3c24xx,
        }, {
                .cfg_eint       = 2,
                .set_config     = s3c_gpio_setcfg_s3c24xx,
+               .get_config     = s3c_gpio_getcfg_s3c24xx,
        }, {
                .cfg_eint       = 3,
                .set_config     = s3c_gpio_setcfg_s3c24xx,
+               .get_config     = s3c_gpio_getcfg_s3c24xx,
        },
 };
 
@@ -279,6 +282,8 @@ void __init s5p6440_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
        for (; nr_chips > 0; nr_chips--, chipcfg++) {
                if (!chipcfg->set_config)
                        chipcfg->set_config     = s3c_gpio_setcfg_s3c64xx_4bit;
+               if (!chipcfg->get_config)
+                       chipcfg->get_config     = s3c_gpio_getcfg_s3c64xx_4bit;
                if (!chipcfg->set_pull)
                        chipcfg->set_pull       = s3c_gpio_setpull_updown;
                if (!chipcfg->get_pull)
diff --git a/arch/arm/mach-s5p6440/include/mach/dma.h b/arch/arm/mach-s5p6440/include/mach/dma.h
new file mode 100644 (file)
index 0000000..81209eb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
index 8924e5a..72aedad 100644 (file)
@@ -29,6 +29,8 @@
 #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_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5P6440_PA_SDRAM
 
+/* I2S */
+#define S5P6440_PA_I2S         0xF2000000
+
+/* PCM */
+#define S5P6440_PA_PCM         0xF2100000
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5P6440_PA_UART
 #define S3C_PA_IIC             S5P6440_PA_IIC0
index c4bb7c5..6a2a02f 100644 (file)
@@ -1,11 +1,14 @@
 /* linux/arch/arm/mach-s5p6440/include/mach/pwm-clock.h
  *
+ * Copyright (c) 2009 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/
  *
- * Copyright 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
  *
  * S5P6440 - pwm clock and timer support
  *
  * published by the Free Software Foundation.
 */
 
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
 /**
  * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
  *
  * Return true if the given configuration from TCFG1 is a TCLK instead
  * any of the TDIV clocks.
  */
 static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
 {
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       return 0;
 }
 
 /**
@@ -35,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
  */
 static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
 {
-       return 1 << (1 + tcfg1);
+       return 1 << tcfg1;
 }
 
 /**
@@ -45,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
  */
 static inline unsigned int pwm_tdiv_has_div1(void)
 {
-       return 0;
+       return 1;
 }
 
 /**
@@ -56,7 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
  */
 static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
 {
-       return ilog2(div) - 1;
+       return ilog2(div);
 }
 
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+#define S3C_TCFG1_MUX_TCLK 0
+
+#endif /* __ASM_ARCH_PWMCLK_H */
index 3ae88f2..d7fede9 100644 (file)
@@ -84,6 +84,7 @@ static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdk6440_devices[] __initdata = {
+       &s5p6440_device_iis,
 };
 
 static void __init smdk6440_map_io(void)
diff --git a/arch/arm/mach-s5p6440/setup-i2c0.c b/arch/arm/mach-s5p6440/setup-i2c0.c
new file mode 100644 (file)
index 0000000..69e8a66
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5p6440/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       /* Will be populated later */
+}
index 4f3f6de..0fd41b4 100644 (file)
@@ -12,6 +12,7 @@ if ARCH_S5P6442
 config CPU_S5P6442
        bool
        select PLAT_S5P
+       select S3C_PL330_DMA
        help
          Enable S5P6442 CPU support
 
index dde39a6..e30a7f7 100644 (file)
@@ -12,8 +12,12 @@ obj-                         :=
 
 # Core support for S5P6442 system
 
-obj-$(CONFIG_CPU_S5P6442)      += cpu.o init.o clock.o
+obj-$(CONFIG_CPU_S5P6442)      += cpu.o init.o clock.o dma.o
+obj-$(CONFIG_CPU_S5P6442)      += setup-i2c0.o
 
 # machine support
 
 obj-$(CONFIG_MACH_SMDK6442)    += mach-smdk6442.o
+
+# device support
+obj-y                          += dev-audio.o
index bc2524d..a48fb55 100644 (file)
@@ -95,7 +95,7 @@ void __init s5p6442_init_irq(void)
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
 
-static struct sysdev_class s5p6442_sysclass = {
+struct sysdev_class s5p6442_sysclass = {
        .name   = "s5p6442-core",
 };
 
diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c
new file mode 100644 (file)
index 0000000..cb801e1
--- /dev/null
@@ -0,0 +1,197 @@
+/* linux/arch/arm/mach-s5p6442/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 <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5p6442_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case 1:
+               s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(2));
+               break;
+
+       case -1:
+               s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(2));
+               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 = s5p6442_cfg_i2s,
+};
+
+static struct resource s5p6442_iis0_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_I2S0,
+               .end   = S5P6442_PA_I2S0 + 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 s5p6442_device_iis0 = {
+       .name             = "s3c64xx-iis-v4",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5p6442_iis0_resource),
+       .resource         = s5p6442_iis0_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+static struct resource s5p6442_iis1_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_I2S1,
+               .end   = S5P6442_PA_I2S1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S1_TX,
+               .end   = DMACH_I2S1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S1_RX,
+               .end   = DMACH_I2S1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6442_device_iis1 = {
+       .name             = "s3c64xx-iis",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5p6442_iis1_resource),
+       .resource         = s5p6442_iis1_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5P6442_GPC0(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC0(4), S3C_GPIO_SFN(3));
+               break;
+
+       case 1:
+               s3c_gpio_cfgpin(S5P6442_GPC1(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5P6442_GPC1(4), S3C_GPIO_SFN(3));
+               break;
+
+       default:
+               printk(KERN_DEBUG "Invalid PCM Controller number!");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+       .cfg_gpio = s5p6442_pcm_cfg_gpio,
+};
+
+static struct resource s5p6442_pcm0_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_PCM0,
+               .end   = S5P6442_PA_PCM0 + 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 s5p6442_device_pcm0 = {
+       .name             = "samsung-pcm",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s5p6442_pcm0_resource),
+       .resource         = s5p6442_pcm0_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource s5p6442_pcm1_resource[] = {
+       [0] = {
+               .start = S5P6442_PA_PCM1,
+               .end   = S5P6442_PA_PCM1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM1_TX,
+               .end   = DMACH_PCM1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM1_RX,
+               .end   = DMACH_PCM1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5p6442_device_pcm1 = {
+       .name             = "samsung-pcm",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5p6442_pcm1_resource),
+       .resource         = s5p6442_pcm1_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
diff --git a/arch/arm/mach-s5p6442/dma.c b/arch/arm/mach-s5p6442/dma.c
new file mode 100644 (file)
index 0000000..ad4f870
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <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 <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5p6442_pdma_resource[] = {
+       [0] = {
+               .start  = S5P6442_PA_PDMA,
+               .end    = S5P6442_PA_PDMA + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PDMA,
+               .end    = IRQ_PDMA,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5p6442_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_MAX,
+               [7] = DMACH_MAX,
+               [8] = DMACH_MAX,
+               [9] = DMACH_I2S0_RX,
+               [10] = DMACH_I2S0_TX,
+               [11] = DMACH_I2S0S_TX,
+               [12] = DMACH_I2S1_RX,
+               [13] = DMACH_I2S1_TX,
+               [14] = DMACH_MAX,
+               [15] = DMACH_MAX,
+               [16] = DMACH_SPI0_RX,
+               [17] = DMACH_SPI0_TX,
+               [18] = DMACH_MAX,
+               [19] = DMACH_MAX,
+               [20] = DMACH_PCM0_RX,
+               [21] = DMACH_PCM0_TX,
+               [22] = DMACH_PCM1_RX,
+               [23] = DMACH_PCM1_TX,
+               [24] = DMACH_MAX,
+               [25] = DMACH_MAX,
+               [26] = DMACH_MAX,
+               [27] = DMACH_MSM_REQ0,
+               [28] = DMACH_MSM_REQ1,
+               [29] = DMACH_MSM_REQ2,
+               [30] = DMACH_MSM_REQ3,
+               [31] = DMACH_MAX,
+       },
+};
+
+static struct platform_device s5p6442_device_pdma = {
+       .name           = "s3c-pl330",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5p6442_pdma_resource),
+       .resource       = s5p6442_pdma_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5p6442_pdma_pdata,
+       },
+};
+
+static struct platform_device *s5p6442_dmacs[] __initdata = {
+       &s5p6442_device_pdma,
+};
+
+static int __init s5p6442_dma_init(void)
+{
+       platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs));
+
+       return 0;
+}
+arch_initcall(s5p6442_dma_init);
diff --git a/arch/arm/mach-s5p6442/include/mach/dma.h b/arch/arm/mach-s5p6442/include/mach/dma.h
new file mode 100644 (file)
index 0000000..81209eb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
index 685277d..7568dc0 100644 (file)
@@ -34,6 +34,9 @@
 #define S5P6442_PA_VIC2                (0xE4200000)
 #define S5P_PA_VIC2            S5P6442_PA_VIC2
 
+#define S5P6442_PA_MDMA                0xE8000000
+#define S5P6442_PA_PDMA                0xE9000000
+
 #define S5P6442_PA_TIMER       (0xEA000000)
 #define S5P_PA_TIMER           S5P6442_PA_TIMER
 
 #define S5P6442_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5P6442_PA_SDRAM
 
+/* I2S */
+#define S5P6442_PA_I2S0                0xC0B00000
+#define S5P6442_PA_I2S1                0xF2200000
+
+/* PCM */
+#define S5P6442_PA_PCM0                0xF2400000
+#define S5P6442_PA_PCM1                0xF2500000
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5P6442_PA_UART
 #define S3C_PA_IIC             S5P6442_PA_IIC0
index 15e8525..2724b37 100644 (file)
@@ -1,13 +1,14 @@
 /* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
  *
+ * Copyright (c) 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/
  *
- * Copyright 2010 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
  *
  * S5P6442 - pwm clock and timer support
  *
 
 /**
  * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
  *
  * Return true if the given configuration from TCFG1 is a TCLK instead
  * any of the TDIV clocks.
  */
 static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
 {
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       return tcfg == S3C64XX_TCFG1_MUX_TCLK;
 }
 
 /**
@@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
  */
 static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
 {
-       return 1 << (1 + tcfg1);
+       return 1 << tcfg1;
 }
 
 /**
@@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
  */
 static inline unsigned int pwm_tdiv_has_div1(void)
 {
-       return 0;
+       return 1;
 }
 
 /**
@@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
  */
 static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
 {
-       return ilog2(div) - 1;
+       return ilog2(div);
 }
 
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
 
 #endif /* __ASM_ARCH_PWMCLK_H */
index 0d63371..ebcf997 100644 (file)
@@ -65,6 +65,7 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdk6442_devices[] __initdata = {
+       &s5p6442_device_iis0,
 };
 
 static void __init smdk6442_map_io(void)
diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c
new file mode 100644 (file)
index 0000000..662695d
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5p6442/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       /* Will be populated later */
+}
index 27ec167..8593337 100644 (file)
@@ -12,12 +12,22 @@ config CPU_S5PC100
        help
          Enable S5PC100 CPU support
 
+config S5PC100_SETUP_FB_24BPP
+       bool
+       help
+         Common setup code for S5PC1XX with an 24bpp RGB display helper.
+
 config S5PC100_SETUP_SDHCI
         bool
         select S5PC1XX_SETUP_SDHCI_GPIO
         help
           Internal helper functions for S5PC100 based SDHCI systems
 
+config S5PC100_SETUP_I2C1
+       bool
+       help
+         Common setup code for i2c bus 1.
+
 config MACH_SMDKC100
        bool "SMDKC100"
        select CPU_S5PC100
@@ -26,9 +36,8 @@ config MACH_SMDKC100
        select S3C_DEV_HSMMC
        select S3C_DEV_HSMMC1
        select S3C_DEV_HSMMC2
-       select S5PC1XX_SETUP_I2C0
-       select S5PC1XX_SETUP_I2C1
-       select S5PC1XX_SETUP_FB_24BPP
+       select S5PC100_SETUP_FB_24BPP
+       select S5PC100_SETUP_I2C1
        select S5PC100_SETUP_SDHCI
        help
          Machine support for the Samsung SMDKC100
index 809ff10..373bc54 100644 (file)
@@ -11,10 +11,13 @@ obj-                                :=
 
 # Core support for S5PC100 system
 
-obj-$(CONFIG_CPU_S5PC100)      += cpu.o
+obj-$(CONFIG_CPU_S5PC100)      += cpu.o gpiolib.o
+obj-$(CONFIG_CPU_S5PC100)      += setup-i2c0.o
 
 # Helper and device support
 
+obj-$(CONFIG_S5PC100_SETUP_FB_24BPP)   += setup-fb-24bpp.o
+obj-$(CONFIG_S5PC100_SETUP_I2C1)       += setup-i2c1.o
 obj-$(CONFIG_S5PC100_SETUP_SDHCI)       += setup-sdhci.o
 
 # machine support
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
new file mode 100644 (file)
index 0000000..e3fed4c
--- /dev/null
@@ -0,0 +1,1358 @@
+/* linux/arch/arm/mach-s5pc100/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PC100 - 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/err.h>
+#include <linux/clk.h>
+#include <linux/io.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/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5pc100.h>
+
+static struct clk s5p_clk_otgphy = {
+       .name           = "otg_phy",
+       .id             = -1,
+};
+
+static struct clk *clk_src_mout_href_list[] = {
+       [0] = &s5p_clk_27m,
+       [1] = &clk_fin_hpll,
+};
+
+static struct clksrc_sources clk_src_mout_href = {
+       .sources        = clk_src_mout_href_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_href_list),
+};
+
+static struct clksrc_clk clk_mout_href = {
+       .clk = {
+               .name           = "mout_href",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mout_href,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
+};
+
+static struct clk *clk_src_mout_48m_list[] = {
+       [0] = &clk_xusbxti,
+       [1] = &s5p_clk_otgphy,
+};
+
+static struct clksrc_sources clk_src_mout_48m = {
+       .sources        = clk_src_mout_48m_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_48m_list),
+};
+
+static struct clksrc_clk clk_mout_48m = {
+       .clk = {
+               .name           = "mout_48m",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mout_48m,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 24, .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 = 4, .size = 1 },
+};
+
+
+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 struct clksrc_clk clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_epll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clk *clk_src_mout_hpll_list[] = {
+       [0] = &s5p_clk_27m,
+};
+
+static struct clksrc_sources clk_src_mout_hpll = {
+       .sources        = clk_src_mout_hpll_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_hpll_list),
+};
+
+static struct clksrc_clk clk_mout_hpll = {
+       .clk    = {
+               .name           = "mout_hpll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_mout_hpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_apll = {
+       .clk    = {
+               .name   = "div_apll",
+               .id     = -1,
+               .parent = &clk_mout_apll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_arm = {
+       .clk    = {
+               .name   = "div_arm",
+               .id     = -1,
+               .parent = &clk_div_apll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_d0_bus = {
+       .clk    = {
+               .name   = "div_d0_bus",
+               .id     = -1,
+               .parent = &clk_div_arm.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_pclkd0 = {
+       .clk    = {
+               .name   = "div_pclkd0",
+               .id     = -1,
+               .parent = &clk_div_d0_bus.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_secss = {
+       .clk    = {
+               .name   = "div_secss",
+               .id     = -1,
+               .parent = &clk_div_d0_bus.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_apll2 = {
+       .clk    = {
+               .name   = "div_apll2",
+               .id     = -1,
+               .parent = &clk_mout_apll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 3 },
+};
+
+static struct clk *clk_src_mout_am_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_div_apll2.clk,
+};
+
+struct clksrc_sources clk_src_mout_am = {
+       .sources        = clk_src_mout_am_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_am_list),
+};
+
+static struct clksrc_clk clk_mout_am = {
+       .clk    = {
+               .name   = "mout_am",
+               .id     = -1,
+       },
+       .sources = &clk_src_mout_am,
+       .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_d1_bus = {
+       .clk    = {
+               .name   = "div_d1_bus",
+               .id     = -1,
+               .parent = &clk_mout_am.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_mpll2 = {
+       .clk    = {
+               .name   = "div_mpll2",
+               .id     = -1,
+               .parent = &clk_mout_am.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_mpll = {
+       .clk    = {
+               .name   = "div_mpll",
+               .id     = -1,
+               .parent = &clk_mout_am.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 2 },
+};
+
+static struct clk *clk_src_mout_onenand_list[] = {
+       [0] = &clk_div_d0_bus.clk,
+       [1] = &clk_div_d1_bus.clk,
+};
+
+struct clksrc_sources clk_src_mout_onenand = {
+       .sources        = clk_src_mout_onenand_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mout_onenand_list),
+};
+
+static struct clksrc_clk clk_mout_onenand = {
+       .clk    = {
+               .name   = "mout_onenand",
+               .id     = -1,
+       },
+       .sources = &clk_src_mout_onenand,
+       .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_onenand = {
+       .clk    = {
+               .name   = "div_onenand",
+               .id     = -1,
+               .parent = &clk_mout_onenand.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 2 },
+};
+
+static struct clksrc_clk clk_div_pclkd1 = {
+       .clk    = {
+               .name   = "div_pclkd1",
+               .id     = -1,
+               .parent = &clk_div_d1_bus.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_cam = {
+       .clk    = {
+               .name   = "div_cam",
+               .id     = -1,
+               .parent = &clk_div_mpll2.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV1, .shift = 24, .size = 5 },
+};
+
+static struct clksrc_clk clk_div_hdmi = {
+       .clk    = {
+               .name   = "div_hdmi",
+               .id     = -1,
+               .parent = &clk_mout_hpll.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
+};
+
+static int s5pc100_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 s5pc100_epll_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+
+static u32 epll_div[][4] = {
+       { 32750000,     131, 3, 4 },
+       { 32768000,     131, 3, 4 },
+       { 36000000,     72,  3, 3 },
+       { 45000000,     90,  3, 3 },
+       { 45158000,     90,  3, 3 },
+       { 45158400,     90,  3, 3 },
+       { 48000000,     96,  3, 3 },
+       { 49125000,     131, 4, 3 },
+       { 49152000,     131, 4, 3 },
+       { 60000000,     120, 3, 3 },
+       { 67737600,     226, 5, 3 },
+       { 67738000,     226, 5, 3 },
+       { 73800000,     246, 5, 3 },
+       { 73728000,     246, 5, 3 },
+       { 72000000,     144, 3, 3 },
+       { 84000000,     168, 3, 3 },
+       { 96000000,     96,  3, 2 },
+       { 144000000,    144, 3, 2 },
+       { 192000000,    96,  3, 1 }
+};
+
+static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned int epll_con;
+       unsigned int i;
+
+       if (clk->rate == rate)  /* Return if nothing changed */
+               return 0;
+
+       epll_con = __raw_readl(S5P_EPLL_CON);
+
+       epll_con &= ~(PLL65XX_MDIV_MASK | PLL65XX_PDIV_MASK | PLL65XX_SDIV_MASK);
+
+       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+               if (epll_div[i][0] == rate) {
+                       epll_con |= (epll_div[i][1] << PLL65XX_MDIV_SHIFT) |
+                                   (epll_div[i][2] << PLL65XX_PDIV_SHIFT) |
+                                   (epll_div[i][3] << PLL65XX_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);
+
+       clk->rate = rate;
+
+       return 0;
+}
+
+static struct clk_ops s5pc100_epll_ops = {
+       .get_rate = s5pc100_epll_get_rate,
+       .set_rate = s5pc100_epll_set_rate,
+};
+
+static int s5pc100_d0_0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc100_d0_1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc100_d0_2_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc100_d1_0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc100_d1_1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc100_d1_2_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc100_d1_3_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc100_d1_4_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc100_d1_5_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc100_sclk0_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_SCLK0, clk, enable);
+}
+
+static int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
+{
+       return s5p_gatectrl(S5P_CLKGATE_SCLK1, 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           = "cssys",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "secss",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "g2d",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "mdma",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "cfcon",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "nfcon",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "onenandc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "sdm",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_2_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "seckey",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_2_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "hsmmc",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "hsmmc",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "hsmmc",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "modemif",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "otg",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "usbhost",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "pdma",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "pdma",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "rotator",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "fimc",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "fimc",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "fimc",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "jpeg",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "mipi-dsim",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "mipi-csis",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_1_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "g3d",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_0_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "tv",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "vp",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "mixer",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "hdmi",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "mfc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_2_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "apc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "iec",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "systimer",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "i2c",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "i2c",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "spi",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "spi",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "spi",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "irda",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "ccan",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 10),
+       }, {
+               .name           = "ccan",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 11),
+       }, {
+               .name           = "hsitx",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 12),
+       }, {
+               .name           = "hsirx",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 13),
+       }, {
+               .name           = "iis",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "iis",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "iis",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "ac97",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "pcm",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "pcm",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "spdif",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 6),
+       }, {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "keyif",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_5_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "spi_48m",
+               .id             = 0,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 7),
+       }, {
+               .name           = "spi_48m",
+               .id             = 1,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 8),
+       }, {
+               .name           = "spi_48m",
+               .id             = 2,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 9),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 0,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 15),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 1,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 16),
+       }, {
+               .name           = "mmc_48m",
+               .id             = 2,
+               .parent         = &clk_mout_48m.clk,
+               .enable         = s5pc100_sclk0_ctrl,
+               .ctrlbit        = (1 << 17),
+       },
+};
+
+static struct clk clk_vclk54m = {
+       .name           = "vclk_54m",
+       .id             = -1,
+       .rate           = 54000000,
+};
+
+static struct clk clk_i2scdclk0 = {
+       .name           = "i2s_cdclk0",
+       .id             = -1,
+};
+
+static struct clk clk_i2scdclk1 = {
+       .name           = "i2s_cdclk1",
+       .id             = -1,
+};
+
+static struct clk clk_i2scdclk2 = {
+       .name           = "i2s_cdclk2",
+       .id             = -1,
+};
+
+static struct clk clk_pcmcdclk0 = {
+       .name           = "pcm_cdclk0",
+       .id             = -1,
+};
+
+static struct clk clk_pcmcdclk1 = {
+       .name           = "pcm_cdclk1",
+       .id             = -1,
+};
+
+static struct clk *clk_src_group1_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll2.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group1 = {
+       .sources        = clk_src_group1_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group1_list),
+};
+
+static struct clk *clk_src_group2_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+};
+
+struct clksrc_sources clk_src_group2 = {
+       .sources        = clk_src_group2_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group2_list),
+};
+
+static struct clk *clk_src_group3_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_i2scdclk0,
+       [4] = &clk_pcmcdclk0,
+       [5] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group3 = {
+       .sources        = clk_src_group3_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group3_list),
+};
+
+static struct clk *clk_src_group4_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_i2scdclk1,
+       [4] = &clk_pcmcdclk1,
+       [5] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group4 = {
+       .sources        = clk_src_group4_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group4_list),
+};
+
+static struct clk *clk_src_group5_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_i2scdclk2,
+       [4] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group5 = {
+       .sources        = clk_src_group5_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group5_list),
+};
+
+static struct clk *clk_src_group6_list[] = {
+       [0] = &s5p_clk_27m,
+       [1] = &clk_vclk54m,
+       [2] = &clk_div_hdmi.clk,
+};
+
+struct clksrc_sources clk_src_group6 = {
+       .sources        = clk_src_group6_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group6_list),
+};
+
+static struct clk *clk_src_group7_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_mout_hpll.clk,
+       [3] = &clk_vclk54m,
+};
+
+struct clksrc_sources clk_src_group7 = {
+       .sources        = clk_src_group7_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_group7_list),
+};
+
+static struct clk *clk_src_mmc0_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+};
+
+struct clksrc_sources clk_src_mmc0 = {
+       .sources        = clk_src_mmc0_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mmc0_list),
+};
+
+static struct clk *clk_src_mmc12_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_mmc12 = {
+       .sources        = clk_src_mmc12_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_mmc12_list),
+};
+
+static struct clk *clk_src_irda_usb_list[] = {
+       [0] = &clk_mout_epll.clk,
+       [1] = &clk_div_mpll.clk,
+       [2] = &clk_fin_epll,
+       [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_irda_usb = {
+       .sources        = clk_src_irda_usb_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_irda_usb_list),
+};
+
+static struct clk *clk_src_pwi_list[] = {
+       [0] = &clk_fin_epll,
+       [1] = &clk_mout_epll.clk,
+       [2] = &clk_div_mpll.clk,
+};
+
+struct clksrc_sources clk_src_pwi = {
+       .sources        = clk_src_pwi_list,
+       .nr_sources     = ARRAY_SIZE(clk_src_pwi_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+       {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 4),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 5),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_spi",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 6),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group1,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "uclk1",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 3),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mixer",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 6),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_group6,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 8),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group3,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 9),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group4,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_audio",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group5,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_lcd",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 0),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 12, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 16, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 2),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 20, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 3),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_group7,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 24, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 0,
+                       .ctrlbit        = (1 << 12),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_mmc0,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 1,
+                       .ctrlbit        = (1 << 13),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_mmc12,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "mmc_bus",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 14),
+                       .enable         = s5pc100_sclk1_ctrl,
+
+               },
+               .sources = &clk_src_mmc12,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_irda",
+                       .id             = 2,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_irda_usb,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_irda",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 10),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_mmc12,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_pwi",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 1),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_pwi,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 0, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 3 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_uhost",
+                       .id             = -1,
+                       .ctrlbit        = (1 << 11),
+                       .enable         = s5pc100_sclk0_ctrl,
+
+               },
+               .sources = &clk_src_irda_usb,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 20, .size = 4 },
+       },
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *sysclks[] = {
+       &clk_mout_apll,
+       &clk_mout_epll,
+       &clk_mout_mpll,
+       &clk_mout_hpll,
+       &clk_mout_href,
+       &clk_mout_48m,
+       &clk_div_apll,
+       &clk_div_arm,
+       &clk_div_d0_bus,
+       &clk_div_pclkd0,
+       &clk_div_secss,
+       &clk_div_apll2,
+       &clk_mout_am,
+       &clk_div_d1_bus,
+       &clk_div_mpll2,
+       &clk_div_mpll,
+       &clk_mout_onenand,
+       &clk_div_onenand,
+       &clk_div_pclkd1,
+       &clk_div_cam,
+       &clk_div_hdmi,
+};
+
+void __init_or_cpufreq s5pc100_setup_clocks(void)
+{
+       unsigned long xtal;
+       unsigned long arm;
+       unsigned long hclkd0;
+       unsigned long hclkd1;
+       unsigned long pclkd0;
+       unsigned long pclkd1;
+       unsigned long apll;
+       unsigned long mpll;
+       unsigned long epll;
+       unsigned long hpll;
+       unsigned int ptr;
+
+       /* Set S5PC100 functions for clk_fout_epll */
+       clk_fout_epll.enable = s5pc100_epll_enable;
+       clk_fout_epll.ops = &s5pc100_epll_ops;
+
+       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+       xtal = clk_get_rate(&clk_xtal);
+
+       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+       apll = s5p_get_pll65xx(xtal, __raw_readl(S5P_APLL_CON));
+       mpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_MPLL_CON));
+       epll = s5p_get_pll65xx(xtal, __raw_readl(S5P_EPLL_CON));
+       hpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_HPLL_CON));
+
+       printk(KERN_INFO "S5PC100: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz, E=%ld.%ldMHz, H=%ld.%ldMHz\n",
+                       print_mhz(apll), print_mhz(mpll), print_mhz(epll), print_mhz(hpll));
+
+       clk_fout_apll.rate = apll;
+       clk_fout_mpll.rate = mpll;
+       clk_fout_epll.rate = epll;
+       clk_mout_hpll.clk.rate = hpll;
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_set_clksrc(&clksrcs[ptr], true);
+
+       arm = clk_get_rate(&clk_div_arm.clk);
+       hclkd0 = clk_get_rate(&clk_div_d0_bus.clk);
+       pclkd0 = clk_get_rate(&clk_div_pclkd0.clk);
+       hclkd1 = clk_get_rate(&clk_div_d1_bus.clk);
+       pclkd1 = clk_get_rate(&clk_div_pclkd1.clk);
+
+       printk(KERN_INFO "S5PC100: HCLKD0=%ld.%ldMHz, HCLKD1=%ld.%ldMHz, PCLKD0=%ld.%ldMHz, PCLKD1=%ld.%ldMHz\n",
+                       print_mhz(hclkd0), print_mhz(hclkd1), print_mhz(pclkd0), print_mhz(pclkd1));
+
+       clk_f.rate = arm;
+       clk_h.rate = hclkd1;
+       clk_p.rate = pclkd1;
+}
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+       {
+               .name           = "tzic",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "intc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_0_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "ebi",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 5),
+       }, {
+               .name           = "intmem",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 4),
+       }, {
+               .name           = "sromc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "dmc",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "chipid",
+               .id             = -1,
+               .parent         = &clk_div_d0_bus.clk,
+               .enable         = s5pc100_d0_1_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 0),
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 1),
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 2),
+       }, {
+               .name           = "uart",
+               .id             = 3,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_4_ctrl,
+               .ctrlbit        = (1 << 3),
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_div_d1_bus.clk,
+               .enable         = s5pc100_d1_3_ctrl,
+               .ctrlbit        = (1 << 6),
+       },
+};
+
+static struct clk *clks[] __initdata = {
+       &clk_ext,
+       &clk_i2scdclk0,
+       &clk_i2scdclk1,
+       &clk_i2scdclk2,
+       &clk_pcmcdclk0,
+       &clk_pcmcdclk1,
+};
+
+void __init s5pc100_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-s5pc100/gpiolib.c b/arch/arm/mach-s5pc100/gpiolib.c
new file mode 100644 (file)
index 0000000..c8e8336
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * arch/arm/plat-s5pc1xx/gpiolib.c
+ *
+ *  Copyright 2009 Samsung Electronics Co
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5PC1XX - 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 <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* S5PC100 GPIO bank summary:
+ *
+ * Bank        GPIOs   Style   INT Type
+ * A0  8       4Bit    GPIO_INT0
+ * A1  5       4Bit    GPIO_INT1
+ * B   8       4Bit    GPIO_INT2
+ * C   5       4Bit    GPIO_INT3
+ * D   7       4Bit    GPIO_INT4
+ * E0  8       4Bit    GPIO_INT5
+ * E1  6       4Bit    GPIO_INT6
+ * F0  8       4Bit    GPIO_INT7
+ * F1  8       4Bit    GPIO_INT8
+ * F2  8       4Bit    GPIO_INT9
+ * F3  4       4Bit    GPIO_INT10
+ * G0  8       4Bit    GPIO_INT11
+ * G1  3       4Bit    GPIO_INT12
+ * G2  7       4Bit    GPIO_INT13
+ * G3  7       4Bit    GPIO_INT14
+ * H0  8       4Bit    WKUP_INT
+ * H1  8       4Bit    WKUP_INT
+ * H2  8       4Bit    WKUP_INT
+ * H3  8       4Bit    WKUP_INT
+ * I   8       4Bit    GPIO_INT15
+ * J0  8       4Bit    GPIO_INT16
+ * J1  5       4Bit    GPIO_INT17
+ * J2  8       4Bit    GPIO_INT18
+ * J3  8       4Bit    GPIO_INT19
+ * J4  4       4Bit    GPIO_INT20
+ * K0  8       4Bit    None
+ * K1  6       4Bit    None
+ * K2  8       4Bit    None
+ * K3  8       4Bit    None
+ * L0  8       4Bit    None
+ * L1  8       4Bit    None
+ * L2  8       4Bit    None
+ * L3  8       4Bit    None
+ */
+
+#if 0
+static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+       return S3C_IRQ_GPIO(chip->base + offset);
+}
+
+static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
+{
+       int base;
+
+       base = chip->base - S5PC100_GPH0(0);
+       if (base == 0)
+               return IRQ_EINT(offset);
+       base = chip->base - S5PC100_GPH1(0);
+       if (base == 0)
+               return IRQ_EINT(8 + offset);
+       base = chip->base - S5PC100_GPH2(0);
+       if (base == 0)
+               return IRQ_EINT(16 + offset);
+       base = chip->base - S5PC100_GPH3(0);
+       if (base == 0)
+               return IRQ_EINT(24 + offset);
+       return -EINVAL;
+}
+#endif
+static struct s3c_gpio_cfg gpio_cfg = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_eint = {
+       .cfg_eint       = 0xf,
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
+       {
+               .base   = S5PC100_GPA0_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPA0(0),
+                       .ngpio  = S5PC100_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .base   = S5PC100_GPA1_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPA1(0),
+                       .ngpio  = S5PC100_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .base   = S5PC100_GPB_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPB(0),
+                       .ngpio  = S5PC100_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .base   = S5PC100_GPC_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPC(0),
+                       .ngpio  = S5PC100_GPIO_C_NR,
+                       .label  = "GPC",
+               },
+       }, {
+               .base   = S5PC100_GPD_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPD(0),
+                       .ngpio  = S5PC100_GPIO_D_NR,
+                       .label  = "GPD",
+               },
+       }, {
+               .base   = S5PC100_GPE0_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPE0(0),
+                       .ngpio  = S5PC100_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .base   = S5PC100_GPE1_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPE1(0),
+                       .ngpio  = S5PC100_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .base   = S5PC100_GPF0_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPF0(0),
+                       .ngpio  = S5PC100_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .base   = S5PC100_GPF1_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPF1(0),
+                       .ngpio  = S5PC100_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .base   = S5PC100_GPF2_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPF2(0),
+                       .ngpio  = S5PC100_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .base   = S5PC100_GPF3_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPF3(0),
+                       .ngpio  = S5PC100_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       }, {
+               .base   = S5PC100_GPG0_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPG0(0),
+                       .ngpio  = S5PC100_GPIO_G0_NR,
+                       .label  = "GPG0",
+               },
+       }, {
+               .base   = S5PC100_GPG1_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPG1(0),
+                       .ngpio  = S5PC100_GPIO_G1_NR,
+                       .label  = "GPG1",
+               },
+       }, {
+               .base   = S5PC100_GPG2_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPG2(0),
+                       .ngpio  = S5PC100_GPIO_G2_NR,
+                       .label  = "GPG2",
+               },
+       }, {
+               .base   = S5PC100_GPG3_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPG3(0),
+                       .ngpio  = S5PC100_GPIO_G3_NR,
+                       .label  = "GPG3",
+               },
+       }, {
+               .base   = S5PC100_GPH0_BASE,
+               .config = &gpio_cfg_eint,
+               .chip   = {
+                       .base   = S5PC100_GPH0(0),
+                       .ngpio  = S5PC100_GPIO_H0_NR,
+                       .label  = "GPH0",
+               },
+       }, {
+               .base   = S5PC100_GPH1_BASE,
+               .config = &gpio_cfg_eint,
+               .chip   = {
+                       .base   = S5PC100_GPH1(0),
+                       .ngpio  = S5PC100_GPIO_H1_NR,
+                       .label  = "GPH1",
+               },
+       }, {
+               .base   = S5PC100_GPH2_BASE,
+               .config = &gpio_cfg_eint,
+               .chip   = {
+                       .base   = S5PC100_GPH2(0),
+                       .ngpio  = S5PC100_GPIO_H2_NR,
+                       .label  = "GPH2",
+               },
+       }, {
+               .base   = S5PC100_GPH3_BASE,
+               .config = &gpio_cfg_eint,
+               .chip   = {
+                       .base   = S5PC100_GPH3(0),
+                       .ngpio  = S5PC100_GPIO_H3_NR,
+                       .label  = "GPH3",
+               },
+       }, {
+               .base   = S5PC100_GPI_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPI(0),
+                       .ngpio  = S5PC100_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .base   = S5PC100_GPJ0_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPJ0(0),
+                       .ngpio  = S5PC100_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .base   = S5PC100_GPJ1_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPJ1(0),
+                       .ngpio  = S5PC100_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .base   = S5PC100_GPJ2_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPJ2(0),
+                       .ngpio  = S5PC100_GPIO_J2_NR,
+                       .label  = "GPJ2",
+               },
+       }, {
+               .base   = S5PC100_GPJ3_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPJ3(0),
+                       .ngpio  = S5PC100_GPIO_J3_NR,
+                       .label  = "GPJ3",
+               },
+       }, {
+               .base   = S5PC100_GPJ4_BASE,
+               .config = &gpio_cfg,
+               .chip   = {
+                       .base   = S5PC100_GPJ4(0),
+                       .ngpio  = S5PC100_GPIO_J4_NR,
+                       .label  = "GPJ4",
+               },
+       }, {
+               .base   = S5PC100_GPK0_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPK0(0),
+                       .ngpio  = S5PC100_GPIO_K0_NR,
+                       .label  = "GPK0",
+               },
+       }, {
+               .base   = S5PC100_GPK1_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPK1(0),
+                       .ngpio  = S5PC100_GPIO_K1_NR,
+                       .label  = "GPK1",
+               },
+       }, {
+               .base   = S5PC100_GPK2_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPK2(0),
+                       .ngpio  = S5PC100_GPIO_K2_NR,
+                       .label  = "GPK2",
+               },
+       }, {
+               .base   = S5PC100_GPK3_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPK3(0),
+                       .ngpio  = S5PC100_GPIO_K3_NR,
+                       .label  = "GPK3",
+               },
+       }, {
+               .base   = S5PC100_GPL0_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPL0(0),
+                       .ngpio  = S5PC100_GPIO_L0_NR,
+                       .label  = "GPL0",
+               },
+       }, {
+               .base   = S5PC100_GPL1_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPL1(0),
+                       .ngpio  = S5PC100_GPIO_L1_NR,
+                       .label  = "GPL1",
+               },
+       }, {
+               .base   = S5PC100_GPL2_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPL2(0),
+                       .ngpio  = S5PC100_GPIO_L2_NR,
+                       .label  = "GPL2",
+               },
+       }, {
+               .base   = S5PC100_GPL3_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPL3(0),
+                       .ngpio  = S5PC100_GPIO_L3_NR,
+                       .label  = "GPL3",
+               },
+       }, {
+               .base   = S5PC100_GPL4_BASE,
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PC100_GPL4(0),
+                       .ngpio  = S5PC100_GPIO_L4_NR,
+                       .label  = "GPL4",
+               },
+       },
+};
+
+/* FIXME move from irq-gpio.c */
+extern struct irq_chip s5pc1xx_gpioint;
+extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
+
+static __init void s5pc100_gpiolib_link(struct s3c_gpio_chip *chip)
+{
+#if 0
+       /* Interrupt */
+       if (chip->config == &gpio_cfg) {
+               int i, irq;
+
+               chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
+
+               for (i = 0;  i < chip->chip.ngpio; i++) {
+                       irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
+                       set_irq_chip(irq, &s5pc1xx_gpioint);
+                       set_irq_data(irq, &chip->chip);
+                       set_irq_handler(irq, handle_level_irq);
+                       set_irq_flags(irq, IRQF_VALID);
+               }
+       } else if (chip->config == &gpio_cfg_eint)
+               chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
+#endif
+}
+
+static __init int s5pc1xx_gpiolib_init(void)
+{
+       struct s3c_gpio_chip *chip;
+       int nr_chips;
+
+       chip = s5pc100_gpio_chips;
+       nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+
+       for (; nr_chips > 0; nr_chips--, chip++)
+               s5pc100_gpiolib_link(chip);
+
+       samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips,
+                                      ARRAY_SIZE(s5pc100_gpio_chips));
+#if 0
+       /* Interrupt */
+       set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
+#endif
+       return 0;
+}
+core_initcall(s5pc1xx_gpiolib_init);
index 2c4cbe8..29a8a12 100644 (file)
@@ -12,6 +12,9 @@
  * 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 S5PC100_GPIO_L2_NR     (8)
 #define S5PC100_GPIO_L3_NR     (8)
 #define S5PC100_GPIO_L4_NR     (8)
-#define S5PC100_GPIO_MP00_NR   (8)
-#define S5PC100_GPIO_MP01_NR   (8)
-#define S5PC100_GPIO_MP02_NR   (8)
-#define S5PC100_GPIO_MP03_NR   (8)
-#define S5PC100_GPIO_MP04_NR   (5)
 
 /* GPIO bank numbes */
 
  * change from one gpio bank to another can be caught.
 */
 
-#define S5PC1XX_GPIO_NEXT(__gpio) \
+#define S5PC100_GPIO_NEXT(__gpio) \
        ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
 
-enum s3c_gpio_number {
+enum s5p_gpio_number {
        S5PC100_GPIO_A0_START   = 0,
-       S5PC100_GPIO_A1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A0),
-       S5PC100_GPIO_B_START    = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_A1),
-       S5PC100_GPIO_C_START    = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_B),
-       S5PC100_GPIO_D_START    = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_C),
-       S5PC100_GPIO_E0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_D),
-       S5PC100_GPIO_E1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E0),
-       S5PC100_GPIO_F0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_E1),
-       S5PC100_GPIO_F1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F0),
-       S5PC100_GPIO_F2_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F1),
-       S5PC100_GPIO_F3_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F2),
-       S5PC100_GPIO_G0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_F3),
-       S5PC100_GPIO_G1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G0),
-       S5PC100_GPIO_G2_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G1),
-       S5PC100_GPIO_G3_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G2),
-       S5PC100_GPIO_H0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_G3),
-       S5PC100_GPIO_H1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H0),
-       S5PC100_GPIO_H2_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H1),
-       S5PC100_GPIO_H3_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H2),
-       S5PC100_GPIO_I_START    = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_H3),
-       S5PC100_GPIO_J0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_I),
-       S5PC100_GPIO_J1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J0),
-       S5PC100_GPIO_J2_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J1),
-       S5PC100_GPIO_J3_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J2),
-       S5PC100_GPIO_J4_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J3),
-       S5PC100_GPIO_K0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_J4),
-       S5PC100_GPIO_K1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K0),
-       S5PC100_GPIO_K2_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K1),
-       S5PC100_GPIO_K3_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K2),
-       S5PC100_GPIO_L0_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_K3),
-       S5PC100_GPIO_L1_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L0),
-       S5PC100_GPIO_L2_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L1),
-       S5PC100_GPIO_L3_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L2),
-       S5PC100_GPIO_L4_START   = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L3),
-       S5PC100_GPIO_MP00_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_L4),
-       S5PC100_GPIO_MP01_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP00),
-       S5PC100_GPIO_MP02_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP01),
-       S5PC100_GPIO_MP03_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP02),
-       S5PC100_GPIO_MP04_START = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP03),
-       S5PC100_GPIO_END        = S5PC1XX_GPIO_NEXT(S5PC100_GPIO_MP04),
+       S5PC100_GPIO_A1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_A0),
+       S5PC100_GPIO_B_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_A1),
+       S5PC100_GPIO_C_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_B),
+       S5PC100_GPIO_D_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_C),
+       S5PC100_GPIO_E0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_D),
+       S5PC100_GPIO_E1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_E0),
+       S5PC100_GPIO_F0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_E1),
+       S5PC100_GPIO_F1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F0),
+       S5PC100_GPIO_F2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F1),
+       S5PC100_GPIO_F3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F2),
+       S5PC100_GPIO_G0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_F3),
+       S5PC100_GPIO_G1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G0),
+       S5PC100_GPIO_G2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G1),
+       S5PC100_GPIO_G3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G2),
+       S5PC100_GPIO_H0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_G3),
+       S5PC100_GPIO_H1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_H0),
+       S5PC100_GPIO_H2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_H1),
+       S5PC100_GPIO_H3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_H2),
+       S5PC100_GPIO_I_START    = S5PC100_GPIO_NEXT(S5PC100_GPIO_H3),
+       S5PC100_GPIO_J0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_I),
+       S5PC100_GPIO_J1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J0),
+       S5PC100_GPIO_J2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J1),
+       S5PC100_GPIO_J3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J2),
+       S5PC100_GPIO_J4_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J3),
+       S5PC100_GPIO_K0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_J4),
+       S5PC100_GPIO_K1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K0),
+       S5PC100_GPIO_K2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K1),
+       S5PC100_GPIO_K3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K2),
+       S5PC100_GPIO_L0_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_K3),
+       S5PC100_GPIO_L1_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L0),
+       S5PC100_GPIO_L2_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L1),
+       S5PC100_GPIO_L3_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L2),
+       S5PC100_GPIO_L4_START   = S5PC100_GPIO_NEXT(S5PC100_GPIO_L3),
+       S5PC100_GPIO_END        = S5PC100_GPIO_NEXT(S5PC100_GPIO_L4),
 };
 
 /* S5PC100 GPIO number definitions. */
@@ -146,17 +139,13 @@ enum s3c_gpio_number {
 #define S5PC100_GPL2(_nr)      (S5PC100_GPIO_L2_START + (_nr))
 #define S5PC100_GPL3(_nr)      (S5PC100_GPIO_L3_START + (_nr))
 #define S5PC100_GPL4(_nr)      (S5PC100_GPIO_L4_START + (_nr))
-#define S5PC100_MP00(_nr)      (S5PC100_GPIO_MP00_START + (_nr))
-#define S5PC100_MP01(_nr)      (S5PC100_GPIO_MP01_START + (_nr))
-#define S5PC100_MP02(_nr)      (S5PC100_GPIO_MP02_START + (_nr))
-#define S5PC100_MP03(_nr)      (S5PC100_GPIO_MP03_START + (_nr))
-#define S5PC100_MP04(_nr)      (S5PC100_GPIO_MP04_START + (_nr))
-#define S5PC100_MP05(_nr)      (S5PC100_GPIO_MP05_START + (_nr))
 
-/* It used the end of the S5PC1XX gpios */
+/* It used the end of the S5PC100 gpios */
 #define S3C_GPIO_END           S5PC100_GPIO_END
 
 /* define the number of gpios we need to the one after the MP04() range */
 #define ARCH_NR_GPIOS          (S5PC100_GPIO_END + 1)
 
 #include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-clock.h b/arch/arm/mach-s5pc100/include/mach/regs-clock.h
new file mode 100644 (file)
index 0000000..f2283bd
--- /dev/null
@@ -0,0 +1,71 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PC100 - 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_HPLL_LOCK          S5P_CLKREG(0x0C)
+
+#define S5P_APLL_CON           S5P_CLKREG(0x100)
+#define S5P_MPLL_CON           S5P_CLKREG(0x104)
+#define S5P_EPLL_CON           S5P_CLKREG(0x108)
+#define S5P_HPLL_CON           S5P_CLKREG(0x10C)
+
+#define S5P_CLK_SRC0           S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1           S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2           S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3           S5P_CLKREG(0x20C)
+
+#define S5P_CLK_DIV0           S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1           S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2           S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3           S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4           S5P_CLKREG(0x310)
+
+#define S5P_CLK_OUT            S5P_CLKREG(0x400)
+
+#define S5P_CLKGATE_D00                S5P_CLKREG(0x500)
+#define S5P_CLKGATE_D01                S5P_CLKREG(0x504)
+#define S5P_CLKGATE_D02                S5P_CLKREG(0x508)
+
+#define S5P_CLKGATE_D10                S5P_CLKREG(0x520)
+#define S5P_CLKGATE_D11                S5P_CLKREG(0x524)
+#define S5P_CLKGATE_D12                S5P_CLKREG(0x528)
+#define S5P_CLKGATE_D13                S5P_CLKREG(0x52C)
+#define S5P_CLKGATE_D14                S5P_CLKREG(0x530)
+#define S5P_CLKGATE_D15                S5P_CLKREG(0x534)
+
+#define S5P_CLKGATE_D20                S5P_CLKREG(0x540)
+
+#define S5P_CLKGATE_SCLK0      S5P_CLKREG(0x560)
+#define S5P_CLKGATE_SCLK1      S5P_CLKREG(0x564)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_D0_MASK            (0x7<<8)
+#define S5P_CLKDIV0_D0_SHIFT           (8)
+#define S5P_CLKDIV0_PCLKD0_MASK                (0x7<<12)
+#define S5P_CLKDIV0_PCLKD0_SHIFT       (12)
+
+/* CLKDIV1 */
+#define S5P_CLKDIV1_D1_MASK            (0x7<<12)
+#define S5P_CLKDIV1_D1_SHIFT           (12)
+#define S5P_CLKDIV1_PCLKD1_MASK                (0x7<<16)
+#define S5P_CLKDIV1_PCLKD1_SHIFT       (16)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
new file mode 100644 (file)
index 0000000..6866691
--- /dev/null
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - GPIO register definitions
+ */
+
+#ifndef __ASM_MACH_S5PC100_REGS_GPIO_H
+#define __ASM_MACH_S5PC100_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* S5PC100 */
+#define S5PC100_GPIO_BASE      S5PC1XX_VA_GPIO
+#define S5PC100_GPA0_BASE      (S5PC100_GPIO_BASE + 0x0000)
+#define S5PC100_GPA1_BASE      (S5PC100_GPIO_BASE + 0x0020)
+#define S5PC100_GPB_BASE       (S5PC100_GPIO_BASE + 0x0040)
+#define S5PC100_GPC_BASE       (S5PC100_GPIO_BASE + 0x0060)
+#define S5PC100_GPD_BASE       (S5PC100_GPIO_BASE + 0x0080)
+#define S5PC100_GPE0_BASE      (S5PC100_GPIO_BASE + 0x00A0)
+#define S5PC100_GPE1_BASE      (S5PC100_GPIO_BASE + 0x00C0)
+#define S5PC100_GPF0_BASE      (S5PC100_GPIO_BASE + 0x00E0)
+#define S5PC100_GPF1_BASE      (S5PC100_GPIO_BASE + 0x0100)
+#define S5PC100_GPF2_BASE      (S5PC100_GPIO_BASE + 0x0120)
+#define S5PC100_GPF3_BASE      (S5PC100_GPIO_BASE + 0x0140)
+#define S5PC100_GPG0_BASE      (S5PC100_GPIO_BASE + 0x0160)
+#define S5PC100_GPG1_BASE      (S5PC100_GPIO_BASE + 0x0180)
+#define S5PC100_GPG2_BASE      (S5PC100_GPIO_BASE + 0x01A0)
+#define S5PC100_GPG3_BASE      (S5PC100_GPIO_BASE + 0x01C0)
+#define S5PC100_GPH0_BASE      (S5PC100_GPIO_BASE + 0x0C00)
+#define S5PC100_GPH1_BASE      (S5PC100_GPIO_BASE + 0x0C20)
+#define S5PC100_GPH2_BASE      (S5PC100_GPIO_BASE + 0x0C40)
+#define S5PC100_GPH3_BASE      (S5PC100_GPIO_BASE + 0x0C60)
+#define S5PC100_GPI_BASE       (S5PC100_GPIO_BASE + 0x01E0)
+#define S5PC100_GPJ0_BASE      (S5PC100_GPIO_BASE + 0x0200)
+#define S5PC100_GPJ1_BASE      (S5PC100_GPIO_BASE + 0x0220)
+#define S5PC100_GPJ2_BASE      (S5PC100_GPIO_BASE + 0x0240)
+#define S5PC100_GPJ3_BASE      (S5PC100_GPIO_BASE + 0x0260)
+#define S5PC100_GPJ4_BASE      (S5PC100_GPIO_BASE + 0x0280)
+#define S5PC100_GPK0_BASE      (S5PC100_GPIO_BASE + 0x02A0)
+#define S5PC100_GPK1_BASE      (S5PC100_GPIO_BASE + 0x02C0)
+#define S5PC100_GPK2_BASE      (S5PC100_GPIO_BASE + 0x02E0)
+#define S5PC100_GPK3_BASE      (S5PC100_GPIO_BASE + 0x0300)
+#define S5PC100_GPL0_BASE      (S5PC100_GPIO_BASE + 0x0320)
+#define S5PC100_GPL1_BASE      (S5PC100_GPIO_BASE + 0x0340)
+#define S5PC100_GPL2_BASE      (S5PC100_GPIO_BASE + 0x0360)
+#define S5PC100_GPL3_BASE      (S5PC100_GPIO_BASE + 0x0380)
+#define S5PC100_GPL4_BASE      (S5PC100_GPIO_BASE + 0x03A0)
+#define S5PC100_EINT_BASE      (S5PC100_GPIO_BASE + 0x0E00)
+
+#define S5PC100_UHOST          (S5PC100_GPIO_BASE + 0x0B68)
+#define S5PC100_PDNEN          (S5PC100_GPIO_BASE + 0x0F80)
+
+/* PDNEN */
+#define S5PC100_PDNEN_CFG_PDNEN        (1 << 1)
+#define S5PC100_PDNEN_CFG_AUTO (0 << 1)
+#define S5PC100_PDNEN_POWERDOWN        (1 << 0)
+#define S5PC100_PDNEN_NORMAL   (0 << 0)
+
+/* Common part */
+/* External interrupt base is same at both s5pc100 and s5pc110 */
+#define S5PC1XX_EINT_BASE      (S5PC100_EINT_BASE)
+
+#define S5PC100_GPx_INPUT(__gpio)      (0x0 << ((__gpio) * 4))
+#define S5PC100_GPx_OUTPUT(__gpio)     (0x1 << ((__gpio) * 4))
+#define S5PC100_GPx_CONMASK(__gpio)    (0xf << ((__gpio) * 4))
+
+#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
+
index ae3c52c..bfe67db 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <plat/regs-serial.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-gpio.h>
 
 #include <plat/clock.h>
 #include <plat/devs.h>
diff --git a/arch/arm/mach-s5pc100/setup-fb-24bpp.c b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
new file mode 100644 (file)
index 0000000..6eba6cb
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/arm/mach-s5pc100/setup-fb-24bpp.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *
+ * Base S5PC100 setup information for 24bpp LCD framebuffer
+ *
+ * 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/fb.h>
+#include <linux/gpio.h>
+
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#define DISR_OFFSET    0x7008
+
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+       unsigned int gpio = 0;
+
+       for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+
+       for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
+               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+       }
+}
diff --git a/arch/arm/mach-s5pc100/setup-i2c0.c b/arch/arm/mach-s5pc100/setup-i2c0.c
new file mode 100644 (file)
index 0000000..dd3174e
--- /dev/null
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-s5pc100/setup-i2c0.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *     Byungho Min <bhmin@samsung.com>
+ *
+ * Base S5PC100 I2C bus 0 gpio configuration
+ *
+ * Based on plat-s3c64xx/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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
+       s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
+       s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pc100/setup-i2c1.c b/arch/arm/mach-s5pc100/setup-i2c1.c
new file mode 100644 (file)
index 0000000..d1fec26
--- /dev/null
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-s5pc100/setup-i2c1.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *     Byungho Min <bhmin@samsung.com>
+ *
+ * Base S5PC100 I2C bus 1 gpio configuration
+ *
+ * Based on plat-s3c64xx/setup-i2c1.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+       s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
+       s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
+       s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
+       s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
+}
index af33a1a..7601c28 100644 (file)
@@ -12,6 +12,7 @@ if ARCH_S5PV210
 config CPU_S5PV210
        bool
        select PLAT_S5P
+       select S3C_PL330_DMA
        help
          Enable S5PV210 CPU support
 
index 8ebf51c..9982781 100644 (file)
@@ -12,9 +12,14 @@ obj-                         :=
 
 # Core support for S5PV210 system
 
-obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o
+obj-$(CONFIG_CPU_S5PV210)      += cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_CPU_S5PV210)      += setup-i2c0.o
 
 # machine support
 
 obj-$(CONFIG_MACH_SMDKV210)    += mach-smdkv210.o
 obj-$(CONFIG_MACH_SMDKC110)    += mach-smdkc110.o
+
+# device support
+
+obj-y                          += dev-audio.o
index ccccae2..154bca4 100644 (file)
 #include <plat/clock-clksrc.h>
 #include <plat/s5pv210.h>
 
+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 struct clksrc_clk clk_mout_epll = {
+       .clk    = {
+               .name           = "mout_epll",
+               .id             = -1,
+       },
+       .sources        = &clk_src_epll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .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 = 4, .size = 1 },
+};
+
+static struct clk *clkset_armclk_list[] = {
+       [0] = &clk_mout_apll.clk,
+       [1] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_armclk = {
+       .sources        = clkset_armclk_list,
+       .nr_sources     = ARRAY_SIZE(clkset_armclk_list),
+};
+
+static struct clksrc_clk clk_armclk = {
+       .clk    = {
+               .name           = "armclk",
+               .id             = -1,
+       },
+       .sources        = &clkset_armclk,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk clk_hclk_msys = {
+       .clk    = {
+               .name           = "hclk_msys",
+               .id             = -1,
+               .parent         = &clk_armclk.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_pclk_msys = {
+       .clk    = {
+               .name           = "pclk_msys",
+               .id             = -1,
+               .parent         = &clk_hclk_msys.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_sclk_a2m = {
+       .clk    = {
+               .name           = "sclk_a2m",
+               .id             = -1,
+               .parent         = &clk_mout_apll.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+};
+
+static struct clk *clkset_hclk_sys_list[] = {
+       [0] = &clk_mout_mpll.clk,
+       [1] = &clk_sclk_a2m.clk,
+};
+
+static struct clksrc_sources clkset_hclk_sys = {
+       .sources        = clkset_hclk_sys_list,
+       .nr_sources     = ARRAY_SIZE(clkset_hclk_sys_list),
+};
+
+static struct clksrc_clk clk_hclk_dsys = {
+       .clk    = {
+               .name   = "hclk_dsys",
+               .id     = -1,
+       },
+       .sources        = &clkset_hclk_sys,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_dsys = {
+       .clk    = {
+               .name   = "pclk_dsys",
+               .id     = -1,
+               .parent = &clk_hclk_dsys.clk,
+       },
+       .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk clk_hclk_psys = {
+       .clk    = {
+               .name   = "hclk_psys",
+               .id     = -1,
+       },
+       .sources        = &clkset_hclk_sys,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_psys = {
+       .clk    = {
+               .name   = "pclk_psys",
+               .id     = -1,
+               .parent = &clk_hclk_psys.clk,
+       },
+       .reg_div        = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
+};
+
 static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
 {
        return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
@@ -51,176 +173,226 @@ static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
        return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
 }
 
-static struct clk clk_h200 = {
-       .name           = "hclk200",
+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);
+}
+
+static struct clk clk_sclk_hdmi27m = {
+       .name           = "sclk_hdmi27m",
        .id             = -1,
+       .rate           = 27000000,
 };
 
-static struct clk clk_h100 = {
-       .name           = "hclk100",
+static struct clk clk_sclk_hdmiphy = {
+       .name           = "sclk_hdmiphy",
        .id             = -1,
 };
 
-static struct clk clk_h166 = {
-       .name           = "hclk166",
+static struct clk clk_sclk_usbphy0 = {
+       .name           = "sclk_usbphy0",
        .id             = -1,
 };
 
-static struct clk clk_h133 = {
-       .name           = "hclk133",
+static struct clk clk_sclk_usbphy1 = {
+       .name           = "sclk_usbphy1",
        .id             = -1,
 };
 
-static struct clk clk_p100 = {
-       .name           = "pclk100",
+static struct clk clk_pcmcdclk0 = {
+       .name           = "pcmcdclk",
        .id             = -1,
 };
 
-static struct clk clk_p83 = {
-       .name           = "pclk83",
+static struct clk clk_pcmcdclk1 = {
+       .name           = "pcmcdclk",
        .id             = -1,
 };
 
-static struct clk clk_p66 = {
-       .name           = "pclk66",
+static struct clk clk_pcmcdclk2 = {
+       .name           = "pcmcdclk",
        .id             = -1,
 };
 
-static struct clk *sys_clks[] = {
-       &clk_h200,
-       &clk_h100,
-       &clk_h166,
-       &clk_h133,
-       &clk_p100,
-       &clk_p83,
-       &clk_p66
+static struct clk *clkset_vpllsrc_list[] = {
+       [0] = &clk_fin_vpll,
+       [1] = &clk_sclk_hdmi27m,
+};
+
+static struct clksrc_sources clkset_vpllsrc = {
+       .sources        = clkset_vpllsrc_list,
+       .nr_sources     = ARRAY_SIZE(clkset_vpllsrc_list),
+};
+
+static struct clksrc_clk clk_vpllsrc = {
+       .clk    = {
+               .name           = "vpll_src",
+               .id             = -1,
+               .enable         = s5pv210_clk_mask0_ctrl,
+               .ctrlbit        = (1 << 7),
+       },
+       .sources        = &clkset_vpllsrc,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
+};
+
+static struct clk *clkset_sclk_vpll_list[] = {
+       [0] = &clk_vpllsrc.clk,
+       [1] = &clk_fout_vpll,
+};
+
+static struct clksrc_sources clkset_sclk_vpll = {
+       .sources        = clkset_sclk_vpll_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_vpll_list),
+};
+
+static struct clksrc_clk clk_sclk_vpll = {
+       .clk    = {
+               .name           = "sclk_vpll",
+               .id             = -1,
+       },
+       .sources        = &clkset_sclk_vpll,
+       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
+static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
+{
+       return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk_ops clk_hclk_imem_ops = {
+       .get_rate       = s5pv210_clk_imem_get_rate,
 };
 
 static struct clk init_clocks_disable[] = {
        {
                .name           = "rot",
                .id             = -1,
-               .parent         = &clk_h166,
+               .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip0_ctrl,
                .ctrlbit        = (1<<29),
        }, {
                .name           = "otg",
                .id             = -1,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<16),
        }, {
                .name           = "usb-host",
                .id             = -1,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<17),
        }, {
                .name           = "lcd",
                .id             = -1,
-               .parent         = &clk_h166,
+               .parent         = &clk_hclk_dsys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<0),
        }, {
                .name           = "cfcon",
                .id             = 0,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip1_ctrl,
                .ctrlbit        = (1<<25),
        }, {
                .name           = "hsmmc",
                .id             = 0,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<16),
        }, {
                .name           = "hsmmc",
                .id             = 1,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<17),
        }, {
                .name           = "hsmmc",
                .id             = 2,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<18),
        }, {
                .name           = "hsmmc",
                .id             = 3,
-               .parent         = &clk_h133,
+               .parent         = &clk_hclk_psys.clk,
                .enable         = s5pv210_clk_ip2_ctrl,
                .ctrlbit        = (1<<19),
        }, {
                .name           = "systimer",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<16),
        }, {
                .name           = "watchdog",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<22),
        }, {
                .name           = "rtc",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<15),
        }, {
                .name           = "i2c",
                .id             = 0,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<7),
        }, {
                .name           = "i2c",
                .id             = 1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<8),
        }, {
                .name           = "i2c",
                .id             = 2,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<9),
        }, {
                .name           = "spi",
                .id             = 0,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<12),
        }, {
                .name           = "spi",
                .id             = 1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<13),
        }, {
                .name           = "spi",
                .id             = 2,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<14),
        }, {
                .name           = "timers",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<23),
        }, {
                .name           = "adc",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<24),
        }, {
                .name           = "keypad",
                .id             = -1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<21),
        }, {
@@ -246,106 +418,537 @@ static struct clk init_clocks_disable[] = {
 
 static struct clk init_clocks[] = {
        {
+               .name           = "hclk_imem",
+               .id             = -1,
+               .parent         = &clk_hclk_msys.clk,
+               .ctrlbit        = (1 << 5),
+               .enable         = s5pv210_clk_ip0_ctrl,
+               .ops            = &clk_hclk_imem_ops,
+       }, {
                .name           = "uart",
                .id             = 0,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<7),
        }, {
                .name           = "uart",
                .id             = 1,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<8),
        }, {
                .name           = "uart",
                .id             = 2,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<9),
        }, {
                .name           = "uart",
                .id             = 3,
-               .parent         = &clk_p66,
+               .parent         = &clk_pclk_psys.clk,
                .enable         = s5pv210_clk_ip3_ctrl,
                .ctrlbit        = (1<<10),
        },
 };
 
-static struct clksrc_clk clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
+static struct clk *clkset_uart_list[] = {
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+       .sources        = clkset_uart_list,
+       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_group1_list[] = {
+       [0] = &clk_sclk_a2m.clk,
+       [1] = &clk_mout_mpll.clk,
+       [2] = &clk_mout_epll.clk,
+       [3] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_group1 = {
+       .sources        = clkset_group1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_sclk_onenand_list[] = {
+       [0] = &clk_hclk_psys.clk,
+       [1] = &clk_hclk_dsys.clk,
+};
+
+static struct clksrc_sources clkset_sclk_onenand = {
+       .sources        = clkset_sclk_onenand_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_onenand_list),
+};
+
+static struct clk *clkset_sclk_dac_list[] = {
+       [0] = &clk_sclk_vpll.clk,
+       [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_dac = {
+       .sources        = clkset_sclk_dac_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk clk_sclk_dac = {
+       .clk            = {
+               .name           = "sclk_dac",
                .id             = -1,
+               .ctrlbit        = (1 << 10),
+               .enable         = s5pv210_clk_ip1_ctrl,
        },
-       .sources        = &clk_src_apll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+       .sources        = &clkset_sclk_dac,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
 };
 
-static struct clksrc_clk clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
+static struct clksrc_clk clk_sclk_pixel = {
+       .clk            = {
+               .name           = "sclk_pixel",
                .id             = -1,
+               .parent         = &clk_sclk_vpll.clk,
        },
-       .sources        = &clk_src_epll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+       .reg_div        = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
 };
 
-static struct clksrc_clk clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
+static struct clk *clkset_sclk_hdmi_list[] = {
+       [0] = &clk_sclk_pixel.clk,
+       [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_hdmi = {
+       .sources        = clkset_sclk_hdmi_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk clk_sclk_hdmi = {
+       .clk            = {
+               .name           = "sclk_hdmi",
                .id             = -1,
+               .enable         = s5pv210_clk_ip1_ctrl,
+               .ctrlbit        = (1 << 11),
        },
-       .sources        = &clk_src_mpll,
-       .reg_src        = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+       .sources        = &clkset_sclk_hdmi,
+       .reg_src        = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
 };
 
-static struct clk *clkset_uart_list[] = {
+static struct clk *clkset_sclk_mixer_list[] = {
+       [0] = &clk_sclk_dac.clk,
+       [1] = &clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources clkset_sclk_mixer = {
+       .sources        = clkset_sclk_mixer_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_mixer_list),
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_pcmcdclk0,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
        [6] = &clk_mout_mpll.clk,
        [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
 };
 
-static struct clksrc_sources clkset_uart = {
-       .sources        = clkset_uart_list,
-       .nr_sources     = ARRAY_SIZE(clkset_uart_list),
+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           = "sclk_audio",
+               .id             = 0,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 4),
+       },
+       .sources = &clkset_sclk_audio0,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
+       .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
+};
+
+static struct clk *clkset_sclk_audio1_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_pcmcdclk1,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_sclk_audio1 = {
+       .sources        = clkset_sclk_audio1_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_audio1_list),
+};
+
+static struct clksrc_clk clk_sclk_audio1 = {
+       .clk            = {
+               .name           = "sclk_audio",
+               .id             = 1,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 5),
+       },
+       .sources = &clkset_sclk_audio1,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
+       .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
+};
+
+static struct clk *clkset_sclk_audio2_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_pcmcdclk0,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_sclk_audio2 = {
+       .sources        = clkset_sclk_audio2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_audio2_list),
+};
+
+static struct clksrc_clk clk_sclk_audio2 = {
+       .clk            = {
+               .name           = "sclk_audio",
+               .id             = 2,
+               .enable         = s5pv210_clk_ip3_ctrl,
+               .ctrlbit        = (1 << 6),
+       },
+       .sources = &clkset_sclk_audio2,
+       .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
+       .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
+};
+
+static struct clk *clkset_sclk_spdif_list[] = {
+       [0] = &clk_sclk_audio0.clk,
+       [1] = &clk_sclk_audio1.clk,
+       [2] = &clk_sclk_audio2.clk,
+};
+
+static struct clksrc_sources clkset_sclk_spdif = {
+       .sources        = clkset_sclk_spdif_list,
+       .nr_sources     = ARRAY_SIZE(clkset_sclk_spdif_list),
+};
+
+static struct clk *clkset_group2_list[] = {
+       [0] = &clk_ext_xtal_mux,
+       [1] = &clk_xusbxti,
+       [2] = &clk_sclk_hdmi27m,
+       [3] = &clk_sclk_usbphy0,
+       [4] = &clk_sclk_usbphy1,
+       [5] = &clk_sclk_hdmiphy,
+       [6] = &clk_mout_mpll.clk,
+       [7] = &clk_mout_epll.clk,
+       [8] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_group2 = {
+       .sources        = clkset_group2_list,
+       .nr_sources     = ARRAY_SIZE(clkset_group2_list),
 };
 
 static struct clksrc_clk clksrcs[] = {
        {
                .clk    = {
-                       .name           = "uclk1",
+                       .name           = "sclk_dmc",
                        .id             = -1,
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_onenand",
+                       .id             = -1,
+               },
+               .sources = &clkset_sclk_onenand,
+               .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
+       }, {
+               .clk    = {
+                       .name           = "uclk1",
+                       .id             = 0,
                        .ctrlbit        = (1<<17),
                        .enable         = s5pv210_clk_ip3_ctrl,
                },
                .sources = &clkset_uart,
                .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
                .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
-       }
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 18),
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .id             = 2,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 19),
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "uclk1",
+                       .id             = 3,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 20),
+               },
+               .sources = &clkset_uart,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_mixer",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip1_ctrl,
+                       .ctrlbit        = (1 << 9),
+               },
+               .sources = &clkset_sclk_mixer,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spdif",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_mask0_ctrl,
+                       .ctrlbit        = (1 << 27),
+               },
+               .sources = &clkset_sclk_spdif,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 0,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 24),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 25),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
+       }, {
+               .clk    = {
+                       .name           = "sclk_fimc",
+                       .id             = 2,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 26),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam",
+                       .id             = 0,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_cam",
+                       .id             = 1,
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_fimd",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip1_ctrl,
+                       .ctrlbit        = (1 << 0),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 0,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 17),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 2,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 18),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mmc",
+                       .id             = 3,
+                       .enable         = s5pv210_clk_ip2_ctrl,
+                       .ctrlbit        = (1 << 19),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_mfc",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 16),
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_g2d",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_g3d",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 8),
+               },
+               .sources = &clkset_group1,
+               .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
+               .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_csis",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip0_ctrl,
+                       .ctrlbit        = (1 << 31),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 0,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 12),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_spi",
+                       .id             = 1,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 13),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_pwi",
+                       .id             = -1,
+                       .enable         = &s5pv210_clk_ip4_ctrl,
+                       .ctrlbit        = (1 << 2),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
+       }, {
+               .clk            = {
+                       .name           = "sclk_pwm",
+                       .id             = -1,
+                       .enable         = s5pv210_clk_ip3_ctrl,
+                       .ctrlbit        = (1 << 23),
+               },
+               .sources = &clkset_group2,
+               .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
+               .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
+       },
 };
 
 /* Clock initialisation code */
-static struct clksrc_clk *init_parents[] = {
+static struct clksrc_clk *sysclks[] = {
        &clk_mout_apll,
        &clk_mout_epll,
        &clk_mout_mpll,
+       &clk_armclk,
+       &clk_hclk_msys,
+       &clk_sclk_a2m,
+       &clk_hclk_dsys,
+       &clk_hclk_psys,
+       &clk_pclk_msys,
+       &clk_pclk_dsys,
+       &clk_pclk_psys,
+       &clk_vpllsrc,
+       &clk_sclk_vpll,
+       &clk_sclk_dac,
+       &clk_sclk_pixel,
+       &clk_sclk_hdmi,
 };
 
-#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
-
 void __init_or_cpufreq s5pv210_setup_clocks(void)
 {
        struct clk *xtal_clk;
        unsigned long xtal;
+       unsigned long vpllsrc;
        unsigned long armclk;
-       unsigned long hclk200;
-       unsigned long hclk166;
-       unsigned long hclk133;
-       unsigned long pclk100;
-       unsigned long pclk83;
-       unsigned long pclk66;
+       unsigned long hclk_msys;
+       unsigned long hclk_dsys;
+       unsigned long hclk_psys;
+       unsigned long pclk_msys;
+       unsigned long pclk_dsys;
+       unsigned long pclk_psys;
        unsigned long apll;
        unsigned long mpll;
        unsigned long epll;
+       unsigned long vpll;
        unsigned int ptr;
        u32 clkdiv0, clkdiv1;
 
@@ -368,59 +971,46 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
        apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
        mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
        epll = s5p_get_pll45xx(xtal, __raw_readl(S5P_EPLL_CON), pll_4500);
-
-       printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld",
-                       apll, mpll, epll);
-
-       armclk = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_APLL);
-       if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX200_MASK)
-               hclk200 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
-       else
-               hclk200 = armclk / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK200);
-
-       if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX166_MASK) {
-               hclk166 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
-               hclk166 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
-       } else
-               hclk166 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK166);
-
-       if (__raw_readl(S5P_CLK_SRC0) & S5P_CLKSRC0_MUX133_MASK) {
-               hclk133 = apll / GET_DIV(clkdiv0, S5P_CLKDIV0_A2M);
-               hclk133 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
-       } else
-               hclk133 = mpll / GET_DIV(clkdiv0, S5P_CLKDIV0_HCLK133);
-
-       pclk100 = hclk200 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK100);
-       pclk83 = hclk166 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK83);
-       pclk66 = hclk133 / GET_DIV(clkdiv0, S5P_CLKDIV0_PCLK66);
-
-       printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld, \
-                       HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
-              armclk, hclk200, hclk166, hclk133, pclk100, pclk83, pclk66);
+       vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+       vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
 
        clk_fout_apll.rate = apll;
        clk_fout_mpll.rate = mpll;
        clk_fout_epll.rate = epll;
+       clk_fout_vpll.rate = vpll;
 
-       clk_f.rate = armclk;
-       clk_h.rate = hclk133;
-       clk_p.rate = pclk66;
-       clk_p66.rate = pclk66;
-       clk_p83.rate = pclk83;
-       clk_h133.rate = hclk133;
-       clk_h166.rate = hclk166;
-       clk_h200.rate = hclk200;
+       printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+                       apll, mpll, epll, vpll);
+
+       armclk = clk_get_rate(&clk_armclk.clk);
+       hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
+       hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
+       hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
+       pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
+       pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
+       pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
+
+       printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
+                        "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
+                       armclk, hclk_msys, hclk_dsys, hclk_psys,
+                       pclk_msys, pclk_dsys, pclk_psys);
 
-       for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-               s3c_set_clksrc(init_parents[ptr], true);
+       clk_f.rate = armclk;
+       clk_h.rate = hclk_psys;
+       clk_p.rate = pclk_psys;
 
        for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
                s3c_set_clksrc(&clksrcs[ptr], true);
 }
 
 static struct clk *clks[] __initdata = {
-       &clk_mout_epll.clk,
-       &clk_mout_mpll.clk,
+       &clk_sclk_hdmi27m,
+       &clk_sclk_hdmiphy,
+       &clk_sclk_usbphy0,
+       &clk_sclk_usbphy1,
+       &clk_pcmcdclk0,
+       &clk_pcmcdclk1,
+       &clk_pcmcdclk2,
 };
 
 void __init s5pv210_register_clocks(void)
@@ -433,13 +1023,12 @@ void __init s5pv210_register_clocks(void)
        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));
 
-       ret = s3c24xx_register_clocks(sys_clks, ARRAY_SIZE(sys_clks));
-       if (ret > 0)
-               printk(KERN_ERR "Failed to register system clocks\n");
-
        clkp = init_clocks_disable;
        for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
                ret = s3c24xx_register_clock(clkp);
index 0e0f8fd..2b776eb 100644 (file)
@@ -100,7 +100,7 @@ void __init s5pv210_init_irq(void)
        s5p_init_irq(vic, ARRAY_SIZE(vic));
 }
 
-static struct sysdev_class s5pv210_sysclass = {
+struct sysdev_class s5pv210_sysclass = {
        .name   = "s5pv210-core",
 };
 
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
new file mode 100644 (file)
index 0000000..6e21533
--- /dev/null
@@ -0,0 +1,327 @@
+/* linux/arch/arm/mach-s5pv210/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 <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/gpio.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5pv210_cfg_i2s(struct platform_device *pdev)
+{
+       /* configure GPIO for i2s port */
+       switch (pdev->id) {
+       case 1:
+               s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(2));
+               break;
+
+       case 2:
+               s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(4));
+               s3c_gpio_cfgpin(S5PV210_GPC1(4), S3C_GPIO_SFN(4));
+               break;
+
+       case -1:
+               s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(5), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPI(6), S3C_GPIO_SFN(2));
+               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 = s5pv210_cfg_i2s,
+};
+
+static struct resource s5pv210_iis0_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_IIS0,
+               .end   = S5PV210_PA_IIS0 + 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 s5pv210_device_iis0 = {
+       .name             = "s3c64xx-iis-v4",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5pv210_iis0_resource),
+       .resource         = s5pv210_iis0_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+static struct resource s5pv210_iis1_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_IIS1,
+               .end   = S5PV210_PA_IIS1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S1_TX,
+               .end   = DMACH_I2S1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S1_RX,
+               .end   = DMACH_I2S1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_iis1 = {
+       .name             = "s3c64xx-iis",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5pv210_iis1_resource),
+       .resource         = s5pv210_iis1_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+static struct resource s5pv210_iis2_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_IIS2,
+               .end   = S5PV210_PA_IIS2 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_I2S2_TX,
+               .end   = DMACH_I2S2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_I2S2_RX,
+               .end   = DMACH_I2S2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_iis2 = {
+       .name             = "s3c64xx-iis",
+       .id               = 2,
+       .num_resources    = ARRAY_SIZE(s5pv210_iis2_resource),
+       .resource         = s5pv210_iis2_resource,
+       .dev = {
+               .platform_data = &s3c_i2s_pdata,
+       },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
+{
+       switch (pdev->id) {
+       case 0:
+               s3c_gpio_cfgpin(S5PV210_GPI(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPI(4), S3C_GPIO_SFN(3));
+               break;
+       case 1:
+               s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(3));
+               s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(3));
+               break;
+       case 2:
+               s3c_gpio_cfgpin(S5PV210_GPC1(0), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(1), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(2), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(3), S3C_GPIO_SFN(2));
+               s3c_gpio_cfgpin(S5PV210_GPC1(4), 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 = s5pv210_pcm_cfg_gpio,
+};
+
+static struct resource s5pv210_pcm0_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_PCM0,
+               .end   = S5PV210_PA_PCM0 + 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 s5pv210_device_pcm0 = {
+       .name             = "samsung-pcm",
+       .id               = 0,
+       .num_resources    = ARRAY_SIZE(s5pv210_pcm0_resource),
+       .resource         = s5pv210_pcm0_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource s5pv210_pcm1_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_PCM1,
+               .end   = S5PV210_PA_PCM1 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM1_TX,
+               .end   = DMACH_PCM1_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM1_RX,
+               .end   = DMACH_PCM1_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_pcm1 = {
+       .name             = "samsung-pcm",
+       .id               = 1,
+       .num_resources    = ARRAY_SIZE(s5pv210_pcm1_resource),
+       .resource         = s5pv210_pcm1_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+static struct resource s5pv210_pcm2_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_PCM2,
+               .end   = S5PV210_PA_PCM2 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_PCM2_TX,
+               .end   = DMACH_PCM2_TX,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_PCM2_RX,
+               .end   = DMACH_PCM2_RX,
+               .flags = IORESOURCE_DMA,
+       },
+};
+
+struct platform_device s5pv210_device_pcm2 = {
+       .name             = "samsung-pcm",
+       .id               = 2,
+       .num_resources    = ARRAY_SIZE(s5pv210_pcm2_resource),
+       .resource         = s5pv210_pcm2_resource,
+       .dev = {
+               .platform_data = &s3c_pcm_pdata,
+       },
+};
+
+/* AC97 Controller platform devices */
+
+static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
+{
+       s3c_gpio_cfgpin(S5PV210_GPC0(0), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(1), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(2), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(3), S3C_GPIO_SFN(4));
+       s3c_gpio_cfgpin(S5PV210_GPC0(4), S3C_GPIO_SFN(4));
+
+       return 0;
+}
+
+static struct resource s5pv210_ac97_resource[] = {
+       [0] = {
+               .start = S5PV210_PA_AC97,
+               .end   = S5PV210_PA_AC97 + 0x100 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = DMACH_AC97_PCMOUT,
+               .end   = DMACH_AC97_PCMOUT,
+               .flags = IORESOURCE_DMA,
+       },
+       [2] = {
+               .start = DMACH_AC97_PCMIN,
+               .end   = DMACH_AC97_PCMIN,
+               .flags = IORESOURCE_DMA,
+       },
+       [3] = {
+               .start = DMACH_AC97_MICIN,
+               .end   = DMACH_AC97_MICIN,
+               .flags = IORESOURCE_DMA,
+       },
+       [4] = {
+               .start = IRQ_AC97,
+               .end   = IRQ_AC97,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_audio_pdata s3c_ac97_pdata = {
+       .cfg_gpio = s5pv210_ac97_cfg_gpio,
+};
+
+static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_ac97 = {
+       .name             = "s3c-ac97",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(s5pv210_ac97_resource),
+       .resource         = s5pv210_ac97_resource,
+       .dev = {
+               .platform_data = &s3c_ac97_pdata,
+               .dma_mask = &s5pv210_ac97_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
new file mode 100644 (file)
index 0000000..778ad5f
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <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 <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5pv210_pdma0_resource[] = {
+       [0] = {
+               .start  = S5PV210_PA_PDMA0,
+               .end    = S5PV210_PA_PDMA0 + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PDMA0,
+               .end    = IRQ_PDMA0,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5pv210_pdma0_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_MAX,
+               [9] = DMACH_I2S0_RX,
+               [10] = DMACH_I2S0_TX,
+               [11] = DMACH_I2S0S_TX,
+               [12] = DMACH_I2S1_RX,
+               [13] = DMACH_I2S1_TX,
+               [14] = DMACH_MAX,
+               [15] = DMACH_MAX,
+               [16] = DMACH_SPI0_RX,
+               [17] = DMACH_SPI0_TX,
+               [18] = DMACH_SPI1_RX,
+               [19] = DMACH_SPI1_TX,
+               [20] = DMACH_MAX,
+               [21] = DMACH_MAX,
+               [22] = DMACH_AC97_MICIN,
+               [23] = DMACH_AC97_PCMIN,
+               [24] = DMACH_AC97_PCMOUT,
+               [25] = DMACH_MAX,
+               [26] = DMACH_PWM,
+               [27] = DMACH_SPDIF,
+               [28] = DMACH_MAX,
+               [29] = DMACH_MAX,
+               [30] = DMACH_MAX,
+               [31] = DMACH_MAX,
+       },
+};
+
+static struct platform_device s5pv210_device_pdma0 = {
+       .name           = "s3c-pl330",
+       .id             = 1,
+       .num_resources  = ARRAY_SIZE(s5pv210_pdma0_resource),
+       .resource       = s5pv210_pdma0_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5pv210_pdma0_pdata,
+       },
+};
+
+static struct resource s5pv210_pdma1_resource[] = {
+       [0] = {
+               .start  = S5PV210_PA_PDMA1,
+               .end    = S5PV210_PA_PDMA1 + SZ_4K,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_PDMA1,
+               .end    = IRQ_PDMA1,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct s3c_pl330_platdata s5pv210_pdma1_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_MAX,
+               [9] = DMACH_I2S0_RX,
+               [10] = DMACH_I2S0_TX,
+               [11] = DMACH_I2S0S_TX,
+               [12] = DMACH_I2S1_RX,
+               [13] = DMACH_I2S1_TX,
+               [14] = DMACH_I2S2_RX,
+               [15] = DMACH_I2S2_TX,
+               [16] = DMACH_SPI0_RX,
+               [17] = DMACH_SPI0_TX,
+               [18] = DMACH_SPI1_RX,
+               [19] = DMACH_SPI1_TX,
+               [20] = DMACH_MAX,
+               [21] = DMACH_MAX,
+               [22] = DMACH_PCM0_RX,
+               [23] = DMACH_PCM0_TX,
+               [24] = DMACH_PCM1_RX,
+               [25] = DMACH_PCM1_TX,
+               [26] = DMACH_MSM_REQ0,
+               [27] = DMACH_MSM_REQ1,
+               [28] = DMACH_MSM_REQ2,
+               [29] = DMACH_MSM_REQ3,
+               [30] = DMACH_PCM2_RX,
+               [31] = DMACH_PCM2_TX,
+       },
+};
+
+static struct platform_device s5pv210_device_pdma1 = {
+       .name           = "s3c-pl330",
+       .id             = 2,
+       .num_resources  = ARRAY_SIZE(s5pv210_pdma1_resource),
+       .resource       = s5pv210_pdma1_resource,
+       .dev            = {
+               .dma_mask = &dma_dmamask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+               .platform_data = &s5pv210_pdma1_pdata,
+       },
+};
+
+static struct platform_device *s5pv210_dmacs[] __initdata = {
+       &s5pv210_device_pdma0,
+       &s5pv210_device_pdma1,
+};
+
+static int __init s5pv210_dma_init(void)
+{
+       platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs));
+
+       return 0;
+}
+arch_initcall(s5pv210_dma_init);
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
new file mode 100644 (file)
index 0000000..9ea8972
--- /dev/null
@@ -0,0 +1,261 @@
+/* linux/arch/arm/mach-s5pv210/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * S5PV210 - 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 <linux/io.h>
+#include <linux/gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/map.h>
+
+static struct s3c_gpio_cfg gpio_cfg = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
+       .set_pull       = s3c_gpio_setpull_updown,
+       .get_pull       = s3c_gpio_getpull_updown,
+};
+
+/* GPIO bank's base address given the index of the bank in the
+ * list of all gpio banks.
+ */
+#define S5PV210_BANK_BASE(bank_nr)     (S5P_VA_GPIO + ((bank_nr) * 0x20))
+
+/*
+ * Following are the gpio banks in v210.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
+       {
+               .chip   = {
+                       .base   = S5PV210_GPA0(0),
+                       .ngpio  = S5PV210_GPIO_A0_NR,
+                       .label  = "GPA0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPA1(0),
+                       .ngpio  = S5PV210_GPIO_A1_NR,
+                       .label  = "GPA1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPB(0),
+                       .ngpio  = S5PV210_GPIO_B_NR,
+                       .label  = "GPB",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPC0(0),
+                       .ngpio  = S5PV210_GPIO_C0_NR,
+                       .label  = "GPC0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPC1(0),
+                       .ngpio  = S5PV210_GPIO_C1_NR,
+                       .label  = "GPC1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPD0(0),
+                       .ngpio  = S5PV210_GPIO_D0_NR,
+                       .label  = "GPD0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPD1(0),
+                       .ngpio  = S5PV210_GPIO_D1_NR,
+                       .label  = "GPD1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPE0(0),
+                       .ngpio  = S5PV210_GPIO_E0_NR,
+                       .label  = "GPE0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPE1(0),
+                       .ngpio  = S5PV210_GPIO_E1_NR,
+                       .label  = "GPE1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF0(0),
+                       .ngpio  = S5PV210_GPIO_F0_NR,
+                       .label  = "GPF0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF1(0),
+                       .ngpio  = S5PV210_GPIO_F1_NR,
+                       .label  = "GPF1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF2(0),
+                       .ngpio  = S5PV210_GPIO_F2_NR,
+                       .label  = "GPF2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPF3(0),
+                       .ngpio  = S5PV210_GPIO_F3_NR,
+                       .label  = "GPF3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG0(0),
+                       .ngpio  = S5PV210_GPIO_G0_NR,
+                       .label  = "GPG0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG1(0),
+                       .ngpio  = S5PV210_GPIO_G1_NR,
+                       .label  = "GPG1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG2(0),
+                       .ngpio  = S5PV210_GPIO_G2_NR,
+                       .label  = "GPG2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPG3(0),
+                       .ngpio  = S5PV210_GPIO_G3_NR,
+                       .label  = "GPG3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPI(0),
+                       .ngpio  = S5PV210_GPIO_I_NR,
+                       .label  = "GPI",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ0(0),
+                       .ngpio  = S5PV210_GPIO_J0_NR,
+                       .label  = "GPJ0",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ1(0),
+                       .ngpio  = S5PV210_GPIO_J1_NR,
+                       .label  = "GPJ1",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ2(0),
+                       .ngpio  = S5PV210_GPIO_J2_NR,
+                       .label  = "GPJ2",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ3(0),
+                       .ngpio  = S5PV210_GPIO_J3_NR,
+                       .label  = "GPJ3",
+               },
+       }, {
+               .chip   = {
+                       .base   = S5PV210_GPJ4(0),
+                       .ngpio  = S5PV210_GPIO_J4_NR,
+                       .label  = "GPJ4",
+               },
+       }, {
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_MP01(0),
+                       .ngpio  = S5PV210_GPIO_MP01_NR,
+                       .label  = "MP01",
+               },
+       }, {
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_MP02(0),
+                       .ngpio  = S5PV210_GPIO_MP02_NR,
+                       .label  = "MP02",
+               },
+       }, {
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_MP03(0),
+                       .ngpio  = S5PV210_GPIO_MP03_NR,
+                       .label  = "MP03",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC00),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH0(0),
+                       .ngpio  = S5PV210_GPIO_H0_NR,
+                       .label  = "GPH0",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC20),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH1(0),
+                       .ngpio  = S5PV210_GPIO_H1_NR,
+                       .label  = "GPH1",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC40),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH2(0),
+                       .ngpio  = S5PV210_GPIO_H2_NR,
+                       .label  = "GPH2",
+               },
+       }, {
+               .base   = (S5P_VA_GPIO + 0xC60),
+               .config = &gpio_cfg_noint,
+               .chip   = {
+                       .base   = S5PV210_GPH3(0),
+                       .ngpio  = S5PV210_GPIO_H3_NR,
+                       .label  = "GPH3",
+               },
+       },
+};
+
+static __init int s5pv210_gpiolib_init(void)
+{
+       struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
+       int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
+       int i = 0;
+
+       for (i = 0; i < nr_chips; i++, chip++) {
+               if (chip->config == NULL)
+                       chip->config = &gpio_cfg;
+               if (chip->base == NULL)
+                       chip->base = S5PV210_BANK_BASE(i);
+       }
+
+       samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
+
+       return 0;
+}
+core_initcall(s5pv210_gpiolib_init);
diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h
new file mode 100644 (file)
index 0000000..81209eb
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
index 533b020..d6461ba 100644 (file)
@@ -18,6 +18,8 @@
 #define gpio_cansleep  __gpio_cansleep
 #define gpio_to_irq    __gpio_to_irq
 
+/* Practically, GPIO banks upto MP03 are the configurable gpio banks */
+
 /* GPIO bank sizes */
 #define S5PV210_GPIO_A0_NR     (8)
 #define S5PV210_GPIO_A1_NR     (4)
 #define S5PV210_GPIO_J3_NR     (8)
 #define S5PV210_GPIO_J4_NR     (5)
 
+#define S5PV210_GPIO_MP01_NR   (8)
+#define S5PV210_GPIO_MP02_NR   (4)
+#define S5PV210_GPIO_MP03_NR   (8)
+
 /* GPIO bank numbers */
 
 /* CONFIG_S3C_GPIO_SPACE allows the user to select extra
@@ -85,6 +91,9 @@ enum s5p_gpio_number {
        S5PV210_GPIO_J2_START   = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1),
        S5PV210_GPIO_J3_START   = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2),
        S5PV210_GPIO_J4_START   = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3),
+       S5PV210_GPIO_MP01_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J4),
+       S5PV210_GPIO_MP02_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP01),
+       S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02),
 };
 
 /* S5PV210 GPIO number definitions */
@@ -115,13 +124,16 @@ enum s5p_gpio_number {
 #define S5PV210_GPJ2(_nr)      (S5PV210_GPIO_J2_START + (_nr))
 #define S5PV210_GPJ3(_nr)      (S5PV210_GPIO_J3_START + (_nr))
 #define S5PV210_GPJ4(_nr)      (S5PV210_GPIO_J4_START + (_nr))
+#define S5PV210_MP01(_nr)      (S5PV210_GPIO_MP01_START + (_nr))
+#define S5PV210_MP02(_nr)      (S5PV210_GPIO_MP02_START + (_nr))
+#define S5PV210_MP03(_nr)      (S5PV210_GPIO_MP03_START + (_nr))
 
 /* the end of the S5PV210 specific gpios */
-#define S5PV210_GPIO_END       (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) + 1)
+#define S5PV210_GPIO_END       (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + 1)
 #define S3C_GPIO_END           S5PV210_GPIO_END
 
-/* define the number of gpios we need to the one after the GPJ4() range */
-#define ARCH_NR_GPIOS          (S5PV210_GPJ4(S5PV210_GPIO_J4_NR) +     \
+/* define the number of gpios we need to the one after the MP03() range */
+#define ARCH_NR_GPIOS          (S5PV210_MP03(S5PV210_GPIO_MP03_NR) +   \
                                 CONFIG_SAMSUNG_GPIO_EXTRA + 1)
 
 #include <asm-generic/gpio.h>
index c22694c..5adcb9f 100644 (file)
 
 #define S5PV210_PA_SROMC       (0xE8000000)
 
+#define S5PV210_PA_MDMA                0xFA200000
+#define S5PV210_PA_PDMA0       0xE0900000
+#define S5PV210_PA_PDMA1       0xE0A00000
+
 #define S5PV210_PA_VIC0                (0xF2000000)
 #define S5P_PA_VIC0            S5PV210_PA_VIC0
 
 #define S5PV210_PA_SDRAM       (0x20000000)
 #define S5P_PA_SDRAM           S5PV210_PA_SDRAM
 
+/* I2S */
+#define S5PV210_PA_IIS0                0xEEE30000
+#define S5PV210_PA_IIS1                0xE2100000
+#define S5PV210_PA_IIS2                0xE2A00000
+
+/* PCM */
+#define S5PV210_PA_PCM0                0xE2300000
+#define S5PV210_PA_PCM1                0xE1200000
+#define S5PV210_PA_PCM2                0xE2B00000
+
+/* AC97 */
+#define S5PV210_PA_AC97                0xE2200000
+
 /* compatibiltiy defines. */
 #define S3C_PA_UART            S5PV210_PA_UART
 #define S3C_PA_IIC             S5PV210_PA_IIC0
index 69027fe..f8a9f1b 100644 (file)
@@ -1,13 +1,14 @@
 /* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
  *
+ * Copyright (c) 2009 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/
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Based on arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
  *
  * S5PV210 - pwm clock and timer support
  *
 
 /**
  * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
- * @cfg: The timer TCFG1 register bits shifted down to 0.
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
  *
  * Return true if the given configuration from TCFG1 is a TCLK instead
  * any of the TDIV clocks.
  */
 static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
 {
-       return tcfg == S3C2410_TCFG1_MUX_TCLK;
+       return tcfg == S3C64XX_TCFG1_MUX_TCLK;
 }
 
 /**
@@ -40,7 +41,7 @@ static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
  */
 static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
 {
-       return 1 << (1 + tcfg1);
+       return 1 << tcfg1;
 }
 
 /**
@@ -50,7 +51,7 @@ static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
  */
 static inline unsigned int pwm_tdiv_has_div1(void)
 {
-       return 0;
+       return 1;
 }
 
 /**
@@ -61,9 +62,9 @@ static inline unsigned int pwm_tdiv_has_div1(void)
  */
 static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
 {
-       return ilog2(div) - 1;
+       return ilog2(div);
 }
 
-#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
 
 #endif /* __ASM_ARCH_PWMCLK_H */
index ab4869d..6f9fd32 100644 (file)
@@ -72,6 +72,8 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdkc110_devices[] __initdata = {
+       &s5pv210_device_iis0,
+       &s5pv210_device_ac97,
 };
 
 static void __init smdkc110_map_io(void)
index a278832..3c29e18 100644 (file)
@@ -72,6 +72,8 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
 };
 
 static struct platform_device *smdkv210_devices[] __initdata = {
+       &s5pv210_device_iis0,
+       &s5pv210_device_ac97,
 };
 
 static void __init smdkv210_map_io(void)
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
new file mode 100644 (file)
index 0000000..9ec6845
--- /dev/null
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/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
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+       /* Will be populated later */
+}
index b17d52f..fd4c52b 100644 (file)
@@ -57,7 +57,7 @@ config SA1100_COLLIE
 config SA1100_H3100
        bool "Compaq iPAQ H3100"
        select HTC_EGPIO
-       select CPU_FREQ_SA1100
+       select CPU_FREQ_SA1110
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ
          H3100 handheld computer.  Information about this machine and the
@@ -68,7 +68,7 @@ config SA1100_H3100
 config SA1100_H3600
        bool "Compaq iPAQ H3600/H3700"
        select HTC_EGPIO
-       select CPU_FREQ_SA1100
+       select CPU_FREQ_SA1110
        help
          Say Y here if you intend to run this kernel on the Compaq iPAQ
          H3600 handheld computer.  Information about this machine and the
index 63b32b6..7252874 100644 (file)
@@ -363,6 +363,9 @@ static int __init sa1110_clk_init(void)
        struct sdram_params *sdram;
        const char *name = sdram_name;
 
+       if (!cpu_is_sa1110())
+               return -ENODEV;
+
        if (!name[0]) {
                if (machine_is_assabet())
                        name = "TC59SM716-CL3";
index aeceb9b..f2b88c5 100644 (file)
@@ -7,7 +7,6 @@ config ARCH_SH7367
        select CPU_V6
        select HAVE_CLK
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
 
 config ARCH_SH7377
@@ -15,7 +14,6 @@ config ARCH_SH7377
        select CPU_V7
        select HAVE_CLK
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
 
 config ARCH_SH7372
@@ -23,7 +21,6 @@ config ARCH_SH7372
        select CPU_V7
        select HAVE_CLK
        select COMMON_CLKDEV
-       select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
 
 comment "SH-Mobile Board Type"
diff --git a/arch/arm/mach-spear3xx/Kconfig b/arch/arm/mach-spear3xx/Kconfig
new file mode 100644 (file)
index 0000000..20d1317
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# SPEAr3XX Machine configuration file
+#
+
+if ARCH_SPEAR3XX
+
+choice
+       prompt "SPEAr3XX Family"
+       default MACH_SPEAR300
+
+config MACH_SPEAR300
+       bool "SPEAr300"
+       help
+         Supports ST SPEAr300 Machine
+
+config MACH_SPEAR310
+       bool "SPEAr310"
+       help
+         Supports ST SPEAr310 Machine
+
+config MACH_SPEAR320
+       bool "SPEAr320"
+       help
+         Supports ST SPEAr320 Machine
+
+endchoice
+
+# Adding SPEAr3XX machine specific configuration files
+source "arch/arm/mach-spear3xx/Kconfig300"
+source "arch/arm/mach-spear3xx/Kconfig310"
+source "arch/arm/mach-spear3xx/Kconfig320"
+
+endif #ARCH_SPEAR3XX
diff --git a/arch/arm/mach-spear3xx/Kconfig300 b/arch/arm/mach-spear3xx/Kconfig300
new file mode 100644 (file)
index 0000000..c519a05
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# SPEAr300 machine configuration file
+#
+
+if MACH_SPEAR300
+
+choice
+       prompt "SPEAr300 Boards"
+       default BOARD_SPEAR300_EVB
+
+config BOARD_SPEAR300_EVB
+       bool "SPEAr300 Evaluation Board"
+       help
+         Supports ST SPEAr300 Evaluation Board
+endchoice
+
+endif  #MACH_SPEAR300
diff --git a/arch/arm/mach-spear3xx/Kconfig310 b/arch/arm/mach-spear3xx/Kconfig310
new file mode 100644 (file)
index 0000000..60e7442
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# SPEAr310 machine configuration file
+#
+
+if MACH_SPEAR310
+
+choice
+       prompt "SPEAr310 Boards"
+       default BOARD_SPEAR310_EVB
+
+config BOARD_SPEAR310_EVB
+       bool "SPEAr310 Evaluation Board"
+       help
+         Supports ST SPEAr310 Evaluation Board
+endchoice
+
+endif  #MACH_SPEAR310
diff --git a/arch/arm/mach-spear3xx/Kconfig320 b/arch/arm/mach-spear3xx/Kconfig320
new file mode 100644 (file)
index 0000000..1c1d438
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# SPEAr320 machine configuration file
+#
+
+if MACH_SPEAR320
+
+choice
+       prompt "SPEAr320 Boards"
+       default BOARD_SPEAR320_EVB
+
+config BOARD_SPEAR320_EVB
+       bool "SPEAr320 Evaluation Board"
+       help
+         Supports ST SPEAr320 Evaluation Board
+endchoice
+
+endif  #MACH_SPEAR320
diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
new file mode 100644 (file)
index 0000000..b248624
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Makefile for SPEAr3XX machine series
+#
+
+# common files
+obj-y  += spear3xx.o clock.o
+
+# spear300 specific files
+obj-$(CONFIG_MACH_SPEAR300) += spear300.o
+
+# spear300 boards files
+obj-$(CONFIG_BOARD_SPEAR300_EVB) += spear300_evb.o
+
+
+# spear310 specific files
+obj-$(CONFIG_MACH_SPEAR310) += spear310.o
+
+# spear310 boards files
+obj-$(CONFIG_BOARD_SPEAR310_EVB) += spear310_evb.o
+
+
+# spear320 specific files
+obj-$(CONFIG_MACH_SPEAR320) += spear320.o
+
+# spear320 boards files
+obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o
diff --git a/arch/arm/mach-spear3xx/Makefile.boot b/arch/arm/mach-spear3xx/Makefile.boot
new file mode 100644 (file)
index 0000000..7a1f3c0
--- /dev/null
@@ -0,0 +1,3 @@
+zreladdr-y     := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
new file mode 100644 (file)
index 0000000..39f6ccf
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * arch/arm/mach-spear3xx/clock.c
+ *
+ * SPEAr3xx machines clock framework source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+/* root clks */
+/* 32 KHz oscillator clock */
+static struct clk osc_32k_clk = {
+       .flags = ALWAYS_ENABLED,
+       .rate = 32000,
+};
+
+/* 24 MHz oscillator clock */
+static struct clk osc_24m_clk = {
+       .flags = ALWAYS_ENABLED,
+       .rate = 24000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+       .pclk = &osc_32k_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = RTC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from 24 MHz osc clk */
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+       .mode_reg = PLL1_CTR,
+       .cfg_reg = PLL1_FRQ,
+};
+
+/* PLL1 clock */
+static struct clk pll1_clk = {
+       .pclk = &osc_24m_clk,
+       .en_reg = PLL1_CTR,
+       .en_reg_bit = PLL_ENABLE,
+       .recalc = &pll1_clk_recalc,
+       .private_data = &pll1_config,
+};
+
+/* PLL3 48 MHz clock */
+static struct clk pll3_48m_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &osc_24m_clk,
+       .rate = 48000000,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &osc_24m_clk,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &pll1_clk,
+       .recalc = &follow_parent,
+};
+
+/* ahb configuration structure */
+static struct bus_clk_config ahb_config = {
+       .reg = CORE_CLK_CFG,
+       .mask = PLL_HCLK_RATIO_MASK,
+       .shift = PLL_HCLK_RATIO_SHIFT,
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &pll1_clk,
+       .recalc = &bus_clk_recalc,
+       .private_data = &ahb_config,
+};
+
+/* uart configurations */
+static struct aux_clk_config uart_config = {
+       .synth_reg = UART_CLK_SYNT,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+       .pclk_info = uart_pclk_info,
+       .pclk_count = ARRAY_SIZE(uart_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart clock */
+static struct clk uart_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = UART_CLK_ENB,
+       .pclk_sel = &uart_pclk_sel,
+       .pclk_sel_shift = UART_CLK_SHIFT,
+       .recalc = &aux_clk_recalc,
+       .private_data = &uart_config,
+};
+
+/* firda configurations */
+static struct aux_clk_config firda_config = {
+       .synth_reg = FIRDA_CLK_SYNT,
+};
+
+/* firda parents */
+static struct pclk_info firda_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* firda parent select structure */
+static struct pclk_sel firda_pclk_sel = {
+       .pclk_info = firda_pclk_info,
+       .pclk_count = ARRAY_SIZE(firda_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = FIRDA_CLK_MASK,
+};
+
+/* firda clock */
+static struct clk firda_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = FIRDA_CLK_ENB,
+       .pclk_sel = &firda_pclk_sel,
+       .pclk_sel_shift = FIRDA_CLK_SHIFT,
+       .recalc = &aux_clk_recalc,
+       .private_data = &firda_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt_pclk_sel = {
+       .pclk_info = gpt_pclk_info,
+       .pclk_count = ARRAY_SIZE(gpt_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0 configurations */
+static struct aux_clk_config gpt0_config = {
+       .synth_reg = PRSC1_CLK_CFG,
+};
+
+/* gpt0 timer clock */
+static struct clk gpt0_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT0_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt0_config,
+};
+
+/* gpt1 configurations */
+static struct aux_clk_config gpt1_config = {
+       .synth_reg = PRSC2_CLK_CFG,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPT1_CLK_ENB,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT1_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt1_config,
+};
+
+/* gpt2 configurations */
+static struct aux_clk_config gpt2_config = {
+       .synth_reg = PRSC3_CLK_CFG,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPT2_CLK_ENB,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT2_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt2_config,
+};
+
+/* clock derived from pll3 clk */
+/* usbh clock */
+static struct clk usbh_clk = {
+       .pclk = &pll3_48m_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = USBH_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+       .pclk = &pll3_48m_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = USBD_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* clcd clock */
+static struct clk clcd_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &pll3_48m_clk,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+/* apb configuration structure */
+static struct bus_clk_config apb_config = {
+       .reg = CORE_CLK_CFG,
+       .mask = HCLK_PCLK_RATIO_MASK,
+       .shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &ahb_clk,
+       .recalc = &bus_clk_recalc,
+       .private_data = &apb_config,
+};
+
+/* i2c clock */
+static struct clk i2c_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = I2C_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = DMA_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = JPEG_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GMAC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = SMI_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* c3 clock */
+static struct clk c3_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = C3_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = ADC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* ssp clock */
+static struct clk ssp_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = SSP_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* gpio clock */
+static struct clk gpio_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPIO_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* array of all spear 3xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+       /* root clks */
+       { .con_id = "osc_32k_clk",      .clk = &osc_32k_clk},
+       { .con_id = "osc_24m_clk",      .clk = &osc_24m_clk},
+       /* clock derived from 32 KHz osc clk */
+       { .dev_id = "rtc",              .clk = &rtc_clk},
+       /* clock derived from 24 MHz osc clk */
+       { .con_id = "pll1_clk",         .clk = &pll1_clk},
+       { .con_id = "pll3_48m_clk",     .clk = &pll3_48m_clk},
+       { .dev_id = "wdt",              .clk = &wdt_clk},
+       /* clock derived from pll1 clk */
+       { .con_id = "cpu_clk",          .clk = &cpu_clk},
+       { .con_id = "ahb_clk",          .clk = &ahb_clk},
+       { .dev_id = "uart",             .clk = &uart_clk},
+       { .dev_id = "firda",            .clk = &firda_clk},
+       { .dev_id = "gpt0",             .clk = &gpt0_clk},
+       { .dev_id = "gpt1",             .clk = &gpt1_clk},
+       { .dev_id = "gpt2",             .clk = &gpt2_clk},
+       /* clock derived from pll3 clk */
+       { .dev_id = "usbh",             .clk = &usbh_clk},
+       { .dev_id = "usbd",             .clk = &usbd_clk},
+       { .dev_id = "clcd",             .clk = &clcd_clk},
+       /* clock derived from ahb clk */
+       { .con_id = "apb_clk",          .clk = &apb_clk},
+       { .dev_id = "i2c",              .clk = &i2c_clk},
+       { .dev_id = "dma",              .clk = &dma_clk},
+       { .dev_id = "jpeg",             .clk = &jpeg_clk},
+       { .dev_id = "gmac",             .clk = &gmac_clk},
+       { .dev_id = "smi",              .clk = &smi_clk},
+       { .dev_id = "c3",               .clk = &c3_clk},
+       /* clock derived from apb clk */
+       { .dev_id = "adc",              .clk = &adc_clk},
+       { .dev_id = "ssp",              .clk = &ssp_clk},
+       { .dev_id = "gpio",             .clk = &gpio_clk},
+};
+
+void __init clk_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+               clk_register(&spear_clk_lookups[i]);
+
+       recalc_root_clocks();
+}
diff --git a/arch/arm/mach-spear3xx/include/mach/clkdev.h b/arch/arm/mach-spear3xx/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..a3d0733
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/arch/arm/mach-spear3xx/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..590519f
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header spear3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear3xx/include/mach/entry-macro.S b/arch/arm/mach-spear3xx/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..947625d
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/spear.h>
+#include <asm/hardware/vic.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, =VA_SPEAR3XX_ML1_VIC_BASE
+               ldr     \irqstat, [\base, #VIC_IRQ_STATUS]      @ get status
+               teq     \irqstat, #0
+               beq     1001f                           @ this will set/reset
+                                                       @ zero register
+               /*
+                * Following code will find bit position of least significang
+                * bit set in irqstat, using following equation
+                * least significant bit set in n = (n & ~(n-1))
+                */
+               sub     \tmp, \irqstat, #1              @ tmp = irqstat - 1
+               mvn     \tmp, \tmp                      @ tmp = ~tmp
+               and     \irqstat, \irqstat, \tmp        @ irqstat &= tmp
+               /* Now, irqstat is = bit no. of 1st bit set in vic irq status */
+               clz     \tmp, \irqstat                  @ tmp = leading zeros
+               rsb     \irqnr, \tmp, #0x1F             @ irqnr = 32 - tmp - 1
+
+1001:          /* EQ will be set if no irqs pending */
+               .endm
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
new file mode 100644 (file)
index 0000000..af7e02c
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * arch/arm/mach-spear3xx/generic.h
+ *
+ * SPEAr3XX machine family generic header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <plat/padmux.h>
+
+/* spear3xx declarations */
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE                SPEAR3XX_ML1_TMR_BASE
+#define SPEAR_GPT0_CHAN0_IRQ   IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ   IRQ_CPU_GPT1_2
+
+/* Add spear3xx family device structure declarations here */
+extern struct amba_device gpio_device;
+extern struct amba_device uart_device;
+extern struct sys_timer spear_sys_timer;
+
+/* Add spear3xx family function declarations here */
+void __init clk_init(void);
+void __init spear3xx_map_io(void);
+void __init spear3xx_init_irq(void);
+void __init spear3xx_init(void);
+void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size);
+
+/* pad mux declarations */
+#define PMX_FIRDA_MASK         (1 << 14)
+#define PMX_I2C_MASK           (1 << 13)
+#define PMX_SSP_CS_MASK                (1 << 12)
+#define PMX_SSP_MASK           (1 << 11)
+#define PMX_MII_MASK           (1 << 10)
+#define PMX_GPIO_PIN0_MASK     (1 << 9)
+#define PMX_GPIO_PIN1_MASK     (1 << 8)
+#define PMX_GPIO_PIN2_MASK     (1 << 7)
+#define PMX_GPIO_PIN3_MASK     (1 << 6)
+#define PMX_GPIO_PIN4_MASK     (1 << 5)
+#define PMX_GPIO_PIN5_MASK     (1 << 4)
+#define PMX_UART0_MODEM_MASK   (1 << 3)
+#define PMX_UART0_MASK         (1 << 2)
+#define PMX_TIMER_3_4_MASK     (1 << 1)
+#define PMX_TIMER_1_2_MASK     (1 << 0)
+
+/* pad mux devices */
+extern struct pmx_dev pmx_firda;
+extern struct pmx_dev pmx_i2c;
+extern struct pmx_dev pmx_ssp_cs;
+extern struct pmx_dev pmx_ssp;
+extern struct pmx_dev pmx_mii;
+extern struct pmx_dev pmx_gpio_pin0;
+extern struct pmx_dev pmx_gpio_pin1;
+extern struct pmx_dev pmx_gpio_pin2;
+extern struct pmx_dev pmx_gpio_pin3;
+extern struct pmx_dev pmx_gpio_pin4;
+extern struct pmx_dev pmx_gpio_pin5;
+extern struct pmx_dev pmx_uart0_modem;
+extern struct pmx_dev pmx_uart0;
+extern struct pmx_dev pmx_timer_3_4;
+extern struct pmx_dev pmx_timer_1_2;
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* padmux plgpio devices */
+extern struct pmx_dev pmx_plgpio_0_1;
+extern struct pmx_dev pmx_plgpio_2_3;
+extern struct pmx_dev pmx_plgpio_4_5;
+extern struct pmx_dev pmx_plgpio_6_9;
+extern struct pmx_dev pmx_plgpio_10_27;
+extern struct pmx_dev pmx_plgpio_28;
+extern struct pmx_dev pmx_plgpio_29;
+extern struct pmx_dev pmx_plgpio_30;
+extern struct pmx_dev pmx_plgpio_31;
+extern struct pmx_dev pmx_plgpio_32;
+extern struct pmx_dev pmx_plgpio_33;
+extern struct pmx_dev pmx_plgpio_34_36;
+extern struct pmx_dev pmx_plgpio_37_42;
+extern struct pmx_dev pmx_plgpio_43_44_47_48;
+extern struct pmx_dev pmx_plgpio_45_46_49_50;
+#endif
+
+extern struct pmx_driver pmx_driver;
+
+/* spear300 declarations */
+#ifdef CONFIG_MACH_SPEAR300
+/* Add spear300 machine device structure declarations here */
+extern struct amba_device gpio1_device;
+
+/* pad mux modes */
+extern struct pmx_mode nand_mode;
+extern struct pmx_mode nor_mode;
+extern struct pmx_mode photo_frame_mode;
+extern struct pmx_mode lend_ip_phone_mode;
+extern struct pmx_mode hend_ip_phone_mode;
+extern struct pmx_mode lend_wifi_phone_mode;
+extern struct pmx_mode hend_wifi_phone_mode;
+extern struct pmx_mode ata_pabx_wi2s_mode;
+extern struct pmx_mode ata_pabx_i2s_mode;
+extern struct pmx_mode caml_lcdw_mode;
+extern struct pmx_mode camu_lcd_mode;
+extern struct pmx_mode camu_wlcd_mode;
+extern struct pmx_mode caml_lcd_mode;
+
+/* pad mux devices */
+extern struct pmx_dev pmx_fsmc_2_chips;
+extern struct pmx_dev pmx_fsmc_4_chips;
+extern struct pmx_dev pmx_keyboard;
+extern struct pmx_dev pmx_clcd;
+extern struct pmx_dev pmx_telecom_gpio;
+extern struct pmx_dev pmx_telecom_tdm;
+extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk;
+extern struct pmx_dev pmx_telecom_camera;
+extern struct pmx_dev pmx_telecom_dac;
+extern struct pmx_dev pmx_telecom_i2s;
+extern struct pmx_dev pmx_telecom_boot_pins;
+extern struct pmx_dev pmx_telecom_sdio_4bit;
+extern struct pmx_dev pmx_telecom_sdio_8bit;
+extern struct pmx_dev pmx_gpio1;
+
+void spear300_pmx_init(void);
+
+/* Add spear300 machine function declarations here */
+void __init spear300_init(void);
+
+#endif /* CONFIG_MACH_SPEAR300 */
+
+/* spear310 declarations */
+#ifdef CONFIG_MACH_SPEAR310
+/* Add spear310 machine device structure declarations here */
+
+/* pad mux devices */
+extern struct pmx_dev pmx_emi_cs_0_1_4_5;
+extern struct pmx_dev pmx_emi_cs_2_3;
+extern struct pmx_dev pmx_uart1;
+extern struct pmx_dev pmx_uart2;
+extern struct pmx_dev pmx_uart3_4_5;
+extern struct pmx_dev pmx_fsmc;
+extern struct pmx_dev pmx_rs485_0_1;
+extern struct pmx_dev pmx_tdm0;
+
+void spear310_pmx_init(void);
+
+/* Add spear310 machine function declarations here */
+void __init spear310_init(void);
+
+#endif /* CONFIG_MACH_SPEAR310 */
+
+/* spear320 declarations */
+#ifdef CONFIG_MACH_SPEAR320
+/* Add spear320 machine device structure declarations here */
+
+/* pad mux modes */
+extern struct pmx_mode auto_net_smii_mode;
+extern struct pmx_mode auto_net_mii_mode;
+extern struct pmx_mode auto_exp_mode;
+extern struct pmx_mode small_printers_mode;
+
+/* pad mux devices */
+extern struct pmx_dev pmx_clcd;
+extern struct pmx_dev pmx_emi;
+extern struct pmx_dev pmx_fsmc;
+extern struct pmx_dev pmx_spp;
+extern struct pmx_dev pmx_sdio;
+extern struct pmx_dev pmx_i2s;
+extern struct pmx_dev pmx_uart1;
+extern struct pmx_dev pmx_uart1_modem;
+extern struct pmx_dev pmx_uart2;
+extern struct pmx_dev pmx_touchscreen;
+extern struct pmx_dev pmx_can;
+extern struct pmx_dev pmx_sdio_led;
+extern struct pmx_dev pmx_pwm0;
+extern struct pmx_dev pmx_pwm1;
+extern struct pmx_dev pmx_pwm2;
+extern struct pmx_dev pmx_pwm3;
+extern struct pmx_dev pmx_ssp1;
+extern struct pmx_dev pmx_ssp2;
+extern struct pmx_dev pmx_mii1;
+extern struct pmx_dev pmx_smii0;
+extern struct pmx_dev pmx_smii1;
+extern struct pmx_dev pmx_i2c1;
+
+void spear320_pmx_init(void);
+
+/* Add spear320 machine function declarations here */
+void __init spear320_init(void);
+
+#endif /* CONFIG_MACH_SPEAR320 */
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..451b208
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/hardware.h b/arch/arm/mach-spear3xx/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..4a86e6a
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/hardware.h
+ *
+ * Hardware definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x)          (x | 0xF0000000)
+
+#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/io.h b/arch/arm/mach-spear3xx/include/mach/io.h
new file mode 100644 (file)
index 0000000..30cff8a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/io.h
+ *
+ * IO definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif /* __MACH_IO_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..7f940b8
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+/* SPEAr3xx IRQ definitions */
+#define IRQ_HW_ACCEL_MOD_0                     0
+#define IRQ_INTRCOMM_RAS_ARM                   1
+#define IRQ_CPU_GPT1_1                         2
+#define IRQ_CPU_GPT1_2                         3
+#define IRQ_BASIC_GPT1_1                       4
+#define IRQ_BASIC_GPT1_2                       5
+#define IRQ_BASIC_GPT2_1                       6
+#define IRQ_BASIC_GPT2_2                       7
+#define IRQ_BASIC_DMA                          8
+#define IRQ_BASIC_SMI                          9
+#define IRQ_BASIC_RTC                          10
+#define IRQ_BASIC_GPIO                         11
+#define IRQ_BASIC_WDT                          12
+#define IRQ_DDR_CONTROLLER                     13
+#define IRQ_SYS_ERROR                          14
+#define IRQ_WAKEUP_RCV                         15
+#define IRQ_JPEG                               16
+#define IRQ_IRDA                               17
+#define IRQ_ADC                                        18
+#define IRQ_UART                               19
+#define IRQ_SSP                                        20
+#define IRQ_I2C                                        21
+#define IRQ_MAC_1                              22
+#define IRQ_MAC_2                              23
+#define IRQ_USB_DEV                            24
+#define IRQ_USB_H_OHCI_0                       25
+#define IRQ_USB_H_EHCI_0                       26
+#define IRQ_USB_H_EHCI_1                       IRQ_USB_H_EHCI_0
+#define IRQ_USB_H_OHCI_1                       27
+#define IRQ_GEN_RAS_1                          28
+#define IRQ_GEN_RAS_2                          29
+#define IRQ_GEN_RAS_3                          30
+#define IRQ_HW_ACCEL_MOD_1                     31
+#define IRQ_VIC_END                            32
+
+#define VIRQ_START                             IRQ_VIC_END
+
+/* SPEAr300 Virtual irq definitions */
+#ifdef CONFIG_MACH_SPEAR300
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_IT_PERS_S                         (VIRQ_START + 0)
+#define VIRQ_IT_CHANGE_S                       (VIRQ_START + 1)
+#define VIRQ_I2S                               (VIRQ_START + 2)
+#define VIRQ_TDM                               (VIRQ_START + 3)
+#define VIRQ_CAMERA_L                          (VIRQ_START + 4)
+#define VIRQ_CAMERA_F                          (VIRQ_START + 5)
+#define VIRQ_CAMERA_V                          (VIRQ_START + 6)
+#define VIRQ_KEYBOARD                          (VIRQ_START + 7)
+#define VIRQ_GPIO1                             (VIRQ_START + 8)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define IRQ_CLCD                               IRQ_GEN_RAS_3
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define IRQ_SDIO                               IRQ_INTRCOMM_RAS_ARM
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE                    (VIRQ_START + 9)
+#define SPEAR_GPIO1_INT_BASE                   (SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END                     (SPEAR_GPIO1_INT_BASE + 8)
+
+/* SPEAr310 Virtual irq definitions */
+#elif defined(CONFIG_MACH_SPEAR310)
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_SMII0                             (VIRQ_START + 0)
+#define VIRQ_SMII1                             (VIRQ_START + 1)
+#define VIRQ_SMII2                             (VIRQ_START + 2)
+#define VIRQ_SMII3                             (VIRQ_START + 3)
+#define VIRQ_WAKEUP_SMII0                      (VIRQ_START + 4)
+#define VIRQ_WAKEUP_SMII1                      (VIRQ_START + 5)
+#define VIRQ_WAKEUP_SMII2                      (VIRQ_START + 6)
+#define VIRQ_WAKEUP_SMII3                      (VIRQ_START + 7)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define VIRQ_UART1                             (VIRQ_START + 8)
+#define VIRQ_UART2                             (VIRQ_START + 9)
+#define VIRQ_UART3                             (VIRQ_START + 10)
+#define VIRQ_UART4                             (VIRQ_START + 11)
+#define VIRQ_UART5                             (VIRQ_START + 12)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define VIRQ_EMI                               (VIRQ_START + 13)
+#define VIRQ_PLGPIO                            (VIRQ_START + 14)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define VIRQ_TDM_HDLC                          (VIRQ_START + 15)
+#define VIRQ_RS485_0                           (VIRQ_START + 16)
+#define VIRQ_RS485_1                           (VIRQ_START + 17)
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE                    (VIRQ_START + 18)
+
+/* SPEAr320 Virtual irq definitions */
+#else
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_EMI                               (VIRQ_START + 0)
+#define VIRQ_CLCD                              (VIRQ_START + 1)
+#define VIRQ_SPP                               (VIRQ_START + 2)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define IRQ_SDIO                               IRQ_GEN_RAS_2
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define VIRQ_PLGPIO                            (VIRQ_START + 3)
+#define VIRQ_I2S_PLAY                          (VIRQ_START + 4)
+#define VIRQ_I2S_REC                           (VIRQ_START + 5)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define VIRQ_CANU                              (VIRQ_START + 6)
+#define VIRQ_CANL                              (VIRQ_START + 7)
+#define VIRQ_UART1                             (VIRQ_START + 8)
+#define VIRQ_UART2                             (VIRQ_START + 9)
+#define VIRQ_SSP1                              (VIRQ_START + 10)
+#define VIRQ_SSP2                              (VIRQ_START + 11)
+#define VIRQ_SMII0                             (VIRQ_START + 12)
+#define VIRQ_MII1_SMII1                                (VIRQ_START + 13)
+#define VIRQ_WAKEUP_SMII0                      (VIRQ_START + 14)
+#define VIRQ_WAKEUP_MII1_SMII1                 (VIRQ_START + 15)
+#define VIRQ_I2C                               (VIRQ_START + 16)
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE                    (VIRQ_START + 17)
+
+#endif
+
+/* PLGPIO Virtual IRQs */
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+#define SPEAR_PLGPIO_INT_BASE                  (SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END                     (SPEAR_PLGPIO_INT_BASE + 102)
+#endif
+
+#define VIRQ_END                               SPEAR_GPIO_INT_END
+#define NR_IRQS                                        VIRQ_END
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/memory.h b/arch/arm/mach-spear3xx/include/mach/memory.h
new file mode 100644 (file)
index 0000000..5173522
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/memory.h
+ *
+ * Memory map for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
new file mode 100644 (file)
index 0000000..38d767a
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/spear.h>
+
+#define MISC_BASE              VA_SPEAR3XX_ICM3_MISC_REG_BASE
+
+#define SOC_CFG_CTR            ((unsigned int *)(MISC_BASE + 0x000))
+#define DIAG_CFG_CTR           ((unsigned int *)(MISC_BASE + 0x004))
+#define PLL1_CTR               ((unsigned int *)(MISC_BASE + 0x008))
+#define PLL1_FRQ               ((unsigned int *)(MISC_BASE + 0x00C))
+#define PLL1_MOD               ((unsigned int *)(MISC_BASE + 0x010))
+#define PLL2_CTR               ((unsigned int *)(MISC_BASE + 0x014))
+/* PLL_CTR register masks */
+#define PLL_ENABLE             2
+#define PLL_MODE_SHIFT         4
+#define PLL_MODE_MASK          0x3
+#define PLL_MODE_NORMAL                0
+#define PLL_MODE_FRACTION      1
+#define PLL_MODE_DITH_DSB      2
+#define PLL_MODE_DITH_SSB      3
+
+#define PLL2_FRQ               ((unsigned int *)(MISC_BASE + 0x018))
+/* PLL FRQ register masks */
+#define PLL_DIV_N_SHIFT                0
+#define PLL_DIV_N_MASK         0xFF
+#define PLL_DIV_P_SHIFT                8
+#define PLL_DIV_P_MASK         0x7
+#define PLL_NORM_FDBK_M_SHIFT  24
+#define PLL_NORM_FDBK_M_MASK   0xFF
+#define PLL_DITH_FDBK_M_SHIFT  16
+#define PLL_DITH_FDBK_M_MASK   0xFFFF
+
+#define PLL2_MOD               ((unsigned int *)(MISC_BASE + 0x01C))
+#define PLL_CLK_CFG            ((unsigned int *)(MISC_BASE + 0x020))
+#define CORE_CLK_CFG           ((unsigned int *)(MISC_BASE + 0x024))
+/* CORE CLK CFG register masks */
+#define PLL_HCLK_RATIO_SHIFT   10
+#define PLL_HCLK_RATIO_MASK    0x3
+#define HCLK_PCLK_RATIO_SHIFT  8
+#define HCLK_PCLK_RATIO_MASK   0x3
+
+#define PERIP_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x028))
+/* PERIP_CLK_CFG register masks */
+#define UART_CLK_SHIFT         4
+#define UART_CLK_MASK          0x1
+#define FIRDA_CLK_SHIFT                5
+#define FIRDA_CLK_MASK         0x3
+#define GPT0_CLK_SHIFT         8
+#define GPT1_CLK_SHIFT         11
+#define GPT2_CLK_SHIFT         12
+#define GPT_CLK_MASK           0x1
+#define AUX_CLK_PLL3_MASK      0
+#define AUX_CLK_PLL1_MASK      1
+
+#define PERIP1_CLK_ENB         ((unsigned int *)(MISC_BASE + 0x02C))
+/* PERIP1_CLK_ENB register masks */
+#define UART_CLK_ENB           3
+#define SSP_CLK_ENB            5
+#define I2C_CLK_ENB            7
+#define JPEG_CLK_ENB           8
+#define FIRDA_CLK_ENB          10
+#define GPT1_CLK_ENB           11
+#define GPT2_CLK_ENB           12
+#define ADC_CLK_ENB            15
+#define RTC_CLK_ENB            17
+#define GPIO_CLK_ENB           18
+#define DMA_CLK_ENB            19
+#define SMI_CLK_ENB            21
+#define GMAC_CLK_ENB           23
+#define USBD_CLK_ENB           24
+#define USBH_CLK_ENB           25
+#define C3_CLK_ENB             31
+
+#define SOC_CORE_ID            ((unsigned int *)(MISC_BASE + 0x030))
+#define RAS_CLK_ENB            ((unsigned int *)(MISC_BASE + 0x034))
+#define PERIP1_SOF_RST         ((unsigned int *)(MISC_BASE + 0x038))
+/* PERIP1_SOF_RST register masks */
+#define JPEG_SOF_RST           8
+
+#define SOC_USER_ID            ((unsigned int *)(MISC_BASE + 0x03C))
+#define RAS_SOF_RST            ((unsigned int *)(MISC_BASE + 0x040))
+#define PRSC1_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x044))
+#define PRSC2_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x048))
+#define PRSC3_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x04C))
+/* gpt synthesizer register masks */
+#define GPT_MSCALE_SHIFT       0
+#define GPT_MSCALE_MASK                0xFFF
+#define GPT_NSCALE_SHIFT       12
+#define GPT_NSCALE_MASK                0xF
+
+#define AMEM_CLK_CFG           ((unsigned int *)(MISC_BASE + 0x050))
+#define EXPI_CLK_CFG           ((unsigned int *)(MISC_BASE + 0x054))
+#define CLCD_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x05C))
+#define FIRDA_CLK_SYNT         ((unsigned int *)(MISC_BASE + 0x060))
+#define UART_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x064))
+#define GMAC_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x068))
+#define RAS1_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x06C))
+#define RAS2_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x070))
+#define RAS3_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x074))
+#define RAS4_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x078))
+/* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_EQ_SEL_SHIFT       30
+#define AUX_EQ_SEL_MASK                1
+#define AUX_EQ1_SEL            0
+#define AUX_EQ2_SEL            1
+#define AUX_XSCALE_SHIFT       16
+#define AUX_XSCALE_MASK                0xFFF
+#define AUX_YSCALE_SHIFT       0
+#define AUX_YSCALE_MASK                0xFFF
+
+#define ICM1_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x07C))
+#define ICM2_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x080))
+#define ICM3_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x084))
+#define ICM4_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x088))
+#define ICM5_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x08C))
+#define ICM6_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x090))
+#define ICM7_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x094))
+#define ICM8_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x098))
+#define ICM9_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x09C))
+#define DMA_CHN_CFG            ((unsigned int *)(MISC_BASE + 0x0A0))
+#define USB2_PHY_CFG           ((unsigned int *)(MISC_BASE + 0x0A4))
+#define GMAC_CFG_CTR           ((unsigned int *)(MISC_BASE + 0x0A8))
+#define EXPI_CFG_CTR           ((unsigned int *)(MISC_BASE + 0x0AC))
+#define PRC1_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0C0))
+#define PRC2_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0C4))
+#define PRC3_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0C8))
+#define PRC4_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0CC))
+#define PRC1_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0D0))
+#define PRC2_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0D4))
+#define PRC3_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0D8))
+#define PRC4_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0DC))
+#define PWRDOWN_CFG_CTR                ((unsigned int *)(MISC_BASE + 0x0E0))
+#define COMPSSTL_1V8_CFG       ((unsigned int *)(MISC_BASE + 0x0E4))
+#define COMPSSTL_2V5_CFG       ((unsigned int *)(MISC_BASE + 0x0E8))
+#define COMPCOR_3V3_CFG                ((unsigned int *)(MISC_BASE + 0x0EC))
+#define SSTLPAD_CFG_CTR                ((unsigned int *)(MISC_BASE + 0x0F0))
+#define BIST1_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x0F4))
+#define BIST2_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x0F8))
+#define BIST3_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x0FC))
+#define BIST4_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x100))
+#define BIST5_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x104))
+#define BIST1_STS_RES          ((unsigned int *)(MISC_BASE + 0x108))
+#define BIST2_STS_RES          ((unsigned int *)(MISC_BASE + 0x10C))
+#define BIST3_STS_RES          ((unsigned int *)(MISC_BASE + 0x110))
+#define BIST4_STS_RES          ((unsigned int *)(MISC_BASE + 0x114))
+#define BIST5_STS_RES          ((unsigned int *)(MISC_BASE + 0x118))
+#define SYSERR_CFG_CTR         ((unsigned int *)(MISC_BASE + 0x11C))
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
new file mode 100644 (file)
index 0000000..dcca856
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear.h
+ *
+ * SPEAr3xx Machine family specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPEAR3XX_H
+#define __MACH_SPEAR3XX_H
+
+#include <mach/hardware.h>
+#include <mach/spear300.h>
+#include <mach/spear310.h>
+#include <mach/spear320.h>
+
+#define SPEAR3XX_ML_SDRAM_BASE         0x00000000
+#define SPEAR3XX_ML_SDRAM_SIZE         0x40000000
+
+#define SPEAR3XX_ICM9_BASE             0xC0000000
+#define SPEAR3XX_ICM9_SIZE             0x10000000
+
+/* ICM1 - Low speed connection */
+#define SPEAR3XX_ICM1_2_BASE           0xD0000000
+#define SPEAR3XX_ICM1_2_SIZE           0x10000000
+
+#define SPEAR3XX_ICM1_UART_BASE                0xD0000000
+#define VA_SPEAR3XX_ICM1_UART_BASE     IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE)
+#define SPEAR3XX_ICM1_UART_SIZE                0x00080000
+
+#define SPEAR3XX_ICM1_ADC_BASE         0xD0080000
+#define SPEAR3XX_ICM1_ADC_SIZE         0x00080000
+
+#define SPEAR3XX_ICM1_SSP_BASE         0xD0100000
+#define SPEAR3XX_ICM1_SSP_SIZE         0x00080000
+
+#define SPEAR3XX_ICM1_I2C_BASE         0xD0180000
+#define SPEAR3XX_ICM1_I2C_SIZE         0x00080000
+
+#define SPEAR3XX_ICM1_JPEG_BASE                0xD0800000
+#define SPEAR3XX_ICM1_JPEG_SIZE                0x00800000
+
+#define SPEAR3XX_ICM1_IRDA_BASE                0xD1000000
+#define SPEAR3XX_ICM1_IRDA_SIZE                0x00080000
+
+#define SPEAR3XX_ICM1_SRAM_BASE                0xD2800000
+#define SPEAR3XX_ICM1_SRAM_SIZE                0x05800000
+
+/* ICM2 - Application Subsystem */
+#define SPEAR3XX_ICM2_HWACCEL0_BASE    0xD8800000
+#define SPEAR3XX_ICM2_HWACCEL0_SIZE    0x00800000
+
+#define SPEAR3XX_ICM2_HWACCEL1_BASE    0xD9000000
+#define SPEAR3XX_ICM2_HWACCEL1_SIZE    0x00800000
+
+/* ICM4 - High Speed Connection */
+#define SPEAR3XX_ICM4_BASE             0xE0000000
+#define SPEAR3XX_ICM4_SIZE             0x08000000
+
+#define SPEAR3XX_ICM4_MII_BASE         0xE0800000
+#define SPEAR3XX_ICM4_MII_SIZE         0x00800000
+
+#define SPEAR3XX_ICM4_USBD_FIFO_BASE   0xE1000000
+#define SPEAR3XX_ICM4_USBD_FIFO_SIZE   0x00100000
+
+#define SPEAR3XX_ICM4_USBD_CSR_BASE    0xE1100000
+#define SPEAR3XX_ICM4_USBD_CSR_SIZE    0x00100000
+
+#define SPEAR3XX_ICM4_USBD_PLDT_BASE   0xE1200000
+#define SPEAR3XX_ICM4_USBD_PLDT_SIZE   0x00100000
+
+#define SPEAR3XX_ICM4_USB_EHCI0_1_BASE 0xE1800000
+#define SPEAR3XX_ICM4_USB_EHCI0_1_SIZE 0x00100000
+
+#define SPEAR3XX_ICM4_USB_OHCI0_BASE   0xE1900000
+#define SPEAR3XX_ICM4_USB_OHCI0_SIZE   0x00100000
+
+#define SPEAR3XX_ICM4_USB_OHCI1_BASE   0xE2100000
+#define SPEAR3XX_ICM4_USB_OHCI1_SIZE   0x00100000
+
+#define SPEAR3XX_ICM4_USB_ARB_BASE     0xE2800000
+#define SPEAR3XX_ICM4_USB_ARB_SIZE     0x00010000
+
+/* ML1 - Multi Layer CPU Subsystem */
+#define SPEAR3XX_ICM3_ML1_2_BASE       0xF0000000
+#define SPEAR3XX_ICM3_ML1_2_SIZE       0x0F000000
+
+#define SPEAR3XX_ML1_TMR_BASE          0xF0000000
+#define SPEAR3XX_ML1_TMR_SIZE          0x00100000
+
+#define SPEAR3XX_ML1_VIC_BASE          0xF1100000
+#define VA_SPEAR3XX_ML1_VIC_BASE       IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE)
+#define SPEAR3XX_ML1_VIC_SIZE          0x00100000
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR3XX_ICM3_SMEM_BASE                0xF8000000
+#define SPEAR3XX_ICM3_SMEM_SIZE                0x04000000
+
+#define SPEAR3XX_ICM3_SMI_CTRL_BASE    0xFC000000
+#define SPEAR3XX_ICM3_SMI_CTRL_SIZE    0x00200000
+
+#define SPEAR3XX_ICM3_DMA_BASE         0xFC400000
+#define SPEAR3XX_ICM3_DMA_SIZE         0x00200000
+
+#define SPEAR3XX_ICM3_SDRAM_CTRL_BASE  0xFC600000
+#define SPEAR3XX_ICM3_SDRAM_CTRL_SIZE  0x00200000
+
+#define SPEAR3XX_ICM3_TMR0_BASE                0xFC800000
+#define SPEAR3XX_ICM3_TMR0_SIZE                0x00080000
+
+#define SPEAR3XX_ICM3_WDT_BASE         0xFC880000
+#define SPEAR3XX_ICM3_WDT_SIZE         0x00080000
+
+#define SPEAR3XX_ICM3_RTC_BASE         0xFC900000
+#define SPEAR3XX_ICM3_RTC_SIZE         0x00080000
+
+#define SPEAR3XX_ICM3_GPIO_BASE                0xFC980000
+#define SPEAR3XX_ICM3_GPIO_SIZE                0x00080000
+
+#define SPEAR3XX_ICM3_SYS_CTRL_BASE    0xFCA00000
+#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE)
+#define SPEAR3XX_ICM3_SYS_CTRL_SIZE    0x00080000
+
+#define SPEAR3XX_ICM3_MISC_REG_BASE    0xFCA80000
+#define VA_SPEAR3XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE)
+#define SPEAR3XX_ICM3_MISC_REG_SIZE    0x00080000
+
+#define SPEAR3XX_ICM3_TMR1_BASE                0xFCB00000
+#define SPEAR3XX_ICM3_TMR1_SIZE                0x00080000
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE            SPEAR3XX_ICM1_UART_BASE
+#define VA_SPEAR_DBG_UART_BASE         VA_SPEAR3XX_ICM1_UART_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE            SPEAR3XX_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE         VA_SPEAR3XX_ICM3_SYS_CTRL_BASE
+
+#endif /* __MACH_SPEAR3XX_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
new file mode 100644 (file)
index 0000000..ccaa765
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear300.h
+ *
+ * SPEAr300 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR300
+
+#ifndef __MACH_SPEAR300_H
+#define __MACH_SPEAR300_H
+
+/* Base address of various IPs */
+#define SPEAR300_TELECOM_BASE          0x50000000
+#define SPEAR300_TELECOM_SIZE          0x10000000
+
+/* Interrupt registers offsets and masks */
+#define SPEAR300_TELECOM_REG_SIZE      0x00010000
+#define INT_ENB_MASK_REG               0x54
+#define INT_STS_MASK_REG               0x58
+#define IT_PERS_S_IRQ_MASK             (1 << 0)
+#define IT_CHANGE_S_IRQ_MASK           (1 << 1)
+#define I2S_IRQ_MASK                   (1 << 2)
+#define TDM_IRQ_MASK                   (1 << 3)
+#define CAMERA_L_IRQ_MASK              (1 << 4)
+#define CAMERA_F_IRQ_MASK              (1 << 5)
+#define CAMERA_V_IRQ_MASK              (1 << 6)
+#define KEYBOARD_IRQ_MASK              (1 << 7)
+#define GPIO1_IRQ_MASK                 (1 << 8)
+
+#define SHIRQ_RAS1_MASK                        0x1FF
+
+#define SPEAR300_CLCD_BASE             0x60000000
+#define SPEAR300_CLCD_SIZE             0x10000000
+
+#define SPEAR300_SDIO_BASE             0x70000000
+#define SPEAR300_SDIO_SIZE             0x10000000
+
+#define SPEAR300_NAND_0_BASE           0x80000000
+#define SPEAR300_NAND_0_SIZE           0x04000000
+
+#define SPEAR300_NAND_1_BASE           0x84000000
+#define SPEAR300_NAND_1_SIZE           0x04000000
+
+#define SPEAR300_NAND_2_BASE           0x88000000
+#define SPEAR300_NAND_2_SIZE           0x04000000
+
+#define SPEAR300_NAND_3_BASE           0x8c000000
+#define SPEAR300_NAND_3_SIZE           0x04000000
+
+#define SPEAR300_NOR_0_BASE            0x90000000
+#define SPEAR300_NOR_0_SIZE            0x01000000
+
+#define SPEAR300_NOR_1_BASE            0x91000000
+#define SPEAR300_NOR_1_SIZE            0x01000000
+
+#define SPEAR300_NOR_2_BASE            0x92000000
+#define SPEAR300_NOR_2_SIZE            0x01000000
+
+#define SPEAR300_NOR_3_BASE            0x93000000
+#define SPEAR300_NOR_3_SIZE            0x01000000
+
+#define SPEAR300_FSMC_BASE             0x94000000
+#define SPEAR300_FSMC_SIZE             0x05000000
+
+#define SPEAR300_SOC_CONFIG_BASE       0x99000000
+#define SPEAR300_SOC_CONFIG_SIZE       0x00000008
+
+#define SPEAR300_KEYBOARD_BASE         0xA0000000
+#define SPEAR300_KEYBOARD_SIZE         0x09000000
+
+#define SPEAR300_GPIO_BASE             0xA9000000
+#define SPEAR300_GPIO_SIZE             0x07000000
+
+#endif /* __MACH_SPEAR300_H */
+
+#endif /* CONFIG_MACH_SPEAR300 */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
new file mode 100644 (file)
index 0000000..b27bb8a
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear310.h
+ *
+ * SPEAr310 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR310
+
+#ifndef __MACH_SPEAR310_H
+#define __MACH_SPEAR310_H
+
+#define SPEAR310_NAND_BASE             0x40000000
+#define SPEAR310_NAND_SIZE             0x04000000
+
+#define SPEAR310_FSMC_BASE             0x44000000
+#define SPEAR310_FSMC_SIZE             0x01000000
+
+#define SPEAR310_UART1_BASE            0xB2000000
+#define SPEAR310_UART2_BASE            0xB2080000
+#define SPEAR310_UART3_BASE            0xB2100000
+#define SPEAR310_UART4_BASE            0xB2180000
+#define SPEAR310_UART5_BASE            0xB2200000
+#define SPEAR310_UART_SIZE             0x00080000
+
+#define SPEAR310_HDLC_BASE             0xB2800000
+#define SPEAR310_HDLC_SIZE             0x00800000
+
+#define SPEAR310_RS485_0_BASE          0xB3000000
+#define SPEAR310_RS485_0_SIZE          0x00800000
+
+#define SPEAR310_RS485_1_BASE          0xB3800000
+#define SPEAR310_RS485_1_SIZE          0x00800000
+
+#define SPEAR310_SOC_CONFIG_BASE       0xB4000000
+#define SPEAR310_SOC_CONFIG_SIZE       0x00000070
+/* Interrupt registers offsets and masks */
+#define INT_STS_MASK_REG               0x04
+#define SMII0_IRQ_MASK                 (1 << 0)
+#define SMII1_IRQ_MASK                 (1 << 1)
+#define SMII2_IRQ_MASK                 (1 << 2)
+#define SMII3_IRQ_MASK                 (1 << 3)
+#define WAKEUP_SMII0_IRQ_MASK          (1 << 4)
+#define WAKEUP_SMII1_IRQ_MASK          (1 << 5)
+#define WAKEUP_SMII2_IRQ_MASK          (1 << 6)
+#define WAKEUP_SMII3_IRQ_MASK          (1 << 7)
+#define UART1_IRQ_MASK                 (1 << 8)
+#define UART2_IRQ_MASK                 (1 << 9)
+#define UART3_IRQ_MASK                 (1 << 10)
+#define UART4_IRQ_MASK                 (1 << 11)
+#define UART5_IRQ_MASK                 (1 << 12)
+#define EMI_IRQ_MASK                   (1 << 13)
+#define TDM_HDLC_IRQ_MASK              (1 << 14)
+#define RS485_0_IRQ_MASK               (1 << 15)
+#define RS485_1_IRQ_MASK               (1 << 16)
+
+#define SHIRQ_RAS1_MASK                        0x000FF
+#define SHIRQ_RAS2_MASK                        0x01F00
+#define SHIRQ_RAS3_MASK                        0x02000
+#define SHIRQ_INTRCOMM_RAS_MASK                0x1C000
+
+#endif /* __MACH_SPEAR310_H */
+
+#endif /* CONFIG_MACH_SPEAR310 */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
new file mode 100644 (file)
index 0000000..cacf17a
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear320.h
+ *
+ * SPEAr320 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR320
+
+#ifndef __MACH_SPEAR320_H
+#define __MACH_SPEAR320_H
+
+#define SPEAR320_EMI_CTRL_BASE         0x40000000
+#define SPEAR320_EMI_CTRL_SIZE         0x08000000
+
+#define SPEAR320_FSMC_BASE             0x4C000000
+#define SPEAR320_FSMC_SIZE             0x01000000
+
+#define SPEAR320_I2S_BASE              0x60000000
+#define SPEAR320_I2S_SIZE              0x10000000
+
+#define SPEAR320_SDIO_BASE             0x70000000
+#define SPEAR320_SDIO_SIZE             0x10000000
+
+#define SPEAR320_CLCD_BASE             0x90000000
+#define SPEAR320_CLCD_SIZE             0x10000000
+
+#define SPEAR320_PAR_PORT_BASE         0xA0000000
+#define SPEAR320_PAR_PORT_SIZE         0x01000000
+
+#define SPEAR320_CAN0_BASE             0xA1000000
+#define SPEAR320_CAN0_SIZE             0x01000000
+
+#define SPEAR320_CAN1_BASE             0xA2000000
+#define SPEAR320_CAN1_SIZE             0x01000000
+
+#define SPEAR320_UART1_BASE            0xA3000000
+#define SPEAR320_UART2_BASE            0xA4000000
+#define SPEAR320_UART_SIZE             0x01000000
+
+#define SPEAR320_SSP0_BASE             0xA5000000
+#define SPEAR320_SSP0_SIZE             0x01000000
+
+#define SPEAR320_SSP1_BASE             0xA6000000
+#define SPEAR320_SSP1_SIZE             0x01000000
+
+#define SPEAR320_I2C_BASE              0xA7000000
+#define SPEAR320_I2C_SIZE              0x01000000
+
+#define SPEAR320_PWM_BASE              0xA8000000
+#define SPEAR320_PWM_SIZE              0x01000000
+
+#define SPEAR320_SMII0_BASE            0xAA000000
+#define SPEAR320_SMII0_SIZE            0x01000000
+
+#define SPEAR320_SMII1_BASE            0xAB000000
+#define SPEAR320_SMII1_SIZE            0x01000000
+
+#define SPEAR320_SOC_CONFIG_BASE       0xB4000000
+#define SPEAR320_SOC_CONFIG_SIZE       0x00000070
+/* Interrupt registers offsets and masks */
+#define INT_STS_MASK_REG               0x04
+#define INT_CLR_MASK_REG               0x04
+#define INT_ENB_MASK_REG               0x08
+#define GPIO_IRQ_MASK                  (1 << 0)
+#define I2S_PLAY_IRQ_MASK              (1 << 1)
+#define I2S_REC_IRQ_MASK               (1 << 2)
+#define EMI_IRQ_MASK                   (1 << 7)
+#define CLCD_IRQ_MASK                  (1 << 8)
+#define SPP_IRQ_MASK                   (1 << 9)
+#define SDIO_IRQ_MASK                  (1 << 10)
+#define CAN_U_IRQ_MASK                 (1 << 11)
+#define CAN_L_IRQ_MASK                 (1 << 12)
+#define UART1_IRQ_MASK                 (1 << 13)
+#define UART2_IRQ_MASK                 (1 << 14)
+#define SSP1_IRQ_MASK                  (1 << 15)
+#define SSP2_IRQ_MASK                  (1 << 16)
+#define SMII0_IRQ_MASK                 (1 << 17)
+#define MII1_SMII1_IRQ_MASK            (1 << 18)
+#define WAKEUP_SMII0_IRQ_MASK          (1 << 19)
+#define WAKEUP_MII1_SMII1_IRQ_MASK     (1 << 20)
+#define I2C1_IRQ_MASK                  (1 << 21)
+
+#define SHIRQ_RAS1_MASK                        0x000380
+#define SHIRQ_RAS3_MASK                        0x000007
+#define SHIRQ_INTRCOMM_RAS_MASK                0x3FF800
+
+#endif /* __MACH_SPEAR320_H */
+
+#endif /* CONFIG_MACH_SPEAR320 */
diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h
new file mode 100644 (file)
index 0000000..92cee63
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/system.h
+ *
+ * SPEAr3xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <plat/system.h>
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/timex.h b/arch/arm/mach-spear3xx/include/mach/timex.h
new file mode 100644 (file)
index 0000000..a38cc9d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/timex.h
+ *
+ * SPEAr3XX machine family specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/uncompress.h b/arch/arm/mach-spear3xx/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..53ba8bb
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/vmalloc.h b/arch/arm/mach-spear3xx/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..df977b3
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif /* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
new file mode 100644 (file)
index 0000000..3560f8c
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+ * arch/arm/mach-spear3xx/spear300.c
+ *
+ * SPEAr300 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <plat/shirq.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG     0x00
+#define MODE_CONFIG_REG                0x04
+
+/* modes */
+#define NAND_MODE                      (1 << 0)
+#define NOR_MODE                       (1 << 1)
+#define PHOTO_FRAME_MODE               (1 << 2)
+#define LEND_IP_PHONE_MODE             (1 << 3)
+#define HEND_IP_PHONE_MODE             (1 << 4)
+#define LEND_WIFI_PHONE_MODE           (1 << 5)
+#define HEND_WIFI_PHONE_MODE           (1 << 6)
+#define ATA_PABX_WI2S_MODE             (1 << 7)
+#define ATA_PABX_I2S_MODE              (1 << 8)
+#define CAML_LCDW_MODE                 (1 << 9)
+#define CAMU_LCD_MODE                  (1 << 10)
+#define CAMU_WLCD_MODE                 (1 << 11)
+#define CAML_LCD_MODE                  (1 << 12)
+#define ALL_MODES                      0x1FFF
+
+struct pmx_mode nand_mode = {
+       .id = NAND_MODE,
+       .name = "nand mode",
+       .mask = 0x00,
+};
+
+struct pmx_mode nor_mode = {
+       .id = NOR_MODE,
+       .name = "nor mode",
+       .mask = 0x01,
+};
+
+struct pmx_mode photo_frame_mode = {
+       .id = PHOTO_FRAME_MODE,
+       .name = "photo frame mode",
+       .mask = 0x02,
+};
+
+struct pmx_mode lend_ip_phone_mode = {
+       .id = LEND_IP_PHONE_MODE,
+       .name = "lend ip phone mode",
+       .mask = 0x03,
+};
+
+struct pmx_mode hend_ip_phone_mode = {
+       .id = HEND_IP_PHONE_MODE,
+       .name = "hend ip phone mode",
+       .mask = 0x04,
+};
+
+struct pmx_mode lend_wifi_phone_mode = {
+       .id = LEND_WIFI_PHONE_MODE,
+       .name = "lend wifi phone mode",
+       .mask = 0x05,
+};
+
+struct pmx_mode hend_wifi_phone_mode = {
+       .id = HEND_WIFI_PHONE_MODE,
+       .name = "hend wifi phone mode",
+       .mask = 0x06,
+};
+
+struct pmx_mode ata_pabx_wi2s_mode = {
+       .id = ATA_PABX_WI2S_MODE,
+       .name = "ata pabx wi2s mode",
+       .mask = 0x07,
+};
+
+struct pmx_mode ata_pabx_i2s_mode = {
+       .id = ATA_PABX_I2S_MODE,
+       .name = "ata pabx i2s mode",
+       .mask = 0x08,
+};
+
+struct pmx_mode caml_lcdw_mode = {
+       .id = CAML_LCDW_MODE,
+       .name = "caml lcdw mode",
+       .mask = 0x0C,
+};
+
+struct pmx_mode camu_lcd_mode = {
+       .id = CAMU_LCD_MODE,
+       .name = "camu lcd mode",
+       .mask = 0x0D,
+};
+
+struct pmx_mode camu_wlcd_mode = {
+       .id = CAMU_WLCD_MODE,
+       .name = "camu wlcd mode",
+       .mask = 0x0E,
+};
+
+struct pmx_mode caml_lcd_mode = {
+       .id = CAML_LCD_MODE,
+       .name = "caml lcd mode",
+       .mask = 0x0F,
+};
+
+/* devices */
+struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
+       {
+               .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+               .mask = PMX_FIRDA_MASK,
+       },
+};
+
+struct pmx_dev pmx_fsmc_2_chips = {
+       .name = "fsmc_2_chips",
+       .modes = pmx_fsmc_2_chips_modes,
+       .mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
+       {
+               .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+                       ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+               .mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+       },
+};
+
+struct pmx_dev pmx_fsmc_4_chips = {
+       .name = "fsmc_4_chips",
+       .modes = pmx_fsmc_4_chips_modes,
+       .mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_keyboard_modes[] = {
+       {
+               .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+                       LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+                       CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE |
+                       CAML_LCD_MODE,
+               .mask = 0x0,
+       },
+};
+
+struct pmx_dev pmx_keyboard = {
+       .name = "keyboard",
+       .modes = pmx_keyboard_modes,
+       .mode_count = ARRAY_SIZE(pmx_keyboard_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_clcd_modes[] = {
+       {
+               .ids = PHOTO_FRAME_MODE,
+               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK ,
+       }, {
+               .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+                       CAMU_LCD_MODE | CAML_LCD_MODE,
+               .mask = PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_clcd = {
+       .name = "clcd",
+       .modes = pmx_clcd_modes,
+       .mode_count = ARRAY_SIZE(pmx_clcd_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
+       {
+               .ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
+               .mask = PMX_MII_MASK,
+       }, {
+               .ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE,
+               .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+       }, {
+               .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE,
+               .mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
+       }, {
+               .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE,
+               .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
+       }, {
+               .ids = ATA_PABX_WI2S_MODE,
+               .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
+                       | PMX_UART0_MODEM_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_gpio = {
+       .name = "telecom_gpio",
+       .modes = pmx_telecom_gpio_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
+       {
+               .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
+                       | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
+                       | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_tdm = {
+       .name = "telecom_tdm",
+       .modes = pmx_telecom_tdm_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
+       {
+               .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+                       LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE
+                       | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE |
+                       CAML_LCDW_MODE | CAML_LCD_MODE,
+               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
+       .name = "telecom_spi_cs_i2c_clk",
+       .modes = pmx_telecom_spi_cs_i2c_clk_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_camera_modes[] = {
+       {
+               .ids = CAML_LCDW_MODE | CAML_LCD_MODE,
+               .mask = PMX_MII_MASK,
+       }, {
+               .ids = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_camera = {
+       .name = "telecom_camera",
+       .modes = pmx_telecom_camera_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_dac_modes[] = {
+       {
+               .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .mask = PMX_TIMER_1_2_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_dac = {
+       .name = "telecom_dac",
+       .modes = pmx_telecom_dac_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
+       {
+               .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
+                       | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+                       ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+                       | CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .mask = PMX_UART0_MODEM_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_i2s = {
+       .name = "telecom_i2s",
+       .modes = pmx_telecom_i2s_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
+       {
+               .ids = NAND_MODE | NOR_MODE,
+               .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
+                       PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_boot_pins = {
+       .name = "telecom_boot_pins",
+       .modes = pmx_telecom_boot_pins_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = {
+       {
+               .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+                       HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+                       CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE |
+                       ATA_PABX_I2S_MODE,
+               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+                       PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_sdio_4bit = {
+       .name = "telecom_sdio_4bit",
+       .modes = pmx_telecom_sdio_4bit_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = {
+       {
+               .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+                       HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+                       HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+                       CAMU_WLCD_MODE | CAML_LCD_MODE,
+               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+                       PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_telecom_sdio_8bit = {
+       .name = "telecom_sdio_8bit",
+       .modes = pmx_telecom_sdio_8bit_modes,
+       .mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_gpio1_modes[] = {
+       {
+               .ids = PHOTO_FRAME_MODE,
+               .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
+                       PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio1 = {
+       .name = "arm gpio1",
+       .modes = pmx_gpio1_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio1_modes),
+       .enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+struct pmx_driver pmx_driver = {
+       .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
+       .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* Add spear300 specific devices here */
+/* arm gpio1 device registeration */
+static struct pl061_platform_data gpio1_plat_data = {
+       .gpio_base      = 8,
+       .irq_base       = SPEAR_GPIO1_INT_BASE,
+};
+
+struct amba_device gpio1_device = {
+       .dev = {
+               .init_name = "gpio1",
+               .platform_data = &gpio1_plat_data,
+       },
+       .res = {
+               .start = SPEAR300_GPIO_BASE,
+               .end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {VIRQ_GPIO1, NO_IRQ},
+};
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+       {
+               .virq = VIRQ_IT_PERS_S,
+               .enb_mask = IT_PERS_S_IRQ_MASK,
+               .status_mask = IT_PERS_S_IRQ_MASK,
+       }, {
+               .virq = VIRQ_IT_CHANGE_S,
+               .enb_mask = IT_CHANGE_S_IRQ_MASK,
+               .status_mask = IT_CHANGE_S_IRQ_MASK,
+       }, {
+               .virq = VIRQ_I2S,
+               .enb_mask = I2S_IRQ_MASK,
+               .status_mask = I2S_IRQ_MASK,
+       }, {
+               .virq = VIRQ_TDM,
+               .enb_mask = TDM_IRQ_MASK,
+               .status_mask = TDM_IRQ_MASK,
+       }, {
+               .virq = VIRQ_CAMERA_L,
+               .enb_mask = CAMERA_L_IRQ_MASK,
+               .status_mask = CAMERA_L_IRQ_MASK,
+       }, {
+               .virq = VIRQ_CAMERA_F,
+               .enb_mask = CAMERA_F_IRQ_MASK,
+               .status_mask = CAMERA_F_IRQ_MASK,
+       }, {
+               .virq = VIRQ_CAMERA_V,
+               .enb_mask = CAMERA_V_IRQ_MASK,
+               .status_mask = CAMERA_V_IRQ_MASK,
+       }, {
+               .virq = VIRQ_KEYBOARD,
+               .enb_mask = KEYBOARD_IRQ_MASK,
+               .status_mask = KEYBOARD_IRQ_MASK,
+       }, {
+               .virq = VIRQ_GPIO1,
+               .enb_mask = GPIO1_IRQ_MASK,
+               .status_mask = GPIO1_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_ras1 = {
+       .irq = IRQ_GEN_RAS_1,
+       .dev_config = shirq_ras1_config,
+       .dev_count = ARRAY_SIZE(shirq_ras1_config),
+       .regs = {
+               .enb_reg = INT_ENB_MASK_REG,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_RAS1_MASK,
+               .clear_reg = -1,
+       },
+};
+
+/* spear300 routines */
+void __init spear300_init(void)
+{
+       int ret = 0;
+
+       /* call spear3xx family common init function */
+       spear3xx_init();
+
+       /* shared irq registeration */
+       shirq_ras1.regs.base =
+               ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE);
+       if (shirq_ras1.regs.base) {
+               ret = spear_shirq_register(&shirq_ras1);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ\n");
+       }
+}
+
+void spear300_pmx_init(void)
+{
+       spear_pmx_init(&pmx_driver, SPEAR300_SOC_CONFIG_BASE,
+                       SPEAR300_SOC_CONFIG_SIZE);
+}
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
new file mode 100644 (file)
index 0000000..bb21db1
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-spear3xx/spear300_evb.c
+ *
+ * SPEAr300 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+       /* spear3xx specific devices */
+       &pmx_i2c,
+       &pmx_ssp_cs,
+       &pmx_ssp,
+       &pmx_mii,
+       &pmx_uart0,
+
+       /* spear300 specific devices */
+       &pmx_fsmc_2_chips,
+       &pmx_clcd,
+       &pmx_telecom_sdio_4bit,
+       &pmx_gpio1,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+       /* spear3xx specific devices */
+       &gpio_device,
+       &uart_device,
+
+       /* spear300 specific devices */
+       &gpio1_device,
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+       /* spear3xx specific devices */
+
+       /* spear300 specific devices */
+};
+
+static void __init spear300_evb_init(void)
+{
+       unsigned int i;
+
+       /* call spear300 machine init function */
+       spear300_init();
+
+       /* padmux initialization */
+       pmx_driver.mode = &photo_frame_mode;
+       pmx_driver.devs = pmx_devs;
+       pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+       spear300_pmx_init();
+
+       /* Add Platform Devices */
+       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+       /* Add Amba Devices */
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+               amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
+       .boot_params    =       0x00000100,
+       .map_io         =       spear3xx_map_io,
+       .init_irq       =       spear3xx_init_irq,
+       .timer          =       &spear_sys_timer,
+       .init_machine   =       spear300_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
new file mode 100644 (file)
index 0000000..96a1ab8
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * arch/arm/mach-spear3xx/spear310.c
+ *
+ * SPEAr310 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <plat/shirq.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG     0x08
+
+/* devices */
+struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_emi_cs_0_1_4_5 = {
+       .name = "emi_cs_0_1_4_5",
+       .modes = pmx_emi_cs_0_1_4_5_modes,
+       .mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_TIMER_1_2_MASK,
+       },
+};
+
+struct pmx_dev pmx_emi_cs_2_3 = {
+       .name = "emi_cs_2_3",
+       .modes = pmx_emi_cs_2_3_modes,
+       .mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart1_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_FIRDA_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart1 = {
+       .name = "uart1",
+       .modes = pmx_uart1_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart2_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_TIMER_1_2_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart2 = {
+       .name = "uart2",
+       .modes = pmx_uart2_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart2_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_UART0_MODEM_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart3_4_5 = {
+       .name = "uart3_4_5",
+       .modes = pmx_uart3_4_5_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_fsmc_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_fsmc = {
+       .name = "fsmc",
+       .modes = pmx_fsmc_modes,
+       .mode_count = ARRAY_SIZE(pmx_fsmc_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_rs485_0_1 = {
+       .name = "rs485_0_1",
+       .modes = pmx_rs485_0_1_modes,
+       .mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_tdm0_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_tdm0 = {
+       .name = "tdm0",
+       .modes = pmx_tdm0_modes,
+       .mode_count = ARRAY_SIZE(pmx_tdm0_modes),
+       .enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+struct pmx_driver pmx_driver = {
+       .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* Add spear310 specific devices here */
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+       {
+               .virq = VIRQ_SMII0,
+               .status_mask = SMII0_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SMII1,
+               .status_mask = SMII1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SMII2,
+               .status_mask = SMII2_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SMII3,
+               .status_mask = SMII3_IRQ_MASK,
+       }, {
+               .virq = VIRQ_WAKEUP_SMII0,
+               .status_mask = WAKEUP_SMII0_IRQ_MASK,
+       }, {
+               .virq = VIRQ_WAKEUP_SMII1,
+               .status_mask = WAKEUP_SMII1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_WAKEUP_SMII2,
+               .status_mask = WAKEUP_SMII2_IRQ_MASK,
+       }, {
+               .virq = VIRQ_WAKEUP_SMII3,
+               .status_mask = WAKEUP_SMII3_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_ras1 = {
+       .irq = IRQ_GEN_RAS_1,
+       .dev_config = shirq_ras1_config,
+       .dev_count = ARRAY_SIZE(shirq_ras1_config),
+       .regs = {
+               .enb_reg = -1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_RAS1_MASK,
+               .clear_reg = -1,
+       },
+};
+
+struct shirq_dev_config shirq_ras2_config[] = {
+       {
+               .virq = VIRQ_UART1,
+               .status_mask = UART1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_UART2,
+               .status_mask = UART2_IRQ_MASK,
+       }, {
+               .virq = VIRQ_UART3,
+               .status_mask = UART3_IRQ_MASK,
+       }, {
+               .virq = VIRQ_UART4,
+               .status_mask = UART4_IRQ_MASK,
+       }, {
+               .virq = VIRQ_UART5,
+               .status_mask = UART5_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_ras2 = {
+       .irq = IRQ_GEN_RAS_2,
+       .dev_config = shirq_ras2_config,
+       .dev_count = ARRAY_SIZE(shirq_ras2_config),
+       .regs = {
+               .enb_reg = -1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_RAS2_MASK,
+               .clear_reg = -1,
+       },
+};
+
+struct shirq_dev_config shirq_ras3_config[] = {
+       {
+               .virq = VIRQ_EMI,
+               .status_mask = EMI_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_ras3 = {
+       .irq = IRQ_GEN_RAS_3,
+       .dev_config = shirq_ras3_config,
+       .dev_count = ARRAY_SIZE(shirq_ras3_config),
+       .regs = {
+               .enb_reg = -1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_RAS3_MASK,
+               .clear_reg = -1,
+       },
+};
+
+struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+       {
+               .virq = VIRQ_TDM_HDLC,
+               .status_mask = TDM_HDLC_IRQ_MASK,
+       }, {
+               .virq = VIRQ_RS485_0,
+               .status_mask = RS485_0_IRQ_MASK,
+       }, {
+               .virq = VIRQ_RS485_1,
+               .status_mask = RS485_1_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_intrcomm_ras = {
+       .irq = IRQ_INTRCOMM_RAS_ARM,
+       .dev_config = shirq_intrcomm_ras_config,
+       .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+       .regs = {
+               .enb_reg = -1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+               .clear_reg = -1,
+       },
+};
+
+/* spear310 routines */
+void __init spear310_init(void)
+{
+       void __iomem *base;
+       int ret = 0;
+
+       /* call spear3xx family common init function */
+       spear3xx_init();
+
+       /* shared irq registeration */
+       base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE);
+       if (base) {
+               /* shirq 1 */
+               shirq_ras1.regs.base = base;
+               ret = spear_shirq_register(&shirq_ras1);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+               /* shirq 2 */
+               shirq_ras2.regs.base = base;
+               ret = spear_shirq_register(&shirq_ras2);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 2\n");
+
+               /* shirq 3 */
+               shirq_ras3.regs.base = base;
+               ret = spear_shirq_register(&shirq_ras3);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+               /* shirq 4 */
+               shirq_intrcomm_ras.regs.base = base;
+               ret = spear_shirq_register(&shirq_intrcomm_ras);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 4\n");
+       }
+}
+
+void spear310_pmx_init(void)
+{
+       spear_pmx_init(&pmx_driver, SPEAR310_SOC_CONFIG_BASE,
+                       SPEAR310_SOC_CONFIG_SIZE);
+}
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
new file mode 100644 (file)
index 0000000..7facf66
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-spear3xx/spear310_evb.c
+ *
+ * SPEAr310 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+       /* spear3xx specific devices */
+       &pmx_i2c,
+       &pmx_ssp,
+       &pmx_gpio_pin0,
+       &pmx_gpio_pin1,
+       &pmx_gpio_pin2,
+       &pmx_gpio_pin3,
+       &pmx_gpio_pin4,
+       &pmx_gpio_pin5,
+       &pmx_uart0,
+
+       /* spear310 specific devices */
+       &pmx_emi_cs_0_1_4_5,
+       &pmx_emi_cs_2_3,
+       &pmx_uart1,
+       &pmx_uart2,
+       &pmx_uart3_4_5,
+       &pmx_fsmc,
+       &pmx_rs485_0_1,
+       &pmx_tdm0,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+       /* spear3xx specific devices */
+       &gpio_device,
+       &uart_device,
+
+       /* spear310 specific devices */
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+       /* spear3xx specific devices */
+
+       /* spear310 specific devices */
+};
+
+static void __init spear310_evb_init(void)
+{
+       unsigned int i;
+
+       /* call spear310 machine init function */
+       spear310_init();
+
+       /* padmux initialization */
+       pmx_driver.mode = NULL;
+       pmx_driver.devs = pmx_devs;
+       pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+       spear310_pmx_init();
+
+       /* Add Platform Devices */
+       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+       /* Add Amba Devices */
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+               amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
+       .boot_params    =       0x00000100,
+       .map_io         =       spear3xx_map_io,
+       .init_irq       =       spear3xx_init_irq,
+       .timer          =       &spear_sys_timer,
+       .init_machine   =       spear310_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
new file mode 100644 (file)
index 0000000..6a12195
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * arch/arm/mach-spear3xx/spear320.c
+ *
+ * SPEAr320 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+#include <plat/shirq.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG     0x0C
+#define MODE_CONFIG_REG                0x10
+
+/* modes */
+#define AUTO_NET_SMII_MODE     (1 << 0)
+#define AUTO_NET_MII_MODE      (1 << 1)
+#define AUTO_EXP_MODE          (1 << 2)
+#define SMALL_PRINTERS_MODE    (1 << 3)
+#define ALL_MODES              0xF
+
+struct pmx_mode auto_net_smii_mode = {
+       .id = AUTO_NET_SMII_MODE,
+       .name = "Automation Networking SMII Mode",
+       .mask = 0x00,
+};
+
+struct pmx_mode auto_net_mii_mode = {
+       .id = AUTO_NET_MII_MODE,
+       .name = "Automation Networking MII Mode",
+       .mask = 0x01,
+};
+
+struct pmx_mode auto_exp_mode = {
+       .id = AUTO_EXP_MODE,
+       .name = "Automation Expanded Mode",
+       .mask = 0x02,
+};
+
+struct pmx_mode small_printers_mode = {
+       .id = SMALL_PRINTERS_MODE,
+       .name = "Small Printers Mode",
+       .mask = 0x03,
+};
+
+/* devices */
+struct pmx_dev_mode pmx_clcd_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE,
+               .mask = 0x0,
+       },
+};
+
+struct pmx_dev pmx_clcd = {
+       .name = "clcd",
+       .modes = pmx_clcd_modes,
+       .mode_count = ARRAY_SIZE(pmx_clcd_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_emi_modes[] = {
+       {
+               .ids = AUTO_EXP_MODE,
+               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_emi = {
+       .name = "emi",
+       .modes = pmx_emi_modes,
+       .mode_count = ARRAY_SIZE(pmx_emi_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_fsmc_modes[] = {
+       {
+               .ids = ALL_MODES,
+               .mask = 0x0,
+       },
+};
+
+struct pmx_dev pmx_fsmc = {
+       .name = "fsmc",
+       .modes = pmx_fsmc_modes,
+       .mode_count = ARRAY_SIZE(pmx_fsmc_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_spp_modes[] = {
+       {
+               .ids = SMALL_PRINTERS_MODE,
+               .mask = 0x0,
+       },
+};
+
+struct pmx_dev pmx_spp = {
+       .name = "spp",
+       .modes = pmx_spp_modes,
+       .mode_count = ARRAY_SIZE(pmx_spp_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_sdio_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
+                       SMALL_PRINTERS_MODE,
+               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_sdio = {
+       .name = "sdio",
+       .modes = pmx_sdio_modes,
+       .mode_count = ARRAY_SIZE(pmx_sdio_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_i2s_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+               .mask = PMX_UART0_MODEM_MASK,
+       },
+};
+
+struct pmx_dev pmx_i2s = {
+       .name = "i2s",
+       .modes = pmx_i2s_modes,
+       .mode_count = ARRAY_SIZE(pmx_i2s_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart1_modes[] = {
+       {
+               .ids = ALL_MODES,
+               .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart1 = {
+       .name = "uart1",
+       .modes = pmx_uart1_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+       {
+               .ids = AUTO_EXP_MODE,
+               .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
+                       PMX_SSP_CS_MASK,
+       }, {
+               .ids = SMALL_PRINTERS_MODE,
+               .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
+                       PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart1_modem = {
+       .name = "uart1_modem",
+       .modes = pmx_uart1_modem_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_uart2_modes[] = {
+       {
+               .ids = ALL_MODES,
+               .mask = PMX_FIRDA_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart2 = {
+       .name = "uart2",
+       .modes = pmx_uart2_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart2_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_touchscreen_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE,
+               .mask = PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_touchscreen = {
+       .name = "touchscreen",
+       .modes = pmx_touchscreen_modes,
+       .mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_can_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
+               .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+                       PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+       },
+};
+
+struct pmx_dev pmx_can = {
+       .name = "can",
+       .modes = pmx_can_modes,
+       .mode_count = ARRAY_SIZE(pmx_can_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_sdio_led_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+               .mask = PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_sdio_led = {
+       .name = "sdio_led",
+       .modes = pmx_sdio_led_modes,
+       .mode_count = ARRAY_SIZE(pmx_sdio_led_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm0_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+               .mask = PMX_UART0_MODEM_MASK,
+       }, {
+               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_pwm0 = {
+       .name = "pwm0",
+       .modes = pmx_pwm0_modes,
+       .mode_count = ARRAY_SIZE(pmx_pwm0_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm1_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+               .mask = PMX_UART0_MODEM_MASK,
+       }, {
+               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_pwm1 = {
+       .name = "pwm1",
+       .modes = pmx_pwm1_modes,
+       .mode_count = ARRAY_SIZE(pmx_pwm1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm2_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+               .mask = PMX_SSP_CS_MASK,
+       }, {
+               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_pwm2 = {
+       .name = "pwm2",
+       .modes = pmx_pwm2_modes,
+       .mode_count = ARRAY_SIZE(pmx_pwm2_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_pwm3_modes[] = {
+       {
+               .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_pwm3 = {
+       .name = "pwm3",
+       .modes = pmx_pwm3_modes,
+       .mode_count = ARRAY_SIZE(pmx_pwm3_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_ssp1_modes[] = {
+       {
+               .ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_ssp1 = {
+       .name = "ssp1",
+       .modes = pmx_ssp1_modes,
+       .mode_count = ARRAY_SIZE(pmx_ssp1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_ssp2_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_ssp2 = {
+       .name = "ssp2",
+       .modes = pmx_ssp2_modes,
+       .mode_count = ARRAY_SIZE(pmx_ssp2_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_mii1_modes[] = {
+       {
+               .ids = AUTO_NET_MII_MODE,
+               .mask = 0x0,
+       },
+};
+
+struct pmx_dev pmx_mii1 = {
+       .name = "mii1",
+       .modes = pmx_mii1_modes,
+       .mode_count = ARRAY_SIZE(pmx_mii1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_smii0_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_smii0 = {
+       .name = "smii0",
+       .modes = pmx_smii0_modes,
+       .mode_count = ARRAY_SIZE(pmx_smii0_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_smii1_modes[] = {
+       {
+               .ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_smii1 = {
+       .name = "smii1",
+       .modes = pmx_smii1_modes,
+       .mode_count = ARRAY_SIZE(pmx_smii1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_i2c1_modes[] = {
+       {
+               .ids = AUTO_EXP_MODE,
+               .mask = 0x0,
+       },
+};
+
+struct pmx_dev pmx_i2c1 = {
+       .name = "i2c1",
+       .modes = pmx_i2c1_modes,
+       .mode_count = ARRAY_SIZE(pmx_i2c1_modes),
+       .enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+struct pmx_driver pmx_driver = {
+       .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
+       .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* Add spear320 specific devices here */
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+       {
+               .virq = VIRQ_EMI,
+               .status_mask = EMI_IRQ_MASK,
+               .clear_mask = EMI_IRQ_MASK,
+       }, {
+               .virq = VIRQ_CLCD,
+               .status_mask = CLCD_IRQ_MASK,
+               .clear_mask = CLCD_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SPP,
+               .status_mask = SPP_IRQ_MASK,
+               .clear_mask = SPP_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_ras1 = {
+       .irq = IRQ_GEN_RAS_1,
+       .dev_config = shirq_ras1_config,
+       .dev_count = ARRAY_SIZE(shirq_ras1_config),
+       .regs = {
+               .enb_reg = -1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_RAS1_MASK,
+               .clear_reg = INT_CLR_MASK_REG,
+               .reset_to_clear = 1,
+       },
+};
+
+struct shirq_dev_config shirq_ras3_config[] = {
+       {
+               .virq = VIRQ_PLGPIO,
+               .enb_mask = GPIO_IRQ_MASK,
+               .status_mask = GPIO_IRQ_MASK,
+               .clear_mask = GPIO_IRQ_MASK,
+       }, {
+               .virq = VIRQ_I2S_PLAY,
+               .enb_mask = I2S_PLAY_IRQ_MASK,
+               .status_mask = I2S_PLAY_IRQ_MASK,
+               .clear_mask = I2S_PLAY_IRQ_MASK,
+       }, {
+               .virq = VIRQ_I2S_REC,
+               .enb_mask = I2S_REC_IRQ_MASK,
+               .status_mask = I2S_REC_IRQ_MASK,
+               .clear_mask = I2S_REC_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_ras3 = {
+       .irq = IRQ_GEN_RAS_3,
+       .dev_config = shirq_ras3_config,
+       .dev_count = ARRAY_SIZE(shirq_ras3_config),
+       .regs = {
+               .enb_reg = INT_ENB_MASK_REG,
+               .reset_to_enb = 1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_RAS3_MASK,
+               .clear_reg = INT_CLR_MASK_REG,
+               .reset_to_clear = 1,
+       },
+};
+
+struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+       {
+               .virq = VIRQ_CANU,
+               .status_mask = CAN_U_IRQ_MASK,
+               .clear_mask = CAN_U_IRQ_MASK,
+       }, {
+               .virq = VIRQ_CANL,
+               .status_mask = CAN_L_IRQ_MASK,
+               .clear_mask = CAN_L_IRQ_MASK,
+       }, {
+               .virq = VIRQ_UART1,
+               .status_mask = UART1_IRQ_MASK,
+               .clear_mask = UART1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_UART2,
+               .status_mask = UART2_IRQ_MASK,
+               .clear_mask = UART2_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SSP1,
+               .status_mask = SSP1_IRQ_MASK,
+               .clear_mask = SSP1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SSP2,
+               .status_mask = SSP2_IRQ_MASK,
+               .clear_mask = SSP2_IRQ_MASK,
+       }, {
+               .virq = VIRQ_SMII0,
+               .status_mask = SMII0_IRQ_MASK,
+               .clear_mask = SMII0_IRQ_MASK,
+       }, {
+               .virq = VIRQ_MII1_SMII1,
+               .status_mask = MII1_SMII1_IRQ_MASK,
+               .clear_mask = MII1_SMII1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_WAKEUP_SMII0,
+               .status_mask = WAKEUP_SMII0_IRQ_MASK,
+               .clear_mask = WAKEUP_SMII0_IRQ_MASK,
+       }, {
+               .virq = VIRQ_WAKEUP_MII1_SMII1,
+               .status_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+               .clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+       }, {
+               .virq = VIRQ_I2C,
+               .status_mask = I2C1_IRQ_MASK,
+               .clear_mask = I2C1_IRQ_MASK,
+       },
+};
+
+struct spear_shirq shirq_intrcomm_ras = {
+       .irq = IRQ_INTRCOMM_RAS_ARM,
+       .dev_config = shirq_intrcomm_ras_config,
+       .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+       .regs = {
+               .enb_reg = -1,
+               .status_reg = INT_STS_MASK_REG,
+               .status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+               .clear_reg = INT_CLR_MASK_REG,
+               .reset_to_clear = 1,
+       },
+};
+
+/* spear320 routines */
+void __init spear320_init(void)
+{
+       void __iomem *base;
+       int ret = 0;
+
+       /* call spear3xx family common init function */
+       spear3xx_init();
+
+       /* shared irq registeration */
+       base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE);
+       if (base) {
+               /* shirq 1 */
+               shirq_ras1.regs.base = base;
+               ret = spear_shirq_register(&shirq_ras1);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+               /* shirq 3 */
+               shirq_ras3.regs.base = base;
+               ret = spear_shirq_register(&shirq_ras3);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+               /* shirq 4 */
+               shirq_intrcomm_ras.regs.base = base;
+               ret = spear_shirq_register(&shirq_intrcomm_ras);
+               if (ret)
+                       printk(KERN_ERR "Error registering Shared IRQ 4\n");
+       }
+}
+
+void spear320_pmx_init(void)
+{
+       spear_pmx_init(&pmx_driver, SPEAR320_SOC_CONFIG_BASE,
+                       SPEAR320_SOC_CONFIG_SIZE);
+}
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
new file mode 100644 (file)
index 0000000..62ac685
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-spear3xx/spear320_evb.c
+ *
+ * SPEAr320 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+       /* spear3xx specific devices */
+       &pmx_i2c,
+       &pmx_ssp,
+       &pmx_mii,
+       &pmx_uart0,
+
+       /* spear320 specific devices */
+       &pmx_fsmc,
+       &pmx_sdio,
+       &pmx_i2s,
+       &pmx_uart1,
+       &pmx_uart2,
+       &pmx_can,
+       &pmx_pwm0,
+       &pmx_pwm1,
+       &pmx_pwm2,
+       &pmx_mii1,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+       /* spear3xx specific devices */
+       &gpio_device,
+       &uart_device,
+
+       /* spear320 specific devices */
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+       /* spear3xx specific devices */
+
+       /* spear320 specific devices */
+};
+
+static void __init spear320_evb_init(void)
+{
+       unsigned int i;
+
+       /* call spear320 machine init function */
+       spear320_init();
+
+       /* padmux initialization */
+       pmx_driver.mode = &auto_net_mii_mode;
+       pmx_driver.devs = pmx_devs;
+       pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
+       spear320_pmx_init();
+
+       /* Add Platform Devices */
+       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+       /* Add Amba Devices */
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+               amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
+       .boot_params    =       0x00000100,
+       .map_io         =       spear3xx_map_io,
+       .init_irq       =       spear3xx_init_irq,
+       .timer          =       &spear_sys_timer,
+       .init_machine   =       spear320_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
new file mode 100644 (file)
index 0000000..e87313a
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ * arch/arm/mach-spear3xx/spear3xx.c
+ *
+ * SPEAr3XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear3xx machines common devices here */
+/* gpio device registeration */
+static struct pl061_platform_data gpio_plat_data = {
+       .gpio_base      = 0,
+       .irq_base       = SPEAR_GPIO_INT_BASE,
+};
+
+struct amba_device gpio_device = {
+       .dev = {
+               .init_name = "gpio",
+               .platform_data = &gpio_plat_data,
+       },
+       .res = {
+               .start = SPEAR3XX_ICM3_GPIO_BASE,
+               .end = SPEAR3XX_ICM3_GPIO_BASE + SPEAR3XX_ICM3_GPIO_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_BASIC_GPIO, NO_IRQ},
+};
+
+/* uart device registeration */
+struct amba_device uart_device = {
+       .dev = {
+               .init_name = "uart",
+       },
+       .res = {
+               .start = SPEAR3XX_ICM1_UART_BASE,
+               .end = SPEAR3XX_ICM1_UART_BASE + SPEAR3XX_ICM1_UART_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_UART, NO_IRQ},
+};
+
+/* Do spear3xx familiy common initialization part here */
+void __init spear3xx_init(void)
+{
+       /* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear3xx_init_irq(void)
+{
+       vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0, 0);
+}
+
+/* Following will create static virtual/physical mappings */
+struct map_desc spear3xx_io_desc[] __initdata = {
+       {
+               .virtual        = VA_SPEAR3XX_ICM1_UART_BASE,
+               .pfn            = __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE),
+               .length         = SPEAR3XX_ICM1_UART_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR3XX_ML1_VIC_BASE,
+               .pfn            = __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE),
+               .length         = SPEAR3XX_ML1_VIC_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR3XX_ICM3_SYS_CTRL_BASE,
+               .pfn            = __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE),
+               .length         = SPEAR3XX_ICM3_SYS_CTRL_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR3XX_ICM3_MISC_REG_BASE,
+               .pfn            = __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
+               .length         = SPEAR3XX_ICM3_MISC_REG_SIZE,
+               .type           = MT_DEVICE
+       },
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear3xx_map_io(void)
+{
+       iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
+
+       /* This will initialize clock framework */
+       clk_init();
+}
+
+/* pad multiplexing support */
+/* devices */
+struct pmx_dev_mode pmx_firda_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_FIRDA_MASK,
+       },
+};
+
+struct pmx_dev pmx_firda = {
+       .name = "firda",
+       .modes = pmx_firda_modes,
+       .mode_count = ARRAY_SIZE(pmx_firda_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_i2c_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_I2C_MASK,
+       },
+};
+
+struct pmx_dev pmx_i2c = {
+       .name = "i2c",
+       .modes = pmx_i2c_modes,
+       .mode_count = ARRAY_SIZE(pmx_i2c_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_ssp_cs_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_ssp_cs = {
+       .name = "ssp_chip_selects",
+       .modes = pmx_ssp_cs_modes,
+       .mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_ssp_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_SSP_MASK,
+       },
+};
+
+struct pmx_dev pmx_ssp = {
+       .name = "ssp",
+       .modes = pmx_ssp_modes,
+       .mode_count = ARRAY_SIZE(pmx_ssp_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_mii_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_mii = {
+       .name = "mii",
+       .modes = pmx_mii_modes,
+       .mode_count = ARRAY_SIZE(pmx_mii_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_GPIO_PIN0_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio_pin0 = {
+       .name = "gpio_pin0",
+       .modes = pmx_gpio_pin0_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_GPIO_PIN1_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio_pin1 = {
+       .name = "gpio_pin1",
+       .modes = pmx_gpio_pin1_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_GPIO_PIN2_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio_pin2 = {
+       .name = "gpio_pin2",
+       .modes = pmx_gpio_pin2_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_GPIO_PIN3_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio_pin3 = {
+       .name = "gpio_pin3",
+       .modes = pmx_gpio_pin3_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_GPIO_PIN4_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio_pin4 = {
+       .name = "gpio_pin4",
+       .modes = pmx_gpio_pin4_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_GPIO_PIN5_MASK,
+       },
+};
+
+struct pmx_dev pmx_gpio_pin5 = {
+       .name = "gpio_pin5",
+       .modes = pmx_gpio_pin5_modes,
+       .mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_UART0_MODEM_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart0_modem = {
+       .name = "uart0_modem",
+       .modes = pmx_uart0_modem_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_uart0_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_UART0_MASK,
+       },
+};
+
+struct pmx_dev pmx_uart0 = {
+       .name = "uart0",
+       .modes = pmx_uart0_modes,
+       .mode_count = ARRAY_SIZE(pmx_uart0_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_timer_3_4_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_timer_3_4 = {
+       .name = "timer_3_4",
+       .modes = pmx_timer_3_4_modes,
+       .mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
+       .enb_on_reset = 0,
+};
+
+struct pmx_dev_mode pmx_timer_1_2_modes[] = {
+       {
+               .ids = 0xffffffff,
+               .mask = PMX_TIMER_1_2_MASK,
+       },
+};
+
+struct pmx_dev pmx_timer_1_2 = {
+       .name = "timer_1_2",
+       .modes = pmx_timer_1_2_modes,
+       .mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
+       .enb_on_reset = 0,
+};
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* plgpios devices */
+struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_FIRDA_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_0_1 = {
+       .name = "plgpio 0 and 1",
+       .modes = pmx_plgpio_0_1_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_UART0_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_2_3 = {
+       .name = "plgpio 2 and 3",
+       .modes = pmx_plgpio_2_3_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_I2C_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_4_5 = {
+       .name = "plgpio 4 and 5",
+       .modes = pmx_plgpio_4_5_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_SSP_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_6_9 = {
+       .name = "plgpio 6 to 9",
+       .modes = pmx_plgpio_6_9_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_MII_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_10_27 = {
+       .name = "plgpio 10 to 27",
+       .modes = pmx_plgpio_10_27_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_28_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_GPIO_PIN0_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_28 = {
+       .name = "plgpio 28",
+       .modes = pmx_plgpio_28_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_29_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_GPIO_PIN1_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_29 = {
+       .name = "plgpio 29",
+       .modes = pmx_plgpio_29_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_30_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_GPIO_PIN2_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_30 = {
+       .name = "plgpio 30",
+       .modes = pmx_plgpio_30_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_31_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_GPIO_PIN3_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_31 = {
+       .name = "plgpio 31",
+       .modes = pmx_plgpio_31_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_32_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_GPIO_PIN4_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_32 = {
+       .name = "plgpio 32",
+       .modes = pmx_plgpio_32_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_33_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_GPIO_PIN5_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_33 = {
+       .name = "plgpio 33",
+       .modes = pmx_plgpio_33_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_SSP_CS_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_34_36 = {
+       .name = "plgpio 34 to 36",
+       .modes = pmx_plgpio_34_36_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_UART0_MODEM_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_37_42 = {
+       .name = "plgpio 37 to 42",
+       .modes = pmx_plgpio_37_42_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_TIMER_1_2_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_43_44_47_48 = {
+       .name = "plgpio 43, 44, 47 and 48",
+       .modes = pmx_plgpio_43_44_47_48_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
+       .enb_on_reset = 1,
+};
+
+struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
+       {
+               .ids = 0x00,
+               .mask = PMX_TIMER_3_4_MASK,
+       },
+};
+
+struct pmx_dev pmx_plgpio_45_46_49_50 = {
+       .name = "plgpio 45, 46, 49 and 50",
+       .modes = pmx_plgpio_45_46_49_50_modes,
+       .mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
+       .enb_on_reset = 1,
+};
+
+#endif
+
+/* spear padmux initialization function */
+void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size)
+{
+       int ret = 0;
+
+       /* pad mux initialization */
+       pmx_driver->base = ioremap(base, size);
+       if (!pmx_driver->base) {
+               ret = -ENOMEM;
+               goto pmx_fail;
+       }
+
+       ret = pmx_register(pmx_driver);
+       iounmap(pmx_driver->base);
+
+pmx_fail:
+       if (ret)
+               printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+                               ret);
+}
diff --git a/arch/arm/mach-spear6xx/Kconfig b/arch/arm/mach-spear6xx/Kconfig
new file mode 100644 (file)
index 0000000..bddba03
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# SPEAr6XX Machine configuration file
+#
+
+if ARCH_SPEAR6XX
+
+choice
+       prompt "SPEAr6XX Family"
+       default MACH_SPEAR600
+
+config MACH_SPEAR600
+       bool "SPEAr600"
+       help
+         Supports ST SPEAr600 Machine
+endchoice
+
+# Adding SPEAr6XX machine specific configuration files
+source "arch/arm/mach-spear6xx/Kconfig600"
+
+endif #ARCH_SPEAR6XX
diff --git a/arch/arm/mach-spear6xx/Kconfig600 b/arch/arm/mach-spear6xx/Kconfig600
new file mode 100644 (file)
index 0000000..9e19f65
--- /dev/null
@@ -0,0 +1,17 @@
+#
+# SPEAr600 machine configuration file
+#
+
+if MACH_SPEAR600
+
+choice
+       prompt "SPEAr600 Boards"
+       default BOARD_SPEAR600_EVB
+
+config BOARD_SPEAR600_EVB
+       bool "SPEAr600 Evaluation Board"
+       help
+         Supports ST SPEAr600 Evaluation Board
+endchoice
+
+endif  #MACH_SPEAR600
diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile
new file mode 100644 (file)
index 0000000..cc1a4d8
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for SPEAr6XX machine series
+#
+
+# common files
+obj-y  += clock.o spear6xx.o
+
+# spear600 specific files
+obj-$(CONFIG_MACH_SPEAR600) += spear600.o
+
+# spear600 boards files
+obj-$(CONFIG_BOARD_SPEAR600_EVB) += spear600_evb.o
diff --git a/arch/arm/mach-spear6xx/Makefile.boot b/arch/arm/mach-spear6xx/Makefile.boot
new file mode 100644 (file)
index 0000000..7a1f3c0
--- /dev/null
@@ -0,0 +1,3 @@
+zreladdr-y     := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
new file mode 100644 (file)
index 0000000..13e27c7
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * arch/arm/mach-spear6xx/clock.c
+ *
+ * SPEAr6xx machines clock framework source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+/* root clks */
+/* 32 KHz oscillator clock */
+static struct clk osc_32k_clk = {
+       .flags = ALWAYS_ENABLED,
+       .rate = 32000,
+};
+
+/* 30 MHz oscillator clock */
+static struct clk osc_30m_clk = {
+       .flags = ALWAYS_ENABLED,
+       .rate = 30000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+       .pclk = &osc_32k_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = RTC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from 30 MHz osc clk */
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+       .mode_reg = PLL1_CTR,
+       .cfg_reg = PLL1_FRQ,
+};
+
+/* PLL1 clock */
+static struct clk pll1_clk = {
+       .pclk = &osc_30m_clk,
+       .en_reg = PLL1_CTR,
+       .en_reg_bit = PLL_ENABLE,
+       .recalc = &pll1_clk_recalc,
+       .private_data = &pll1_config,
+};
+
+/* PLL3 48 MHz clock */
+static struct clk pll3_48m_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &osc_30m_clk,
+       .rate = 48000000,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &osc_30m_clk,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &pll1_clk,
+       .recalc = &follow_parent,
+};
+
+/* ahb configuration structure */
+static struct bus_clk_config ahb_config = {
+       .reg = CORE_CLK_CFG,
+       .mask = PLL_HCLK_RATIO_MASK,
+       .shift = PLL_HCLK_RATIO_SHIFT,
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &pll1_clk,
+       .recalc = &bus_clk_recalc,
+       .private_data = &ahb_config,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+       .pclk_info = uart_pclk_info,
+       .pclk_count = ARRAY_SIZE(uart_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart configurations */
+static struct aux_clk_config uart_config = {
+       .synth_reg = UART_CLK_SYNT,
+};
+
+/* uart0 clock */
+static struct clk uart0_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = UART0_CLK_ENB,
+       .pclk_sel = &uart_pclk_sel,
+       .pclk_sel_shift = UART_CLK_SHIFT,
+       .recalc = &aux_clk_recalc,
+       .private_data = &uart_config,
+};
+
+/* uart1 clock */
+static struct clk uart1_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = UART1_CLK_ENB,
+       .pclk_sel = &uart_pclk_sel,
+       .pclk_sel_shift = UART_CLK_SHIFT,
+       .recalc = &aux_clk_recalc,
+       .private_data = &uart_config,
+};
+
+/* firda configurations */
+static struct aux_clk_config firda_config = {
+       .synth_reg = FIRDA_CLK_SYNT,
+};
+
+/* firda parents */
+static struct pclk_info firda_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* firda parent select structure */
+static struct pclk_sel firda_pclk_sel = {
+       .pclk_info = firda_pclk_info,
+       .pclk_count = ARRAY_SIZE(firda_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = FIRDA_CLK_MASK,
+};
+
+/* firda clock */
+static struct clk firda_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = FIRDA_CLK_ENB,
+       .pclk_sel = &firda_pclk_sel,
+       .pclk_sel_shift = FIRDA_CLK_SHIFT,
+       .recalc = &aux_clk_recalc,
+       .private_data = &firda_config,
+};
+
+/* clcd configurations */
+static struct aux_clk_config clcd_config = {
+       .synth_reg = CLCD_CLK_SYNT,
+};
+
+/* clcd parents */
+static struct pclk_info clcd_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* clcd parent select structure */
+static struct pclk_sel clcd_pclk_sel = {
+       .pclk_info = clcd_pclk_info,
+       .pclk_count = ARRAY_SIZE(clcd_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = CLCD_CLK_MASK,
+};
+
+/* clcd clock */
+static struct clk clcd_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = CLCD_CLK_ENB,
+       .pclk_sel = &clcd_pclk_sel,
+       .pclk_sel_shift = CLCD_CLK_SHIFT,
+       .recalc = &aux_clk_recalc,
+       .private_data = &clcd_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt_pclk_info[] = {
+       {
+               .pclk = &pll1_clk,
+               .pclk_mask = AUX_CLK_PLL1_MASK,
+               .scalable = 1,
+       }, {
+               .pclk = &pll3_48m_clk,
+               .pclk_mask = AUX_CLK_PLL3_MASK,
+               .scalable = 0,
+       },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt_pclk_sel = {
+       .pclk_info = gpt_pclk_info,
+       .pclk_count = ARRAY_SIZE(gpt_pclk_info),
+       .pclk_sel_reg = PERIP_CLK_CFG,
+       .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0_1 configurations */
+static struct aux_clk_config gpt0_1_config = {
+       .synth_reg = PRSC1_CLK_CFG,
+};
+
+/* gpt0 ARM1 subsystem timer clock */
+static struct clk gpt0_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT0_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt0_1_config,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT1_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt0_1_config,
+};
+
+/* gpt2 configurations */
+static struct aux_clk_config gpt2_config = {
+       .synth_reg = PRSC2_CLK_CFG,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPT2_CLK_ENB,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT2_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt2_config,
+};
+
+/* gpt3 configurations */
+static struct aux_clk_config gpt3_config = {
+       .synth_reg = PRSC3_CLK_CFG,
+};
+
+/* gpt3 timer clock */
+static struct clk gpt3_clk = {
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPT3_CLK_ENB,
+       .pclk_sel = &gpt_pclk_sel,
+       .pclk_sel_shift = GPT3_CLK_SHIFT,
+       .recalc = &gpt_clk_recalc,
+       .private_data = &gpt3_config,
+};
+
+/* clock derived from pll3 clk */
+/* usbh0 clock */
+static struct clk usbh0_clk = {
+       .pclk = &pll3_48m_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = USBH0_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* usbh1 clock */
+static struct clk usbh1_clk = {
+       .pclk = &pll3_48m_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = USBH1_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+       .pclk = &pll3_48m_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = USBD_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+/* apb configuration structure */
+static struct bus_clk_config apb_config = {
+       .reg = CORE_CLK_CFG,
+       .mask = HCLK_PCLK_RATIO_MASK,
+       .shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &ahb_clk,
+       .recalc = &bus_clk_recalc,
+       .private_data = &apb_config,
+};
+
+/* i2c clock */
+static struct clk i2c_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = I2C_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = DMA_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = JPEG_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GMAC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = SMI_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* fsmc clock */
+static struct clk fsmc_clk = {
+       .pclk = &ahb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = FSMC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = ADC_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* ssp0 clock */
+static struct clk ssp0_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = SSP0_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* ssp1 clock */
+static struct clk ssp1_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = SSP1_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* ssp2 clock */
+static struct clk ssp2_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = SSP2_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* gpio0 ARM subsystem clock */
+static struct clk gpio0_clk = {
+       .flags = ALWAYS_ENABLED,
+       .pclk = &apb_clk,
+       .recalc = &follow_parent,
+};
+
+/* gpio1 clock */
+static struct clk gpio1_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPIO1_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* gpio2 clock */
+static struct clk gpio2_clk = {
+       .pclk = &apb_clk,
+       .en_reg = PERIP1_CLK_ENB,
+       .en_reg_bit = GPIO2_CLK_ENB,
+       .recalc = &follow_parent,
+};
+
+/* array of all spear 6xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+       /* root clks */
+       { .con_id = "osc_32k_clk",      .clk = &osc_32k_clk},
+       { .con_id = "osc_30m_clk",      .clk = &osc_30m_clk},
+       /* clock derived from 32 KHz os          clk */
+       { .dev_id = "rtc",              .clk = &rtc_clk},
+       /* clock derived from 30 MHz os          clk */
+       { .con_id = "pll1_clk",         .clk = &pll1_clk},
+       { .con_id = "pll3_48m_clk",     .clk = &pll3_48m_clk},
+       { .dev_id = "wdt",              .clk = &wdt_clk},
+       /* clock derived from pll1 clk */
+       { .con_id = "cpu_clk",          .clk = &cpu_clk},
+       { .con_id = "ahb_clk",          .clk = &ahb_clk},
+       { .dev_id = "uart0",            .clk = &uart0_clk},
+       { .dev_id = "uart1",            .clk = &uart1_clk},
+       { .dev_id = "firda",            .clk = &firda_clk},
+       { .dev_id = "clcd",             .clk = &clcd_clk},
+       { .dev_id = "gpt0",             .clk = &gpt0_clk},
+       { .dev_id = "gpt1",             .clk = &gpt1_clk},
+       { .dev_id = "gpt2",             .clk = &gpt2_clk},
+       { .dev_id = "gpt3",             .clk = &gpt3_clk},
+       /* clock derived from pll3 clk */
+       { .dev_id = "usbh0",            .clk = &usbh0_clk},
+       { .dev_id = "usbh1",            .clk = &usbh1_clk},
+       { .dev_id = "usbd",             .clk = &usbd_clk},
+       /* clock derived from ahb clk */
+       { .con_id = "apb_clk",          .clk = &apb_clk},
+       { .dev_id = "i2c",              .clk = &i2c_clk},
+       { .dev_id = "dma",              .clk = &dma_clk},
+       { .dev_id = "jpeg",             .clk = &jpeg_clk},
+       { .dev_id = "gmac",             .clk = &gmac_clk},
+       { .dev_id = "smi",              .clk = &smi_clk},
+       { .dev_id = "fsmc",             .clk = &fsmc_clk},
+       /* clock derived from apb clk */
+       { .dev_id = "adc",              .clk = &adc_clk},
+       { .dev_id = "ssp0",             .clk = &ssp0_clk},
+       { .dev_id = "ssp1",             .clk = &ssp1_clk},
+       { .dev_id = "ssp2",             .clk = &ssp2_clk},
+       { .dev_id = "gpio0",            .clk = &gpio0_clk},
+       { .dev_id = "gpio1",            .clk = &gpio1_clk},
+       { .dev_id = "gpio2",            .clk = &gpio2_clk},
+};
+
+void __init clk_init(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+               clk_register(&spear_clk_lookups[i]);
+
+       recalc_root_clocks();
+}
diff --git a/arch/arm/mach-spear6xx/include/mach/clkdev.h b/arch/arm/mach-spear6xx/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..05676bf
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/debug-macro.S b/arch/arm/mach-spear6xx/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..0f3ea39
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear6xx/include/mach/entry-macro.S b/arch/arm/mach-spear6xx/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..9eaecae
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/spear.h>
+#include <asm/hardware/vic.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, =VA_SPEAR6XX_CPU_VIC_PRI_BASE
+               ldr     \irqstat, [\base, #VIC_IRQ_STATUS]      @ get status
+               mov     \irqnr, #0
+               teq     \irqstat, #0
+               bne     1001f
+               ldr     \base, =VA_SPEAR6XX_CPU_VIC_SEC_BASE
+               ldr     \irqstat, [\base, #VIC_IRQ_STATUS]      @ get status
+               teq     \irqstat, #0
+               beq     1002f                           @ this will set/reset
+                                                       @ zero register
+               mov     \irqnr, #32
+1001:
+               /*
+                * Following code will find bit position of least significang
+                * bit set in irqstat, using following equation
+                * least significant bit set in n = (n & ~(n-1))
+                */
+               sub     \tmp, \irqstat, #1              @ tmp = irqstat - 1
+               mvn     \tmp, \tmp                      @ tmp = ~tmp
+               and     \irqstat, \irqstat, \tmp        @ irqstat &= tmp
+               /* Now, irqstat is = bit no. of 1st bit set in vic irq status */
+               clz     \tmp, \irqstat                  @ tmp = leading zeros
+
+               rsb     \tmp, \tmp, #0x1F               @ tmp = 32 - tmp - 1
+               add     \irqnr, \irqnr, \tmp
+
+1002:          /* EQ will be set if no irqs pending */
+               .endm
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
new file mode 100644 (file)
index 0000000..16205a5
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/generic.h
+ *
+ * SPEAr6XX machine family specific generic header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE                SPEAR6XX_CPU_TMR_BASE
+#define SPEAR_GPT0_CHAN0_IRQ   IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ   IRQ_CPU_GPT1_2
+
+/* Add spear6xx family device structure declarations here */
+extern struct amba_device gpio_device[];
+extern struct amba_device uart_device[];
+extern struct sys_timer spear_sys_timer;
+
+/* Add spear6xx family function declarations here */
+void __init spear6xx_map_io(void);
+void __init spear6xx_init_irq(void);
+void __init spear6xx_init(void);
+void __init spear600_init(void);
+void __init clk_init(void);
+
+/* Add spear600 machine device structure declarations here */
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..3a789db
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/hardware.h b/arch/arm/mach-spear6xx/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..7545116
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/hardware.h
+ *
+ * Hardware definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x)          (x | 0xF0000000)
+
+#endif /* __MACH_HARDWARE_H */
+
diff --git a/arch/arm/mach-spear6xx/include/mach/io.h b/arch/arm/mach-spear6xx/include/mach/io.h
new file mode 100644 (file)
index 0000000..fb7c106
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/io.h
+ *
+ * IO definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif /* __MACH_IO_H */
+
diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..8f214b0
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+/* IRQ definitions */
+/* VIC 1 */
+#define IRQ_INTRCOMM_SW_IRQ                    0
+#define IRQ_INTRCOMM_CPU_1                     1
+#define IRQ_INTRCOMM_CPU_2                     2
+#define IRQ_INTRCOMM_RAS2A11_1                 3
+#define IRQ_INTRCOMM_RAS2A11_2                 4
+#define IRQ_INTRCOMM_RAS2A12_1                 5
+#define IRQ_INTRCOMM_RAS2A12_2                 6
+#define IRQ_GEN_RAS_0                          7
+#define IRQ_GEN_RAS_1                          8
+#define IRQ_GEN_RAS_2                          9
+#define IRQ_GEN_RAS_3                          10
+#define IRQ_GEN_RAS_4                          11
+#define IRQ_GEN_RAS_5                          12
+#define IRQ_GEN_RAS_6                          13
+#define IRQ_GEN_RAS_7                          14
+#define IRQ_GEN_RAS_8                          15
+#define IRQ_CPU_GPT1_1                         16
+#define IRQ_CPU_GPT1_2                         17
+#define IRQ_LOCAL_GPIO                         18
+#define IRQ_PLL_UNLOCK                         19
+#define IRQ_JPEG                               20
+#define IRQ_FSMC                               21
+#define IRQ_IRDA                               22
+#define IRQ_RESERVED                           23
+#define IRQ_UART_0                             24
+#define IRQ_UART_1                             25
+#define IRQ_SSP_1                              26
+#define IRQ_SSP_2                              27
+#define IRQ_I2C                                        28
+#define IRQ_GEN_RAS_9                          29
+#define IRQ_GEN_RAS_10                         30
+#define IRQ_GEN_RAS_11                         31
+
+/* VIC 2 */
+#define IRQ_APPL_GPT1_1                                32
+#define IRQ_APPL_GPT1_2                                33
+#define IRQ_APPL_GPT2_1                                34
+#define IRQ_APPL_GPT2_2                                35
+#define IRQ_APPL_GPIO                          36
+#define IRQ_APPL_SSP                           37
+#define IRQ_APPL_ADC                           38
+#define IRQ_APPL_RESERVED                      39
+#define IRQ_AHB_EXP_MASTER                     40
+#define IRQ_DDR_CONTROLLER                     41
+#define IRQ_BASIC_DMA                          42
+#define IRQ_BASIC_RESERVED1                    43
+#define IRQ_BASIC_SMI                          44
+#define IRQ_BASIC_CLCD                         45
+#define IRQ_EXP_AHB_1                          46
+#define IRQ_EXP_AHB_2                          47
+#define IRQ_BASIC_GPT1_1                       48
+#define IRQ_BASIC_GPT1_2                       49
+#define IRQ_BASIC_RTC                          50
+#define IRQ_BASIC_GPIO                         51
+#define IRQ_BASIC_WDT                          52
+#define IRQ_BASIC_RESERVED                     53
+#define IRQ_AHB_EXP_SLAVE                      54
+#define IRQ_GMAC_1                             55
+#define IRQ_GMAC_2                             56
+#define IRQ_USB_DEV                            57
+#define IRQ_USB_H_OHCI_0                       58
+#define IRQ_USB_H_EHCI_0                       59
+#define IRQ_USB_H_OHCI_1                       60
+#define IRQ_USB_H_EHCI_1                       61
+#define IRQ_EXP_AHB_3                          62
+#define IRQ_EXP_AHB_4                          63
+
+#define IRQ_VIC_END                            64
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE    IRQ_VIC_END
+#define SPEAR_GPIO0_INT_BASE   SPEAR_GPIO_INT_BASE
+#define SPEAR_GPIO1_INT_BASE   (SPEAR_GPIO0_INT_BASE + 8)
+#define SPEAR_GPIO2_INT_BASE   (SPEAR_GPIO1_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END     (SPEAR_GPIO2_INT_BASE + 8)
+#define VIRTUAL_IRQS           (SPEAR_GPIO_INT_END - IRQ_VIC_END)
+#define NR_IRQS                        (IRQ_VIC_END + VIRTUAL_IRQS)
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/memory.h b/arch/arm/mach-spear6xx/include/mach/memory.h
new file mode 100644 (file)
index 0000000..781f088
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/memory.h
+ *
+ * Memory map for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
new file mode 100644 (file)
index 0000000..0390803
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/spear.h>
+
+#define MISC_BASE              VA_SPEAR6XX_ICM3_MISC_REG_BASE
+
+#define SOC_CFG_CTR            ((unsigned int *)(MISC_BASE + 0x000))
+#define DIAG_CFG_CTR           ((unsigned int *)(MISC_BASE + 0x004))
+#define PLL1_CTR               ((unsigned int *)(MISC_BASE + 0x008))
+#define PLL1_FRQ               ((unsigned int *)(MISC_BASE + 0x00C))
+#define PLL1_MOD               ((unsigned int *)(MISC_BASE + 0x010))
+#define PLL2_CTR               ((unsigned int *)(MISC_BASE + 0x014))
+/* PLL_CTR register masks */
+#define PLL_ENABLE             2
+#define PLL_MODE_SHIFT         4
+#define PLL_MODE_MASK          0x3
+#define PLL_MODE_NORMAL                0
+#define PLL_MODE_FRACTION      1
+#define PLL_MODE_DITH_DSB      2
+#define PLL_MODE_DITH_SSB      3
+
+#define PLL2_FRQ               ((unsigned int *)(MISC_BASE + 0x018))
+/* PLL FRQ register masks */
+#define PLL_DIV_N_SHIFT                0
+#define PLL_DIV_N_MASK         0xFF
+#define PLL_DIV_P_SHIFT                8
+#define PLL_DIV_P_MASK         0x7
+#define PLL_NORM_FDBK_M_SHIFT  24
+#define PLL_NORM_FDBK_M_MASK   0xFF
+#define PLL_DITH_FDBK_M_SHIFT  16
+#define PLL_DITH_FDBK_M_MASK   0xFFFF
+
+#define PLL2_MOD               ((unsigned int *)(MISC_BASE + 0x01C))
+#define PLL_CLK_CFG            ((unsigned int *)(MISC_BASE + 0x020))
+#define CORE_CLK_CFG           ((unsigned int *)(MISC_BASE + 0x024))
+/* CORE CLK CFG register masks */
+#define PLL_HCLK_RATIO_SHIFT   10
+#define PLL_HCLK_RATIO_MASK    0x3
+#define HCLK_PCLK_RATIO_SHIFT  8
+#define HCLK_PCLK_RATIO_MASK   0x3
+
+#define PERIP_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x028))
+/* PERIP_CLK_CFG register masks */
+#define CLCD_CLK_SHIFT         2
+#define CLCD_CLK_MASK          0x3
+#define UART_CLK_SHIFT         4
+#define UART_CLK_MASK          0x1
+#define FIRDA_CLK_SHIFT                5
+#define FIRDA_CLK_MASK         0x3
+#define GPT0_CLK_SHIFT         8
+#define GPT1_CLK_SHIFT         10
+#define GPT2_CLK_SHIFT         11
+#define GPT3_CLK_SHIFT         12
+#define GPT_CLK_MASK           0x1
+#define AUX_CLK_PLL3_MASK      0
+#define AUX_CLK_PLL1_MASK      1
+
+#define PERIP1_CLK_ENB         ((unsigned int *)(MISC_BASE + 0x02C))
+/* PERIP1_CLK_ENB register masks */
+#define UART0_CLK_ENB          3
+#define UART1_CLK_ENB          4
+#define SSP0_CLK_ENB           5
+#define SSP1_CLK_ENB           6
+#define I2C_CLK_ENB            7
+#define JPEG_CLK_ENB           8
+#define FSMC_CLK_ENB           9
+#define FIRDA_CLK_ENB          10
+#define GPT2_CLK_ENB           11
+#define GPT3_CLK_ENB           12
+#define GPIO2_CLK_ENB          13
+#define SSP2_CLK_ENB           14
+#define ADC_CLK_ENB            15
+#define GPT1_CLK_ENB           11
+#define RTC_CLK_ENB            17
+#define GPIO1_CLK_ENB          18
+#define DMA_CLK_ENB            19
+#define SMI_CLK_ENB            21
+#define CLCD_CLK_ENB           22
+#define GMAC_CLK_ENB           23
+#define USBD_CLK_ENB           24
+#define USBH0_CLK_ENB          25
+#define USBH1_CLK_ENB          26
+
+#define SOC_CORE_ID            ((unsigned int *)(MISC_BASE + 0x030))
+#define RAS_CLK_ENB            ((unsigned int *)(MISC_BASE + 0x034))
+#define PERIP1_SOF_RST         ((unsigned int *)(MISC_BASE + 0x038))
+/* PERIP1_SOF_RST register masks */
+#define JPEG_SOF_RST           8
+
+#define SOC_USER_ID            ((unsigned int *)(MISC_BASE + 0x03C))
+#define RAS_SOF_RST            ((unsigned int *)(MISC_BASE + 0x040))
+#define PRSC1_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x044))
+#define PRSC2_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x048))
+#define PRSC3_CLK_CFG          ((unsigned int *)(MISC_BASE + 0x04C))
+/* gpt synthesizer register masks */
+#define GPT_MSCALE_SHIFT       0
+#define GPT_MSCALE_MASK                0xFFF
+#define GPT_NSCALE_SHIFT       12
+#define GPT_NSCALE_MASK                0xF
+
+#define AMEM_CLK_CFG           ((unsigned int *)(MISC_BASE + 0x050))
+#define EXPI_CLK_CFG           ((unsigned int *)(MISC_BASE + 0x054))
+#define CLCD_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x05C))
+#define FIRDA_CLK_SYNT         ((unsigned int *)(MISC_BASE + 0x060))
+#define UART_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x064))
+#define GMAC_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x068))
+#define RAS1_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x06C))
+#define RAS2_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x070))
+#define RAS3_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x074))
+#define RAS4_CLK_SYNT          ((unsigned int *)(MISC_BASE + 0x078))
+/* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_EQ_SEL_SHIFT       30
+#define AUX_EQ_SEL_MASK                1
+#define AUX_EQ1_SEL            0
+#define AUX_EQ2_SEL            1
+#define AUX_XSCALE_SHIFT       16
+#define AUX_XSCALE_MASK                0xFFF
+#define AUX_YSCALE_SHIFT       0
+#define AUX_YSCALE_MASK                0xFFF
+
+#define ICM1_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x07C))
+#define ICM2_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x080))
+#define ICM3_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x084))
+#define ICM4_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x088))
+#define ICM5_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x08C))
+#define ICM6_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x090))
+#define ICM7_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x094))
+#define ICM8_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x098))
+#define ICM9_ARB_CFG           ((unsigned int *)(MISC_BASE + 0x09C))
+#define DMA_CHN_CFG            ((unsigned int *)(MISC_BASE + 0x0A0))
+#define USB2_PHY_CFG           ((unsigned int *)(MISC_BASE + 0x0A4))
+#define GMAC_CFG_CTR           ((unsigned int *)(MISC_BASE + 0x0A8))
+#define EXPI_CFG_CTR           ((unsigned int *)(MISC_BASE + 0x0AC))
+#define PRC1_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0C0))
+#define PRC2_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0C4))
+#define PRC3_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0C8))
+#define PRC4_LOCK_CTR          ((unsigned int *)(MISC_BASE + 0x0CC))
+#define PRC1_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0D0))
+#define PRC2_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0D4))
+#define PRC3_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0D8))
+#define PRC4_IRQ_CTR           ((unsigned int *)(MISC_BASE + 0x0DC))
+#define PWRDOWN_CFG_CTR                ((unsigned int *)(MISC_BASE + 0x0E0))
+#define COMPSSTL_1V8_CFG       ((unsigned int *)(MISC_BASE + 0x0E4))
+#define COMPSSTL_2V5_CFG       ((unsigned int *)(MISC_BASE + 0x0E8))
+#define COMPCOR_3V3_CFG                ((unsigned int *)(MISC_BASE + 0x0EC))
+#define SSTLPAD_CFG_CTR                ((unsigned int *)(MISC_BASE + 0x0F0))
+#define BIST1_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x0F4))
+#define BIST2_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x0F8))
+#define BIST3_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x0FC))
+#define BIST4_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x100))
+#define BIST5_CFG_CTR          ((unsigned int *)(MISC_BASE + 0x104))
+#define BIST1_STS_RES          ((unsigned int *)(MISC_BASE + 0x108))
+#define BIST2_STS_RES          ((unsigned int *)(MISC_BASE + 0x10C))
+#define BIST3_STS_RES          ((unsigned int *)(MISC_BASE + 0x110))
+#define BIST4_STS_RES          ((unsigned int *)(MISC_BASE + 0x114))
+#define BIST5_STS_RES          ((unsigned int *)(MISC_BASE + 0x118))
+#define SYSERR_CFG_CTR         ((unsigned int *)(MISC_BASE + 0x11C))
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
new file mode 100644 (file)
index 0000000..a835f5b
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/spear.h
+ *
+ * SPEAr6xx Machine family specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPEAR6XX_H
+#define __MACH_SPEAR6XX_H
+
+#include <mach/hardware.h>
+#include <mach/spear600.h>
+
+#define SPEAR6XX_ML_SDRAM_BASE         0x00000000
+#define SPEAR6XX_ML_SDRAM_SIZE         0x40000000
+
+/* ICM1 - Low speed connection */
+#define SPEAR6XX_ICM1_BASE             0xD0000000
+#define SPEAR6XX_ICM1_SIZE             0x08000000
+
+#define SPEAR6XX_ICM1_UART0_BASE       0xD0000000
+#define VA_SPEAR6XX_ICM1_UART0_BASE    IO_ADDRESS(SPEAR6XX_ICM1_UART0_BASE)
+#define SPEAR6XX_ICM1_UART0_SIZE       0x00080000
+
+#define SPEAR6XX_ICM1_UART1_BASE       0xD0080000
+#define SPEAR6XX_ICM1_UART1_SIZE       0x00080000
+
+#define SPEAR6XX_ICM1_SSP0_BASE                0xD0100000
+#define SPEAR6XX_ICM1_SSP0_SIZE                0x00080000
+
+#define SPEAR6XX_ICM1_SSP1_BASE                0xD0180000
+#define SPEAR6XX_ICM1_SSP1_SIZE                0x00080000
+
+#define SPEAR6XX_ICM1_I2C_BASE         0xD0200000
+#define SPEAR6XX_ICM1_I2C_SIZE         0x00080000
+
+#define SPEAR6XX_ICM1_JPEG_BASE                0xD0800000
+#define SPEAR6XX_ICM1_JPEG_SIZE                0x00800000
+
+#define SPEAR6XX_ICM1_IRDA_BASE                0xD1000000
+#define SPEAR6XX_ICM1_IRDA_SIZE                0x00800000
+
+#define SPEAR6XX_ICM1_FSMC_BASE                0xD1800000
+#define SPEAR6XX_ICM1_FSMC_SIZE                0x00800000
+
+#define SPEAR6XX_ICM1_NAND_BASE                0xD2000000
+#define SPEAR6XX_ICM1_NAND_SIZE                0x00800000
+
+#define SPEAR6XX_ICM1_SRAM_BASE                0xD2800000
+#define SPEAR6XX_ICM1_SRAM_SIZE                0x00800000
+
+/* ICM2 - Application Subsystem */
+#define SPEAR6XX_ICM2_BASE             0xD8000000
+#define SPEAR6XX_ICM2_SIZE             0x08000000
+
+#define SPEAR6XX_ICM2_TMR0_BASE                0xD8000000
+#define SPEAR6XX_ICM2_TMR0_SIZE                0x00080000
+
+#define SPEAR6XX_ICM2_TMR1_BASE                0xD8080000
+#define SPEAR6XX_ICM2_TMR1_SIZE                0x00080000
+
+#define SPEAR6XX_ICM2_GPIO_BASE                0xD8100000
+#define SPEAR6XX_ICM2_GPIO_SIZE                0x00080000
+
+#define SPEAR6XX_ICM2_SPI2_BASE                0xD8180000
+#define SPEAR6XX_ICM2_SPI2_SIZE                0x00080000
+
+#define SPEAR6XX_ICM2_ADC_BASE         0xD8200000
+#define SPEAR6XX_ICM2_ADC_SIZE         0x00080000
+
+/* ML-1, 2 - Multi Layer CPU Subsystem */
+#define SPEAR6XX_ML_CPU_BASE           0xF0000000
+#define SPEAR6XX_ML_CPU_SIZE           0x08000000
+
+#define SPEAR6XX_CPU_TMR_BASE          0xF0000000
+#define SPEAR6XX_CPU_TMR_SIZE          0x00100000
+
+#define SPEAR6XX_CPU_GPIO_BASE         0xF0100000
+#define SPEAR6XX_CPU_GPIO_SIZE         0x00100000
+
+#define SPEAR6XX_CPU_VIC_SEC_BASE      0xF1000000
+#define VA_SPEAR6XX_CPU_VIC_SEC_BASE   IO_ADDRESS(SPEAR6XX_CPU_VIC_SEC_BASE)
+#define SPEAR6XX_CPU_VIC_SEC_SIZE      0x00100000
+
+#define SPEAR6XX_CPU_VIC_PRI_BASE      0xF1100000
+#define VA_SPEAR6XX_CPU_VIC_PRI_BASE   IO_ADDRESS(SPEAR6XX_CPU_VIC_PRI_BASE)
+#define SPEAR6XX_CPU_VIC_PRI_SIZE      0x00100000
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR6XX_ICM3_BASE             0xF8000000
+#define SPEAR6XX_ICM3_SIZE             0x08000000
+
+#define SPEAR6XX_ICM3_SMEM_BASE                0xF8000000
+#define SPEAR6XX_ICM3_SMEM_SIZE                0x04000000
+
+#define SPEAR6XX_ICM3_SMI_CTRL_BASE    0xFC000000
+#define SPEAR6XX_ICM3_SMI_CTRL_SIZE    0x00200000
+
+#define SPEAR6XX_ICM3_CLCD_BASE                0xFC200000
+#define SPEAR6XX_ICM3_CLCD_SIZE                0x00200000
+
+#define SPEAR6XX_ICM3_DMA_BASE         0xFC400000
+#define SPEAR6XX_ICM3_DMA_SIZE         0x00200000
+
+#define SPEAR6XX_ICM3_SDRAM_CTRL_BASE  0xFC600000
+#define SPEAR6XX_ICM3_SDRAM_CTRL_SIZE  0x00200000
+
+#define SPEAR6XX_ICM3_TMR_BASE         0xFC800000
+#define SPEAR6XX_ICM3_TMR_SIZE         0x00080000
+
+#define SPEAR6XX_ICM3_WDT_BASE         0xFC880000
+#define SPEAR6XX_ICM3_WDT_SIZE         0x00080000
+
+#define SPEAR6XX_ICM3_RTC_BASE         0xFC900000
+#define SPEAR6XX_ICM3_RTC_SIZE         0x00080000
+
+#define SPEAR6XX_ICM3_GPIO_BASE                0xFC980000
+#define SPEAR6XX_ICM3_GPIO_SIZE                0x00080000
+
+#define SPEAR6XX_ICM3_SYS_CTRL_BASE    0xFCA00000
+#define VA_SPEAR6XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR6XX_ICM3_SYS_CTRL_BASE)
+#define SPEAR6XX_ICM3_SYS_CTRL_SIZE    0x00080000
+
+#define SPEAR6XX_ICM3_MISC_REG_BASE    0xFCA80000
+#define VA_SPEAR6XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR6XX_ICM3_MISC_REG_BASE)
+#define SPEAR6XX_ICM3_MISC_REG_SIZE    0x00080000
+
+/* ICM4 - High Speed Connection */
+#define SPEAR6XX_ICM4_BASE             0xE0000000
+#define SPEAR6XX_ICM4_SIZE             0x08000000
+
+#define SPEAR6XX_ICM4_GMAC_BASE                0xE0800000
+#define SPEAR6XX_ICM4_GMAC_SIZE                0x00800000
+
+#define SPEAR6XX_ICM4_USBD_FIFO_BASE   0xE1000000
+#define SPEAR6XX_ICM4_USBD_FIFO_SIZE   0x00100000
+
+#define SPEAR6XX_ICM4_USBD_CSR_BASE    0xE1100000
+#define SPEAR6XX_ICM4_USBD_CSR_SIZE    0x00100000
+
+#define SPEAR6XX_ICM4_USBD_PLDT_BASE   0xE1200000
+#define SPEAR6XX_ICM4_USBD_PLDT_SIZE   0x00100000
+
+#define SPEAR6XX_ICM4_USB_EHCI0_BASE   0xE1800000
+#define SPEAR6XX_ICM4_USB_EHCI0_SIZE   0x00100000
+
+#define SPEAR6XX_ICM4_USB_OHCI0_BASE   0xE1900000
+#define SPEAR6XX_ICM4_USB_OHCI0_SIZE   0x00100000
+
+#define SPEAR6XX_ICM4_USB_EHCI1_BASE   0xE2000000
+#define SPEAR6XX_ICM4_USB_EHCI1_SIZE   0x00100000
+
+#define SPEAR6XX_ICM4_USB_OHCI1_BASE   0xE2100000
+#define SPEAR6XX_ICM4_USB_OHCI1_SIZE   0x00100000
+
+#define SPEAR6XX_ICM4_USB_ARB_BASE     0xE2800000
+#define SPEAR6XX_ICM4_USB_ARB_SIZE     0x00010000
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE            SPEAR6XX_ICM1_UART0_BASE
+#define VA_SPEAR_DBG_UART_BASE         VA_SPEAR6XX_ICM1_UART0_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE            SPEAR6XX_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE         VA_SPEAR6XX_ICM3_SYS_CTRL_BASE
+
+#endif /* __MACH_SPEAR6XX_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/spear600.h b/arch/arm/mach-spear6xx/include/mach/spear600.h
new file mode 100644 (file)
index 0000000..c068cc5
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-spear66xx/include/mach/spear600.h
+ *
+ * SPEAr600 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR600
+
+#ifndef __MACH_SPEAR600_H
+#define __MACH_SPEAR600_H
+
+#endif /* __MACH_SPEAR600_H */
+
+#endif /* CONFIG_MACH_SPEAR600 */
diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h
new file mode 100644 (file)
index 0000000..0b1d2be
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/system.h
+ *
+ * SPEAr6xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <plat/system.h>
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/timex.h b/arch/arm/mach-spear6xx/include/mach/timex.h
new file mode 100644 (file)
index 0000000..ac1c5b0
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/timex.h
+ *
+ * SPEAr6XX machine family specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/uncompress.h b/arch/arm/mach-spear6xx/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..77f0765
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/vmalloc.h b/arch/arm/mach-spear6xx/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..4a0b56c
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif /* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear6xx/spear600.c b/arch/arm/mach-spear6xx/spear600.c
new file mode 100644 (file)
index 0000000..5c484c4
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-spear6xx/spear600.c
+ *
+ * SPEAr600 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear600 specific devices here */
+
+void __init spear600_init(void)
+{
+       /* call spear6xx family common init function */
+       spear6xx_init();
+}
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
new file mode 100644 (file)
index 0000000..daff8d0
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-spear6xx/spear600_evb.c
+ *
+ * SPEAr600 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+static struct amba_device *amba_devs[] __initdata = {
+       &gpio_device[0],
+       &gpio_device[1],
+       &gpio_device[2],
+       &uart_device[0],
+       &uart_device[1],
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+};
+
+static void __init spear600_evb_init(void)
+{
+       unsigned int i;
+
+       /* call spear600 machine init function */
+       spear600_init();
+
+       /* Add Platform Devices */
+       platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+       /* Add Amba Devices */
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+               amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
+       .boot_params    =       0x00000100,
+       .map_io         =       spear6xx_map_io,
+       .init_irq       =       spear6xx_init_irq,
+       .timer          =       &spear_sys_timer,
+       .init_machine   =       spear600_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
new file mode 100644 (file)
index 0000000..b67e571
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * arch/arm/mach-spear6xx/spear6xx.c
+ *
+ * SPEAr6XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+#include <mach/generic.h>
+#include <mach/spear.h>
+
+/* Add spear6xx machines common devices here */
+/* uart device registeration */
+struct amba_device uart_device[] = {
+       {
+               .dev = {
+                       .init_name = "uart0",
+               },
+               .res = {
+                       .start = SPEAR6XX_ICM1_UART0_BASE,
+                       .end = SPEAR6XX_ICM1_UART0_BASE +
+                               SPEAR6XX_ICM1_UART0_SIZE - 1,
+                       .flags = IORESOURCE_MEM,
+               },
+               .irq = {IRQ_UART_0, NO_IRQ},
+       }, {
+               .dev = {
+                       .init_name = "uart1",
+               },
+               .res = {
+                       .start = SPEAR6XX_ICM1_UART1_BASE,
+                       .end = SPEAR6XX_ICM1_UART1_BASE +
+                               SPEAR6XX_ICM1_UART1_SIZE - 1,
+                       .flags = IORESOURCE_MEM,
+               },
+               .irq = {IRQ_UART_1, NO_IRQ},
+       }
+};
+
+/* gpio device registeration */
+static struct pl061_platform_data gpio_plat_data[] = {
+       {
+               .gpio_base      = 0,
+               .irq_base       = SPEAR_GPIO0_INT_BASE,
+       }, {
+               .gpio_base      = 8,
+               .irq_base       = SPEAR_GPIO1_INT_BASE,
+       }, {
+               .gpio_base      = 16,
+               .irq_base       = SPEAR_GPIO2_INT_BASE,
+       },
+};
+
+struct amba_device gpio_device[] = {
+       {
+               .dev = {
+                       .init_name = "gpio0",
+                       .platform_data = &gpio_plat_data[0],
+               },
+               .res = {
+                       .start = SPEAR6XX_CPU_GPIO_BASE,
+                       .end = SPEAR6XX_CPU_GPIO_BASE +
+                               SPEAR6XX_CPU_GPIO_SIZE - 1,
+                       .flags = IORESOURCE_MEM,
+               },
+               .irq = {IRQ_LOCAL_GPIO, NO_IRQ},
+       }, {
+               .dev = {
+                       .init_name = "gpio1",
+                       .platform_data = &gpio_plat_data[1],
+               },
+               .res = {
+                       .start = SPEAR6XX_ICM3_GPIO_BASE,
+                       .end = SPEAR6XX_ICM3_GPIO_BASE +
+                               SPEAR6XX_ICM3_GPIO_SIZE - 1,
+                       .flags = IORESOURCE_MEM,
+               },
+               .irq = {IRQ_BASIC_GPIO, NO_IRQ},
+       }, {
+               .dev = {
+                       .init_name = "gpio2",
+                       .platform_data = &gpio_plat_data[2],
+               },
+               .res = {
+                       .start = SPEAR6XX_ICM2_GPIO_BASE,
+                       .end = SPEAR6XX_ICM2_GPIO_BASE +
+                               SPEAR6XX_ICM2_GPIO_SIZE - 1,
+                       .flags = IORESOURCE_MEM,
+               },
+               .irq = {IRQ_APPL_GPIO, NO_IRQ},
+       }
+};
+
+/* This will add devices, and do machine specific tasks */
+void __init spear6xx_init(void)
+{
+       /* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear6xx_init_irq(void)
+{
+       vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0);
+       vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0);
+}
+
+/* Following will create static virtual/physical mappings */
+static struct map_desc spear6xx_io_desc[] __initdata = {
+       {
+               .virtual        = VA_SPEAR6XX_ICM1_UART0_BASE,
+               .pfn            = __phys_to_pfn(SPEAR6XX_ICM1_UART0_BASE),
+               .length         = SPEAR6XX_ICM1_UART0_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR6XX_CPU_VIC_PRI_BASE,
+               .pfn            = __phys_to_pfn(SPEAR6XX_CPU_VIC_PRI_BASE),
+               .length         = SPEAR6XX_CPU_VIC_PRI_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR6XX_CPU_VIC_SEC_BASE,
+               .pfn            = __phys_to_pfn(SPEAR6XX_CPU_VIC_SEC_BASE),
+               .length         = SPEAR6XX_CPU_VIC_SEC_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR6XX_ICM3_SYS_CTRL_BASE,
+               .pfn            = __phys_to_pfn(SPEAR6XX_ICM3_SYS_CTRL_BASE),
+               .length         = SPEAR6XX_ICM3_MISC_REG_BASE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = VA_SPEAR6XX_ICM3_MISC_REG_BASE,
+               .pfn            = __phys_to_pfn(SPEAR6XX_ICM3_MISC_REG_BASE),
+               .length         = SPEAR6XX_ICM3_MISC_REG_SIZE,
+               .type           = MT_DEVICE
+       },
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear6xx_map_io(void)
+{
+       iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
+
+       /* This will initialize clock framework */
+       clk_init();
+}
index 77fbb1e..88506d0 100644 (file)
@@ -102,11 +102,12 @@ int __devinit mmc_init(struct amba_device *adev)
         * we have a regulator we can control instead.
         */
        /* Nominally 2.85V on our platform */
+       mmci_card->mmc0_plat_data.f_max = 24000000;
        mmci_card->mmc0_plat_data.status = mmc_status;
        mmci_card->mmc0_plat_data.gpio_wp = -1;
        mmci_card->mmc0_plat_data.gpio_cd = -1;
        mmci_card->mmc0_plat_data.capabilities = MMC_CAP_MMC_HIGHSPEED |
-               MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA;
+               MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
 
        mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data;
 
index 03625d7..6625e5b 100644 (file)
@@ -1,15 +1,42 @@
-menu "ST-Ericsson platform type"
-       depends on ARCH_U8500
+if ARCH_U8500
 
-comment "ST-Ericsson Multicore Mobile Platforms"
-
-config MACH_U8500_MOP
-       bool "U8500 Early Development platform"
+config UX500_SOC_COMMON
+       bool
        default y
        select ARM_GIC
        select HAS_MTU
+       select NOMADIK_GPIO
+
+config UX500_SOC_DB8500
+       bool
+
+config UX500_SOC_DB5500
+       bool
+
+choice
+       prompt "Ux500 target platform"
+       default MACH_U8500_MOP
+
+config MACH_U8500_MOP
+       bool "U8500 Development platform"
+       select UX500_SOC_DB8500
        help
          Include support for mop500 development platform
          based on U8500 architecture. The platform is based
          on early drop silicon version of 8500.
-endmenu
+
+config MACH_U5500
+       bool "U5500 Development platform"
+       select UX500_SOC_DB5500
+       help
+         Include support for the U5500 development platform.
+endchoice
+
+config UX500_DEBUG_UART
+       int "Ux500 UART to use for low-level debug"
+       default 2
+       help
+         Choose the UART on which kernel low-level debug messages should be
+         output.
+
+endif
index 95e6e24..c7bc419 100644 (file)
@@ -2,7 +2,9 @@
 # Makefile for the linux kernel, U8500 machine.
 #
 
-obj-y                          := clock.o
-obj-$(CONFIG_ARCH_U8500)       += cpu-u8500.o
+obj-y                          := clock.o cpu.o devices.o
+obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o
+obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
 obj-$(CONFIG_MACH_U8500_MOP)   += board-mop500.o
+obj-$(CONFIG_MACH_U5500)       += board-u5500.o
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o localtimer.o
index 803aec1..072196c 100644 (file)
 #include <linux/amba/pl022.h>
 #include <linux/spi/spi.h>
 
-#include <asm/localtimer.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <plat/mtu.h>
 #include <plat/i2c.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
-
-#define __MEM_4K_RESOURCE(x) \
-       .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
-
-/* These are active devices on this board */
-static struct amba_device uart0_device = {
-       .dev = { .init_name = "uart0" },
-       __MEM_4K_RESOURCE(U8500_UART0_BASE),
-       .irq = {IRQ_UART0, NO_IRQ},
-};
-
-static struct amba_device uart1_device = {
-       .dev = { .init_name = "uart1" },
-       __MEM_4K_RESOURCE(U8500_UART1_BASE),
-       .irq = {IRQ_UART1, NO_IRQ},
-};
-
-static struct amba_device uart2_device = {
-       .dev = { .init_name = "uart2" },
-       __MEM_4K_RESOURCE(U8500_UART2_BASE),
-       .irq = {IRQ_UART2, NO_IRQ},
-};
+#include <mach/devices.h>
 
 static void ab4500_spi_cs_control(u32 command)
 {
@@ -93,55 +70,8 @@ static struct pl022_ssp_controller ssp0_platform_data = {
        .num_chipselect = 5,
 };
 
-static struct amba_device pl022_device = {
-       .dev = {
-               .coherent_dma_mask = ~0,
-               .init_name = "pl022",
-               .platform_data = &ssp0_platform_data,
-       },
-       .res = {
-               .start = U8500_SSP0_BASE,
-               .end   = U8500_SSP0_BASE + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       .irq = {IRQ_SSP0, NO_IRQ },
-       /* ST-Ericsson modified id */
-       .periphid = SSP_PER_ID,
-};
-
-static struct amba_device pl031_device = {
-       .dev = {
-               .init_name = "pl031",
-       },
-       .res = {
-               .start = U8500_RTC_BASE,
-               .end = U8500_RTC_BASE + SZ_4K - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       .irq = {IRQ_RTC_RTT, NO_IRQ},
-};
-
-#define U8500_I2C_RESOURCES(id, size)          \
-static struct resource u8500_i2c_resources_##id[] = {  \
-       [0] = {                                 \
-               .start  = U8500_I2C##id##_BASE, \
-               .end    = U8500_I2C##id##_BASE + size - 1, \
-               .flags  = IORESOURCE_MEM,       \
-       },                                      \
-       [1] = {                                 \
-               .start  = IRQ_I2C##id,          \
-               .end    = IRQ_I2C##id,          \
-               .flags  = IORESOURCE_IRQ        \
-       }                                       \
-}
-
-U8500_I2C_RESOURCES(0, SZ_4K);
-U8500_I2C_RESOURCES(1, SZ_4K);
-U8500_I2C_RESOURCES(2, SZ_4K);
-U8500_I2C_RESOURCES(3, SZ_4K);
-
 #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
-static struct nmk_i2c_controller u8500_i2c_##id = { \
+static struct nmk_i2c_controller u8500_i2c##id##_data = { \
        /*                              \
         * slave data setup time, which is      \
         * 250 ns,100ns,10ns which is 14,6,2    \
@@ -169,58 +99,32 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
 U8500_I2C_CONTROLLER(2,        0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
 U8500_I2C_CONTROLLER(3,        0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
 
-#define U8500_I2C_PDEVICE(cid)         \
-static struct platform_device i2c_controller##cid = { \
-       .name = "nmk-i2c",              \
-       .id      = cid,                 \
-       .num_resources = 2,             \
-       .resource = u8500_i2c_resources_##cid,  \
-       .dev = {                        \
-               .platform_data = &u8500_i2c_##cid \
-       }                               \
-}
-
-U8500_I2C_PDEVICE(0);
-U8500_I2C_PDEVICE(1);
-U8500_I2C_PDEVICE(2);
-U8500_I2C_PDEVICE(3);
-
 static struct amba_device *amba_devs[] __initdata = {
-       &uart0_device,
-       &uart1_device,
-       &uart2_device,
-       &pl022_device,
-       &pl031_device,
+       &ux500_uart0_device,
+       &ux500_uart1_device,
+       &ux500_uart2_device,
+       &u8500_ssp0_device,
 };
 
 /* add any platform devices here - TODO */
 static struct platform_device *platform_devs[] __initdata = {
-       &i2c_controller0,
-       &i2c_controller1,
-       &i2c_controller2,
-       &i2c_controller3,
-};
-
-static void __init u8500_timer_init(void)
-{
-#ifdef CONFIG_LOCAL_TIMERS
-       /* Setup the local timer base */
-       twd_base = __io_address(U8500_TWD_BASE);
-#endif
-       /* Setup the MTU base */
-       mtu_base = __io_address(U8500_MTU0_BASE);
-
-       nmdk_timer_init();
-}
-
-static struct sys_timer u8500_timer = {
-       .init   = u8500_timer_init,
+       &u8500_i2c0_device,
+       &ux500_i2c1_device,
+       &ux500_i2c2_device,
+       &ux500_i2c3_device,
 };
 
 static void __init u8500_init_machine(void)
 {
        int i;
 
+       u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data;
+       ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
+       ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
+       ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data;
+
+       u8500_ssp0_device.dev.platform_data = &ssp0_platform_data;
+
        /* Register the active AMBA devices on this board */
        for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
                amba_device_register(amba_devs[i], &iomem_resource);
@@ -239,8 +143,8 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
        .io_pg_offst    = (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc,
        .boot_params    = 0x100,
        .map_io         = u8500_map_io,
-       .init_irq       = u8500_init_irq,
+       .init_irq       = ux500_init_irq,
        /* we re-use nomadik timer here */
-       .timer          = &u8500_timer,
+       .timer          = &ux500_timer,
        .init_machine   = u8500_init_machine,
 MACHINE_END
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
new file mode 100644 (file)
index 0000000..4430e69
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+#include <mach/setup.h>
+
+static struct amba_device *amba_board_devs[] __initdata = {
+       &ux500_uart0_device,
+       &ux500_uart1_device,
+       &ux500_uart2_device,
+};
+
+static void __init u5500_init_machine(void)
+{
+       u5500_init_devices();
+
+       amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs));
+}
+
+MACHINE_START(U8500, "ST-Ericsson U5500 Platform")
+       .phys_io        = UX500_UART0_BASE,
+       .io_pg_offst    = (IO_ADDRESS(UX500_UART0_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x00000100,
+       .map_io         = u5500_map_io,
+       .init_irq       = ux500_init_irq,
+       .timer          = &ux500_timer,
+       .init_machine   = u5500_init_machine,
+MACHINE_END
index 8359a73..1b2c989 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2009 ST-Ericsson
- *     heavily based on realview platform
+ *  Copyright (C) 2009 STMicroelectronics
  *
  * 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/errno.h>
 #include <linux/err.h>
 #include <linux/clk.h>
-#include <linux/mutex.h>
+#include <linux/io.h>
 
 #include <asm/clkdev.h>
 
-/* currently the clk structure
- * just supports rate. This would
- * be extended as and when new devices are
- * added - TODO
- */
-struct clk {
-       unsigned long           rate;
-};
+#include <mach/hardware.h>
+#include "clock.h"
+
+#define PRCC_PCKEN             0x00
+#define PRCC_PCKDIS            0x04
+#define PRCC_KCKEN             0x08
+#define PRCC_KCKDIS            0x0C
+
+#define PRCM_YYCLKEN0_MGT_SET  0x510
+#define PRCM_YYCLKEN1_MGT_SET  0x514
+#define PRCM_YYCLKEN0_MGT_CLR  0x518
+#define PRCM_YYCLKEN1_MGT_CLR  0x51C
+#define PRCM_YYCLKEN0_MGT_VAL  0x520
+#define PRCM_YYCLKEN1_MGT_VAL  0x524
+
+#define PRCM_SVAMMDSPCLK_MGT   0x008
+#define PRCM_SIAMMDSPCLK_MGT   0x00C
+#define PRCM_SGACLK_MGT                0x014
+#define PRCM_UARTCLK_MGT       0x018
+#define PRCM_MSP02CLK_MGT      0x01C
+#define PRCM_MSP1CLK_MGT       0x288
+#define PRCM_I2CCLK_MGT                0x020
+#define PRCM_SDMMCCLK_MGT      0x024
+#define PRCM_SLIMCLK_MGT       0x028
+#define PRCM_PER1CLK_MGT       0x02C
+#define PRCM_PER2CLK_MGT       0x030
+#define PRCM_PER3CLK_MGT       0x034
+#define PRCM_PER5CLK_MGT       0x038
+#define PRCM_PER6CLK_MGT       0x03C
+#define PRCM_PER7CLK_MGT       0x040
+#define PRCM_LCDCLK_MGT                0x044
+#define PRCM_BMLCLK_MGT                0x04C
+#define PRCM_HSITXCLK_MGT      0x050
+#define PRCM_HSIRXCLK_MGT      0x054
+#define PRCM_HDMICLK_MGT       0x058
+#define PRCM_APEATCLK_MGT      0x05C
+#define PRCM_APETRACECLK_MGT   0x060
+#define PRCM_MCDECLK_MGT       0x064
+#define PRCM_IPI2CCLK_MGT      0x068
+#define PRCM_DSIALTCLK_MGT     0x06C
+#define PRCM_DMACLK_MGT                0x074
+#define PRCM_B2R2CLK_MGT       0x078
+#define PRCM_TVCLK_MGT         0x07C
+#define PRCM_UNIPROCLK_MGT     0x278
+#define PRCM_SSPCLK_MGT                0x280
+#define PRCM_RNGCLK_MGT                0x284
+#define PRCM_UICCCLK_MGT       0x27C
+
+#define PRCM_MGT_ENABLE                (1 << 8)
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+       if (clk->enabled++ == 0) {
+               if (clk->parent_cluster)
+                       __clk_enable(clk->parent_cluster);
+
+               if (clk->parent_periph)
+                       __clk_enable(clk->parent_periph);
+
+               if (clk->ops && clk->ops->enable)
+                       clk->ops->enable(clk);
+       }
+}
 
 int clk_enable(struct clk *clk)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       __clk_enable(clk);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
        return 0;
 }
 EXPORT_SYMBOL(clk_enable);
 
+static void __clk_disable(struct clk *clk)
+{
+       if (--clk->enabled == 0) {
+               if (clk->ops && clk->ops->disable)
+                       clk->ops->disable(clk);
+
+               if (clk->parent_periph)
+                       __clk_disable(clk->parent_periph);
+
+               if (clk->parent_cluster)
+                       __clk_disable(clk->parent_cluster);
+       }
+}
+
 void clk_disable(struct clk *clk)
 {
+       unsigned long flags;
+
+       WARN_ON(!clk->enabled);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       __clk_disable(clk);
+       spin_unlock_irqrestore(&clocks_lock, flags);
 }
 EXPORT_SYMBOL(clk_disable);
 
 unsigned long clk_get_rate(struct clk *clk)
 {
-       return clk->rate;
+       unsigned long rate;
+
+       if (clk->ops && clk->ops->get_rate)
+               return clk->ops->get_rate(clk);
+
+       rate = clk->rate;
+       if (!rate) {
+               if (clk->parent_periph)
+                       rate = clk_get_rate(clk->parent_periph);
+               else if (clk->parent_cluster)
+                       rate = clk_get_rate(clk->parent_cluster);
+       }
+
+       return rate;
 }
 EXPORT_SYMBOL(clk_get_rate);
 
@@ -56,37 +153,373 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL(clk_set_rate);
 
-/* ssp clock */
-static struct clk ssp_clk = {
-       .rate = 48000000,
+static void clk_prcmu_enable(struct clk *clk)
+{
+       void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
+                                  + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off;
+
+       writel(1 << clk->prcmu_cg_bit, cg_set_reg);
+}
+
+static void clk_prcmu_disable(struct clk *clk)
+{
+       void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE)
+                                  + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off;
+
+       writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
+}
+
+/* ED doesn't have the combined set/clr registers */
+static void clk_prcmu_ed_enable(struct clk *clk)
+{
+       void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+                            + clk->prcmu_cg_mgt;
+
+       writel(readl(addr) | PRCM_MGT_ENABLE, addr);
+}
+
+static void clk_prcmu_ed_disable(struct clk *clk)
+{
+       void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+                            + clk->prcmu_cg_mgt;
+
+       writel(readl(addr) & ~PRCM_MGT_ENABLE, addr);
+}
+
+static struct clkops clk_prcmu_ops = {
+       .enable = clk_prcmu_enable,
+       .disable = clk_prcmu_disable,
 };
 
-/* fixed clock */
-static struct clk f38_clk = {
-       .rate = 38400000,
+static unsigned int clkrst_base[] = {
+       [1] = U8500_CLKRST1_BASE,
+       [2] = U8500_CLKRST2_BASE,
+       [3] = U8500_CLKRST3_BASE,
+       [5] = U8500_CLKRST5_BASE,
+       [6] = U8500_CLKRST6_BASE,
+       [7] = U8500_CLKRST7_BASE_ED,
 };
 
-static struct clk_lookup lookups[] = {
-       {
-               /* UART0 */
-               .dev_id         = "uart0",
-               .clk            = &f38_clk,
-       }, {    /* UART1 */
-               .dev_id         = "uart1",
-               .clk            = &f38_clk,
-       }, {    /* UART2 */
-               .dev_id         = "uart2",
-               .clk            = &f38_clk,
-       }, {    /* SSP */
-               .dev_id         = "pl022",
-               .clk            = &ssp_clk,
-       }
+static void clk_prcc_enable(struct clk *clk)
+{
+       void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
+
+       if (clk->prcc_kernel != -1)
+               writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN);
+
+       if (clk->prcc_bus != -1)
+               writel(1 << clk->prcc_bus, addr + PRCC_PCKEN);
+}
+
+static void clk_prcc_disable(struct clk *clk)
+{
+       void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
+
+       if (clk->prcc_bus != -1)
+               writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS);
+
+       if (clk->prcc_kernel != -1)
+               writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS);
+}
+
+static struct clkops clk_prcc_ops = {
+       .enable = clk_prcc_enable,
+       .disable = clk_prcc_disable,
+};
+
+static struct clk clk_32khz = {
+       .rate = 32000,
+};
+
+/*
+ * PRCMU level clock gating
+ */
+
+/* Bank 0 */
+static DEFINE_PRCMU_CLK(svaclk,                0x0, 2, SVAMMDSPCLK);
+static DEFINE_PRCMU_CLK(siaclk,                0x0, 3, SIAMMDSPCLK);
+static DEFINE_PRCMU_CLK(sgaclk,                0x0, 4, SGACLK);
+static DEFINE_PRCMU_CLK_RATE(uartclk,  0x0, 5, UARTCLK, 38400000);
+static DEFINE_PRCMU_CLK(msp02clk,      0x0, 6, MSP02CLK);
+static DEFINE_PRCMU_CLK(msp1clk,       0x0, 7, MSP1CLK); /* v1 */
+static DEFINE_PRCMU_CLK_RATE(i2cclk,   0x0, 8, I2CCLK, 48000000);
+static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 50000000);
+static DEFINE_PRCMU_CLK(slimclk,       0x0, 10, SLIMCLK);
+static DEFINE_PRCMU_CLK(per1clk,       0x0, 11, PER1CLK);
+static DEFINE_PRCMU_CLK(per2clk,       0x0, 12, PER2CLK);
+static DEFINE_PRCMU_CLK(per3clk,       0x0, 13, PER3CLK);
+static DEFINE_PRCMU_CLK(per5clk,       0x0, 14, PER5CLK);
+static DEFINE_PRCMU_CLK_RATE(per6clk,  0x0, 15, PER6CLK, 133330000);
+static DEFINE_PRCMU_CLK_RATE(per7clk,  0x0, 16, PER7CLK, 100000000);
+static DEFINE_PRCMU_CLK(lcdclk,                0x0, 17, LCDCLK);
+static DEFINE_PRCMU_CLK(bmlclk,                0x0, 18, BMLCLK);
+static DEFINE_PRCMU_CLK(hsitxclk,      0x0, 19, HSITXCLK);
+static DEFINE_PRCMU_CLK(hsirxclk,      0x0, 20, HSIRXCLK);
+static DEFINE_PRCMU_CLK(hdmiclk,       0x0, 21, HDMICLK);
+static DEFINE_PRCMU_CLK(apeatclk,      0x0, 22, APEATCLK);
+static DEFINE_PRCMU_CLK(apetraceclk,   0x0, 23, APETRACECLK);
+static DEFINE_PRCMU_CLK(mcdeclk,       0x0, 24, MCDECLK);
+static DEFINE_PRCMU_CLK(ipi2clk,       0x0, 25, IPI2CCLK);
+static DEFINE_PRCMU_CLK(dsialtclk,     0x0, 26, DSIALTCLK); /* v1 */
+static DEFINE_PRCMU_CLK(dmaclk,                0x0, 27, DMACLK);
+static DEFINE_PRCMU_CLK(b2r2clk,       0x0, 28, B2R2CLK);
+static DEFINE_PRCMU_CLK(tvclk,         0x0, 29, TVCLK);
+static DEFINE_PRCMU_CLK(uniproclk,     0x0, 30, UNIPROCLK); /* v1 */
+static DEFINE_PRCMU_CLK_RATE(sspclk,   0x0, 31, SSPCLK, 48000000); /* v1 */
+
+/* Bank 1 */
+static DEFINE_PRCMU_CLK(rngclk,                0x4, 0, RNGCLK); /* v1 */
+static DEFINE_PRCMU_CLK(uiccclk,       0x4, 1, UICCCLK); /* v1 */
+
+/*
+ * PRCC level clock gating
+ * Format: per#, clk, PCKEN bit, KCKEN bit, parent
+ */
+
+/* Peripheral Cluster #1 */
+static DEFINE_PRCC_CLK(1, i2c4,        10, 9, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, gpio0,       9, -1, NULL);
+static DEFINE_PRCC_CLK(1, slimbus0,    8,  8, &clk_slimclk);
+static DEFINE_PRCC_CLK(1, spi3_ed,     7,  7, NULL);
+static DEFINE_PRCC_CLK(1, spi3_v1,     7, -1, NULL);
+static DEFINE_PRCC_CLK(1, i2c2,        6,  6, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, sdi0,                5,  5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(1, msp1_ed,     4,  4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, msp1_v1,     4,  4, &clk_msp1clk);
+static DEFINE_PRCC_CLK(1, msp0,        3,  3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, i2c1,        2,  2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, uart1,       1,  1, &clk_uartclk);
+static DEFINE_PRCC_CLK(1, uart0,       0,  0, &clk_uartclk);
+
+/* Peripheral Cluster #2 */
+
+static DEFINE_PRCC_CLK(2, gpio1_ed,    12, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssitx_ed,    11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_ed,    10, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi0_ed,      9, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_ed,      8,  6, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_ed,      7,  5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_ed,      6,  4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_ed,      4,  2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, pwl_ed,       3,  1, NULL);
+static DEFINE_PRCC_CLK(2, spi1_ed,      2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_ed,      1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_ed,      0,  0, &clk_i2cclk);
+
+static DEFINE_PRCC_CLK(2, gpio1_v1,    11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssitx_v1,    10,  7, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_v1,     9,  6, NULL);
+static DEFINE_PRCC_CLK(2, spi0_v1,      8, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_v1,      7,  5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_v1,      6,  4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_v1,      5,  3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_v1,      4,  2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, pwl_v1,       3,  1, NULL);
+static DEFINE_PRCC_CLK(2, spi1_v1,      2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_v1,      1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_v1,      0,  0, &clk_i2cclk);
+
+/* Peripheral Cluster #3 */
+static DEFINE_PRCC_CLK(3, gpio2,       8, -1, NULL);
+static DEFINE_PRCC_CLK(3, sdi5,        7,  7, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, uart2,       6,  6, &clk_uartclk);
+static DEFINE_PRCC_CLK(3, ske,                 5,  5, &clk_32khz);
+static DEFINE_PRCC_CLK(3, sdi2,        4,  4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, i2c0,        3,  3, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_ed,     2,  2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp0_ed,     1,  1, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_v1,     2,  2, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, ssp0_v1,     1,  1, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, fsmc,        0, -1, NULL);
+
+/* Peripheral Cluster #4 is in the always on domain */
+
+/* Peripheral Cluster #5 */
+static DEFINE_PRCC_CLK(5, gpio3,       1, -1, NULL);
+static DEFINE_PRCC_CLK(5, usb_ed,      0,  0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(5, usb_v1,      0,  0, NULL);
+
+/* Peripheral Cluster #6 */
+
+static DEFINE_PRCC_CLK(6, mtu1_v1,     8, -1, NULL);
+static DEFINE_PRCC_CLK(6, mtu0_v1,     7, -1, NULL);
+static DEFINE_PRCC_CLK(6, cfgreg_v1,   6,  6, NULL);
+static DEFINE_PRCC_CLK(6, dmc_ed,      6,  6, NULL);
+static DEFINE_PRCC_CLK(6, hash1,       5, -1, NULL);
+static DEFINE_PRCC_CLK(6, unipro_v1,   4,  1, &clk_uniproclk);
+static DEFINE_PRCC_CLK(6, cryp1_ed,    4, -1, NULL);
+static DEFINE_PRCC_CLK(6, pka,                 3, -1, NULL);
+static DEFINE_PRCC_CLK(6, hash0,       2, -1, NULL);
+static DEFINE_PRCC_CLK(6, cryp0,       1, -1, NULL);
+static DEFINE_PRCC_CLK(6, rng_ed,      0,  0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(6, rng_v1,      0,  0, &clk_rngclk);
+
+/* Peripheral Cluster #7 */
+
+static DEFINE_PRCC_CLK(7, tzpc0_ed,    4, -1, NULL);
+static DEFINE_PRCC_CLK(7, mtu1_ed,     3, -1, NULL);
+static DEFINE_PRCC_CLK(7, mtu0_ed,     2, -1, NULL);
+static DEFINE_PRCC_CLK(7, wdg_ed,      1, -1, NULL);
+static DEFINE_PRCC_CLK(7, cfgreg_ed,   0, -1, NULL);
+
+static struct clk_lookup u8500_common_clks[] = {
+       /* Peripheral Cluster #1 */
+       CLK(gpio0,      "gpio.0",       NULL),
+       CLK(gpio0,      "gpio.1",       NULL),
+       CLK(slimbus0,   "slimbus0",     NULL),
+       CLK(i2c2,       "nmk-i2c.2",    NULL),
+       CLK(sdi0,       "sdi0",         NULL),
+       CLK(msp0,       "msp0",         NULL),
+       CLK(i2c1,       "nmk-i2c.1",    NULL),
+       CLK(uart1,      "uart1",        NULL),
+       CLK(uart0,      "uart0",        NULL),
+
+       /* Peripheral Cluster #3 */
+       CLK(gpio2,      "gpio.2",       NULL),
+       CLK(gpio2,      "gpio.3",       NULL),
+       CLK(gpio2,      "gpio.4",       NULL),
+       CLK(gpio2,      "gpio.5",       NULL),
+       CLK(sdi5,       "sdi5",         NULL),
+       CLK(uart2,      "uart2",        NULL),
+       CLK(ske,        "ske",          NULL),
+       CLK(sdi2,       "sdi2",         NULL),
+       CLK(i2c0,       "nmk-i2c.0",    NULL),
+       CLK(fsmc,       "fsmc",         NULL),
+
+       /* Peripheral Cluster #5 */
+       CLK(gpio3,      "gpio.8",       NULL),
+
+       /* Peripheral Cluster #6 */
+       CLK(hash1,      "hash1",        NULL),
+       CLK(pka,        "pka",          NULL),
+       CLK(hash0,      "hash0",        NULL),
+       CLK(cryp0,      "cryp0",        NULL),
+
+       /* PRCMU level clock gating */
+
+       /* Bank 0 */
+       CLK(svaclk,     "sva",          NULL),
+       CLK(siaclk,     "sia",          NULL),
+       CLK(sgaclk,     "sga",          NULL),
+       CLK(slimclk,    "slim",         NULL),
+       CLK(lcdclk,     "lcd",          NULL),
+       CLK(bmlclk,     "bml",          NULL),
+       CLK(hsitxclk,   "stm-hsi.0",    NULL),
+       CLK(hsirxclk,   "stm-hsi.1",    NULL),
+       CLK(hdmiclk,    "hdmi",         NULL),
+       CLK(apeatclk,   "apeat",        NULL),
+       CLK(apetraceclk,        "apetrace",     NULL),
+       CLK(mcdeclk,    "mcde",         NULL),
+       CLK(ipi2clk,    "ipi2",         NULL),
+       CLK(dmaclk,     "dma40",        NULL),
+       CLK(b2r2clk,    "b2r2",         NULL),
+       CLK(tvclk,      "tv",           NULL),
+};
+
+static struct clk_lookup u8500_ed_clks[] = {
+       /* Peripheral Cluster #1 */
+       CLK(spi3_ed,    "spi3",         NULL),
+       CLK(msp1_ed,    "msp1",         NULL),
+
+       /* Peripheral Cluster #2 */
+       CLK(gpio1_ed,   "gpio.6",       NULL),
+       CLK(gpio1_ed,   "gpio.7",       NULL),
+       CLK(ssitx_ed,   "ssitx",        NULL),
+       CLK(ssirx_ed,   "ssirx",        NULL),
+       CLK(spi0_ed,    "spi0",         NULL),
+       CLK(sdi3_ed,    "sdi3",         NULL),
+       CLK(sdi1_ed,    "sdi1",         NULL),
+       CLK(msp2_ed,    "msp2",         NULL),
+       CLK(sdi4_ed,    "sdi4",         NULL),
+       CLK(pwl_ed,     "pwl",          NULL),
+       CLK(spi1_ed,    "spi1",         NULL),
+       CLK(spi2_ed,    "spi2",         NULL),
+       CLK(i2c3_ed,    "nmk-i2c.3",    NULL),
+
+       /* Peripheral Cluster #3 */
+       CLK(ssp1_ed,    "ssp1",         NULL),
+       CLK(ssp0_ed,    "ssp0",         NULL),
+
+       /* Peripheral Cluster #5 */
+       CLK(usb_ed,     "musb_hdrc.0",  "usb"),
+
+       /* Peripheral Cluster #6 */
+       CLK(dmc_ed,     "dmc",          NULL),
+       CLK(cryp1_ed,   "cryp1",        NULL),
+       CLK(rng_ed,     "rng",          NULL),
+
+       /* Peripheral Cluster #7 */
+       CLK(tzpc0_ed,   "tzpc0",        NULL),
+       CLK(mtu1_ed,    "mtu1",         NULL),
+       CLK(mtu0_ed,    "mtu0",         NULL),
+       CLK(wdg_ed,     "wdg",          NULL),
+       CLK(cfgreg_ed,  "cfgreg",       NULL),
+};
+
+static struct clk_lookup u8500_v1_clks[] = {
+       /* Peripheral Cluster #1 */
+       CLK(i2c4,       "nmk-i2c.4",    NULL),
+       CLK(spi3_v1,    "spi3",         NULL),
+       CLK(msp1_v1,    "msp1",         NULL),
+
+       /* Peripheral Cluster #2 */
+       CLK(gpio1_v1,   "gpio.6",       NULL),
+       CLK(gpio1_v1,   "gpio.7",       NULL),
+       CLK(ssitx_v1,   "ssitx",        NULL),
+       CLK(ssirx_v1,   "ssirx",        NULL),
+       CLK(spi0_v1,    "spi0",         NULL),
+       CLK(sdi3_v1,    "sdi3",         NULL),
+       CLK(sdi1_v1,    "sdi1",         NULL),
+       CLK(msp2_v1,    "msp2",         NULL),
+       CLK(sdi4_v1,    "sdi4",         NULL),
+       CLK(pwl_v1,     "pwl",          NULL),
+       CLK(spi1_v1,    "spi1",         NULL),
+       CLK(spi2_v1,    "spi2",         NULL),
+       CLK(i2c3_v1,    "nmk-i2c.3",    NULL),
+
+       /* Peripheral Cluster #3 */
+       CLK(ssp1_v1,    "ssp1",         NULL),
+       CLK(ssp0_v1,    "ssp0",         NULL),
+
+       /* Peripheral Cluster #5 */
+       CLK(usb_v1,     "musb_hdrc.0",  "usb"),
+
+       /* Peripheral Cluster #6 */
+       CLK(mtu1_v1,    "mtu1",         NULL),
+       CLK(mtu0_v1,    "mtu0",         NULL),
+       CLK(cfgreg_v1,  "cfgreg",       NULL),
+       CLK(hash1,      "hash1",        NULL),
+       CLK(unipro_v1,  "unipro",       NULL),
+       CLK(rng_v1,     "rng",          NULL),
+
+       /* PRCMU level clock gating */
+
+       /* Bank 0 */
+       CLK(uniproclk,  "uniproclk",    NULL),
+       CLK(dsialtclk,  "dsialt",       NULL),
+
+       /* Bank 1 */
+       CLK(rngclk,     "rng",          NULL),
+       CLK(uiccclk,    "uicc",         NULL),
 };
 
 static int __init clk_init(void)
 {
-       /* register the clock lookups */
-       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+       if (cpu_is_u8500ed()) {
+               clk_prcmu_ops.enable = clk_prcmu_ed_enable;
+               clk_prcmu_ops.disable = clk_prcmu_ed_disable;
+       } else if (cpu_is_u5500()) {
+               /* Clock tree for U5500 not implemented yet */
+               clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
+               clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
+       }
+
+       clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
+       if (cpu_is_u8500ed())
+               clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
+       else
+               clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
+
        return 0;
 }
 arch_initcall(clk_init);
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
new file mode 100644 (file)
index 0000000..e4f99b6
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ *  Copyright (C) 2010 ST-Ericsson
+ *  Copyright (C) 2009 STMicroelectronics
+ *
+ * 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.
+ */
+
+/**
+ * struct clkops - ux500 clock operations
+ * @enable:    function to enable the clock
+ * @disable:   function to disable the clock
+ * @get_rate:  function to get the current clock rate
+ *
+ * This structure contains function pointers to functions that will be used to
+ * control the clock.  All of these functions are optional.  If get_rate is
+ * NULL, the rate in the struct clk will be used.
+ */
+struct clkops {
+       void (*enable) (struct clk *);
+       void (*disable) (struct clk *);
+       unsigned long (*get_rate) (struct clk *);
+};
+
+/**
+ * struct clk - ux500 clock structure
+ * @ops:               pointer to clkops struct used to control this clock
+ * @name:              name, for debugging
+ * @enabled:           refcount. positive if enabled, zero if disabled
+ * @rate:              fixed rate for clocks which don't implement
+ *                     ops->getrate
+ * @prcmu_cg_off:      address offset of the combined enable/disable register
+ *                     (used on u8500v1)
+ * @prcmu_cg_bit:      bit in the combined enable/disable register (used on
+ *                     u8500v1)
+ * @prcmu_cg_mgt:      address of the enable/disable register (used on
+ *                     u8500ed)
+ * @cluster:           peripheral cluster number
+ * @prcc_bus:          bit for the bus clock in the peripheral's CLKRST
+ * @prcc_kernel:       bit for the kernel clock in the peripheral's CLKRST.
+ *                     -1 if no kernel clock exists.
+ * @parent_cluster:    pointer to parent's cluster clk struct
+ * @parent_periph:     pointer to parent's peripheral clk struct
+ *
+ * Peripherals are organised into clusters, and each cluster has an associated
+ * bus clock.  Some peripherals also have a parent peripheral clock.
+ *
+ * In order to enable a clock for a peripheral, we need to enable:
+ *     (1) the parent cluster (bus) clock at the PRCMU level
+ *     (2) the parent peripheral clock (if any) at the PRCMU level
+ *     (3) the peripheral's bus & kernel clock at the PRCC level
+ *
+ * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each
+ * of the cluster and peripheral clocks, and hooking these as the parents of
+ * the individual peripheral clocks.
+ *
+ * (3) is handled by specifying the bits in the PRCC control registers required
+ * to enable these clocks and modifying them in the ->enable and
+ * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK).
+ *
+ * This structure describes both the PRCMU-level clocks and PRCC-level clocks.
+ * The prcmu_* fields are only used for the PRCMU clocks, and the cluster,
+ * prcc, and parent pointers are only used for the PRCC-level clocks.
+ */
+struct clk {
+       const struct clkops     *ops;
+       const char              *name;
+       unsigned int            enabled;
+
+       unsigned long           rate;
+       struct list_head        list;
+
+       /* These three are only for PRCMU clks */
+
+       unsigned int            prcmu_cg_off;
+       unsigned int            prcmu_cg_bit;
+       unsigned int            prcmu_cg_mgt;
+
+       /* The rest are only for PRCC clks */
+
+       int                     cluster;
+       unsigned int            prcc_bus;
+       unsigned int            prcc_kernel;
+
+       struct clk              *parent_cluster;
+       struct clk              *parent_periph;
+};
+
+#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg)                \
+struct clk clk_##_name = {                                     \
+               .name           = #_name,                       \
+               .ops            = &clk_prcmu_ops,               \
+               .prcmu_cg_off   = _cg_off,                      \
+               .prcmu_cg_bit   = _cg_bit,                      \
+               .prcmu_cg_mgt   = PRCM_##_reg##_MGT             \
+       }
+
+#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate)    \
+struct clk clk_##_name = {                                             \
+               .name           = #_name,                               \
+               .ops            = &clk_prcmu_ops,                       \
+               .prcmu_cg_off   = _cg_off,                              \
+               .prcmu_cg_bit   = _cg_bit,                              \
+               .rate           = _rate,                                \
+               .prcmu_cg_mgt   = PRCM_##_reg##_MGT                     \
+       }
+
+#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \
+struct clk clk_##_name = {                                             \
+               .name           = #_name,                               \
+               .ops            = &clk_prcc_ops,                        \
+               .cluster        = _pclust,                              \
+               .prcc_bus       = _bus_en,                              \
+               .prcc_kernel    = _kernel_en,                           \
+               .parent_cluster = &clk_per##_pclust##clk,               \
+               .parent_periph  = _kernclk                              \
+       }
+
+#define CLK(_clk, _devname, _conname)                  \
+       {                                               \
+               .clk    = &clk_##_clk,                  \
+               .dev_id = _devname,                     \
+               .con_id = _conname,                     \
+       }
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
new file mode 100644 (file)
index 0000000..6a3ac45
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+#include <mach/setup.h>
+
+static struct map_desc u5500_io_desc[] __initdata = {
+       __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
+       __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
+       __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
+       __IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K),
+       __IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K),
+};
+
+static struct platform_device *u5500_platform_devs[] __initdata = {
+       &u5500_gpio_devs[0],
+       &u5500_gpio_devs[1],
+       &u5500_gpio_devs[2],
+       &u5500_gpio_devs[3],
+       &u5500_gpio_devs[4],
+       &u5500_gpio_devs[5],
+       &u5500_gpio_devs[6],
+       &u5500_gpio_devs[7],
+};
+
+void __init u5500_map_io(void)
+{
+       ux500_map_io();
+
+       iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
+}
+
+void __init u5500_init_devices(void)
+{
+       ux500_init_devices();
+
+       platform_add_devices(u5500_platform_devs,
+                            ARRAY_SIZE(u5500_platform_devs));
+}
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
new file mode 100644 (file)
index 0000000..d04299f
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+
+static struct platform_device *platform_devs[] __initdata = {
+       &u8500_gpio_devs[0],
+       &u8500_gpio_devs[1],
+       &u8500_gpio_devs[2],
+       &u8500_gpio_devs[3],
+       &u8500_gpio_devs[4],
+       &u8500_gpio_devs[5],
+       &u8500_gpio_devs[6],
+       &u8500_gpio_devs[7],
+       &u8500_gpio_devs[8],
+};
+
+/* minimum static i/o mapping required to boot U8500 platforms */
+static struct map_desc u8500_io_desc[] __initdata = {
+       __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
+};
+
+static struct map_desc u8500ed_io_desc[] __initdata = {
+       __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K),
+       __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K),
+};
+
+static struct map_desc u8500v1_io_desc[] __initdata = {
+       __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+};
+
+void __init u8500_map_io(void)
+{
+       ux500_map_io();
+
+       iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+
+       if (cpu_is_u8500ed())
+               iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc));
+       else
+               iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc));
+}
+
+/*
+ * This function is called from the board init
+ */
+void __init u8500_init_devices(void)
+{
+       ux500_init_devices();
+
+       /* Register the platform devices */
+       platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+       return ;
+}
diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c
deleted file mode 100644 (file)
index 397bc1f..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008-2009 ST-Ericsson
- *
- * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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/types.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/amba/bus.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-
-#include <asm/hardware/gic.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-
-/* add any platform devices here - TODO */
-static struct platform_device *platform_devs[] __initdata = {
-       /* yet to be added, add i2c0, gpio.. */
-};
-
-#define __IO_DEV_DESC(x, sz)   {               \
-       .virtual        = IO_ADDRESS(x),        \
-       .pfn            = __phys_to_pfn(x),     \
-       .length         = sz,                   \
-       .type           = MT_DEVICE,            \
-}
-
-/* minimum static i/o mapping required to boot U8500 platforms */
-static struct map_desc u8500_io_desc[] __initdata = {
-       __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
-       __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
-       __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
-       __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
-       __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
-       __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
-       __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
-};
-
-void __init u8500_map_io(void)
-{
-       iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
-}
-
-void __init u8500_init_irq(void)
-{
-       gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29);
-       gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
-}
-
-/*
- * This function is called from the board init
- */
-void __init u8500_init_devices(void)
-{
-       /* Register the platform devices */
-       platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
-
-       return ;
-}
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
new file mode 100644 (file)
index 0000000..d81ad02
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <asm/localtimer.h>
+
+#include <plat/mtu.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+
+#include "clock.h"
+
+static struct map_desc ux500_io_desc[] __initdata = {
+       __IO_DEV_DESC(UX500_UART0_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_UART2_BASE, SZ_4K),
+
+       __IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_TWD_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_SCU_BASE, SZ_4K),
+
+       __IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K),
+
+       __IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K),
+       __IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K),
+
+       __IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K),
+};
+
+static struct amba_device *ux500_amba_devs[] __initdata = {
+       &ux500_pl031_device,
+};
+
+void __init ux500_map_io(void)
+{
+       iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
+}
+
+void __init ux500_init_devices(void)
+{
+       amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs));
+}
+
+void __init ux500_init_irq(void)
+{
+       gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
+       gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
+}
+
+#ifdef CONFIG_CACHE_L2X0
+static int ux500_l2x0_init(void)
+{
+       void __iomem *l2x0_base;
+
+       l2x0_base = __io_address(UX500_L2CC_BASE);
+
+       /* 64KB way size, 8 way associativity, force WA */
+       l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
+
+       return 0;
+}
+early_initcall(ux500_l2x0_init);
+#endif
+
+static void __init ux500_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+       /* Setup the local timer base */
+       twd_base = __io_address(UX500_TWD_BASE);
+#endif
+       /* Setup the MTU base */
+       if (cpu_is_u8500ed())
+               mtu_base = __io_address(U8500_MTU0_BASE_ED);
+       else
+               mtu_base = __io_address(UX500_MTU0_BASE);
+
+       nmdk_timer_init();
+}
+
+struct sys_timer ux500_timer = {
+       .init   = ux500_timer_init,
+};
diff --git a/arch/arm/mach-ux500/devices-db5500.c b/arch/arm/mach-ux500/devices-db5500.c
new file mode 100644 (file)
index 0000000..33e5b56
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+
+static struct nmk_gpio_platform_data u5500_gpio_data[] = {
+       GPIO_DATA("GPIO-0-31", 0),
+       GPIO_DATA("GPIO-32-63", 32), /* 36..63 not routed to pin */
+       GPIO_DATA("GPIO-64-95", 64), /* 83..95 not routed to pin */
+       GPIO_DATA("GPIO-96-127", 96), /* 102..127 not routed to pin */
+       GPIO_DATA("GPIO-128-159", 128), /* 149..159 not routed to pin */
+       GPIO_DATA("GPIO-160-191", 160),
+       GPIO_DATA("GPIO-192-223", 192),
+       GPIO_DATA("GPIO-224-255", 224), /* 228..255 not routed to pin */
+};
+
+static struct resource u5500_gpio_resources[] = {
+       GPIO_RESOURCE(0),
+       GPIO_RESOURCE(1),
+       GPIO_RESOURCE(2),
+       GPIO_RESOURCE(3),
+       GPIO_RESOURCE(4),
+       GPIO_RESOURCE(5),
+       GPIO_RESOURCE(6),
+       GPIO_RESOURCE(7),
+};
+
+struct platform_device u5500_gpio_devs[] = {
+       GPIO_DEVICE(0),
+       GPIO_DEVICE(1),
+       GPIO_DEVICE(2),
+       GPIO_DEVICE(3),
+       GPIO_DEVICE(4),
+       GPIO_DEVICE(5),
+       GPIO_DEVICE(6),
+       GPIO_DEVICE(7),
+};
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
new file mode 100644 (file)
index 0000000..2033423
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+static struct nmk_gpio_platform_data u8500_gpio_data[] = {
+       GPIO_DATA("GPIO-0-31", 0),
+       GPIO_DATA("GPIO-32-63", 32), /* 37..63 not routed to pin */
+       GPIO_DATA("GPIO-64-95", 64),
+       GPIO_DATA("GPIO-96-127", 96), /* 98..127 not routed to pin */
+       GPIO_DATA("GPIO-128-159", 128),
+       GPIO_DATA("GPIO-160-191", 160), /* 172..191 not routed to pin */
+       GPIO_DATA("GPIO-192-223", 192),
+       GPIO_DATA("GPIO-224-255", 224), /* 231..255 not routed to pin */
+       GPIO_DATA("GPIO-256-288", 256), /* 268..288 not routed to pin */
+};
+
+static struct resource u8500_gpio_resources[] = {
+       GPIO_RESOURCE(0),
+       GPIO_RESOURCE(1),
+       GPIO_RESOURCE(2),
+       GPIO_RESOURCE(3),
+       GPIO_RESOURCE(4),
+       GPIO_RESOURCE(5),
+       GPIO_RESOURCE(6),
+       GPIO_RESOURCE(7),
+       GPIO_RESOURCE(8),
+};
+
+struct platform_device u8500_gpio_devs[] = {
+       GPIO_DEVICE(0),
+       GPIO_DEVICE(1),
+       GPIO_DEVICE(2),
+       GPIO_DEVICE(3),
+       GPIO_DEVICE(4),
+       GPIO_DEVICE(5),
+       GPIO_DEVICE(6),
+       GPIO_DEVICE(7),
+       GPIO_DEVICE(8),
+};
+
+struct amba_device u8500_ssp0_device = {
+       .dev = {
+               .coherent_dma_mask = ~0,
+               .init_name = "ssp0",
+       },
+       .res = {
+               .start = U8500_SSP0_BASE,
+               .end   = U8500_SSP0_BASE + SZ_4K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_SSP0, NO_IRQ },
+       /* ST-Ericsson modified id */
+       .periphid = SSP_PER_ID,
+};
+
+static struct resource u8500_i2c0_resources[] = {
+       [0] = {
+               .start  = U8500_I2C0_BASE,
+               .end    = U8500_I2C0_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_I2C0,
+               .end    = IRQ_I2C0,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device u8500_i2c0_device = {
+       .name           = "nmk-i2c",
+       .id             = 0,
+       .resource       = u8500_i2c0_resources,
+       .num_resources  = ARRAY_SIZE(u8500_i2c0_resources),
+};
+
+static struct resource u8500_i2c4_resources[] = {
+       [0] = {
+               .start  = U8500_I2C4_BASE,
+               .end    = U8500_I2C4_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_I2C4,
+               .end    = IRQ_I2C4,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device u8500_i2c4_device = {
+       .name           = "nmk-i2c",
+       .id             = 4,
+       .resource       = u8500_i2c4_resources,
+       .num_resources  = ARRAY_SIZE(u8500_i2c4_resources),
+};
diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c
new file mode 100644 (file)
index 0000000..8a26889
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+#define __MEM_4K_RESOURCE(x) \
+       .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+struct amba_device ux500_pl031_device = {
+       .dev = {
+               .init_name = "pl031",
+       },
+       .res = {
+               .start  = UX500_RTC_BASE,
+               .end    = UX500_RTC_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_RTC_RTT, NO_IRQ},
+};
+
+struct amba_device ux500_uart0_device = {
+       .dev = { .init_name = "uart0" },
+       __MEM_4K_RESOURCE(UX500_UART0_BASE),
+       .irq = {IRQ_UART0, NO_IRQ},
+};
+
+struct amba_device ux500_uart1_device = {
+       .dev = { .init_name = "uart1" },
+       __MEM_4K_RESOURCE(UX500_UART1_BASE),
+       .irq = {IRQ_UART1, NO_IRQ},
+};
+
+struct amba_device ux500_uart2_device = {
+       .dev = { .init_name = "uart2" },
+       __MEM_4K_RESOURCE(UX500_UART2_BASE),
+       .irq = {IRQ_UART2, NO_IRQ},
+};
+
+#define UX500_I2C_RESOURCES(id, size)                          \
+static struct resource ux500_i2c##id##_resources[] = {         \
+       [0] = {                                                 \
+               .start  = UX500_I2C##id##_BASE,                 \
+               .end    = UX500_I2C##id##_BASE + size - 1,      \
+               .flags  = IORESOURCE_MEM,                       \
+       },                                                      \
+       [1] = {                                                 \
+               .start  = IRQ_I2C##id,                          \
+               .end    = IRQ_I2C##id,                          \
+               .flags  = IORESOURCE_IRQ                        \
+       }                                                       \
+}
+
+UX500_I2C_RESOURCES(1, SZ_4K);
+UX500_I2C_RESOURCES(2, SZ_4K);
+UX500_I2C_RESOURCES(3, SZ_4K);
+
+#define UX500_I2C_PDEVICE(cid)                                 \
+struct platform_device ux500_i2c##cid##_device = {             \
+       .name           = "nmk-i2c",                            \
+       .id             = cid,                                  \
+       .num_resources  = 2,                                    \
+       .resource       = ux500_i2c##cid##_resources,           \
+}
+
+UX500_I2C_PDEVICE(1);
+UX500_I2C_PDEVICE(2);
+UX500_I2C_PDEVICE(3);
+
+void __init amba_add_devices(struct amba_device *devs[], int num)
+{
+       int i;
+
+       for (i = 0; i < num; i++) {
+               struct amba_device *d = devs[i];
+               amba_device_register(d, &iomem_resource);
+       }
+}
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
new file mode 100644 (file)
index 0000000..545c80f
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_DB5500_REGS_H
+#define __MACH_DB5500_REGS_H
+
+#define U5500_PER1_BASE                0xA0020000
+#define U5500_PER2_BASE                0xA0010000
+#define U5500_PER3_BASE                0x80140000
+#define U5500_PER4_BASE                0x80150000
+#define U5500_PER5_BASE                0x80100000
+#define U5500_PER6_BASE                0x80120000
+
+#define U5500_GIC_DIST_BASE    0xA0411000
+#define U5500_GIC_CPU_BASE     0xA0410100
+#define U5500_DMA_BASE         0x90030000
+#define U5500_MCDE_BASE                0xA0400000
+#define U5500_MODEM_BASE       0xB0000000
+#define U5500_L2CC_BASE                0xA0412000
+#define U5500_SCU_BASE         0xA0410000
+#define U5500_DSI1_BASE                0xA0401000
+#define U5500_DSI2_BASE                0xA0402000
+#define U5500_SIA_BASE         0xA0100000
+#define U5500_SVA_BASE         0x80200000
+#define U5500_HSEM_BASE                0xA0000000
+#define U5500_NAND0_BASE       0x60000000
+#define U5500_NAND1_BASE       0x70000000
+#define U5500_TWD_BASE         0xa0410600
+#define U5500_B2R2_BASE                0xa0200000
+
+#define U5500_FSMC_BASE                (U5500_PER1_BASE + 0x0000)
+#define U5500_SDI0_BASE                (U5500_PER1_BASE + 0x1000)
+#define U5500_SDI2_BASE                (U5500_PER1_BASE + 0x2000)
+#define U5500_UART0_BASE       (U5500_PER1_BASE + 0x3000)
+#define U5500_I2C1_BASE                (U5500_PER1_BASE + 0x4000)
+#define U5500_MSP0_BASE                (U5500_PER1_BASE + 0x5000)
+#define U5500_GPIO0_BASE       (U5500_PER1_BASE + 0xE000)
+#define U5500_CLKRST1_BASE     (U5500_PER1_BASE + 0xF000)
+
+#define U5500_USBOTG_BASE      (U5500_PER2_BASE + 0x0000)
+#define U5500_GPIO1_BASE       (U5500_PER2_BASE + 0xE000)
+#define U5500_CLKRST2_BASE     (U5500_PER2_BASE + 0xF000)
+
+#define U5500_KEYPAD_BASE      (U5500_PER3_BASE + 0x0000)
+#define U5500_PWM_BASE         (U5500_PER3_BASE + 0x1000)
+#define U5500_GPIO3_BASE       (U5500_PER3_BASE + 0xE000)
+#define U5500_CLKRST3_BASE     (U5500_PER3_BASE + 0xF000)
+
+#define U5500_BACKUPRAM0_BASE  (U5500_PER4_BASE + 0x0000)
+#define U5500_BACKUPRAM1_BASE  (U5500_PER4_BASE + 0x1000)
+#define U5500_RTT0_BASE                (U5500_PER4_BASE + 0x2000)
+#define U5500_RTT1_BASE                (U5500_PER4_BASE + 0x3000)
+#define U5500_RTC_BASE         (U5500_PER4_BASE + 0x4000)
+#define U5500_SCR_BASE         (U5500_PER4_BASE + 0x5000)
+#define U5500_DMC_BASE         (U5500_PER4_BASE + 0x6000)
+#define U5500_PRCMU_BASE       (U5500_PER4_BASE + 0x7000)
+#define U5500_MSP1_BASE                (U5500_PER4_BASE + 0x9000)
+#define U5500_GPIO2_BASE       (U5500_PER4_BASE + 0xA000)
+#define U5500_CDETECT_BASE     (U5500_PER4_BASE + 0xF000)
+
+#define U5500_SPI0_BASE                (U5500_PER5_BASE + 0x0000)
+#define U5500_SPI1_BASE                (U5500_PER5_BASE + 0x1000)
+#define U5500_SPI2_BASE                (U5500_PER5_BASE + 0x2000)
+#define U5500_SPI3_BASE                (U5500_PER5_BASE + 0x3000)
+#define U5500_UART1_BASE       (U5500_PER5_BASE + 0x4000)
+#define U5500_UART2_BASE       (U5500_PER5_BASE + 0x5000)
+#define U5500_UART3_BASE       (U5500_PER5_BASE + 0x6000)
+#define U5500_SDI1_BASE                (U5500_PER5_BASE + 0x7000)
+#define U5500_SDI3_BASE                (U5500_PER5_BASE + 0x8000)
+#define U5500_SDI4_BASE                (U5500_PER5_BASE + 0x9000)
+#define U5500_I2C2_BASE                (U5500_PER5_BASE + 0xA000)
+#define U5500_I2C3_BASE                (U5500_PER5_BASE + 0xB000)
+#define U5500_MSP2_BASE                (U5500_PER5_BASE + 0xC000)
+#define U5500_IRDA_BASE                (U5500_PER5_BASE + 0xD000)
+#define U5500_IRRC_BASE                (U5500_PER5_BASE + 0x10000)
+#define U5500_GPIO4_BASE       (U5500_PER5_BASE + 0x1E000)
+#define U5500_CLKRST5_BASE     (U5500_PER5_BASE + 0x1F000)
+
+#define U5500_RNG_BASE         (U5500_PER6_BASE + 0x0000)
+#define U5500_HASH0_BASE       (U5500_PER6_BASE + 0x1000)
+#define U5500_HASH1_BASE       (U5500_PER6_BASE + 0x2000)
+#define U5500_PKA_BASE         (U5500_PER6_BASE + 0x4000)
+#define U5500_PKAM_BASE                (U5500_PER6_BASE + 0x5000)
+#define U5500_MTU0_BASE                (U5500_PER6_BASE + 0x6000)
+#define U5500_MTU1_BASE                (U5500_PER6_BASE + 0x7000)
+#define U5500_CR_BASE          (U5500_PER6_BASE + 0x8000)
+#define U5500_CRYP0_BASE       (U5500_PER6_BASE + 0xA000)
+#define U5500_CRYP1_BASE       (U5500_PER6_BASE + 0xB000)
+#define U5500_CLKRST6_BASE     (U5500_PER6_BASE + 0xF000)
+
+#define U5500_GPIOBANK0_BASE   U5500_GPIO0_BASE
+#define U5500_GPIOBANK1_BASE   (U5500_GPIO0_BASE + 0x80)
+#define U5500_GPIOBANK2_BASE   U5500_GPIO1_BASE
+#define U5500_GPIOBANK3_BASE   U5500_GPIO2_BASE
+#define U5500_GPIOBANK4_BASE   U5500_GPIO3_BASE
+#define U5500_GPIOBANK5_BASE   U5500_GPIO4_BASE
+#define U5500_GPIOBANK6_BASE   (U5500_GPIO4_BASE + 0x80)
+#define U5500_GPIOBANK7_BASE   (U5500_GPIO4_BASE + 0x100)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
new file mode 100644 (file)
index 0000000..9169e1e
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_DB8500_REGS_H
+#define __MACH_DB8500_REGS_H
+
+#define U8500_PER3_BASE                0x80000000
+#define U8500_STM_BASE         0x80100000
+#define U8500_STM_REG_BASE     (U8500_STM_BASE + 0xF000)
+#define U8500_PER2_BASE                0x80110000
+#define U8500_PER1_BASE                0x80120000
+#define U8500_B2R2_BASE                0x80130000
+#define U8500_HSEM_BASE                0x80140000
+#define U8500_PER4_BASE                0x80150000
+#define U8500_ICN_BASE         0x81000000
+
+#define U8500_BOOT_ROM_BASE    0x90000000
+/* ASIC ID is at 0xff4 offset within this region */
+#define U8500_ASIC_ID_BASE     0x9001F000
+
+#define U8500_PER6_BASE                0xa03c0000
+#define U8500_PER5_BASE                0xa03e0000
+#define U8500_PER7_BASE_ED     0xa03d0000
+
+#define U8500_SVA_BASE         0xa0100000
+#define U8500_SIA_BASE         0xa0200000
+
+#define U8500_SGA_BASE         0xa0300000
+#define U8500_MCDE_BASE                0xa0350000
+#define U8500_DMA_BASE_ED      0xa0362000
+#define U8500_DMA_BASE         0x801C0000      /* v1 */
+
+#define U8500_SBAG_BASE                0xa0390000
+
+#define U8500_SCU_BASE         0xa0410000
+#define U8500_GIC_CPU_BASE     0xa0410100
+#define U8500_TWD_BASE         0xa0410600
+#define U8500_GIC_DIST_BASE    0xa0411000
+#define U8500_L2CC_BASE                0xa0412000
+
+#define U8500_MODEM_I2C                0xb7e02000
+
+#define U8500_GPIO0_BASE       (U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE       (U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO2_BASE       (U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO3_BASE       (U8500_PER5_BASE + 0x1E000)
+
+/* per7 base addressess */
+#define U8500_CR_BASE_ED       (U8500_PER7_BASE_ED + 0x8000)
+#define U8500_MTU0_BASE_ED     (U8500_PER7_BASE_ED + 0xa000)
+#define U8500_MTU1_BASE_ED     (U8500_PER7_BASE_ED + 0xb000)
+#define U8500_TZPC0_BASE_ED    (U8500_PER7_BASE_ED + 0xc000)
+#define U8500_CLKRST7_BASE_ED  (U8500_PER7_BASE_ED + 0xf000)
+
+#define U8500_UART0_BASE       (U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE       (U8500_PER1_BASE + 0x1000)
+
+/* per6 base addressess */
+#define U8500_RNG_BASE         (U8500_PER6_BASE + 0x0000)
+#define U8500_PKA_BASE         (U8500_PER6_BASE + 0x1000)
+#define U8500_PKAM_BASE                (U8500_PER6_BASE + 0x2000)
+#define U8500_MTU0_BASE                (U8500_PER6_BASE + 0x6000) /* v1 */
+#define U8500_MTU1_BASE                (U8500_PER6_BASE + 0x7000) /* v1 */
+#define U8500_CR_BASE          (U8500_PER6_BASE + 0x8000) /* v1 */
+#define U8500_CRYPTO0_BASE     (U8500_PER6_BASE + 0xa000)
+#define U8500_CRYPTO1_BASE     (U8500_PER6_BASE + 0xb000)
+#define U8500_CLKRST6_BASE     (U8500_PER6_BASE + 0xf000)
+
+/* per5 base addressess */
+#define U8500_USBOTG_BASE      (U8500_PER5_BASE + 0x00000)
+#define U8500_CLKRST5_BASE     (U8500_PER5_BASE + 0x1f000)
+
+/* per4 base addressess */
+#define U8500_BACKUPRAM0_BASE  (U8500_PER4_BASE + 0x00000)
+#define U8500_BACKUPRAM1_BASE  (U8500_PER4_BASE + 0x01000)
+#define U8500_RTT0_BASE                (U8500_PER4_BASE + 0x02000)
+#define U8500_RTT1_BASE                (U8500_PER4_BASE + 0x03000)
+#define U8500_RTC_BASE         (U8500_PER4_BASE + 0x04000)
+#define U8500_SCR_BASE         (U8500_PER4_BASE + 0x05000)
+#define U8500_DMC_BASE         (U8500_PER4_BASE + 0x06000)
+#define U8500_PRCMU_BASE       (U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE  (U8500_PER4_BASE + 0x0f000)
+
+/* per3 base addresses */
+#define U8500_FSMC_BASE                (U8500_PER3_BASE + 0x0000)
+#define U8500_SSP0_BASE                (U8500_PER3_BASE + 0x2000)
+#define U8500_SSP1_BASE                (U8500_PER3_BASE + 0x3000)
+#define U8500_I2C0_BASE                (U8500_PER3_BASE + 0x4000)
+#define U8500_SDI2_BASE                (U8500_PER3_BASE + 0x5000)
+#define U8500_SKE_BASE         (U8500_PER3_BASE + 0x6000)
+#define U8500_UART2_BASE       (U8500_PER3_BASE + 0x7000)
+#define U8500_SDI5_BASE                (U8500_PER3_BASE + 0x8000)
+#define U8500_CLKRST3_BASE     (U8500_PER3_BASE + 0xf000)
+
+/* per2 base addressess */
+#define U8500_I2C3_BASE                (U8500_PER2_BASE + 0x0000)
+#define U8500_SPI2_BASE                (U8500_PER2_BASE + 0x1000)
+#define U8500_SPI1_BASE                (U8500_PER2_BASE + 0x2000)
+#define U8500_PWL_BASE         (U8500_PER2_BASE + 0x3000)
+#define U8500_SDI4_BASE                (U8500_PER2_BASE + 0x4000)
+#define U8500_MSP2_BASE                (U8500_PER2_BASE + 0x7000)
+#define U8500_SDI1_BASE                (U8500_PER2_BASE + 0x8000)
+#define U8500_SDI3_BASE                (U8500_PER2_BASE + 0x9000)
+#define U8500_SPI0_BASE                (U8500_PER2_BASE + 0xa000)
+#define U8500_HSIR_BASE                (U8500_PER2_BASE + 0xb000)
+#define U8500_HSIT_BASE                (U8500_PER2_BASE + 0xc000)
+#define U8500_CLKRST2_BASE     (U8500_PER2_BASE + 0xf000)
+
+/* per1 base addresses */
+#define U8500_I2C1_BASE                (U8500_PER1_BASE + 0x2000)
+#define U8500_MSP0_BASE                (U8500_PER1_BASE + 0x3000)
+#define U8500_MSP1_BASE                (U8500_PER1_BASE + 0x4000)
+#define U8500_SDI0_BASE                (U8500_PER1_BASE + 0x6000)
+#define U8500_I2C2_BASE                (U8500_PER1_BASE + 0x8000)
+#define U8500_SPI3_BASE                (U8500_PER1_BASE + 0x9000)
+#define U8500_I2C4_BASE                (U8500_PER1_BASE + 0xa000)
+#define U8500_SLIM0_BASE       (U8500_PER1_BASE + 0xb000)
+#define U8500_CLKRST1_BASE     (U8500_PER1_BASE + 0xf000)
+
+#define U8500_SHRM_GOP_INTERRUPT_BASE  0xB7C00040
+
+#define U8500_GPIOBANK0_BASE   U8500_GPIO0_BASE
+#define U8500_GPIOBANK1_BASE   (U8500_GPIO0_BASE + 0x80)
+#define U8500_GPIOBANK2_BASE   U8500_GPIO1_BASE
+#define U8500_GPIOBANK3_BASE   (U8500_GPIO1_BASE + 0x80)
+#define U8500_GPIOBANK4_BASE   (U8500_GPIO1_BASE + 0x100)
+#define U8500_GPIOBANK5_BASE   (U8500_GPIO1_BASE + 0x180)
+#define U8500_GPIOBANK6_BASE   U8500_GPIO2_BASE
+#define U8500_GPIOBANK7_BASE   (U8500_GPIO2_BASE + 0x80)
+#define U8500_GPIOBANK8_BASE   U8500_GPIO3_BASE
+
+#endif
index 09cbfda..c5203b7 100644 (file)
  */
 #include <mach/hardware.h>
 
+#if CONFIG_UX500_DEBUG_UART > 2
+#error Invalid Ux500 debug UART
+#endif
+
+#define __UX500_UART(n)        UX500_UART##n##_BASE
+#define UX500_UART(n)  __UX500_UART(n)
+#define UART_BASE      UX500_UART(CONFIG_UX500_DEBUG_UART)
+
        .macro  addruart, rx, tmp
        mrc     p15, 0, \rx, c1, c0
        tst     \rx, #1                                 @ MMU enabled?
-       ldreq   \rx, =U8500_UART2_BASE                  @ no, physical address
-       ldrne   \rx, =IO_ADDRESS(U8500_UART2_BASE)      @ yes, virtual address
+       ldreq   \rx, =UART_BASE                         @ no, physical address
+       ldrne   \rx, =IO_ADDRESS(UART_BASE)             @ yes, virtual address
        .endm
 
 #include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h
new file mode 100644 (file)
index 0000000..0422af0
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __ASM_ARCH_DEVICES_H__
+#define __ASM_ARCH_DEVICES_H__
+
+struct platform_device;
+struct amba_device;
+
+extern struct platform_device u5500_gpio_devs[];
+extern struct platform_device u8500_gpio_devs[];
+
+extern struct amba_device ux500_pl031_device;
+extern struct amba_device u8500_ssp0_device;
+extern struct amba_device ux500_uart0_device;
+extern struct amba_device ux500_uart1_device;
+extern struct amba_device ux500_uart2_device;
+
+extern struct platform_device ux500_i2c1_device;
+extern struct platform_device ux500_i2c2_device;
+extern struct platform_device ux500_i2c3_device;
+
+extern struct platform_device u8500_i2c0_device;
+extern struct platform_device u8500_i2c4_device;
+
+#endif
index eece330..60ea88d 100644 (file)
@@ -17,7 +17,7 @@
                .endm
 
                .macro  get_irqnr_preamble, base, tmp
-               ldr     \base, =IO_ADDRESS(U8500_GIC_CPU_BASE)
+               ldr     \base, =IO_ADDRESS(UX500_GIC_CPU_BASE)
                .endm
 
                .macro  arch_ret_to_user, tmp1, tmp2
diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h
new file mode 100644 (file)
index 0000000..d548a62
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+/*
+ * 288 (#267 is the highest one actually hooked up) onchip GPIOs, plus enough
+ * room for a couple of GPIO expanders.
+ */
+#define ARCH_NR_GPIOS  350
+
+#include <plat/gpio.h>
+
+#define __GPIO_RESOURCE(soc, block)                                    \
+       {                                                               \
+               .start  = soc##_GPIOBANK##block##_BASE,                 \
+               .end    = soc##_GPIOBANK##block##_BASE + 127,           \
+               .flags  = IORESOURCE_MEM,                               \
+       },                                                              \
+       {                                                               \
+               .start  = IRQ_GPIO##block,                              \
+               .end    = IRQ_GPIO##block,                              \
+               .flags  = IORESOURCE_IRQ,                               \
+       }
+
+#define __GPIO_DEVICE(soc, block)                                      \
+       {                                                               \
+               .name           = "gpio",                               \
+               .id             = block,                                \
+               .num_resources  = 2,                                    \
+               .resource       = &soc##_gpio_resources[block * 2],     \
+               .dev = {                                                \
+                       .platform_data = &soc##_gpio_data[block],       \
+               },                                                      \
+       }
+
+#define GPIO_DATA(_name, first)                                                \
+       {                                                               \
+               .name           = _name,                                \
+               .first_gpio     = first,                                \
+               .first_irq      = NOMADIK_GPIO_TO_IRQ(first),           \
+       }
+
+#ifdef CONFIG_UX500_SOC_DB8500
+#define GPIO_RESOURCE(block)   __GPIO_RESOURCE(U8500, block)
+#define GPIO_DEVICE(block)     __GPIO_DEVICE(u8500, block)
+#elif defined(CONFIG_UX500_SOC_DB5500)
+#define GPIO_RESOURCE(block)   __GPIO_RESOURCE(U5500, block)
+#define GPIO_DEVICE(block)     __GPIO_DEVICE(u5500, block)
+#endif
+
+#endif /* __ASM_ARCH_GPIO_H */
index 04ea836..8656379 100644 (file)
 
 /* typesafe io address */
 #define __io_address(n)                __io(IO_ADDRESS(n))
+/* used by some plat-nomadik code */
+#define io_p2v(n)              __io_address(n)
 
-/*
- * Base address definitions for U8500 Onchip IPs. All the
- * peripherals are contained in a single 1 Mbyte region, with
- * AHB peripherals at the bottom and APB peripherals at the
- * top of the region. PER stands for PERIPHERAL region which
- * itself divided into sub regions.
- */
-#define U8500_PER3_BASE                0x80000000
-#define U8500_PER2_BASE                0x80110000
-#define U8500_PER1_BASE                0x80120000
-#define U8500_PER4_BASE                0x80150000
-
-#define U8500_PER6_BASE                0xa03c0000
-#define U8500_PER5_BASE                0xa03e0000
-#define U8500_PER7_BASE                0xa03d0000
-
-#define U8500_SVA_BASE         0xa0100000
-#define U8500_SIA_BASE         0xa0200000
-
-#define U8500_SGA_BASE         0xa0300000
-#define U8500_MCDE_BASE                0xa0350000
-#define U8500_DMA_BASE         0xa0362000
-
-#define U8500_SCU_BASE         0xa0410000
-#define U8500_GIC_CPU_BASE     0xa0410100
-#define U8500_TWD_BASE         0xa0410600
-#define U8500_GIC_DIST_BASE    0xa0411000
-#define U8500_L2CC_BASE                0xa0412000
-
-#define U8500_TWD_SIZE         0x100
-
-/* per7 base addressess */
-#define U8500_CR_BASE          (U8500_PER7_BASE + 0x8000)
-#define U8500_MTU0_BASE                (U8500_PER7_BASE + 0xa000)
-#define U8500_MTU1_BASE                (U8500_PER7_BASE + 0xb000)
-#define U8500_TZPC0_BASE       (U8500_PER7_BASE + 0xc000)
-#define U8500_CLKRST7_BASE     (U8500_PER7_BASE + 0xf000)
-
-/* per6 base addressess */
-#define U8500_RNG_BASE         (U8500_PER6_BASE + 0x0000)
-#define U8500_PKA_BASE         (U8500_PER6_BASE + 0x1000)
-#define U8500_PKAM_BASE                (U8500_PER6_BASE + 0x2000)
-#define U8500_CRYPTO0_BASE     (U8500_PER6_BASE + 0xa000)
-#define U8500_CRYPTO1_BASE     (U8500_PER6_BASE + 0xb000)
-#define U8500_CLKRST6_BASE     (U8500_PER6_BASE + 0xf000)
-
-/* per5 base addressess */
-#define U8500_USBOTG_BASE      (U8500_PER5_BASE + 0x00000)
-#define U8500_GPIO5_BASE       (U8500_PER5_BASE + 0x1e000)
-#define U8500_CLKRST5_BASE     (U8500_PER5_BASE + 0x1f000)
-
-/* per4 base addressess */
-#define U8500_BACKUPRAM0_BASE  (U8500_PER4_BASE + 0x0000)
-#define U8500_BACKUPRAM1_BASE  (U8500_PER4_BASE + 0x1000)
-#define U8500_RTT0_BASE                (U8500_PER4_BASE + 0x2000)
-#define U8500_RTT1_BASE                (U8500_PER4_BASE + 0x3000)
-#define U8500_RTC_BASE         (U8500_PER4_BASE + 0x4000)
-#define U8500_SCR_BASE         (U8500_PER4_BASE + 0x5000)
-#define U8500_DMC_BASE         (U8500_PER4_BASE + 0x6000)
-#define U8500_PRCMU_BASE       (U8500_PER4_BASE + 0x7000)
-
-/* per3 base addressess */
-#define U8500_FSMC_BASE                (U8500_PER3_BASE + 0x0000)
-#define U8500_SSP0_BASE                (U8500_PER3_BASE + 0x2000)
-#define U8500_SSP1_BASE                (U8500_PER3_BASE + 0x3000)
-#define U8500_I2C0_BASE                (U8500_PER3_BASE + 0x4000)
-#define U8500_SDI2_BASE                (U8500_PER3_BASE + 0x5000)
-#define U8500_SKE_BASE         (U8500_PER3_BASE + 0x6000)
-#define U8500_UART2_BASE       (U8500_PER3_BASE + 0x7000)
-#define U8500_SDI5_BASE                (U8500_PER3_BASE + 0x8000)
-#define U8500_GPIO3_BASE       (U8500_PER3_BASE + 0xe000)
-#define U8500_CLKRST3_BASE     (U8500_PER3_BASE + 0xf000)
-
-/* per2 base addressess */
-#define U8500_I2C3_BASE                (U8500_PER2_BASE + 0x0000)
-#define U8500_SPI2_BASE                (U8500_PER2_BASE + 0x1000)
-#define U8500_SPI1_BASE                (U8500_PER2_BASE + 0x2000)
-#define U8500_PWL_BASE         (U8500_PER2_BASE + 0x3000)
-#define U8500_SDI4_BASE                (U8500_PER2_BASE + 0x4000)
-#define U8500_MSP2_BASE                (U8500_PER2_BASE + 0x7000)
-#define U8500_SDI1_BASE                (U8500_PER2_BASE + 0x8000)
-#define U8500_SDI3_BASE                (U8500_PER2_BASE + 0x9000)
-#define U8500_SPI0_BASE                (U8500_PER2_BASE + 0xa000)
-#define U8500_HSIR_BASE                (U8500_PER2_BASE + 0xb000)
-#define U8500_HSIT_BASE                (U8500_PER2_BASE + 0xc000)
-#define U8500_GPIO2_BASE       (U8500_PER2_BASE + 0xe000)
-#define U8500_CLKRST2_BASE     (U8500_PER2_BASE + 0xf000)
-
-/* per1 base addresses */
-#define U8500_UART0_BASE       (U8500_PER1_BASE + 0x0000)
-#define U8500_UART1_BASE       (U8500_PER1_BASE + 0x1000)
-#define U8500_I2C1_BASE                (U8500_PER1_BASE + 0x2000)
-#define U8500_MSP0_BASE                (U8500_PER1_BASE + 0x3000)
-#define U8500_MSP1_BASE                (U8500_PER1_BASE + 0x4000)
-#define U8500_SDI0_BASE                (U8500_PER1_BASE + 0x6000)
-#define U8500_I2C2_BASE                (U8500_PER1_BASE + 0x8000)
-#define U8500_SPI3_BASE                (U8500_PER1_BASE + 0x9000)
-#define U8500_SLIM0_BASE       (U8500_PER1_BASE + 0xa000)
-#define U8500_GPIO1_BASE       (U8500_PER1_BASE + 0xe000)
-#define U8500_CLKRST1_BASE     (U8500_PER1_BASE + 0xf000)
+#include <mach/db8500-regs.h>
+#include <mach/db5500-regs.h>
+
+#ifdef CONFIG_UX500_SOC_DB8500
+#define UX500(periph)          U8500_##periph##_BASE
+#elif defined(CONFIG_UX500_SOC_DB5500)
+#define UX500(periph)          U5500_##periph##_BASE
+#endif
+
+#define UX500_BACKUPRAM0_BASE  UX500(BACKUPRAM0)
+#define UX500_BACKUPRAM1_BASE  UX500(BACKUPRAM1)
+#define UX500_B2R2_BASE                UX500(B2R2)
+
+#define UX500_CLKRST1_BASE     UX500(CLKRST1)
+#define UX500_CLKRST2_BASE     UX500(CLKRST2)
+#define UX500_CLKRST3_BASE     UX500(CLKRST3)
+#define UX500_CLKRST5_BASE     UX500(CLKRST5)
+#define UX500_CLKRST6_BASE     UX500(CLKRST6)
+
+#define UX500_DMA_BASE         UX500(DMA)
+#define UX500_FSMC_BASE                UX500(FSMC)
+
+#define UX500_GIC_CPU_BASE     UX500(GIC_CPU)
+#define UX500_GIC_DIST_BASE    UX500(GIC_DIST)
+
+#define UX500_I2C1_BASE                UX500(I2C1)
+#define UX500_I2C2_BASE                UX500(I2C2)
+#define UX500_I2C3_BASE                UX500(I2C3)
+
+#define UX500_L2CC_BASE                UX500(L2CC)
+#define UX500_MCDE_BASE                UX500(MCDE)
+#define UX500_MTU0_BASE                UX500(MTU0)
+#define UX500_MTU1_BASE                UX500(MTU1)
+#define UX500_PRCMU_BASE       UX500(PRCMU)
+
+#define UX500_RNG_BASE         UX500(RNG)
+#define UX500_RTC_BASE         UX500(RTC)
+
+#define UX500_SCU_BASE         UX500(SCU)
+
+#define UX500_SDI0_BASE                UX500(SDI0)
+#define UX500_SDI1_BASE                UX500(SDI1)
+#define UX500_SDI2_BASE                UX500(SDI2)
+#define UX500_SDI3_BASE                UX500(SDI3)
+#define UX500_SDI4_BASE                UX500(SDI4)
+
+#define UX500_SPI0_BASE                UX500(SPI0)
+#define UX500_SPI1_BASE                UX500(SPI1)
+#define UX500_SPI2_BASE                UX500(SPI2)
+#define UX500_SPI3_BASE                UX500(SPI3)
+
+#define UX500_SIA_BASE         UX500(SIA)
+#define UX500_SVA_BASE         UX500(SVA)
+
+#define UX500_TWD_BASE         UX500(TWD)
+
+#define UX500_UART0_BASE       UX500(UART0)
+#define UX500_UART1_BASE       UX500(UART1)
+#define UX500_UART2_BASE       UX500(UART2)
+
+#define UX500_USBOTG_BASE      UX500(USBOTG)
 
 /* ST-Ericsson modified pl022 id */
 #define SSP_PER_ID             0x01080022
 
+#ifndef __ASSEMBLY__
+
+#include <asm/cputype.h>
+
+static inline bool cpu_is_u8500(void)
+{
+#ifdef CONFIG_UX500_SOC_DB8500
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+static inline bool cpu_is_u8500ed(void)
+{
+       return cpu_is_u8500() && (read_cpuid_id() & 15) == 0;
+}
+
+static inline bool cpu_is_u8500v1(void)
+{
+       return cpu_is_u8500() && (read_cpuid_id() & 15) == 1;
+}
+
+static inline bool cpu_is_u5500(void)
+{
+#ifdef CONFIG_UX500_SOC_DB5500
+       return 1;
+#else
+       return 0;
+#endif
+}
+
+#endif
+
 #endif                         /* __MACH_HARDWARE_H */
index 394b5dd..7970684 100644 (file)
@@ -42,6 +42,7 @@
 #define IRQ_AB4500             (IRQ_SHPI_START + 40)
 #define IRQ_DISP               (IRQ_SHPI_START + 48)
 #define IRQ_SiPI3              (IRQ_SHPI_START + 49)
+#define IRQ_I2C4               (IRQ_SHPI_START + 51)
 #define IRQ_SSP1               (IRQ_SHPI_START + 52)
 #define IRQ_I2C2               (IRQ_SHPI_START + 55)
 #define IRQ_SDMMC0             (IRQ_SHPI_START + 60)
 /* There are 128 shared peripheral interrupts assigned to
  * INTID[160:32]. The first 32 interrupts are reserved.
  */
-#define NR_IRQS                        161
+#define U8500_SOC_NR_IRQS              161
+
+/* After chip-specific IRQ numbers we have the GPIO ones */
+#define NOMADIK_NR_GPIO                        288
+#define NOMADIK_GPIO_TO_IRQ(gpio)      ((gpio) + U8500_SOC_NR_IRQS)
+#define NOMADIK_IRQ_TO_GPIO(irq)       ((irq) - U8500_SOC_NR_IRQS)
+#define NR_IRQS                                NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
 
 #endif /*ASM_ARCH_IRQS_H*/
index cf0ce16..e978dbd 100644 (file)
 #include <asm/mach/time.h>
 #include <linux/init.h>
 
-extern void u8500_map_io(void);
-extern void u8500_init_devices(void);
-extern void u8500_init_irq(void);
+extern void __init ux500_map_io(void);
+extern void __init u5500_map_io(void);
+extern void __init u8500_map_io(void);
+
+extern void __init ux500_init_devices(void);
+extern void __init u5500_init_devices(void);
+extern void __init u8500_init_devices(void);
+
+extern void __init ux500_init_irq(void);
 /* We re-use nomadik_timer for this platform */
 extern void nmdk_timer_init(void);
 
+extern void __init amba_add_devices(struct amba_device *devs[], int num);
+
+struct sys_timer;
+extern struct sys_timer ux500_timer;
+
+#define __IO_DEV_DESC(x, sz)   {               \
+       .virtual        = IO_ADDRESS(x),        \
+       .pfn            = __phys_to_pfn(x),     \
+       .length         = sz,                   \
+       .type           = MT_DEVICE,            \
+}
+
 #endif /*  __ASM_ARCH_SETUP_H */
index 8dfe7ca..438ef16 100644 (file)
@@ -30,7 +30,7 @@ volatile int __cpuinitdata pen_release = -1;
 
 static unsigned int __init get_core_count(void)
 {
-       return scu_get_core_count(__io_address(U8500_SCU_BASE));
+       return scu_get_core_count(__io_address(UX500_SCU_BASE));
 }
 
 static DEFINE_SPINLOCK(boot_lock);
@@ -44,7 +44,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
         * core (e.g. timer irq), then they will not have been enabled
         * for us: do so
         */
-       gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
+       gic_cpu_init(0, __io_address(UX500_GIC_CPU_BASE));
 
        /*
         * let the primary processor know we're out of the
@@ -75,7 +75,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
         * that it has been released by resetting pen_release.
         */
        pen_release = cpu;
-       flush_cache_all();
+       __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+       outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1);
 
        timeout = jiffies + (1 * HZ);
        while (time_before(jiffies, timeout)) {
@@ -105,12 +106,12 @@ static void __init wakeup_secondary(void)
         */
 #define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4
        __raw_writel(virt_to_phys(u8500_secondary_startup),
-               (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+               __io_address(UX500_BACKUPRAM0_BASE) +
                U8500_CPU1_JUMPADDR_OFFSET);
 
 #define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
        __raw_writel(0xA1FEED01,
-               (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+               __io_address(UX500_BACKUPRAM0_BASE) +
                U8500_CPU1_WAKEMAGIC_OFFSET);
 
        /* make sure write buffer is drained */
@@ -171,7 +172,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
                 * boot CPU, but only if we have more than one CPU.
                 */
                percpu_timer_setup();
-               scu_enable(__io_address(U8500_SCU_BASE));
+               scu_enable(__io_address(UX500_SCU_BASE));
                wakeup_secondary();
        }
 }
index ba81e70..97cf4d8 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                                  := core.o clock.o
+obj-y                                  := core.o
 obj-$(CONFIG_ARCH_VERSATILE_PB)                += versatile_pb.o
 obj-$(CONFIG_MACH_VERSATILE_AB)                += versatile_ab.o
 obj-$(CONFIG_PCI)                      += pci.o
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
deleted file mode 100644 (file)
index c50a44e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/clock.c
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-
-#include <asm/clkdev.h>
-#include <asm/hardware/icst307.h>
-
-#include "clock.h"
-
-int clk_enable(struct clk *clk)
-{
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       struct icst307_vco vco;
-       vco = icst307_khz_to_vco(clk->params, rate / 1000);
-       return icst307_khz(clk->params, vco) * 1000;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       int ret = -EIO;
-
-       if (clk->setvco) {
-               struct icst307_vco vco;
-
-               vco = icst307_khz_to_vco(clk->params, rate / 1000);
-               clk->rate = icst307_khz(clk->params, vco) * 1000;
-               clk->setvco(clk, vco);
-               ret = 0;
-       }
-       return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h
deleted file mode 100644 (file)
index 03468fd..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *  linux/arch/arm/mach-versatile/clock.h
- *
- *  Copyright (C) 2004 ARM Limited.
- *  Written by Deep Blue Solutions Limited.
- *
- * 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.
- */
-struct module;
-struct icst307_params;
-
-struct clk {
-       unsigned long           rate;
-       const struct icst307_params *params;
-       u32                     oscoff;
-       void                    *data;
-       void                    (*setvco)(struct clk *, struct icst307_vco vco);
-};
index 3b1a4ee..3dff864 100644 (file)
 #include <linux/amba/clcd.h>
 #include <linux/amba/pl061.h>
 #include <linux/amba/mmci.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/cnt32_to_63.h>
 #include <linux/io.h>
 #include <linux/gfp.h>
 
 #include <asm/clkdev.h>
 #include <asm/system.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/hardware/arm_timer.h>
-#include <asm/hardware/icst307.h>
+#include <asm/hardware/icst.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach-types.h>
 
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
+#include <mach/clkdev.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <plat/timer-sp.h>
 
 #include "core.h"
-#include "clock.h"
 
 /*
  * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
@@ -59,7 +58,6 @@
  *
  * Setup a VA for the Versatile Vectored Interrupt Controller.
  */
-#define __io_address(n)                __io(IO_ADDRESS(n))
 #define VA_VIC_BASE            __io_address(VERSATILE_VIC_BASE)
 #define VA_SIC_BASE            __io_address(VERSATILE_SIC_BASE)
 
@@ -229,27 +227,6 @@ void __init versatile_map_io(void)
        iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
 }
 
-#define VERSATILE_REFCOUNTER   (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
-
-/*
- * This is the Versatile sched_clock implementation.  This has
- * a resolution of 41.7ns, and a maximum value of about 35583 days.
- *
- * The return value is guaranteed to be monotonic in that range as
- * long as there is always less than 89 seconds between successive
- * calls to this function.
- */
-unsigned long long sched_clock(void)
-{
-       unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER));
-
-       /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
-       v *= 125<<1;
-       do_div(v, 3<<1);
-
-       return v;
-}
-
 
 #define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 
@@ -380,33 +357,40 @@ static struct mmci_platform_data mmc0_plat_data = {
 /*
  * Clock handling
  */
-static const struct icst307_params versatile_oscvco_params = {
-       .ref            = 24000,
-       .vco_max        = 200000,
+static const struct icst_params versatile_oscvco_params = {
+       .ref            = 24000000,
+       .vco_max        = ICST307_VCO_MAX,
+       .vco_min        = ICST307_VCO_MIN,
        .vd_min         = 4 + 8,
        .vd_max         = 511 + 8,
        .rd_min         = 1 + 2,
        .rd_max         = 127 + 2,
+       .s2div          = icst307_s2div,
+       .idx2s          = icst307_idx2s,
 };
 
-static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco)
+static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco)
 {
-       void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
-       void __iomem *sys_lock = sys + VERSATILE_SYS_LOCK_OFFSET;
+       void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
        u32 val;
 
-       val = readl(sys + clk->oscoff) & ~0x7ffff;
+       val = readl(clk->vcoreg) & ~0x7ffff;
        val |= vco.v | (vco.r << 9) | (vco.s << 16);
 
        writel(0xa05f, sys_lock);
-       writel(val, sys + clk->oscoff);
+       writel(val, clk->vcoreg);
        writel(0, sys_lock);
 }
 
+static const struct clk_ops osc4_clk_ops = {
+       .round  = icst_clk_round,
+       .set    = icst_clk_set,
+       .setvco = versatile_oscvco_set,
+};
+
 static struct clk osc4_clk = {
+       .ops    = &osc4_clk_ops,
        .params = &versatile_oscvco_params,
-       .oscoff = VERSATILE_SYS_OSCCLCD_OFFSET,
-       .setvco = versatile_oscvco_set,
 };
 
 /*
@@ -852,6 +836,8 @@ void __init versatile_init(void)
 {
        int i;
 
+       osc4_clk.vcoreg = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;
+
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        platform_device_register(&versatile_flash_device);
@@ -875,120 +861,6 @@ void __init versatile_init(void)
 #define TIMER1_VA_BASE         (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
 #define TIMER2_VA_BASE          __io_address(VERSATILE_TIMER2_3_BASE)
 #define TIMER3_VA_BASE         (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE              __io_address(VERSATILE_VIC_BASE) 
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV256)
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD   (TIMER_INTERVAL >> 4)           /* Divide by 16 */
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV16)
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD   (TIMER_INTERVAL)
-#define TIMER_DIVISOR  (TIMER_CTRL_DIV1)
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-                          struct clock_event_device *clk)
-{
-       unsigned long ctrl;
-
-       switch(mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
-
-               ctrl = TIMER_CTRL_PERIODIC;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               /* period set, and timer enabled in 'next_event' hook */
-               ctrl = TIMER_CTRL_ONESHOT;
-               ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-               break;
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       default:
-               ctrl = 0;
-       }
-
-       writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-                               struct clock_event_device *unused)
-{
-       unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
-
-       writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
-       writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
-
-       return 0;
-}
-
-static struct clock_event_device timer0_clockevent =    {
-       .name           = "timer0",
-       .shift          = 32,
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = timer_set_mode,
-       .set_next_event = timer_set_next_event,
-};
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &timer0_clockevent;
-
-       writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction versatile_timer_irq = {
-       .name           = "Versatile Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = versatile_timer_interrupt,
-};
-
-static cycle_t versatile_get_cycles(struct clocksource *cs)
-{
-       return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_versatile = {
-       .name           = "timer3",
-       .rating         = 200,
-       .read           = versatile_get_cycles,
-       .mask           = CLOCKSOURCE_MASK(32),
-       .shift          = 20,
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static int __init versatile_clocksource_init(void)
-{
-       /* setup timer3 as free-running clocksource */
-       writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-       writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
-       writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
-       writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-              TIMER3_VA_BASE + TIMER_CTRL);
-
-       clocksource_versatile.mult =
-               clocksource_khz2mult(1000, clocksource_versatile.shift);
-       clocksource_register(&clocksource_versatile);
-
-       return 0;
-}
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
@@ -1017,22 +889,8 @@ static void __init versatile_timer_init(void)
        writel(0, TIMER2_VA_BASE + TIMER_CTRL);
        writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 
-       /* 
-        * Make irqs happen for the system timer
-        */
-       setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
-
-       versatile_clocksource_init();
-
-       timer0_clockevent.mult =
-               div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-       timer0_clockevent.max_delta_ns =
-               clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-       timer0_clockevent.min_delta_ns =
-               clockevent_delta2ns(0xf, &timer0_clockevent);
-
-       timer0_clockevent.cpumask = cpumask_of(0);
-       clockevents_register_device(&timer0_clockevent);
+       sp804_clocksource_init(TIMER3_VA_BASE);
+       sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1);
 }
 
 struct sys_timer versatile_timer = {
index 04b37a8..e58d077 100644 (file)
@@ -1,6 +1,15 @@
 #ifndef __ASM_MACH_CLKDEV_H
 #define __ASM_MACH_CLKDEV_H
 
+#include <plat/clock.h>
+
+struct clk {
+       unsigned long           rate;
+       const struct clk_ops    *ops;
+       const struct icst_params *params;
+       void __iomem            *vcoreg;
+};
+
 #define __clk_get(clk) ({ 1; })
 #define __clk_put(clk) do { } while (0)
 
index 8c80209..e6f7c16 100644 (file)
@@ -8,6 +8,7 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
+#include <mach/platform.h>
 #include <asm/hardware/vic.h>
 
                .macro  disable_fiq
index 7aa906c..4f8f99a 100644 (file)
@@ -23,7 +23,6 @@
 #define __ASM_ARCH_HARDWARE_H
 
 #include <asm/sizes.h>
-#include <mach/platform.h>
 
 /*
  * PCI space virtual addresses
@@ -49,4 +48,6 @@
 /* macro to get at IO space when running virtually */
 #define IO_ADDRESS(x)          (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
 
+#define __io_address(n)                __io(IO_ADDRESS(n))
+
 #endif
index 8320739..ec08740 100644 (file)
 #define VERSATILE_CLCD_BASE            0x10120000      /* CLCD */
 #define VERSATILE_DMAC_BASE            0x10130000      /* DMA controller */
 #define VERSATILE_VIC_BASE             0x10140000      /* Vectored interrupt controller */
-#define VERSATILE_PERIPH_BASE          0x10150000    /* off-chip peripherals alias from */
+#define VERSATILE_PERIPH_BASE          0x10150000      /* off-chip peripherals alias from */
                                                 /* 0x10000000 - 0x100FFFFF */
 #define VERSATILE_AHBM_BASE            0x101D0000      /* AHB monitor */
 #define VERSATILE_SCTL_BASE            0x101E0000      /* System controller */
 #define VERSATILE_TIMER0_1_BASE        0x101E2000      /* Timer 0 and 1 */
 #define VERSATILE_TIMER2_3_BASE        0x101E3000      /* Timer 2 and 3 */
 #define VERSATILE_GPIO0_BASE           0x101E4000      /* GPIO port 0 */
-#define VERSATILE_GPIO1_BASE           0x101E5000    /* GPIO port 1 */
+#define VERSATILE_GPIO1_BASE           0x101E5000      /* GPIO port 1 */
 #define VERSATILE_GPIO2_BASE           0x101E6000      /* GPIO port 2 */
 #define VERSATILE_GPIO3_BASE           0x101E7000      /* GPIO port 3 */
 #define VERSATILE_RTC_BASE             0x101E8000      /* Real Time Clock */
 #define SIC_INT_PCI3                    30
 
 
-/* 
- *  Clean base - dummy
- * 
- */
-#define CLEAN_BASE                      VERSATILE_BOOT_ROM_HI
-
 /*
  * System controller bit assignment
  */
 #define VERSATILE_TIMER4_EnSel 21
 
 
-#define MAX_TIMER                       2
-#define MAX_PERIOD                      699050
-#define TICKS_PER_uSEC                  1
-
-/* 
- *  These are useconds NOT ticks.  
- * 
- */
-#define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
-#define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
-
 #define VERSATILE_CSR_BASE             0x10000000
 #define VERSATILE_CSR_SIZE             0x10000000
 
 #endif
 
 #endif
-
-/*     END */
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
new file mode 100644 (file)
index 0000000..3f19b66
--- /dev/null
@@ -0,0 +1,9 @@
+menu "Versatile Express platform type"
+       depends on ARCH_VEXPRESS
+
+config ARCH_VEXPRESS_CA9X4
+       bool "Versatile Express Cortex-A9x4 tile"
+       select CPU_V7
+       select ARM_GIC
+
+endmenu
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
new file mode 100644 (file)
index 0000000..1b71b77
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y                                  := v2m.o
+obj-$(CONFIG_ARCH_VEXPRESS_CA9X4)      += ct-ca9x4.o
+obj-$(CONFIG_SMP)                      += platsmp.o headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS)             += localtimer.o
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot
new file mode 100644 (file)
index 0000000..07c2d9c
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x60008000
+params_phys-y  := 0x60000100
+initrd_phys-y  := 0x60800000
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
new file mode 100644 (file)
index 0000000..57dd95c
--- /dev/null
@@ -0,0 +1,26 @@
+#define __MMIO_P2V(x)  (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000)
+#define MMIO_P2V(x)    ((void __iomem *)__MMIO_P2V(x))
+
+#define AMBA_DEVICE(name,busid,base,plat)      \
+struct amba_device name##_device = {           \
+       .dev            = {                     \
+               .coherent_dma_mask = ~0UL,      \
+               .init_name = busid,             \
+               .platform_data = plat,          \
+       },                                      \
+       .res            = {                     \
+               .start  = base,                 \
+               .end    = base + SZ_4K - 1,     \
+               .flags  = IORESOURCE_MEM,       \
+       },                                      \
+       .dma_mask       = ~0UL,                 \
+       .irq            = IRQ_##base,           \
+       /* .dma         = DMA_##base,*/         \
+}
+
+struct map_desc;
+
+void v2m_map_io(struct map_desc *tile, size_t num);
+extern struct sys_timer v2m_timer;
+
+extern void __iomem *gic_cpu_base_addr;
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
new file mode 100644 (file)
index 0000000..e6f7303
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Versatile Express Core Tile Cortex A9x4 Support
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <asm/clkdev.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+
+#include <mach/clkdev.h>
+#include <mach/ct-ca9x4.h>
+
+#include <plat/timer-sp.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "core.h"
+
+#include <mach/motherboard.h>
+
+#define V2M_PA_CS7     0x10000000
+
+static struct map_desc ct_ca9x4_io_desc[] __initdata = {
+       {
+               .virtual        = __MMIO_P2V(CT_CA9X4_MPIC),
+               .pfn            = __phys_to_pfn(CT_CA9X4_MPIC),
+               .length         = SZ_16K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = __MMIO_P2V(CT_CA9X4_SP804_TIMER),
+               .pfn            = __phys_to_pfn(CT_CA9X4_SP804_TIMER),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       }, {
+               .virtual        = __MMIO_P2V(CT_CA9X4_L2CC),
+               .pfn            = __phys_to_pfn(CT_CA9X4_L2CC),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE,
+       },
+};
+
+static void __init ct_ca9x4_map_io(void)
+{
+       v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
+}
+
+void __iomem *gic_cpu_base_addr;
+
+static void __init ct_ca9x4_init_irq(void)
+{
+       gic_cpu_base_addr = MMIO_P2V(A9_MPCORE_GIC_CPU);
+       gic_dist_init(0, MMIO_P2V(A9_MPCORE_GIC_DIST), 29);
+       gic_cpu_init(0, gic_cpu_base_addr);
+}
+
+#if 0
+static void ct_ca9x4_timer_init(void)
+{
+       writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
+       writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
+
+       sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1));
+       sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0);
+}
+
+static struct sys_timer ct_ca9x4_timer = {
+       .init   = ct_ca9x4_timer_init,
+};
+#endif
+
+static struct clcd_panel xvga_panel = {
+       .mode           = {
+               .name           = "XVGA",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = 15384,
+               .left_margin    = 168,
+               .right_margin   = 8,
+               .upper_margin   = 29,
+               .lower_margin   = 3,
+               .hsync_len      = 144,
+               .vsync_len      = 6,
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       .width          = -1,
+       .height         = -1,
+       .tim2           = TIM2_BCD | TIM2_IPC,
+       .cntl           = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+       .bpp            = 16,
+};
+
+static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
+{
+       v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
+       v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
+}
+
+static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
+{
+       unsigned long framesize = 1024 * 768 * 2;
+       dma_addr_t dma;
+
+       fb->panel = &xvga_panel;
+
+       fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
+                               &dma, GFP_KERNEL);
+       if (!fb->fb.screen_base) {
+               printk(KERN_ERR "CLCD: unable to map frame buffer\n");
+               return -ENOMEM;
+       }
+       fb->fb.fix.smem_start = dma;
+       fb->fb.fix.smem_len = framesize;
+
+       return 0;
+}
+
+static int ct_ca9x4_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+       return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
+               fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static void ct_ca9x4_clcd_remove(struct clcd_fb *fb)
+{
+       dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+               fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board ct_ca9x4_clcd_data = {
+       .name           = "CT-CA9X4",
+       .check          = clcdfb_check,
+       .decode         = clcdfb_decode,
+       .enable         = ct_ca9x4_clcd_enable,
+       .setup          = ct_ca9x4_clcd_setup,
+       .mmap           = ct_ca9x4_clcd_mmap,
+       .remove         = ct_ca9x4_clcd_remove,
+};
+
+static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
+static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
+static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
+static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
+
+static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
+       &clcd_device,
+       &dmc_device,
+       &smc_device,
+       &gpio_device,
+};
+
+
+static long ct_round(struct clk *clk, unsigned long rate)
+{
+       return rate;
+}
+
+static int ct_set(struct clk *clk, unsigned long rate)
+{
+       return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
+}
+
+static const struct clk_ops osc1_clk_ops = {
+       .round  = ct_round,
+       .set    = ct_set,
+};
+
+static struct clk osc1_clk = {
+       .ops    = &osc1_clk_ops,
+       .rate   = 24000000,
+};
+
+static struct clk_lookup lookups[] = {
+       {       /* CLCD */
+               .dev_id         = "ct:clcd",
+               .clk            = &osc1_clk,
+       },
+};
+
+static struct resource pmu_resources[] = {
+       [0] = {
+               .start  = IRQ_CT_CA9X4_PMU_CPU0,
+               .end    = IRQ_CT_CA9X4_PMU_CPU0,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start  = IRQ_CT_CA9X4_PMU_CPU1,
+               .end    = IRQ_CT_CA9X4_PMU_CPU1,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = IRQ_CT_CA9X4_PMU_CPU2,
+               .end    = IRQ_CT_CA9X4_PMU_CPU2,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [3] = {
+               .start  = IRQ_CT_CA9X4_PMU_CPU3,
+               .end    = IRQ_CT_CA9X4_PMU_CPU3,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device pmu_device = {
+       .name           = "arm-pmu",
+       .id             = ARM_PMU_DEVICE_CPU,
+       .num_resources  = ARRAY_SIZE(pmu_resources),
+       .resource       = pmu_resources,
+};
+
+static void ct_ca9x4_init(void)
+{
+       int i;
+
+#ifdef CONFIG_CACHE_L2X0
+       l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff);
+#endif
+
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+       for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
+               amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
+
+       platform_device_register(&pmu_device);
+}
+
+MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
+       .phys_io        = V2M_UART0,
+       .io_pg_offst    = (__MMIO_P2V(V2M_UART0) >> 18) & 0xfffc,
+       .boot_params    = PHYS_OFFSET + 0x00000100,
+       .map_io         = ct_ca9x4_map_io,
+       .init_irq       = ct_ca9x4_init_irq,
+#if 0
+       .timer          = &ct_ca9x4_timer,
+#else
+       .timer          = &v2m_timer,
+#endif
+       .init_machine   = ct_ca9x4_init,
+MACHINE_END
diff --git a/arch/arm/mach-vexpress/headsmp.S b/arch/arm/mach-vexpress/headsmp.S
new file mode 100644 (file)
index 0000000..8a78ff6
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  linux/arch/arm/mach-vexpress/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  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 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+       __INIT
+
+/*
+ * Versatile Express specific entry point for secondary CPUs.  This
+ * provides a "holding pen" into which all secondary cores are held
+ * until we're ready for them to initialise.
+ */
+ENTRY(vexpress_secondary_startup)
+       mrc     p15, 0, r0, c0, c0, 5
+       and     r0, r0, #15
+       adr     r4, 1f
+       ldmia   r4, {r5, r6}
+       sub     r4, r4, r5
+       add     r6, r6, r4
+pen:   ldr     r7, [r6]
+       cmp     r7, r0
+       bne     pen
+
+       /*
+        * we've been released from the holding pen: secondary_stack
+        * should now contain the SVC stack for this core
+        */
+       b       secondary_startup
+
+1:     .long   .
+       .long   pen_release
diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..3f8307d
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#include <plat/clock.h>
+
+struct clk {
+       const struct clk_ops    *ops;
+       unsigned long           rate;
+       const struct icst_params *params;
+};
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
new file mode 100644 (file)
index 0000000..8650f04
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __MACH_CT_CA9X4_H
+#define __MACH_CT_CA9X4_H
+
+/*
+ * Physical base addresses
+ */
+#define CT_CA9X4_CLCDC         (0x10020000)
+#define CT_CA9X4_AXIRAM                (0x10060000)
+#define CT_CA9X4_DMC           (0x100e0000)
+#define CT_CA9X4_SMC           (0x100e1000)
+#define CT_CA9X4_SCC           (0x100e2000)
+#define CT_CA9X4_SP804_TIMER   (0x100e4000)
+#define CT_CA9X4_SP805_WDT     (0x100e5000)
+#define CT_CA9X4_TZPC          (0x100e6000)
+#define CT_CA9X4_GPIO          (0x100e8000)
+#define CT_CA9X4_FASTAXI       (0x100e9000)
+#define CT_CA9X4_SLOWAXI       (0x100ea000)
+#define CT_CA9X4_TZASC         (0x100ec000)
+#define CT_CA9X4_CORESIGHT     (0x10200000)
+#define CT_CA9X4_MPIC          (0x1e000000)
+#define CT_CA9X4_SYSTIMER      (0x1e004000)
+#define CT_CA9X4_SYSWDT                (0x1e007000)
+#define CT_CA9X4_L2CC          (0x1e00a000)
+
+#define CT_CA9X4_TIMER0                (CT_CA9X4_SP804_TIMER + 0x000)
+#define CT_CA9X4_TIMER1                (CT_CA9X4_SP804_TIMER + 0x020)
+
+#define A9_MPCORE_SCU          (CT_CA9X4_MPIC + 0x0000)
+#define A9_MPCORE_GIC_CPU      (CT_CA9X4_MPIC + 0x0100)
+#define A9_MPCORE_GIT          (CT_CA9X4_MPIC + 0x0200)
+#define A9_MPCORE_GIC_DIST     (CT_CA9X4_MPIC + 0x1000)
+
+/*
+ * Interrupts.  Those in {} are for AMBA devices
+ */
+#define IRQ_CT_CA9X4_CLCDC     { 76 }
+#define IRQ_CT_CA9X4_DMC       { -1 }
+#define IRQ_CT_CA9X4_SMC       { 77, 78 }
+#define IRQ_CT_CA9X4_TIMER0    80
+#define IRQ_CT_CA9X4_TIMER1    81
+#define IRQ_CT_CA9X4_GPIO      { 82 }
+#define IRQ_CT_CA9X4_PMU_CPU0  92
+#define IRQ_CT_CA9X4_PMU_CPU1  93
+#define IRQ_CT_CA9X4_PMU_CPU2  94
+#define IRQ_CT_CA9X4_PMU_CPU3  95
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..5167e2a
--- /dev/null
@@ -0,0 +1,23 @@
+/* arch/arm/mach-realview/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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.
+ */
+
+#define DEBUG_LL_UART_OFFSET   0x00009000
+
+               .macro  addruart,rx,tmp
+               mrc     p15, 0, \rx, c1, c0
+               tst     \rx, #1                 @ MMU enabled?
+               moveq   \rx,      #0x10000000
+               movne   \rx,      #0xf8000000   @ virtual base
+               orr     \rx, \rx, #DEBUG_LL_UART_OFFSET
+               .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..20e9fb5
--- /dev/null
@@ -0,0 +1,67 @@
+#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:
+        *
+        * Interrupts 0-15 are IPI
+        * 16-28 are reserved
+        * 29-31 are local.  We allow 30 to be used for the watchdog.
+        * 32-1020 are global
+        * 1021-1022 are reserved
+        * 1023 is "spurious" (no interrupt)
+        *
+        * For now, we ignore all local interrupts so only return an interrupt if it's
+        * between 30 and 1020.  The test_for_ipi routine below will pick up on IPIs.
+        *
+        * 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 (30-1020 inclusive).
+        */
+
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       ldr     \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+       ldr     \tmp, =1021
+       bic     \irqnr, \irqstat, #0x1c00
+       cmp     \irqnr, #29
+       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, #29
+       moveq   \tmp, #1
+       streq   \irqstat, [\base, #GIC_CPU_EOI]
+       cmp     \tmp, #0
+       .endm
+
diff --git a/arch/arm/mach-vexpress/include/mach/hardware.h b/arch/arm/mach-vexpress/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..40a8c17
--- /dev/null
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h
new file mode 100644 (file)
index 0000000..748bb52
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/io.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..7054cbf
--- /dev/null
@@ -0,0 +1,4 @@
+#define IRQ_LOCALTIMER         29
+#define IRQ_LOCALWDOG          30
+
+#define NR_IRQS        128
diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h
new file mode 100644 (file)
index 0000000..be28232
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/memory.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET            UL(0x60000000)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
new file mode 100644 (file)
index 0000000..98a8ded
--- /dev/null
@@ -0,0 +1,121 @@
+#ifndef __MACH_MOTHERBOARD_H
+#define __MACH_MOTHERBOARD_H
+
+/*
+ * Physical addresses, offset from V2M_PA_CS0-3
+ */
+#define V2M_NOR0               (V2M_PA_CS0)
+#define V2M_NOR1               (V2M_PA_CS1)
+#define V2M_SRAM               (V2M_PA_CS2)
+#define V2M_VIDEO_SRAM         (V2M_PA_CS3 + 0x00000000)
+#define V2M_LAN9118            (V2M_PA_CS3 + 0x02000000)
+#define V2M_ISP1761            (V2M_PA_CS3 + 0x03000000)
+
+/*
+ * Physical addresses, offset from V2M_PA_CS7
+ */
+#define V2M_SYSREGS            (V2M_PA_CS7 + 0x00000000)
+#define V2M_SYSCTL             (V2M_PA_CS7 + 0x00001000)
+#define V2M_SERIAL_BUS_PCI     (V2M_PA_CS7 + 0x00002000)
+
+#define V2M_AACI               (V2M_PA_CS7 + 0x00004000)
+#define V2M_MMCI               (V2M_PA_CS7 + 0x00005000)
+#define V2M_KMI0               (V2M_PA_CS7 + 0x00006000)
+#define V2M_KMI1               (V2M_PA_CS7 + 0x00007000)
+
+#define V2M_UART0              (V2M_PA_CS7 + 0x00009000)
+#define V2M_UART1              (V2M_PA_CS7 + 0x0000a000)
+#define V2M_UART2              (V2M_PA_CS7 + 0x0000b000)
+#define V2M_UART3              (V2M_PA_CS7 + 0x0000c000)
+
+#define V2M_WDT                        (V2M_PA_CS7 + 0x0000f000)
+
+#define V2M_TIMER01            (V2M_PA_CS7 + 0x00011000)
+#define V2M_TIMER23            (V2M_PA_CS7 + 0x00012000)
+
+#define V2M_SERIAL_BUS_DVI     (V2M_PA_CS7 + 0x00016000)
+#define V2M_RTC                        (V2M_PA_CS7 + 0x00017000)
+
+#define V2M_CF                 (V2M_PA_CS7 + 0x0001a000)
+#define V2M_CLCD               (V2M_PA_CS7 + 0x0001f000)
+
+#define V2M_SYS_ID             (V2M_SYSREGS + 0x000)
+#define V2M_SYS_SW             (V2M_SYSREGS + 0x004)
+#define V2M_SYS_LED            (V2M_SYSREGS + 0x008)
+#define V2M_SYS_100HZ          (V2M_SYSREGS + 0x024)
+#define V2M_SYS_FLAGS          (V2M_SYSREGS + 0x030)
+#define V2M_SYS_FLAGSSET       (V2M_SYSREGS + 0x030)
+#define V2M_SYS_FLAGSCLR       (V2M_SYSREGS + 0x034)
+#define V2M_SYS_NVFLAGS                (V2M_SYSREGS + 0x038)
+#define V2M_SYS_NVFLAGSSET     (V2M_SYSREGS + 0x038)
+#define V2M_SYS_NVFLAGSCLR     (V2M_SYSREGS + 0x03c)
+#define V2M_SYS_MCI            (V2M_SYSREGS + 0x048)
+#define V2M_SYS_FLASH          (V2M_SYSREGS + 0x03c)
+#define V2M_SYS_CFGSW          (V2M_SYSREGS + 0x058)
+#define V2M_SYS_24MHZ          (V2M_SYSREGS + 0x05c)
+#define V2M_SYS_MISC           (V2M_SYSREGS + 0x060)
+#define V2M_SYS_DMA            (V2M_SYSREGS + 0x064)
+#define V2M_SYS_PROCID0                (V2M_SYSREGS + 0x084)
+#define V2M_SYS_PROCID1                (V2M_SYSREGS + 0x088)
+#define V2M_SYS_CFGDATA                (V2M_SYSREGS + 0x0a0)
+#define V2M_SYS_CFGCTRL                (V2M_SYSREGS + 0x0a4)
+#define V2M_SYS_CFGSTAT                (V2M_SYSREGS + 0x0a8)
+
+#define V2M_TIMER0             (V2M_TIMER01 + 0x000)
+#define V2M_TIMER1             (V2M_TIMER01 + 0x020)
+
+#define V2M_TIMER2             (V2M_TIMER23 + 0x000)
+#define V2M_TIMER3             (V2M_TIMER23 + 0x020)
+
+
+/*
+ * Interrupts.  Those in {} are for AMBA devices
+ */
+#define IRQ_V2M_WDT            { (32 + 0) }
+#define IRQ_V2M_TIMER0         (32 + 2)
+#define IRQ_V2M_TIMER1         (32 + 2)
+#define IRQ_V2M_TIMER2         (32 + 3)
+#define IRQ_V2M_TIMER3         (32 + 3)
+#define IRQ_V2M_RTC            { (32 + 4) }
+#define IRQ_V2M_UART0          { (32 + 5) }
+#define IRQ_V2M_UART1          { (32 + 6) }
+#define IRQ_V2M_UART2          { (32 + 7) }
+#define IRQ_V2M_UART3          { (32 + 8) }
+#define IRQ_V2M_MMCI           { (32 + 9), (32 + 10) }
+#define IRQ_V2M_AACI           { (32 + 11) }
+#define IRQ_V2M_KMI0           { (32 + 12) }
+#define IRQ_V2M_KMI1           { (32 + 13) }
+#define IRQ_V2M_CLCD           { (32 + 14) }
+#define IRQ_V2M_LAN9118                (32 + 15)
+#define IRQ_V2M_ISP1761                (32 + 16)
+#define IRQ_V2M_PCIE           (32 + 17)
+
+
+/*
+ * Configuration
+ */
+#define SYS_CFG_START          (1 << 31)
+#define SYS_CFG_WRITE          (1 << 30)
+#define SYS_CFG_OSC            (1 << 20)
+#define SYS_CFG_VOLT           (2 << 20)
+#define SYS_CFG_AMP            (3 << 20)
+#define SYS_CFG_TEMP           (4 << 20)
+#define SYS_CFG_RESET          (5 << 20)
+#define SYS_CFG_SCC            (6 << 20)
+#define SYS_CFG_MUXFPGA                (7 << 20)
+#define SYS_CFG_SHUTDOWN       (8 << 20)
+#define SYS_CFG_REBOOT         (9 << 20)
+#define SYS_CFG_DVIMODE                (11 << 20)
+#define SYS_CFG_POWER          (12 << 20)
+#define SYS_CFG_SITE_MB                (0 << 16)
+#define SYS_CFG_SITE_DB1       (1 << 16)
+#define SYS_CFG_SITE_DB2       (2 << 16)
+#define SYS_CFG_STACK(n)       ((n) << 12)
+
+#define SYS_CFG_ERR            (1 << 1)
+#define SYS_CFG_COMPLETE       (1 << 0)
+
+int v2m_cfg_write(u32 devfn, u32 data);
+int v2m_cfg_read(u32 devfn, u32 *data);
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h
new file mode 100644 (file)
index 0000000..72a9621
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __MACH_SMP_H
+#define __MACH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id()                                \
+       ({                                              \
+               unsigned int cpunum;                    \
+               __asm__("mrc p15, 0, %0, c0, c0, 5"     \
+                       : "=r" (cpunum));               \
+               cpunum &= 0x0F;                         \
+       })
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+       gic_raise_softirq(mask, 1);
+}
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h
new file mode 100644 (file)
index 0000000..899a4e6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/system.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+       /*
+        * This should do all the clock switching
+        * and wait for interrupt tricks
+        */
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/timex.h b/arch/arm/mach-vexpress/include/mach/timex.h
new file mode 100644 (file)
index 0000000..00029ba
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/timex.h
+ *
+ *  RealView architecture timex specifications
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define CLOCK_TICK_RATE                (50000000 / 16)
diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..7972c57
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/uncompress.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define AMBA_UART_DR(base)     (*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base)   (*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base)     (*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base)     (*(volatile unsigned char *)((base) + 0x18))
+
+#define get_uart_base()        (0x10000000 + 0x00009000)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+       unsigned long base = get_uart_base();
+
+       while (AMBA_UART_FR(base) & (1 << 5))
+               barrier();
+
+       AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+       unsigned long base = get_uart_base();
+
+       while (AMBA_UART_FR(base) & (1 << 3))
+               barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-vexpress/include/mach/vmalloc.h b/arch/arm/mach-vexpress/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..f43a36e
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ *  arch/arm/mach-vexpress/include/mach/vmalloc.h
+ *
+ *  Copyright (C) 2003 ARM Limited
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define VMALLOC_END            0xf8000000UL
diff --git a/arch/arm/mach-vexpress/localtimer.c b/arch/arm/mach-vexpress/localtimer.c
new file mode 100644 (file)
index 0000000..c0e3a59
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ *  linux/arch/arm/mach-vexpress/localtimer.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  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 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+#include <mach/irqs.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+       evt->irq = IRQ_LOCALTIMER;
+       twd_timer_setup(evt);
+}
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
new file mode 100644 (file)
index 0000000..6709706
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ *  linux/arch/arm/mach-vexpress/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  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 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/localtimer.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+
+#include <mach/ct-ca9x4.h>
+#include <mach/motherboard.h>
+#define V2M_PA_CS7 0x10000000
+
+#include "core.h"
+
+extern void vexpress_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+static void __iomem *scu_base_addr(void)
+{
+       return MMIO_P2V(A9_MPCORE_SCU);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+       trace_hardirqs_off();
+
+       /*
+        * if any interrupts are already enabled for the primary
+        * core (e.g. timer irq), then they will not have been enabled
+        * for us: do so
+        */
+       gic_cpu_init(0, gic_cpu_base_addr);
+
+       /*
+        * let the primary processor know we're out of the
+        * pen, then head off into the C entry point
+        */
+       pen_release = -1;
+       smp_wmb();
+
+       /*
+        * Synchronise with the boot thread.
+        */
+       spin_lock(&boot_lock);
+       spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       unsigned long timeout;
+
+       /*
+        * Set synchronisation state between this boot processor
+        * and the secondary one
+        */
+       spin_lock(&boot_lock);
+
+       /*
+        * This is really belt and braces; we hold unintended secondary
+        * CPUs in the holding pen until we're ready for them.  However,
+        * since we haven't sent them a soft interrupt, they shouldn't
+        * be there.
+        */
+       pen_release = cpu;
+       __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+       outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+
+       /*
+        * Send the secondary CPU a soft interrupt, thereby causing
+        * the boot monitor to read the system wide flags register,
+        * and branch to the address found there.
+        */
+       smp_cross_call(cpumask_of(cpu));
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               smp_rmb();
+               if (pen_release == -1)
+                       break;
+
+               udelay(10);
+       }
+
+       /*
+        * now the secondary core is starting up let it run its
+        * calibrations, then wait for it to finish
+        */
+       spin_unlock(&boot_lock);
+
+       return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+       void __iomem *scu_base = scu_base_addr();
+       unsigned int i, ncores;
+
+       ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+       /* sanity check */
+       if (ncores == 0) {
+               printk(KERN_ERR
+                      "vexpress: strange CM count of 0? Default to 1\n");
+
+               ncores = 1;
+       }
+
+       if (ncores > NR_CPUS) {
+               printk(KERN_WARNING
+                      "vexpress: no. of cores (%d) greater than configured "
+                      "maximum of %d - clipping\n",
+                      ncores, NR_CPUS);
+               ncores = NR_CPUS;
+       }
+
+       for (i = 0; i < ncores; i++)
+               set_cpu_possible(i, true);
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+       unsigned int ncores = num_possible_cpus();
+       unsigned int cpu = smp_processor_id();
+       int i;
+
+       smp_store_cpu_info(cpu);
+
+       /*
+        * are we trying to boot more cores than exist?
+        */
+       if (max_cpus > ncores)
+               max_cpus = ncores;
+
+       /*
+        * Initialise the present map, which describes the set of CPUs
+        * actually populated at the present time.
+        */
+       for (i = 0; i < max_cpus; i++)
+               set_cpu_present(i, true);
+
+       /*
+        * Initialise the SCU if there are more than one CPU and let
+        * them know where to start.
+        */
+       if (max_cpus > 1) {
+               /*
+                * Enable the local timer or broadcast device for the
+                * boot CPU, but only if we have more than one CPU.
+                */
+               percpu_timer_setup();
+
+               scu_enable(scu_base_addr());
+
+               /*
+                * Write the address of secondary startup into the
+                * system-wide flags register. The boot monitor waits
+                * until it receives a soft interrupt, and then the
+                * secondary CPU branches to this address.
+                */
+               writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
+               writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
+                       MMIO_P2V(V2M_SYS_FLAGSSET));
+       }
+}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
new file mode 100644 (file)
index 0000000..d250711
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Versatile Express V2M Motherboard Support
+ */
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/spinlock.h>
+#include <linux/sysdev.h>
+#include <linux/usb/isp1760.h>
+
+#include <asm/clkdev.h>
+#include <asm/sizes.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/arm_timer.h>
+
+#include <mach/clkdev.h>
+#include <mach/motherboard.h>
+
+#include <plat/timer-sp.h>
+
+#include "core.h"
+
+#define V2M_PA_CS0     0x40000000
+#define V2M_PA_CS1     0x44000000
+#define V2M_PA_CS2     0x48000000
+#define V2M_PA_CS3     0x4c000000
+#define V2M_PA_CS7     0x10000000
+
+static struct map_desc v2m_io_desc[] __initdata = {
+       {
+               .virtual        = __MMIO_P2V(V2M_PA_CS7),
+               .pfn            = __phys_to_pfn(V2M_PA_CS7),
+               .length         = SZ_128K,
+               .type           = MT_DEVICE,
+       },
+};
+
+void __init v2m_map_io(struct map_desc *tile, size_t num)
+{
+       iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+       iotable_init(tile, num);
+}
+
+
+static void v2m_timer_init(void)
+{
+       writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
+       writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
+
+       sp804_clocksource_init(MMIO_P2V(V2M_TIMER1));
+       sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
+}
+
+struct sys_timer v2m_timer = {
+       .init   = v2m_timer_init,
+};
+
+
+static DEFINE_SPINLOCK(v2m_cfg_lock);
+
+int v2m_cfg_write(u32 devfn, u32 data)
+{
+       /* Configuration interface broken? */
+       u32 val;
+
+       printk("%s: writing %08x to %08x\n", __func__, data, devfn);
+
+       devfn |= SYS_CFG_START | SYS_CFG_WRITE;
+
+       spin_lock(&v2m_cfg_lock);
+       val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+       writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
+
+       writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
+       writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+
+       do {
+               val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+       } while (val == 0);
+       spin_unlock(&v2m_cfg_lock);
+
+       return !!(val & SYS_CFG_ERR);
+}
+
+int v2m_cfg_read(u32 devfn, u32 *data)
+{
+       u32 val;
+
+       devfn |= SYS_CFG_START;
+
+       spin_lock(&v2m_cfg_lock);
+       writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
+       writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+
+       mb();
+
+       do {
+               cpu_relax();
+               val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+       } while (val == 0);
+
+       *data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
+       spin_unlock(&v2m_cfg_lock);
+
+       return !!(val & SYS_CFG_ERR);
+}
+
+
+static struct resource v2m_pcie_i2c_resource = {
+       .start  = V2M_SERIAL_BUS_PCI,
+       .end    = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device v2m_pcie_i2c_device = {
+       .name           = "versatile-i2c",
+       .id             = 0,
+       .num_resources  = 1,
+       .resource       = &v2m_pcie_i2c_resource,
+};
+
+static struct resource v2m_ddc_i2c_resource = {
+       .start  = V2M_SERIAL_BUS_DVI,
+       .end    = V2M_SERIAL_BUS_DVI + SZ_4K - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device v2m_ddc_i2c_device = {
+       .name           = "versatile-i2c",
+       .id             = 1,
+       .num_resources  = 1,
+       .resource       = &v2m_ddc_i2c_resource,
+};
+
+static struct resource v2m_eth_resources[] = {
+       {
+               .start  = V2M_LAN9118,
+               .end    = V2M_LAN9118 + SZ_64K - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_V2M_LAN9118,
+               .end    = IRQ_V2M_LAN9118,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct smsc911x_platform_config v2m_eth_config = {
+       .flags          = SMSC911X_USE_32BIT,
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+       .irq_type       = SMSC911X_IRQ_TYPE_PUSH_PULL,
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device v2m_eth_device = {
+       .name           = "smsc911x",
+       .id             = -1,
+       .resource       = v2m_eth_resources,
+       .num_resources  = ARRAY_SIZE(v2m_eth_resources),
+       .dev.platform_data = &v2m_eth_config,
+};
+
+static struct resource v2m_usb_resources[] = {
+       {
+               .start  = V2M_ISP1761,
+               .end    = V2M_ISP1761 + SZ_128K - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = IRQ_V2M_ISP1761,
+               .end    = IRQ_V2M_ISP1761,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct isp1760_platform_data v2m_usb_config = {
+       .is_isp1761             = true,
+       .bus_width_16           = false,
+       .port1_otg              = true,
+       .analog_oc              = false,
+       .dack_polarity_high     = false,
+       .dreq_polarity_high     = false,
+};
+
+static struct platform_device v2m_usb_device = {
+       .name           = "isp1760",
+       .id             = -1,
+       .resource       = v2m_usb_resources,
+       .num_resources  = ARRAY_SIZE(v2m_usb_resources),
+       .dev.platform_data = &v2m_usb_config,
+};
+
+static int v2m_flash_init(void)
+{
+       writel(0, MMIO_P2V(V2M_SYS_FLASH));
+       return 0;
+}
+
+static void v2m_flash_exit(void)
+{
+       writel(0, MMIO_P2V(V2M_SYS_FLASH));
+}
+
+static void v2m_flash_set_vpp(int on)
+{
+       writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
+}
+
+static struct flash_platform_data v2m_flash_data = {
+       .map_name       = "cfi_probe",
+       .width          = 4,
+       .init           = v2m_flash_init,
+       .exit           = v2m_flash_exit,
+       .set_vpp        = v2m_flash_set_vpp,
+};
+
+static struct resource v2m_flash_resources[] = {
+       {
+               .start  = V2M_NOR0,
+               .end    = V2M_NOR0 + SZ_64M - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = V2M_NOR1,
+               .end    = V2M_NOR1 + SZ_64M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device v2m_flash_device = {
+       .name           = "armflash",
+       .id             = -1,
+       .resource       = v2m_flash_resources,
+       .num_resources  = ARRAY_SIZE(v2m_flash_resources),
+       .dev.platform_data = &v2m_flash_data,
+};
+
+
+static unsigned int v2m_mmci_status(struct device *dev)
+{
+       return !(readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0));
+}
+
+static struct mmci_platform_data v2m_mmci_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = v2m_mmci_status,
+};
+
+static AMBA_DEVICE(aaci,  "mb:aaci",  V2M_AACI, NULL);
+static AMBA_DEVICE(mmci,  "mb:mmci",  V2M_MMCI, &v2m_mmci_data);
+static AMBA_DEVICE(kmi0,  "mb:kmi0",  V2M_KMI0, NULL);
+static AMBA_DEVICE(kmi1,  "mb:kmi1",  V2M_KMI1, NULL);
+static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
+static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
+static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
+static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
+static AMBA_DEVICE(wdt,   "mb:wdt",   V2M_WDT, NULL);
+static AMBA_DEVICE(rtc,   "mb:rtc",   V2M_RTC, NULL);
+
+static struct amba_device *v2m_amba_devs[] __initdata = {
+       &aaci_device,
+       &mmci_device,
+       &kmi0_device,
+       &kmi1_device,
+       &uart0_device,
+       &uart1_device,
+       &uart2_device,
+       &uart3_device,
+       &wdt_device,
+       &rtc_device,
+};
+
+
+static long v2m_osc_round(struct clk *clk, unsigned long rate)
+{
+       return rate;
+}
+
+static int v2m_osc1_set(struct clk *clk, unsigned long rate)
+{
+       return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
+}
+
+static const struct clk_ops osc1_clk_ops = {
+       .round  = v2m_osc_round,
+       .set    = v2m_osc1_set,
+};
+
+static struct clk osc1_clk = {
+       .ops    = &osc1_clk_ops,
+       .rate   = 24000000,
+};
+
+static struct clk osc2_clk = {
+       .rate   = 24000000,
+};
+
+static struct clk_lookup v2m_lookups[] = {
+       {       /* UART0 */
+               .dev_id         = "mb:uart0",
+               .clk            = &osc2_clk,
+       }, {    /* UART1 */
+               .dev_id         = "mb:uart1",
+               .clk            = &osc2_clk,
+       }, {    /* UART2 */
+               .dev_id         = "mb:uart2",
+               .clk            = &osc2_clk,
+       }, {    /* UART3 */
+               .dev_id         = "mb:uart3",
+               .clk            = &osc2_clk,
+       }, {    /* KMI0 */
+               .dev_id         = "mb:kmi0",
+               .clk            = &osc2_clk,
+       }, {    /* KMI1 */
+               .dev_id         = "mb:kmi1",
+               .clk            = &osc2_clk,
+       }, {    /* MMC0 */
+               .dev_id         = "mb:mmci",
+               .clk            = &osc2_clk,
+       }, {    /* CLCD */
+               .dev_id         = "mb:clcd",
+               .clk            = &osc1_clk,
+       },
+};
+
+static void v2m_power_off(void)
+{
+       if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
+               printk(KERN_EMERG "Unable to shutdown\n");
+}
+
+static void v2m_restart(char str, const char *cmd)
+{
+       if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
+               printk(KERN_EMERG "Unable to reboot\n");
+}
+
+static int __init v2m_init(void)
+{
+       int i;
+
+       clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
+
+       platform_device_register(&v2m_pcie_i2c_device);
+       platform_device_register(&v2m_ddc_i2c_device);
+       platform_device_register(&v2m_flash_device);
+       platform_device_register(&v2m_eth_device);
+       platform_device_register(&v2m_usb_device);
+
+       for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
+               amba_device_register(v2m_amba_devs[i], &iomem_resource);
+
+       pm_power_off = v2m_power_off;
+       arm_pm_restart = v2m_restart;
+
+       return 0;
+}
+arch_initcall(v2m_init);
index 5bd7c89..346ae14 100644 (file)
@@ -572,6 +572,8 @@ config CPU_TLB_V6
 config CPU_TLB_V7
        bool
 
+config VERIFY_PERMISSION_FAULT
+       bool
 endif
 
 config CPU_HAS_ASID
@@ -760,7 +762,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
 config CACHE_L2X0
        bool "Enable the L2x0 outer cache controller"
        depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
-                  REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK || ARCH_OMAP4
+                  REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
+                  ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
        default y
        select OUTER_CACHE
        select OUTER_CACHE_SYNC
@@ -769,7 +772,7 @@ config CACHE_L2X0
 
 config CACHE_TAUROS2
        bool "Enable the Tauros2 L2 cache controller"
-       depends on ARCH_DOVE
+       depends on (ARCH_DOVE || ARCH_MMP)
        default y
        select OUTER_CACHE
        help
@@ -789,6 +792,25 @@ config ARM_L1_CACHE_SHIFT
        default 6 if ARM_L1_CACHE_SHIFT_6
        default 5
 
+config ARM_DMA_MEM_BUFFERABLE
+       bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7
+       default y if CPU_V6 || CPU_V7
+       help
+         Historically, the kernel has used strongly ordered mappings to
+         provide DMA coherent memory.  With the advent of ARMv7, mapping
+         memory with differing types results in unpredictable behaviour,
+         so on these CPUs, this option is forced on.
+
+         Multiple mappings with differing attributes is also unpredictable
+         on ARMv6 CPUs, but since they do not have aggressive speculative
+         prefetch, no harm appears to occur.
+
+         However, drivers may be missing the necessary barriers for ARMv6,
+         and therefore turning this on may result in unpredictable driver
+         behaviour.  Therefore, we offer this as an option.
+
+         You are recommended say 'Y' here and debug any affected drivers.
+
 config ARCH_HAS_BARRIERS
        bool
        help
index 2e6dc04..ec88b15 100644 (file)
@@ -29,5 +29,26 @@ ENTRY(v7_early_abort)
         * V6 code adjusts the returned DFSR.
         * New designs should not need to patch up faults.
         */
+
+#if defined(CONFIG_VERIFY_PERMISSION_FAULT)
+       /*
+        * Detect erroneous permission failures and fix
+        */
+       ldr     r3, =0x40d                      @ On permission fault
+       and     r3, r1, r3
+       cmp     r3, #0x0d
+       movne   pc, lr
+
+       mcr     p15, 0, r0, c7, c8, 0           @ Retranslate FAR
+       isb
+       mrc     p15, 0, r2, c7, c4, 0           @ Read the PAR
+       and     r3, r2, #0x7b                   @ On translation fault
+       cmp     r3, #0x0b
+       movne   pc, lr
+       bic     r1, r1, #0xf                    @ Fix up FSR FS[5:0]
+       and     r2, r2, #0x7e
+       orr     r1, r1, r2, LSR #1
+#endif
+
        mov     pc, lr
 ENDPROC(v7_early_abort)
index edddd66..6f98c35 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
@@ -94,36 +95,29 @@ static const char *usermode_action[] = {
        "signal+warn"
 };
 
-static int
-proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
-                   void *data)
+static int alignment_proc_show(struct seq_file *m, void *v)
 {
-       char *p = page;
-       int len;
-
-       p += sprintf(p, "User:\t\t%lu\n", ai_user);
-       p += sprintf(p, "System:\t\t%lu\n", ai_sys);
-       p += sprintf(p, "Skipped:\t%lu\n", ai_skipped);
-       p += sprintf(p, "Half:\t\t%lu\n", ai_half);
-       p += sprintf(p, "Word:\t\t%lu\n", ai_word);
+       seq_printf(m, "User:\t\t%lu\n", ai_user);
+       seq_printf(m, "System:\t\t%lu\n", ai_sys);
+       seq_printf(m, "Skipped:\t%lu\n", ai_skipped);
+       seq_printf(m, "Half:\t\t%lu\n", ai_half);
+       seq_printf(m, "Word:\t\t%lu\n", ai_word);
        if (cpu_architecture() >= CPU_ARCH_ARMv5TE)
-               p += sprintf(p, "DWord:\t\t%lu\n", ai_dword);
-       p += sprintf(p, "Multi:\t\t%lu\n", ai_multi);
-       p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode,
+               seq_printf(m, "DWord:\t\t%lu\n", ai_dword);
+       seq_printf(m, "Multi:\t\t%lu\n", ai_multi);
+       seq_printf(m, "User faults:\t%i (%s)\n", ai_usermode,
                        usermode_action[ai_usermode]);
 
-       len = (p - page) - off;
-       if (len < 0)
-               len = 0;
-
-       *eof = (len <= count) ? 1 : 0;
-       *start = page + off;
+       return 0;
+}
 
-       return len;
+static int alignment_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, alignment_proc_show, NULL);
 }
 
-static int proc_alignment_write(struct file *file, const char __user *buffer,
-                               unsigned long count, void *data)
+static ssize_t alignment_proc_write(struct file *file, const char __user *buffer,
+                                   size_t count, loff_t *pos)
 {
        char mode;
 
@@ -136,6 +130,13 @@ static int proc_alignment_write(struct file *file, const char __user *buffer,
        return count;
 }
 
+static const struct file_operations alignment_proc_fops = {
+       .open           = alignment_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .write          = alignment_proc_write,
+};
 #endif /* CONFIG_PROC_FS */
 
 union offset_union {
@@ -166,15 +167,15 @@ union offset_union {
  THUMB(        "1:     "ins"   %1, [%2]\n"     )               \
  THUMB(        "       add     %2, %2, #1\n"   )               \
        "2:\n"                                          \
-       "       .section .fixup,\"ax\"\n"               \
+       "       .pushsection .fixup,\"ax\"\n"           \
        "       .align  2\n"                            \
        "3:     mov     %0, #1\n"                       \
        "       b       2b\n"                           \
-       "       .previous\n"                            \
-       "       .section __ex_table,\"a\"\n"            \
+       "       .popsection\n"                          \
+       "       .pushsection __ex_table,\"a\"\n"        \
        "       .align  3\n"                            \
        "       .long   1b, 3b\n"                       \
-       "       .previous\n"                            \
+       "       .popsection\n"                          \
        : "=r" (err), "=&r" (val), "=r" (addr)          \
        : "0" (err), "2" (addr))
 
@@ -226,16 +227,16 @@ union offset_union {
                "       mov     %1, %1, "NEXT_BYTE"\n"          \
                "2:     "ins"   %1, [%2]\n"                     \
                "3:\n"                                          \
-               "       .section .fixup,\"ax\"\n"               \
+               "       .pushsection .fixup,\"ax\"\n"           \
                "       .align  2\n"                            \
                "4:     mov     %0, #1\n"                       \
                "       b       3b\n"                           \
-               "       .previous\n"                            \
-               "       .section __ex_table,\"a\"\n"            \
+               "       .popsection\n"                          \
+               "       .pushsection __ex_table,\"a\"\n"        \
                "       .align  3\n"                            \
                "       .long   1b, 4b\n"                       \
                "       .long   2b, 4b\n"                       \
-               "       .previous\n"                            \
+               "       .popsection\n"                          \
                : "=r" (err), "=&r" (v), "=&r" (a)              \
                : "0" (err), "1" (v), "2" (a));                 \
                if (err)                                        \
@@ -266,18 +267,18 @@ union offset_union {
                "       mov     %1, %1, "NEXT_BYTE"\n"          \
                "4:     "ins"   %1, [%2]\n"                     \
                "5:\n"                                          \
-               "       .section .fixup,\"ax\"\n"               \
+               "       .pushsection .fixup,\"ax\"\n"           \
                "       .align  2\n"                            \
                "6:     mov     %0, #1\n"                       \
                "       b       5b\n"                           \
-               "       .previous\n"                            \
-               "       .section __ex_table,\"a\"\n"            \
+               "       .popsection\n"                          \
+               "       .pushsection __ex_table,\"a\"\n"        \
                "       .align  3\n"                            \
                "       .long   1b, 6b\n"                       \
                "       .long   2b, 6b\n"                       \
                "       .long   3b, 6b\n"                       \
                "       .long   4b, 6b\n"                       \
-               "       .previous\n"                            \
+               "       .popsection\n"                          \
                : "=r" (err), "=&r" (v), "=&r" (a)              \
                : "0" (err), "1" (v), "2" (a));                 \
                if (err)                                        \
@@ -901,12 +902,10 @@ static int __init alignment_init(void)
 #ifdef CONFIG_PROC_FS
        struct proc_dir_entry *res;
 
-       res = create_proc_entry("cpu/alignment", S_IWUSR | S_IRUGO, NULL);
+       res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL,
+                         &alignment_proc_fops);
        if (!res)
                return -ENOMEM;
-
-       res->read_proc = proc_alignment_read;
-       res->write_proc = proc_alignment_write;
 #endif
 
        /*
index 21ad68b..9819869 100644 (file)
@@ -27,6 +27,7 @@
 
 static void __iomem *l2x0_base;
 static DEFINE_SPINLOCK(l2x0_lock);
+static uint32_t l2x0_way_mask; /* Bitmask of active ways */
 
 static inline void cache_wait(void __iomem *reg, unsigned long mask)
 {
@@ -108,8 +109,8 @@ static inline void l2x0_inv_all(void)
 
        /* invalidate all ways */
        spin_lock_irqsave(&l2x0_lock, flags);
-       writel(0xff, l2x0_base + L2X0_INV_WAY);
-       cache_wait(l2x0_base + L2X0_INV_WAY, 0xff);
+       writel(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+       cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
        cache_sync();
        spin_unlock_irqrestore(&l2x0_lock, flags);
 }
@@ -208,9 +209,37 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
 void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 {
        __u32 aux;
+       __u32 cache_id;
+       int ways;
+       const char *type;
 
        l2x0_base = base;
 
+       cache_id = readl(l2x0_base + L2X0_CACHE_ID);
+       aux = readl(l2x0_base + L2X0_AUX_CTRL);
+
+       /* Determine the number of ways */
+       switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
+       case L2X0_CACHE_ID_PART_L310:
+               if (aux & (1 << 16))
+                       ways = 16;
+               else
+                       ways = 8;
+               type = "L310";
+               break;
+       case L2X0_CACHE_ID_PART_L210:
+               ways = (aux >> 13) & 0xf;
+               type = "L210";
+               break;
+       default:
+               /* Assume unknown chips have 8 ways */
+               ways = 8;
+               type = "L2x0 series";
+               break;
+       }
+
+       l2x0_way_mask = (1 << ways) - 1;
+
        /*
         * Check if l2x0 controller is already enabled.
         * If you are booting from non-secure mode
@@ -219,8 +248,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
        if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
 
                /* l2x0 controller is disabled */
-
-               aux = readl(l2x0_base + L2X0_AUX_CTRL);
                aux &= aux_mask;
                aux |= aux_val;
                writel(aux, l2x0_base + L2X0_AUX_CTRL);
@@ -236,5 +263,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
        outer_cache.flush_range = l2x0_flush_range;
        outer_cache.sync = l2x0_cache_sync;
 
-       printk(KERN_INFO "L2X0 cache controller enabled\n");
+       printk(KERN_INFO "%s cache controller enabled\n", type);
+       printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
+                        ways, cache_id, aux);
 }
index 9d89c67..e46ecd8 100644 (file)
@@ -211,6 +211,9 @@ v6_dma_inv_range:
        mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
 #endif
 1:
+#ifdef CONFIG_SMP
+       str     r0, [r0]                        @ write for ownership
+#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
 #else
@@ -231,6 +234,9 @@ v6_dma_inv_range:
 v6_dma_clean_range:
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
+#ifdef CONFIG_SMP
+       ldr     r2, [r0]                        @ read for ownership
+#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c10, 1          @ clean D line
 #else
@@ -251,6 +257,10 @@ v6_dma_clean_range:
 ENTRY(v6_dma_flush_range)
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
+#ifdef CONFIG_SMP
+       ldr     r2, [r0]                        @ read for ownership
+       str     r2, [r0]                        @ write for ownership
+#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
 #else
@@ -273,7 +283,9 @@ ENTRY(v6_dma_map_area)
        add     r1, r1, r0
        teq     r2, #DMA_FROM_DEVICE
        beq     v6_dma_inv_range
-       b       v6_dma_clean_range
+       teq     r2, #DMA_TO_DEVICE
+       beq     v6_dma_clean_range
+       b       v6_dma_flush_range
 ENDPROC(v6_dma_map_area)
 
 /*
@@ -283,9 +295,6 @@ ENDPROC(v6_dma_map_area)
  *     - dir   - DMA direction
  */
 ENTRY(v6_dma_unmap_area)
-       add     r1, r1, r0
-       teq     r2, #DMA_TO_DEVICE
-       bne     v6_dma_inv_range
        mov     pc, lr
 ENDPROC(v6_dma_unmap_area)
 
index bcd64f2..06a90dc 100644 (file)
@@ -167,7 +167,11 @@ ENTRY(v7_coherent_user_range)
        cmp     r0, r1
        blo     1b
        mov     r0, #0
+#ifdef CONFIG_SMP
+       mcr     p15, 0, r0, c7, c1, 6           @ invalidate BTB Inner Shareable
+#else
        mcr     p15, 0, r0, c7, c5, 6           @ invalidate BTB
+#endif
        dsb
        isb
        mov     pc, lr
index b2a6008..d2852e1 100644 (file)
@@ -40,7 +40,7 @@ fa_copy_user_page(void *kto, const void *kfrom)
 }
 
 void fa_copy_user_highpage(struct page *to, struct page *from,
-       unsigned long vaddr)
+       unsigned long vaddr, struct vm_area_struct *vma)
 {
        void *kto, *kfrom;
 
index 8bca4de..f55fa10 100644 (file)
@@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
        kfrom = kmap_atomic(from, KM_USER0);
        kto = kmap_atomic(to, KM_USER1);
        copy_page(kto, kfrom);
-#ifdef CONFIG_HIGHMEM
-       /*
-        * kmap_atomic() doesn't set the page virtual address, and
-        * kunmap_atomic() takes care of cache flushing already.
-        */
-       if (page_address(to) != NULL)
-#endif
-               __cpuc_flush_dcache_area(kto, PAGE_SIZE);
+       __cpuc_flush_dcache_area(kto, PAGE_SIZE);
        kunmap_atomic(kto, KM_USER1);
        kunmap_atomic(kfrom, KM_USER0);
 }
index 1351edc..13fa536 100644 (file)
@@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
                                vaddr += offset;
                                op(vaddr, len, dir);
                                kunmap_high(page);
+                       } else if (cache_is_vipt()) {
+                               pte_t saved_pte;
+                               vaddr = kmap_high_l1_vipt(page, &saved_pte);
+                               op(vaddr + offset, len, dir);
+                               kunmap_high_l1_vipt(page, saved_pte);
                        }
                } else {
                        vaddr = page_address(page) + offset;
index 0d414c2..9b906de 100644 (file)
@@ -134,8 +134,6 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
        flush_dcache_mmap_unlock(mapping);
        if (aliases)
                do_adjust_pte(vma, addr, pfn, ptep);
-       else
-               flush_cache_page(vma, addr, pfn);
 }
 
 /*
index 9d40c34..92f5801 100644 (file)
@@ -463,7 +463,12 @@ static struct fsr_info {
        { do_bad,               SIGILL,  BUS_ADRALN,    "alignment exception"              },
        { do_bad,               SIGKILL, 0,             "terminal exception"               },
        { do_bad,               SIGILL,  BUS_ADRALN,    "alignment exception"              },
+/* Do we need runtime check ? */
+#if __LINUX_ARM_ARCH__ < 6
        { do_bad,               SIGBUS,  0,             "external abort on linefetch"      },
+#else
+       { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "I-cache maintenance fault"        },
+#endif
        { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "section translation fault"        },
        { do_bad,               SIGBUS,  0,             "external abort on linefetch"      },
        { do_page_fault,        SIGSEGV, SEGV_MAPERR,   "page translation fault"           },
index e34f095..c6844cb 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
+#include <asm/highmem.h>
 #include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
@@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
-       void *addr = page_address(page);
-
        /*
         * Writeback any data associated with the kernel mapping of this
         * page.  This ensures that data in the physical page is mutually
         * coherent with the kernels mapping.
         */
-#ifdef CONFIG_HIGHMEM
-       /*
-        * kmap_atomic() doesn't set the page virtual address, and
-        * kunmap_atomic() takes care of cache flushing already.
-        */
-       if (addr)
-#endif
-               __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+       if (!PageHighMem(page)) {
+               __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+       } else {
+               void *addr = kmap_high_get(page);
+               if (addr) {
+                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                       kunmap_high(page);
+               } else if (cache_is_vipt()) {
+                       pte_t saved_pte;
+                       addr = kmap_high_l1_vipt(page, &saved_pte);
+                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                       kunmap_high_l1_vipt(page, saved_pte);
+               }
+       }
 
        /*
         * If this is a page cache page, and we have an aliasing VIPT cache,
index 2be1ec7..77b030f 100644 (file)
@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
        unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 
        if (kvaddr >= (void *)FIXADDR_START) {
-               __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+               if (cache_is_vivt())
+                       __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
                BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
                set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
        pte = TOP_PTE(vaddr);
        return pte_page(*pte);
 }
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#include <linux/percpu.h>
+
+/*
+ * The VIVT cache of a highmem page is always flushed before the page
+ * is unmapped. Hence unmapped highmem pages need no cache maintenance
+ * in that case.
+ *
+ * However unmapped pages may still be cached with a VIPT cache, and
+ * it is not possible to perform cache maintenance on them using physical
+ * addresses unfortunately.  So we have no choice but to set up a temporary
+ * virtual mapping for that purpose.
+ *
+ * Yet this VIPT cache maintenance may be triggered from DMA support
+ * functions which are possibly called from interrupt context. As we don't
+ * want to keep interrupt disabled all the time when such maintenance is
+ * taking place, we therefore allow for some reentrancy by preserving and
+ * restoring the previous fixmap entry before the interrupted context is
+ * resumed.  If the reentrancy depth is 0 then there is no need to restore
+ * the previous fixmap, and leaving the current one in place allow it to
+ * be reused the next time without a TLB flush (common with DMA).
+ */
+
+static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
+
+void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
+{
+       unsigned int idx, cpu = smp_processor_id();
+       int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+       unsigned long vaddr, flags;
+       pte_t pte, *ptep;
+
+       idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       ptep = TOP_PTE(vaddr);
+       pte = mk_pte(page, kmap_prot);
+
+       if (!in_interrupt())
+               preempt_disable();
+
+       raw_local_irq_save(flags);
+       (*depth)++;
+       if (pte_val(*ptep) == pte_val(pte)) {
+               *saved_pte = pte;
+       } else {
+               *saved_pte = *ptep;
+               set_pte_ext(ptep, pte, 0);
+               local_flush_tlb_kernel_page(vaddr);
+       }
+       raw_local_irq_restore(flags);
+
+       return (void *)vaddr;
+}
+
+void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
+{
+       unsigned int idx, cpu = smp_processor_id();
+       int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+       unsigned long vaddr, flags;
+       pte_t pte, *ptep;
+
+       idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       ptep = TOP_PTE(vaddr);
+       pte = mk_pte(page, kmap_prot);
+
+       BUG_ON(pte_val(*ptep) != pte_val(pte));
+       BUG_ON(*depth <= 0);
+
+       raw_local_irq_save(flags);
+       (*depth)--;
+       if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
+               set_pte_ext(ptep, saved_pte, 0);
+               local_flush_tlb_kernel_page(vaddr);
+       }
+       raw_local_irq_restore(flags);
+
+       if (!in_interrupt())
+               preempt_enable();
+}
+
+#endif  /* CONFIG_CPU_CACHE_VIPT */
index 83db12a..1ba6cf5 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
-#include <linux/sort.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 
@@ -86,9 +85,6 @@ void show_mem(void)
        printk("Mem-info:\n");
        show_free_areas();
        for_each_online_node(node) {
-               pg_data_t *n = NODE_DATA(node);
-               struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
                for_each_nodebank (i,mi,node) {
                        struct membank *bank = &mi->bank[i];
                        unsigned int pfn1, pfn2;
@@ -97,8 +93,8 @@ void show_mem(void)
                        pfn1 = bank_pfn_start(bank);
                        pfn2 = bank_pfn_end(bank);
 
-                       page = map + pfn1;
-                       end  = map + pfn2;
+                       page = pfn_to_page(pfn1);
+                       end  = pfn_to_page(pfn2 - 1) + 1;
 
                        do {
                                total++;
@@ -227,20 +223,6 @@ static int __init check_initrd(struct meminfo *mi)
        return initrd_node;
 }
 
-static inline void map_memory_bank(struct membank *bank)
-{
-#ifdef CONFIG_MMU
-       struct map_desc map;
-
-       map.pfn = bank_pfn_start(bank);
-       map.virtual = __phys_to_virt(bank_phys_start(bank));
-       map.length = bank_phys_size(bank);
-       map.type = MT_MEMORY;
-
-       create_mapping(&map);
-#endif
-}
-
 static void __init bootmem_init_node(int node, struct meminfo *mi,
        unsigned long start_pfn, unsigned long end_pfn)
 {
@@ -249,16 +231,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
        pg_data_t *pgdat;
        int i;
 
-       /*
-        * Map the memory banks for this node.
-        */
-       for_each_nodebank(i, mi, node) {
-               struct membank *bank = &mi->bank[i];
-
-               if (!bank->highmem)
-                       map_memory_bank(bank);
-       }
-
        /*
         * Allocate the bootmem bitmap page.
         */
@@ -388,21 +360,12 @@ static void arm_memory_present(struct meminfo *mi, int node)
 }
 #endif
 
-static int __init meminfo_cmp(const void *_a, const void *_b)
-{
-       const struct membank *a = _a, *b = _b;
-       long cmp = bank_pfn_start(a) - bank_pfn_start(b);
-       return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
-}
-
 void __init bootmem_init(void)
 {
        struct meminfo *mi = &meminfo;
        unsigned long min, max_low, max_high;
        int node, initrd_node;
 
-       sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
-
        /*
         * Locate which node contains the ramdisk image, if any.
         */
@@ -603,9 +566,6 @@ void __init mem_init(void)
        reserved_pages = free_pages = 0;
 
        for_each_online_node(node) {
-               pg_data_t *n = NODE_DATA(node);
-               struct page *map = pgdat_page_nr(n, 0) - n->node_start_pfn;
-
                for_each_nodebank(i, &meminfo, node) {
                        struct membank *bank = &meminfo.bank[i];
                        unsigned int pfn1, pfn2;
@@ -614,8 +574,8 @@ void __init mem_init(void)
                        pfn1 = bank_pfn_start(bank);
                        pfn2 = bank_pfn_end(bank);
 
-                       page = map + pfn1;
-                       end  = map + pfn2;
+                       page = pfn_to_page(pfn1);
+                       end  = pfn_to_page(pfn2 - 1) + 1;
 
                        do {
                                if (PageReserved(page))
index a888363..815d08e 100644 (file)
@@ -28,10 +28,7 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
 
 #endif
 
-struct map_desc;
-struct meminfo;
 struct pglist_data;
 
-void __init create_mapping(struct map_desc *md);
 void __init bootmem_init(void);
 void reserve_node_zero(struct pglist_data *pgdat);
index 9d4da6a..2858941 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/bootmem.h>
 #include <linux/mman.h>
 #include <linux/nodemask.h>
+#include <linux/sort.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -420,6 +421,10 @@ static void __init build_mem_type_table(void)
                user_pgprot |= L_PTE_SHARED;
                kern_pgprot |= L_PTE_SHARED;
                vecs_pgprot |= L_PTE_SHARED;
+               mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+               mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+               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_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
@@ -599,7 +604,7 @@ static void __init create_36bit_mapping(struct map_desc *md,
  * offsets, and we take full advantage of sections and
  * supersections.
  */
-void __init create_mapping(struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
 {
        unsigned long phys, addr, length, end;
        const struct mem_type *type;
@@ -865,9 +870,10 @@ void __init reserve_node_zero(pg_data_t *pgdat)
        if (machine_is_p720t())
                res_size = 0x00014000;
 
-       /* H1940 and RX3715 need to reserve this for suspend */
+       /* H1940, RX3715 and RX1950 need to reserve this for suspend */
 
-       if (machine_is_h1940() || machine_is_rx3715()) {
+       if (machine_is_h1940() || machine_is_rx3715()
+               || machine_is_rx1950()) {
                reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
                                BOOTMEM_DEFAULT);
                reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
@@ -1013,6 +1019,39 @@ static void __init kmap_init(void)
 #endif
 }
 
+static inline void map_memory_bank(struct membank *bank)
+{
+       struct map_desc map;
+
+       map.pfn = bank_pfn_start(bank);
+       map.virtual = __phys_to_virt(bank_phys_start(bank));
+       map.length = bank_phys_size(bank);
+       map.type = MT_MEMORY;
+
+       create_mapping(&map);
+}
+
+static void __init map_lowmem(void)
+{
+       struct meminfo *mi = &meminfo;
+       int i;
+
+       /* Map all the lowmem memory banks. */
+       for (i = 0; i < mi->nr_banks; i++) {
+               struct membank *bank = &mi->bank[i];
+
+               if (!bank->highmem)
+                       map_memory_bank(bank);
+       }
+}
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+       const struct membank *a = _a, *b = _b;
+       long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+       return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1021,9 +1060,12 @@ void __init paging_init(struct machine_desc *mdesc)
 {
        void *zero_page;
 
+       sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
        build_mem_type_table();
        sanity_check_meminfo();
        prepare_page_table();
+       map_lowmem();
        bootmem_init();
        devicemaps_init(mdesc);
        kmap_init();
@@ -1050,10 +1092,12 @@ void setup_mm_for_reboot(char mode)
        pgd_t *pgd;
        int i;
 
-       if (current->mm && current->mm->pgd)
-               pgd = current->mm->pgd;
-       else
-               pgd = init_mm.pgd;
+       /*
+        * We need to access to user-mode page tables here. For kernel threads
+        * we don't have any user-mode mappings so we use the context that we
+        * "borrowed".
+        */
+       pgd = current->active_mm->pgd;
 
        base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
        if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
index 9bfeb6b..33b3273 100644 (file)
@@ -65,6 +65,15 @@ void flush_dcache_page(struct page *page)
 }
 EXPORT_SYMBOL(flush_dcache_page);
 
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+                      unsigned long uaddr, void *dst, const void *src,
+                      unsigned long len)
+{
+       memcpy(dst, src, len);
+       if (vma->vm_flags & VM_EXEC)
+               __cpuc_coherent_user_range(uaddr, uaddr + len);
+}
+
 void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
                                size_t size, unsigned int mtype)
 {
@@ -87,8 +96,8 @@ void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
 }
 EXPORT_SYMBOL(__arm_ioremap);
 
-void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
-                           unsigned int mtype, void *caller)
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+                                  unsigned int mtype, void *caller)
 {
        return __arm_ioremap(phys_addr, size, mtype);
 }
index ee77002..5c47760 100644 (file)
@@ -45,7 +45,7 @@ ENTRY(cpu_sa1100_proc_init)
        mcr     p15, 0, r0, c9, c0, 5           @ Allow read-buffer operations from userland
        mov     pc, lr
 
-       .previous
+       .section .text
 
 /*
  * cpu_sa1100_proc_fin()
index 0cb1848..f3f288a 100644 (file)
@@ -50,7 +50,11 @@ ENTRY(v7wbi_flush_user_tlb_range)
        cmp     r0, r1
        blo     1b
        mov     ip, #0
+#ifdef CONFIG_SMP
+       mcr     p15, 0, ip, c7, c1, 6           @ flush BTAC/BTB Inner Shareable
+#else
        mcr     p15, 0, ip, c7, c5, 6           @ flush BTAC/BTB
+#endif
        dsb
        mov     pc, lr
 ENDPROC(v7wbi_flush_user_tlb_range)
@@ -79,7 +83,11 @@ ENTRY(v7wbi_flush_kern_tlb_range)
        cmp     r0, r1
        blo     1b
        mov     r2, #0
+#ifdef CONFIG_SMP
+       mcr     p15, 0, r2, c7, c1, 6           @ flush BTAC/BTB Inner Shareable
+#else
        mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
+#endif
        dsb
        isb
        mov     pc, lr
index 48bca0d..cafa183 100644 (file)
@@ -111,12 +111,12 @@ next:
        @ to fault.  Emit the appropriate exception gunk to fix things up.
        @ ??? For some reason, faults can happen at .Lx2 even with a
        @ plain LDR instruction.  Weird, but it seems harmless.
-       .section .fixup,"ax"
+       .pushsection .fixup,"ax"
        .align  2
 .Lfix: mov     pc, r9                  @ let the user eat segfaults
-       .previous
+       .popsection
 
-       .section __ex_table,"a"
+       .pushsection __ex_table,"a"
        .align  3
        .long   .Lx1, .Lfix
-       .previous
+       .popsection
index 4c0ab50..cb7658e 100644 (file)
@@ -24,6 +24,7 @@
 #include "fpa11.h"
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 
 /* XXX */
 #include <linux/errno.h>
@@ -134,13 +135,17 @@ a SIGFPE exception if necessary.  If not the relevant bits in the
 cumulative exceptions flag byte are set and we return.
 */
 
+#ifdef CONFIG_DEBUG_USER
+/* By default, ignore inexact errors as there are far too many of them to log */
+static int debug = ~BIT_IXC;
+#endif
+
 void float_raise(signed char flags)
 {
        register unsigned int fpsr, cumulativeTraps;
 
 #ifdef CONFIG_DEBUG_USER
-       /* Ignore inexact errors as there are far too many of them to log */
-       if (flags & ~BIT_IXC)
+       if (flags & debug)
                printk(KERN_DEBUG
                       "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
                       current->comm, current->pid, flags,
@@ -179,3 +184,7 @@ module_exit(fpe_exit);
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)");
 MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_DEBUG_USER
+module_param(debug, int, 0644);
+#endif
index 88e31f5..e666eaf 100644 (file)
@@ -6,9 +6,4 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
                oprofilefs.o oprofile_stats.o \
                timer_int.o )
 
-oprofile-y                             := $(DRIVER_OBJS) common.o backtrace.o
-oprofile-$(CONFIG_CPU_XSCALE)          += op_model_xscale.o
-oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o
-oprofile-$(CONFIG_OPROFILE_ARMV6)      += op_model_v6.o
-oprofile-$(CONFIG_OPROFILE_MPCORE)     += op_model_mpcore.o
-oprofile-$(CONFIG_OPROFILE_ARMV7)      += op_model_v7.o
+oprofile-y                             := $(DRIVER_OBJS) common.o
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
deleted file mode 100644 (file)
index d805a52..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Arm specific backtracing code for oprofile
- *
- * Copyright 2005 Openedhand Ltd.
- *
- * Author: Richard Purdie <rpurdie@openedhand.com>
- *
- * Based on i386 oprofile backtrace code by John Levon, David Smith
- *
- * 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/oprofile.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <asm/ptrace.h>
-#include <asm/stacktrace.h>
-
-static int report_trace(struct stackframe *frame, void *d)
-{
-       unsigned int *depth = d;
-
-       if (*depth) {
-               oprofile_add_trace(frame->pc);
-               (*depth)--;
-       }
-
-       return *depth == 0;
-}
-
-/*
- * The registers we're interested in are at the end of the variable
- * length saved register structure. The fp points at the end of this
- * structure so the address of this struct is:
- * (struct frame_tail *)(xxx->fp)-1
- */
-struct frame_tail {
-       struct frame_tail *fp;
-       unsigned long sp;
-       unsigned long lr;
-} __attribute__((packed));
-
-static struct frame_tail* user_backtrace(struct frame_tail *tail)
-{
-       struct frame_tail buftail[2];
-
-       /* Also check accessibility of one struct frame_tail beyond */
-       if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
-               return NULL;
-       if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
-               return NULL;
-
-       oprofile_add_trace(buftail[0].lr);
-
-       /* frame pointers should strictly progress back up the stack
-        * (towards higher addresses) */
-       if (tail >= buftail[0].fp)
-               return NULL;
-
-       return buftail[0].fp-1;
-}
-
-void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
-{
-       struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
-
-       if (!user_mode(regs)) {
-               struct stackframe frame;
-               frame.fp = regs->ARM_fp;
-               frame.sp = regs->ARM_sp;
-               frame.lr = regs->ARM_lr;
-               frame.pc = regs->ARM_pc;
-               walk_stackframe(&frame, report_trace, &depth);
-               return;
-       }
-
-       while (depth-- && tail && !((unsigned long) tail & 3))
-               tail = user_backtrace(tail);
-}
index 3fcd752..0691176 100644 (file)
  * @file common.c
  *
  * @remark Copyright 2004 Oprofile Authors
+ * @remark Copyright 2010 ARM Ltd.
  * @remark Read the file COPYING
  *
  * @author Zwane Mwaikambo
+ * @author Will Deacon [move to perf]
  */
 
+#include <linux/cpumask.h>
+#include <linux/err.h>
+#include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/mutex.h>
 #include <linux/oprofile.h>
-#include <linux/errno.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/sysdev.h>
-#include <linux/mutex.h>
+#include <asm/stacktrace.h>
+#include <linux/uaccess.h>
 
-#include "op_counter.h"
-#include "op_arm_model.h"
+#include <asm/perf_event.h>
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_HW_PERF_EVENTS
+/*
+ * Per performance monitor configuration as set via oprofilefs.
+ */
+struct op_counter_config {
+       unsigned long count;
+       unsigned long enabled;
+       unsigned long event;
+       unsigned long unit_mask;
+       unsigned long kernel;
+       unsigned long user;
+       struct perf_event_attr attr;
+};
 
-static struct op_arm_model_spec *op_arm_model;
 static int op_arm_enabled;
 static DEFINE_MUTEX(op_arm_mutex);
 
-struct op_counter_config *counter_config;
+static struct op_counter_config *counter_config;
+static struct perf_event **perf_events[nr_cpumask_bits];
+static int perf_num_counters;
+
+/*
+ * Overflow callback for oprofile.
+ */
+static void op_overflow_handler(struct perf_event *event, int unused,
+                       struct perf_sample_data *data, struct pt_regs *regs)
+{
+       int id;
+       u32 cpu = smp_processor_id();
+
+       for (id = 0; id < perf_num_counters; ++id)
+               if (perf_events[cpu][id] == event)
+                       break;
+
+       if (id != perf_num_counters)
+               oprofile_add_sample(regs, id);
+       else
+               pr_warning("oprofile: ignoring spurious overflow "
+                               "on cpu %u\n", cpu);
+}
+
+/*
+ * Called by op_arm_setup to create perf attributes to mirror the oprofile
+ * settings in counter_config. Attributes are created as `pinned' events and
+ * so are permanently scheduled on the PMU.
+ */
+static void op_perf_setup(void)
+{
+       int i;
+       u32 size = sizeof(struct perf_event_attr);
+       struct perf_event_attr *attr;
+
+       for (i = 0; i < perf_num_counters; ++i) {
+               attr = &counter_config[i].attr;
+               memset(attr, 0, size);
+               attr->type              = PERF_TYPE_RAW;
+               attr->size              = size;
+               attr->config            = counter_config[i].event;
+               attr->sample_period     = counter_config[i].count;
+               attr->pinned            = 1;
+       }
+}
+
+static int op_create_counter(int cpu, int event)
+{
+       int ret = 0;
+       struct perf_event *pevent;
+
+       if (!counter_config[event].enabled || (perf_events[cpu][event] != NULL))
+               return ret;
+
+       pevent = perf_event_create_kernel_counter(&counter_config[event].attr,
+                                                 cpu, -1,
+                                                 op_overflow_handler);
+
+       if (IS_ERR(pevent)) {
+               ret = PTR_ERR(pevent);
+       } else if (pevent->state != PERF_EVENT_STATE_ACTIVE) {
+               pr_warning("oprofile: failed to enable event %d "
+                               "on CPU %d\n", event, cpu);
+               ret = -EBUSY;
+       } else {
+               perf_events[cpu][event] = pevent;
+       }
+
+       return ret;
+}
+
+static void op_destroy_counter(int cpu, int event)
+{
+       struct perf_event *pevent = perf_events[cpu][event];
+
+       if (pevent) {
+               perf_event_release_kernel(pevent);
+               perf_events[cpu][event] = NULL;
+       }
+}
+
+/*
+ * Called by op_arm_start to create active perf events based on the
+ * perviously configured attributes.
+ */
+static int op_perf_start(void)
+{
+       int cpu, event, ret = 0;
+
+       for_each_online_cpu(cpu) {
+               for (event = 0; event < perf_num_counters; ++event) {
+                       ret = op_create_counter(cpu, event);
+                       if (ret)
+                               goto out;
+               }
+       }
+
+out:
+       return ret;
+}
+
+/*
+ * Called by op_arm_stop at the end of a profiling run.
+ */
+static void op_perf_stop(void)
+{
+       int cpu, event;
+
+       for_each_online_cpu(cpu)
+               for (event = 0; event < perf_num_counters; ++event)
+                       op_destroy_counter(cpu, event);
+}
+
+
+static char *op_name_from_perf_id(enum arm_perf_pmu_ids id)
+{
+       switch (id) {
+       case ARM_PERF_PMU_ID_XSCALE1:
+               return "arm/xscale1";
+       case ARM_PERF_PMU_ID_XSCALE2:
+               return "arm/xscale2";
+       case ARM_PERF_PMU_ID_V6:
+               return "arm/armv6";
+       case ARM_PERF_PMU_ID_V6MP:
+               return "arm/mpcore";
+       case ARM_PERF_PMU_ID_CA8:
+               return "arm/armv7";
+       case ARM_PERF_PMU_ID_CA9:
+               return "arm/armv7-ca9";
+       default:
+               return NULL;
+       }
+}
 
 static int op_arm_create_files(struct super_block *sb, struct dentry *root)
 {
        unsigned int i;
 
-       for (i = 0; i < op_arm_model->num_counters; i++) {
+       for (i = 0; i < perf_num_counters; i++) {
                struct dentry *dir;
                char buf[4];
 
@@ -46,12 +198,10 @@ static int op_arm_create_files(struct super_block *sb, struct dentry *root)
 
 static int op_arm_setup(void)
 {
-       int ret;
-
        spin_lock(&oprofilefs_lock);
-       ret = op_arm_model->setup_ctrs();
+       op_perf_setup();
        spin_unlock(&oprofilefs_lock);
-       return ret;
+       return 0;
 }
 
 static int op_arm_start(void)
@@ -60,8 +210,9 @@ static int op_arm_start(void)
 
        mutex_lock(&op_arm_mutex);
        if (!op_arm_enabled) {
-               ret = op_arm_model->start();
-               op_arm_enabled = !ret;
+               ret = 0;
+               op_perf_start();
+               op_arm_enabled = 1;
        }
        mutex_unlock(&op_arm_mutex);
        return ret;
@@ -71,113 +222,205 @@ static void op_arm_stop(void)
 {
        mutex_lock(&op_arm_mutex);
        if (op_arm_enabled)
-               op_arm_model->stop();
+               op_perf_stop();
        op_arm_enabled = 0;
        mutex_unlock(&op_arm_mutex);
 }
 
 #ifdef CONFIG_PM
-static int op_arm_suspend(struct sys_device *dev, pm_message_t state)
+static int op_arm_suspend(struct platform_device *dev, pm_message_t state)
 {
        mutex_lock(&op_arm_mutex);
        if (op_arm_enabled)
-               op_arm_model->stop();
+               op_perf_stop();
        mutex_unlock(&op_arm_mutex);
        return 0;
 }
 
-static int op_arm_resume(struct sys_device *dev)
+static int op_arm_resume(struct platform_device *dev)
 {
        mutex_lock(&op_arm_mutex);
-       if (op_arm_enabled && op_arm_model->start())
+       if (op_arm_enabled && op_perf_start())
                op_arm_enabled = 0;
        mutex_unlock(&op_arm_mutex);
        return 0;
 }
 
-static struct sysdev_class oprofile_sysclass = {
-       .name           = "oprofile",
+static struct platform_driver oprofile_driver = {
+       .driver         = {
+               .name           = "arm-oprofile",
+       },
        .resume         = op_arm_resume,
        .suspend        = op_arm_suspend,
 };
 
-static struct sys_device device_oprofile = {
-       .id             = 0,
-       .cls            = &oprofile_sysclass,
-};
+static struct platform_device *oprofile_pdev;
 
 static int __init init_driverfs(void)
 {
        int ret;
 
-       if (!(ret = sysdev_class_register(&oprofile_sysclass)))
-               ret = sysdev_register(&device_oprofile);
+       ret = platform_driver_register(&oprofile_driver);
+       if (ret)
+               goto out;
 
+       oprofile_pdev = platform_device_register_simple(
+                               oprofile_driver.driver.name, 0, NULL, 0);
+       if (IS_ERR(oprofile_pdev)) {
+               ret = PTR_ERR(oprofile_pdev);
+               platform_driver_unregister(&oprofile_driver);
+       }
+
+out:
        return ret;
 }
 
 static void  exit_driverfs(void)
 {
-       sysdev_unregister(&device_oprofile);
-       sysdev_class_unregister(&oprofile_sysclass);
+       platform_device_unregister(oprofile_pdev);
+       platform_driver_unregister(&oprofile_driver);
 }
 #else
-#define init_driverfs()        do { } while (0)
+static int __init init_driverfs(void) { return 0; }
 #define exit_driverfs() do { } while (0)
 #endif /* CONFIG_PM */
 
-int __init oprofile_arch_init(struct oprofile_operations *ops)
+static int report_trace(struct stackframe *frame, void *d)
 {
-       struct op_arm_model_spec *spec = NULL;
-       int ret = -ENODEV;
+       unsigned int *depth = d;
 
-       ops->backtrace = arm_backtrace;
+       if (*depth) {
+               oprofile_add_trace(frame->pc);
+               (*depth)--;
+       }
 
-#ifdef CONFIG_CPU_XSCALE
-       spec = &op_xscale_spec;
-#endif
+       return *depth == 0;
+}
 
-#ifdef CONFIG_OPROFILE_ARMV6
-       spec = &op_armv6_spec;
-#endif
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+       struct frame_tail *fp;
+       unsigned long sp;
+       unsigned long lr;
+} __attribute__((packed));
 
-#ifdef CONFIG_OPROFILE_MPCORE
-       spec = &op_mpcore_spec;
-#endif
+static struct frame_tail* user_backtrace(struct frame_tail *tail)
+{
+       struct frame_tail buftail[2];
 
-#ifdef CONFIG_OPROFILE_ARMV7
-       spec = &op_armv7_spec;
-#endif
+       /* Also check accessibility of one struct frame_tail beyond */
+       if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+               return NULL;
+       if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
+               return NULL;
 
-       if (spec) {
-               ret = spec->init();
-               if (ret < 0)
-                       return ret;
+       oprofile_add_trace(buftail[0].lr);
 
-               counter_config = kcalloc(spec->num_counters, sizeof(struct op_counter_config),
-                                        GFP_KERNEL);
-               if (!counter_config)
-                       return -ENOMEM;
+       /* frame pointers should strictly progress back up the stack
+        * (towards higher addresses) */
+       if (tail >= buftail[0].fp)
+               return NULL;
 
-               op_arm_model = spec;
-               init_driverfs();
-               ops->create_files = op_arm_create_files;
-               ops->setup = op_arm_setup;
-               ops->shutdown = op_arm_stop;
-               ops->start = op_arm_start;
-               ops->stop = op_arm_stop;
-               ops->cpu_type = op_arm_model->name;
-               printk(KERN_INFO "oprofile: using %s\n", spec->name);
+       return buftail[0].fp-1;
+}
+
+static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+       struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+
+       if (!user_mode(regs)) {
+               struct stackframe frame;
+               frame.fp = regs->ARM_fp;
+               frame.sp = regs->ARM_sp;
+               frame.lr = regs->ARM_lr;
+               frame.pc = regs->ARM_pc;
+               walk_stackframe(&frame, report_trace, &depth);
+               return;
        }
 
+       while (depth-- && tail && !((unsigned long) tail & 3))
+               tail = user_backtrace(tail);
+}
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+       int cpu, ret = 0;
+
+       perf_num_counters = armpmu_get_max_events();
+
+       counter_config = kcalloc(perf_num_counters,
+                       sizeof(struct op_counter_config), GFP_KERNEL);
+
+       if (!counter_config) {
+               pr_info("oprofile: failed to allocate %d "
+                               "counters\n", perf_num_counters);
+               return -ENOMEM;
+       }
+
+       ret = init_driverfs();
+       if (ret) {
+               kfree(counter_config);
+               return ret;
+       }
+
+       for_each_possible_cpu(cpu) {
+               perf_events[cpu] = kcalloc(perf_num_counters,
+                               sizeof(struct perf_event *), GFP_KERNEL);
+               if (!perf_events[cpu]) {
+                       pr_info("oprofile: failed to allocate %d perf events "
+                                       "for cpu %d\n", perf_num_counters, cpu);
+                       while (--cpu >= 0)
+                               kfree(perf_events[cpu]);
+                       return -ENOMEM;
+               }
+       }
+
+       ops->backtrace          = arm_backtrace;
+       ops->create_files       = op_arm_create_files;
+       ops->setup              = op_arm_setup;
+       ops->start              = op_arm_start;
+       ops->stop               = op_arm_stop;
+       ops->shutdown           = op_arm_stop;
+       ops->cpu_type           = op_name_from_perf_id(armpmu_get_pmu_id());
+
+       if (!ops->cpu_type)
+               ret = -ENODEV;
+       else
+               pr_info("oprofile: using %s\n", ops->cpu_type);
+
        return ret;
 }
 
 void oprofile_arch_exit(void)
 {
-       if (op_arm_model) {
+       int cpu, id;
+       struct perf_event *event;
+
+       if (*perf_events) {
                exit_driverfs();
-               op_arm_model = NULL;
+               for_each_possible_cpu(cpu) {
+                       for (id = 0; id < perf_num_counters; ++id) {
+                               event = perf_events[cpu][id];
+                               if (event != NULL)
+                                       perf_event_release_kernel(event);
+                       }
+                       kfree(perf_events[cpu]);
+               }
        }
-       kfree(counter_config);
+
+       if (counter_config)
+               kfree(counter_config);
+}
+#else
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+       pr_info("oprofile: hardware counters not available\n");
+       return -ENODEV;
 }
+void oprofile_arch_exit(void) {}
+#endif /* CONFIG_HW_PERF_EVENTS */
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
deleted file mode 100644 (file)
index 8c4e4f6..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file op_arm_model.h
- * interface to ARM machine specific operations
- *
- * @remark Copyright 2004 Oprofile Authors
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-#ifndef OP_ARM_MODEL_H
-#define OP_ARM_MODEL_H
-
-struct op_arm_model_spec {
-       int (*init)(void);
-       unsigned int num_counters;
-       int (*setup_ctrs)(void);
-       int (*start)(void);
-       void (*stop)(void);
-       char *name;
-};
-
-#ifdef CONFIG_CPU_XSCALE
-extern struct op_arm_model_spec op_xscale_spec;
-#endif
-
-extern struct op_arm_model_spec op_armv6_spec;
-extern struct op_arm_model_spec op_mpcore_spec;
-extern struct op_arm_model_spec op_armv7_spec;
-
-extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
-
-extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
-extern void op_arm_exit(void);
-#endif /* OP_ARM_MODEL_H */
diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h
deleted file mode 100644 (file)
index ca942a6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * @file op_counter.h
- *
- * @remark Copyright 2004 Oprofile Authors
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-#ifndef OP_COUNTER_H
-#define OP_COUNTER_H
-
-/* Per performance monitor configuration as set via
- * oprofilefs.
- */
-struct op_counter_config {
-       unsigned long count;
-       unsigned long enabled;
-       unsigned long event;
-       unsigned long unit_mask;
-       unsigned long kernel;
-       unsigned long user;
-};
-
-extern struct op_counter_config *counter_config;
-
-#endif /* OP_COUNTER_H */
diff --git a/arch/arm/oprofile/op_model_arm11_core.c b/arch/arm/oprofile/op_model_arm11_core.c
deleted file mode 100644 (file)
index ef3e265..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * @file op_model_arm11_core.c
- * ARM11 Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/smp.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_arm11_core.h"
-
-/*
- * ARM11 PMU support
- */
-static inline void arm11_write_pmnc(u32 val)
-{
-       /* upper 4bits and 7, 11 are write-as-0 */
-       val &= 0x0ffff77f;
-       asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r" (val));
-}
-
-static inline u32 arm11_read_pmnc(void)
-{
-       u32 val;
-       asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r" (val));
-       return val;
-}
-
-static void arm11_reset_counter(unsigned int cnt)
-{
-       u32 val = -(u32)counter_config[CPU_COUNTER(smp_processor_id(), cnt)].count;
-       switch (cnt) {
-       case CCNT:
-               asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r" (val));
-               break;
-
-       case PMN0:
-               asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r" (val));
-               break;
-
-       case PMN1:
-               asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r" (val));
-               break;
-       }
-}
-
-int arm11_setup_pmu(void)
-{
-       unsigned int cnt;
-       u32 pmnc;
-
-       if (arm11_read_pmnc() & PMCR_E) {
-               printk(KERN_ERR "oprofile: CPU%u PMU still enabled when setup new event counter.\n", smp_processor_id());
-               return -EBUSY;
-       }
-
-       /* initialize PMNC, reset overflow, D bit, C bit and P bit. */
-       arm11_write_pmnc(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
-                        PMCR_C | PMCR_P);
-
-       for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
-               unsigned long event;
-
-               if (!counter_config[CPU_COUNTER(smp_processor_id(), cnt)].enabled)
-                       continue;
-
-               event = counter_config[CPU_COUNTER(smp_processor_id(), cnt)].event & 255;
-
-               /*
-                * Set event (if destined for PMNx counters)
-                */
-               if (cnt == PMN0) {
-                       pmnc |= event << 20;
-               } else if (cnt == PMN1) {
-                       pmnc |= event << 12;
-               }
-
-               /*
-                * We don't need to set the event if it's a cycle count
-                * Enable interrupt for this counter
-                */
-               pmnc |= PMCR_IEN_PMN0 << cnt;
-               arm11_reset_counter(cnt);
-       }
-       arm11_write_pmnc(pmnc);
-
-       return 0;
-}
-
-int arm11_start_pmu(void)
-{
-       arm11_write_pmnc(arm11_read_pmnc() | PMCR_E);
-       return 0;
-}
-
-int arm11_stop_pmu(void)
-{
-       unsigned int cnt;
-
-       arm11_write_pmnc(arm11_read_pmnc() & ~PMCR_E);
-
-       for (cnt = PMN0; cnt <= CCNT; cnt++)
-               arm11_reset_counter(cnt);
-
-       return 0;
-}
-
-/*
- * CPU counters' IRQ handler (one IRQ per CPU)
- */
-static irqreturn_t arm11_pmu_interrupt(int irq, void *arg)
-{
-       struct pt_regs *regs = get_irq_regs();
-       unsigned int cnt;
-       u32 pmnc;
-
-       pmnc = arm11_read_pmnc();
-
-       for (cnt = PMN0; cnt <= CCNT; cnt++) {
-               if ((pmnc & (PMCR_OFL_PMN0 << cnt)) && (pmnc & (PMCR_IEN_PMN0 << cnt))) {
-                       arm11_reset_counter(cnt);
-                       oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), cnt));
-               }
-       }
-       /* Clear counter flag(s) */
-       arm11_write_pmnc(pmnc);
-       return IRQ_HANDLED;
-}
-
-int arm11_request_interrupts(const int *irqs, int nr)
-{
-       unsigned int i;
-       int ret = 0;
-
-       for(i = 0; i < nr; i++) {
-               ret = request_irq(irqs[i], arm11_pmu_interrupt, IRQF_DISABLED, "CP15 PMU", NULL);
-               if (ret != 0) {
-                       printk(KERN_ERR "oprofile: unable to request IRQ%u for MPCORE-EM\n",
-                              irqs[i]);
-                       break;
-               }
-       }
-
-       if (i != nr)
-               while (i-- != 0)
-                       free_irq(irqs[i], NULL);
-
-       return ret;
-}
-
-void arm11_release_interrupts(const int *irqs, int nr)
-{
-       unsigned int i;
-
-       for (i = 0; i < nr; i++)
-               free_irq(irqs[i], NULL);
-}
diff --git a/arch/arm/oprofile/op_model_arm11_core.h b/arch/arm/oprofile/op_model_arm11_core.h
deleted file mode 100644 (file)
index 1902b99..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file op_model_arm11_core.h
- * ARM11 Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 Oprofile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-#ifndef OP_MODEL_ARM11_CORE_H
-#define OP_MODEL_ARM11_CORE_H
-
-/*
- * Per-CPU PMCR
- */
-#define PMCR_E         (1 << 0)        /* Enable */
-#define PMCR_P         (1 << 1)        /* Count reset */
-#define PMCR_C         (1 << 2)        /* Cycle counter reset */
-#define PMCR_D         (1 << 3)        /* Cycle counter counts every 64th cpu cycle */
-#define PMCR_IEN_PMN0  (1 << 4)        /* Interrupt enable count reg 0 */
-#define PMCR_IEN_PMN1  (1 << 5)        /* Interrupt enable count reg 1 */
-#define PMCR_IEN_CCNT  (1 << 6)        /* Interrupt enable cycle counter */
-#define PMCR_OFL_PMN0  (1 << 8)        /* Count reg 0 overflow */
-#define PMCR_OFL_PMN1  (1 << 9)        /* Count reg 1 overflow */
-#define PMCR_OFL_CCNT  (1 << 10)       /* Cycle counter overflow */
-
-#define PMN0 0
-#define PMN1 1
-#define CCNT 2
-
-#define CPU_COUNTER(cpu, counter)      ((cpu) * 3 + (counter))
-
-int arm11_setup_pmu(void);
-int arm11_start_pmu(void);
-int arm11_stop_pmu(void);
-int arm11_request_interrupts(const int *, int);
-void arm11_release_interrupts(const int *, int);
-
-#endif
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
deleted file mode 100644 (file)
index f73ce87..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/**
- * @file op_model_mpcore.c
- * MPCORE Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 Oprofile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- *
- *  Counters:
- *    0: PMN0 on CPU0, per-cpu configurable event counter
- *    1: PMN1 on CPU0, per-cpu configurable event counter
- *    2: CCNT on CPU0
- *    3: PMN0 on CPU1
- *    4: PMN1 on CPU1
- *    5: CCNT on CPU1
- *    6: PMN0 on CPU1
- *    7: PMN1 on CPU1
- *    8: CCNT on CPU1
- *    9: PMN0 on CPU1
- *   10: PMN1 on CPU1
- *   11: CCNT on CPU1
- *   12-19: configurable SCU event counters
- */
-
-/* #define DEBUG */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <mach/hardware.h>
-#include <mach/board-eb.h>
-#include <asm/system.h>
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_arm11_core.h"
-#include "op_model_mpcore.h"
-
-/*
- * MPCore SCU event monitor support
- */
-#define SCU_EVENTMONITORS_VA_BASE __io_address(REALVIEW_EB11MP_SCU_BASE + 0x10)
-
-/*
- * Bitmask of used SCU counters
- */
-static unsigned int scu_em_used;
-static const struct pmu_irqs *pmu_irqs;
-
-/*
- * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
- */
-static inline void scu_reset_counter(struct eventmonitor __iomem *emc, unsigned int n)
-{
-       writel(-(u32)counter_config[SCU_COUNTER(n)].count, &emc->MC[n]);
-}
-
-static inline void scu_set_event(struct eventmonitor __iomem *emc, unsigned int n, u32 event)
-{
-       event &= 0xff;
-       writeb(event, &emc->MCEB[n]);
-}
-
-/*
- * SCU counters' IRQ handler (one IRQ per counter => 2 IRQs per CPU)
- */
-static irqreturn_t scu_em_interrupt(int irq, void *arg)
-{
-       struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-       unsigned int cnt;
-
-       cnt = irq - IRQ_EB11MP_PMU_SCU0;
-       oprofile_add_sample(get_irq_regs(), SCU_COUNTER(cnt));
-       scu_reset_counter(emc, cnt);
-
-       /* Clear overflow flag for this counter */
-       writel(1 << (cnt + 16), &emc->PMCR);
-
-       return IRQ_HANDLED;
-}
-
-/* Configure just the SCU counters that the user has requested */
-static void scu_setup(void)
-{
-       struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-       unsigned int i;
-
-       scu_em_used = 0;
-
-       for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-               if (counter_config[SCU_COUNTER(i)].enabled &&
-                   counter_config[SCU_COUNTER(i)].event) {
-                       scu_set_event(emc, i, 0); /* disable counter for now */
-                       scu_em_used |= 1 << i;
-               }
-       }
-}
-
-static int scu_start(void)
-{
-       struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-       unsigned int temp, i;
-       unsigned long event;
-       int ret = 0;
-
-       /*
-        * request the SCU counter interrupts that we need
-        */
-       for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-               if (scu_em_used & (1 << i)) {
-                       ret = request_irq(IRQ_EB11MP_PMU_SCU0 + i, scu_em_interrupt, IRQF_DISABLED, "SCU PMU", NULL);
-                       if (ret) {
-                               printk(KERN_ERR "oprofile: unable to request IRQ%u for SCU Event Monitor\n",
-                                      IRQ_EB11MP_PMU_SCU0 + i);
-                               goto err_free_scu;
-                       }
-               }
-       }
-
-       /*
-        * clear overflow and enable interrupt for all used counters
-        */
-       temp = readl(&emc->PMCR);
-       for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-               if (scu_em_used & (1 << i)) {
-                       scu_reset_counter(emc, i);
-                       event = counter_config[SCU_COUNTER(i)].event;
-                       scu_set_event(emc, i, event);
-
-                       /* clear overflow/interrupt */
-                       temp |= 1 << (i + 16);
-                       /* enable interrupt*/
-                       temp |= 1 << (i + 8);
-               }
-       }
-
-       /* Enable all 8 counters */
-       temp |= PMCR_E;
-       writel(temp, &emc->PMCR);
-
-       return 0;
-
- err_free_scu:
-       while (i--)
-               free_irq(IRQ_EB11MP_PMU_SCU0 + i, NULL);
-       return ret;
-}
-
-static void scu_stop(void)
-{
-       struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
-       unsigned int temp, i;
-
-       /* Disable counter interrupts */
-       /* Don't disable all 8 counters (with the E bit) as they may be in use */
-       temp = readl(&emc->PMCR);
-       for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-               if (scu_em_used & (1 << i))
-                       temp &= ~(1 << (i + 8));
-       }
-       writel(temp, &emc->PMCR);
-
-       /* Free counter interrupts and reset counters */
-       for (i = 0; i < NUM_SCU_COUNTERS; i++) {
-               if (scu_em_used & (1 << i)) {
-                       scu_reset_counter(emc, i);
-                       free_irq(IRQ_EB11MP_PMU_SCU0 + i, NULL);
-               }
-       }
-}
-
-struct em_function_data {
-       int (*fn)(void);
-       int ret;
-};
-
-static void em_func(void *data)
-{
-       struct em_function_data *d = data;
-       int ret = d->fn();
-       if (ret)
-               d->ret = ret;
-}
-
-static int em_call_function(int (*fn)(void))
-{
-       struct em_function_data data;
-
-       data.fn = fn;
-       data.ret = 0;
-
-       preempt_disable();
-       smp_call_function(em_func, &data, 1);
-       em_func(&data);
-       preempt_enable();
-
-       return data.ret;
-}
-
-/*
- * Glue to stick the individual ARM11 PMUs and the SCU
- * into the oprofile framework.
- */
-static int em_setup_ctrs(void)
-{
-       int ret;
-
-       /* Configure CPU counters by cross-calling to the other CPUs */
-       ret = em_call_function(arm11_setup_pmu);
-       if (ret == 0)
-               scu_setup();
-
-       return 0;
-}
-
-static int em_start(void)
-{
-       int ret;
-
-       pmu_irqs = reserve_pmu();
-       if (IS_ERR(pmu_irqs)) {
-               ret = PTR_ERR(pmu_irqs);
-               goto out;
-       }
-
-       ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-       if (ret == 0) {
-               em_call_function(arm11_start_pmu);
-
-               ret = scu_start();
-               if (ret) {
-                       arm11_release_interrupts(pmu_irqs->irqs,
-                                                pmu_irqs->num_irqs);
-               } else {
-                       release_pmu(pmu_irqs);
-                       pmu_irqs = NULL;
-               }
-       }
-
-out:
-       return ret;
-}
-
-static void em_stop(void)
-{
-       em_call_function(arm11_stop_pmu);
-       arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-       scu_stop();
-       release_pmu(pmu_irqs);
-}
-
-/*
- * Why isn't there a function to route an IRQ to a specific CPU in
- * genirq?
- */
-static void em_route_irq(int irq, unsigned int cpu)
-{
-       struct irq_desc *desc = irq_desc + irq;
-       const struct cpumask *mask = cpumask_of(cpu);
-
-       spin_lock_irq(&desc->lock);
-       cpumask_copy(desc->affinity, mask);
-       desc->chip->set_affinity(irq, mask);
-       spin_unlock_irq(&desc->lock);
-}
-
-static int em_setup(void)
-{
-       /*
-        * Send SCU PMU interrupts to the "owner" CPU.
-        */
-       em_route_irq(IRQ_EB11MP_PMU_SCU0, 0);
-       em_route_irq(IRQ_EB11MP_PMU_SCU1, 0);
-       em_route_irq(IRQ_EB11MP_PMU_SCU2, 1);
-       em_route_irq(IRQ_EB11MP_PMU_SCU3, 1);
-       em_route_irq(IRQ_EB11MP_PMU_SCU4, 2);
-       em_route_irq(IRQ_EB11MP_PMU_SCU5, 2);
-       em_route_irq(IRQ_EB11MP_PMU_SCU6, 3);
-       em_route_irq(IRQ_EB11MP_PMU_SCU7, 3);
-
-       return init_pmu();
-}
-
-struct op_arm_model_spec op_mpcore_spec = {
-       .init           = em_setup,
-       .num_counters   = MPCORE_NUM_COUNTERS,
-       .setup_ctrs     = em_setup_ctrs,
-       .start          = em_start,
-       .stop           = em_stop,
-       .name           = "arm/mpcore",
-};
diff --git a/arch/arm/oprofile/op_model_mpcore.h b/arch/arm/oprofile/op_model_mpcore.h
deleted file mode 100644 (file)
index 73d8110..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file op_model_mpcore.c
- * MPCORE Event Monitor Driver
- * @remark Copyright 2004 ARM SMP Development Team
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 Oprofile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-#ifndef OP_MODEL_MPCORE_H
-#define OP_MODEL_MPCORE_H
-
-struct eventmonitor {
-       unsigned long PMCR;
-       unsigned char MCEB[8];
-       unsigned long MC[8];
-};
-
-/*
- * List of userspace counter numbers: note that the structure is important.
- * The code relies on CPUn's counters being CPU0's counters + 3n
- * and on CPU0's counters starting at 0
- */
-
-#define COUNTER_CPU0_PMN0 0
-#define COUNTER_CPU0_PMN1 1
-#define COUNTER_CPU0_CCNT 2
-
-#define COUNTER_CPU1_PMN0 3
-#define COUNTER_CPU1_PMN1 4
-#define COUNTER_CPU1_CCNT 5
-
-#define COUNTER_CPU2_PMN0 6
-#define COUNTER_CPU2_PMN1 7
-#define COUNTER_CPU2_CCNT 8
-
-#define COUNTER_CPU3_PMN0 9
-#define COUNTER_CPU3_PMN1 10
-#define COUNTER_CPU3_CCNT 11
-
-#define COUNTER_SCU_MN0 12
-#define COUNTER_SCU_MN1 13
-#define COUNTER_SCU_MN2 14
-#define COUNTER_SCU_MN3 15
-#define COUNTER_SCU_MN4 16
-#define COUNTER_SCU_MN5 17
-#define COUNTER_SCU_MN6 18
-#define COUNTER_SCU_MN7 19
-#define NUM_SCU_COUNTERS 8
-
-#define SCU_COUNTER(number)    ((number) + COUNTER_SCU_MN0)
-
-#define MPCORE_NUM_COUNTERS    SCU_COUNTER(NUM_SCU_COUNTERS)
-
-#endif
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
deleted file mode 100644 (file)
index a22357a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file op_model_v6.c
- * ARM11 Performance Monitor Driver
- *
- * Based on op_model_xscale.c
- *
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 OProfile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Tony Lindgren <tony@atomide.com>
- */
-
-/* #define DEBUG */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_arm11_core.h"
-
-static const struct pmu_irqs *pmu_irqs;
-
-static void armv6_pmu_stop(void)
-{
-       arm11_stop_pmu();
-       arm11_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-       release_pmu(pmu_irqs);
-       pmu_irqs = NULL;
-}
-
-static int armv6_pmu_start(void)
-{
-       int ret;
-
-       pmu_irqs = reserve_pmu();
-       if (IS_ERR(pmu_irqs)) {
-               ret = PTR_ERR(pmu_irqs);
-               goto out;
-       }
-
-       ret = arm11_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-       if (ret >= 0) {
-               ret = arm11_start_pmu();
-       } else {
-               release_pmu(pmu_irqs);
-               pmu_irqs = NULL;
-       }
-
-out:
-       return ret;
-}
-
-static int armv6_detect_pmu(void)
-{
-       return 0;
-}
-
-struct op_arm_model_spec op_armv6_spec = {
-       .init           = armv6_detect_pmu,
-       .num_counters   = 3,
-       .setup_ctrs     = arm11_setup_pmu,
-       .start          = armv6_pmu_start,
-       .stop           = armv6_pmu_stop,
-       .name           = "arm/armv6",
-};
diff --git a/arch/arm/oprofile/op_model_v7.c b/arch/arm/oprofile/op_model_v7.c
deleted file mode 100644 (file)
index 8642d08..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * op_model_v7.c
- * ARM V7 (Cortex A8) Event Monitor Driver
- *
- * Copyright 2008 Jean Pihet <jpihet@mvista.com>
- * Copyright 2004 ARM SMP Development Team
- *
- * 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/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/smp.h>
-
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-#include "op_model_v7.h"
-
-/* #define DEBUG */
-
-
-/*
- * ARM V7 PMNC support
- */
-
-static u32 cnt_en[CNTMAX];
-
-static inline void armv7_pmnc_write(u32 val)
-{
-       val &= PMNC_MASK;
-       asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val));
-}
-
-static inline u32 armv7_pmnc_read(void)
-{
-       u32 val;
-
-       asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
-       return val;
-}
-
-static inline u32 armv7_pmnc_enable_counter(unsigned int cnt)
-{
-       u32 val;
-
-       if (cnt >= CNTMAX) {
-               printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
-                       " %d\n", smp_processor_id(), cnt);
-               return -1;
-       }
-
-       if (cnt == CCNT)
-               val = CNTENS_C;
-       else
-               val = (1 << (cnt - CNT0));
-
-       val &= CNTENS_MASK;
-       asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
-
-       return cnt;
-}
-
-static inline u32 armv7_pmnc_disable_counter(unsigned int cnt)
-{
-       u32 val;
-
-       if (cnt >= CNTMAX) {
-               printk(KERN_ERR "oprofile: CPU%u disabling wrong PMNC counter"
-                       " %d\n", smp_processor_id(), cnt);
-               return -1;
-       }
-
-       if (cnt == CCNT)
-               val = CNTENC_C;
-       else
-               val = (1 << (cnt - CNT0));
-
-       val &= CNTENC_MASK;
-       asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
-
-       return cnt;
-}
-
-static inline u32 armv7_pmnc_enable_intens(unsigned int cnt)
-{
-       u32 val;
-
-       if (cnt >= CNTMAX) {
-               printk(KERN_ERR "oprofile: CPU%u enabling wrong PMNC counter"
-                       " interrupt enable %d\n", smp_processor_id(), cnt);
-               return -1;
-       }
-
-       if (cnt == CCNT)
-               val = INTENS_C;
-       else
-               val = (1 << (cnt - CNT0));
-
-       val &= INTENS_MASK;
-       asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
-
-       return cnt;
-}
-
-static inline u32 armv7_pmnc_getreset_flags(void)
-{
-       u32 val;
-
-       /* Read */
-       asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
-
-       /* Write to clear flags */
-       val &= FLAG_MASK;
-       asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
-
-       return val;
-}
-
-static inline int armv7_pmnc_select_counter(unsigned int cnt)
-{
-       u32 val;
-
-       if ((cnt == CCNT) || (cnt >= CNTMAX)) {
-               printk(KERN_ERR "oprofile: CPU%u selecting wrong PMNC counteri"
-                       " %d\n", smp_processor_id(), cnt);
-               return -1;
-       }
-
-       val = (cnt - CNT0) & SELECT_MASK;
-       asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
-
-       return cnt;
-}
-
-static inline void armv7_pmnc_write_evtsel(unsigned int cnt, u32 val)
-{
-       if (armv7_pmnc_select_counter(cnt) == cnt) {
-               val &= EVTSEL_MASK;
-               asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
-       }
-}
-
-static void armv7_pmnc_reset_counter(unsigned int cnt)
-{
-       u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
-       u32 val = -(u32)counter_config[cpu_cnt].count;
-
-       switch (cnt) {
-       case CCNT:
-               armv7_pmnc_disable_counter(cnt);
-
-               asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val));
-
-               if (cnt_en[cnt] != 0)
-                   armv7_pmnc_enable_counter(cnt);
-
-               break;
-
-       case CNT0:
-       case CNT1:
-       case CNT2:
-       case CNT3:
-               armv7_pmnc_disable_counter(cnt);
-
-               if (armv7_pmnc_select_counter(cnt) == cnt)
-                   asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val));
-
-               if (cnt_en[cnt] != 0)
-                   armv7_pmnc_enable_counter(cnt);
-
-               break;
-
-       default:
-               printk(KERN_ERR "oprofile: CPU%u resetting wrong PMNC counter"
-                       " %d\n", smp_processor_id(), cnt);
-               break;
-       }
-}
-
-int armv7_setup_pmnc(void)
-{
-       unsigned int cnt;
-
-       if (armv7_pmnc_read() & PMNC_E) {
-               printk(KERN_ERR "oprofile: CPU%u PMNC still enabled when setup"
-                       " new event counter.\n", smp_processor_id());
-               return -EBUSY;
-       }
-
-       /* Initialize & Reset PMNC: C bit and P bit */
-       armv7_pmnc_write(PMNC_P | PMNC_C);
-
-
-       for (cnt = CCNT; cnt < CNTMAX; cnt++) {
-               unsigned long event;
-               u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
-
-               /*
-                * Disable counter
-                */
-               armv7_pmnc_disable_counter(cnt);
-               cnt_en[cnt] = 0;
-
-               if (!counter_config[cpu_cnt].enabled)
-                       continue;
-
-               event = counter_config[cpu_cnt].event & 255;
-
-               /*
-                * Set event (if destined for PMNx counters)
-                * We don't need to set the event if it's a cycle count
-                */
-               if (cnt != CCNT)
-                       armv7_pmnc_write_evtsel(cnt, event);
-
-               /*
-                * Enable interrupt for this counter
-                */
-               armv7_pmnc_enable_intens(cnt);
-
-               /*
-                * Reset counter
-                */
-               armv7_pmnc_reset_counter(cnt);
-
-               /*
-                * Enable counter
-                */
-               armv7_pmnc_enable_counter(cnt);
-               cnt_en[cnt] = 1;
-       }
-
-       return 0;
-}
-
-static inline void armv7_start_pmnc(void)
-{
-       armv7_pmnc_write(armv7_pmnc_read() | PMNC_E);
-}
-
-static inline void armv7_stop_pmnc(void)
-{
-       armv7_pmnc_write(armv7_pmnc_read() & ~PMNC_E);
-}
-
-/*
- * CPU counters' IRQ handler (one IRQ per CPU)
- */
-static irqreturn_t armv7_pmnc_interrupt(int irq, void *arg)
-{
-       struct pt_regs *regs = get_irq_regs();
-       unsigned int cnt;
-       u32 flags;
-
-
-       /*
-        * Stop IRQ generation
-        */
-       armv7_stop_pmnc();
-
-       /*
-        * Get and reset overflow status flags
-        */
-       flags = armv7_pmnc_getreset_flags();
-
-       /*
-        * Cycle counter
-        */
-       if (flags & FLAG_C) {
-               u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), CCNT);
-               armv7_pmnc_reset_counter(CCNT);
-               oprofile_add_sample(regs, cpu_cnt);
-       }
-
-       /*
-        * PMNC counters 0:3
-        */
-       for (cnt = CNT0; cnt < CNTMAX; cnt++) {
-               if (flags & (1 << (cnt - CNT0))) {
-                       u32 cpu_cnt = CPU_COUNTER(smp_processor_id(), cnt);
-                       armv7_pmnc_reset_counter(cnt);
-                       oprofile_add_sample(regs, cpu_cnt);
-               }
-       }
-
-       /*
-        * Allow IRQ generation
-        */
-       armv7_start_pmnc();
-
-       return IRQ_HANDLED;
-}
-
-int armv7_request_interrupts(const int *irqs, int nr)
-{
-       unsigned int i;
-       int ret = 0;
-
-       for (i = 0; i < nr; i++) {
-               ret = request_irq(irqs[i], armv7_pmnc_interrupt,
-                               IRQF_DISABLED, "CP15 PMNC", NULL);
-               if (ret != 0) {
-                       printk(KERN_ERR "oprofile: unable to request IRQ%u"
-                               " for ARMv7\n",
-                              irqs[i]);
-                       break;
-               }
-       }
-
-       if (i != nr)
-               while (i-- != 0)
-                       free_irq(irqs[i], NULL);
-
-       return ret;
-}
-
-void armv7_release_interrupts(const int *irqs, int nr)
-{
-       unsigned int i;
-
-       for (i = 0; i < nr; i++)
-               free_irq(irqs[i], NULL);
-}
-
-#ifdef DEBUG
-static void armv7_pmnc_dump_regs(void)
-{
-       u32 val;
-       unsigned int cnt;
-
-       printk(KERN_INFO "PMNC registers dump:\n");
-
-       asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
-       printk(KERN_INFO "PMNC  =0x%08x\n", val);
-
-       asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
-       printk(KERN_INFO "CNTENS=0x%08x\n", val);
-
-       asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
-       printk(KERN_INFO "INTENS=0x%08x\n", val);
-
-       asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
-       printk(KERN_INFO "FLAGS =0x%08x\n", val);
-
-       asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
-       printk(KERN_INFO "SELECT=0x%08x\n", val);
-
-       asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
-       printk(KERN_INFO "CCNT  =0x%08x\n", val);
-
-       for (cnt = CNT0; cnt < CNTMAX; cnt++) {
-               armv7_pmnc_select_counter(cnt);
-               asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
-               printk(KERN_INFO "CNT[%d] count =0x%08x\n", cnt-CNT0, val);
-               asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
-               printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n", cnt-CNT0, val);
-       }
-}
-#endif
-
-static const struct pmu_irqs *pmu_irqs;
-
-static void armv7_pmnc_stop(void)
-{
-#ifdef DEBUG
-       armv7_pmnc_dump_regs();
-#endif
-       armv7_stop_pmnc();
-       armv7_release_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-       release_pmu(pmu_irqs);
-       pmu_irqs = NULL;
-}
-
-static int armv7_pmnc_start(void)
-{
-       int ret;
-
-       pmu_irqs = reserve_pmu();
-       if (IS_ERR(pmu_irqs))
-               return PTR_ERR(pmu_irqs);
-
-#ifdef DEBUG
-       armv7_pmnc_dump_regs();
-#endif
-       ret = armv7_request_interrupts(pmu_irqs->irqs, pmu_irqs->num_irqs);
-       if (ret >= 0) {
-               armv7_start_pmnc();
-       } else {
-               release_pmu(pmu_irqs);
-               pmu_irqs = NULL;
-       }
-
-       return ret;
-}
-
-static int armv7_detect_pmnc(void)
-{
-       return 0;
-}
-
-struct op_arm_model_spec op_armv7_spec = {
-       .init           = armv7_detect_pmnc,
-       .num_counters   = 5,
-       .setup_ctrs     = armv7_setup_pmnc,
-       .start          = armv7_pmnc_start,
-       .stop           = armv7_pmnc_stop,
-       .name           = "arm/armv7",
-};
diff --git a/arch/arm/oprofile/op_model_v7.h b/arch/arm/oprofile/op_model_v7.h
deleted file mode 100644 (file)
index 9ca334b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * op_model_v7.h
- * ARM v7 (Cortex A8) Event Monitor Driver
- *
- * Copyright 2008 Jean Pihet <jpihet@mvista.com>
- * Copyright 2004 ARM SMP Development Team
- * Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * Copyright 2000-2004 MontaVista Software Inc
- * Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * Copyright 2004 Intel Corporation
- * Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * Copyright 2004 Oprofile Authors
- *
- * Read the file COPYING
- *
- * 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 OP_MODEL_V7_H
-#define OP_MODEL_V7_H
-
-/*
- * Per-CPU PMNC: config reg
- */
-#define PMNC_E         (1 << 0)        /* Enable all counters */
-#define PMNC_P         (1 << 1)        /* Reset all counters */
-#define PMNC_C         (1 << 2)        /* Cycle counter reset */
-#define PMNC_D         (1 << 3)        /* CCNT counts every 64th cpu cycle */
-#define PMNC_X         (1 << 4)        /* Export to ETM */
-#define PMNC_DP                (1 << 5)        /* Disable CCNT if non-invasive debug*/
-#define        PMNC_MASK       0x3f            /* Mask for writable bits */
-
-/*
- * Available counters
- */
-#define CCNT           0
-#define CNT0           1
-#define CNT1           2
-#define CNT2           3
-#define CNT3           4
-#define CNTMAX                 5
-
-#define CPU_COUNTER(cpu, counter)      ((cpu) * CNTMAX + (counter))
-
-/*
- * CNTENS: counters enable reg
- */
-#define CNTENS_P0      (1 << 0)
-#define CNTENS_P1      (1 << 1)
-#define CNTENS_P2      (1 << 2)
-#define CNTENS_P3      (1 << 3)
-#define CNTENS_C       (1 << 31)
-#define        CNTENS_MASK     0x8000000f      /* Mask for writable bits */
-
-/*
- * CNTENC: counters disable reg
- */
-#define CNTENC_P0      (1 << 0)
-#define CNTENC_P1      (1 << 1)
-#define CNTENC_P2      (1 << 2)
-#define CNTENC_P3      (1 << 3)
-#define CNTENC_C       (1 << 31)
-#define        CNTENC_MASK     0x8000000f      /* Mask for writable bits */
-
-/*
- * INTENS: counters overflow interrupt enable reg
- */
-#define INTENS_P0      (1 << 0)
-#define INTENS_P1      (1 << 1)
-#define INTENS_P2      (1 << 2)
-#define INTENS_P3      (1 << 3)
-#define INTENS_C       (1 << 31)
-#define        INTENS_MASK     0x8000000f      /* Mask for writable bits */
-
-/*
- * EVTSEL: Event selection reg
- */
-#define        EVTSEL_MASK     0x7f            /* Mask for writable bits */
-
-/*
- * SELECT: Counter selection reg
- */
-#define        SELECT_MASK     0x1f            /* Mask for writable bits */
-
-/*
- * FLAG: counters overflow flag status reg
- */
-#define FLAG_P0                (1 << 0)
-#define FLAG_P1                (1 << 1)
-#define FLAG_P2                (1 << 2)
-#define FLAG_P3                (1 << 3)
-#define FLAG_C         (1 << 31)
-#define        FLAG_MASK       0x8000000f      /* Mask for writable bits */
-
-
-int armv7_setup_pmu(void);
-int armv7_start_pmu(void);
-int armv7_stop_pmu(void);
-int armv7_request_interrupts(const int *, int);
-void armv7_release_interrupts(const int *, int);
-
-#endif
diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c
deleted file mode 100644 (file)
index 1d34a02..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/**
- * @file op_model_xscale.c
- * XScale Performance Monitor Driver
- *
- * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
- * @remark Copyright 2000-2004 MontaVista Software Inc
- * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
- * @remark Copyright 2004 Intel Corporation
- * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
- * @remark Copyright 2004 OProfile Authors
- *
- * @remark Read the file COPYING
- *
- * @author Zwane Mwaikambo
- */
-
-/* #define DEBUG */
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/sched.h>
-#include <linux/oprofile.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/cputype.h>
-#include <asm/pmu.h>
-
-#include "op_counter.h"
-#include "op_arm_model.h"
-
-#define        PMU_ENABLE      0x001   /* Enable counters */
-#define PMN_RESET      0x002   /* Reset event counters */
-#define        CCNT_RESET      0x004   /* Reset clock counter */
-#define        PMU_RESET       (CCNT_RESET | PMN_RESET)
-#define PMU_CNT64      0x008   /* Make CCNT count every 64th cycle */
-
-/*
- * Different types of events that can be counted by the XScale PMU
- * as used by Oprofile userspace. Here primarily for documentation
- * purposes.
- */
-
-#define EVT_ICACHE_MISS                        0x00
-#define        EVT_ICACHE_NO_DELIVER           0x01
-#define        EVT_DATA_STALL                  0x02
-#define        EVT_ITLB_MISS                   0x03
-#define        EVT_DTLB_MISS                   0x04
-#define        EVT_BRANCH                      0x05
-#define        EVT_BRANCH_MISS                 0x06
-#define        EVT_INSTRUCTION                 0x07
-#define        EVT_DCACHE_FULL_STALL           0x08
-#define        EVT_DCACHE_FULL_STALL_CONTIG    0x09
-#define        EVT_DCACHE_ACCESS               0x0A
-#define        EVT_DCACHE_MISS                 0x0B
-#define        EVT_DCACE_WRITE_BACK            0x0C
-#define        EVT_PC_CHANGED                  0x0D
-#define        EVT_BCU_REQUEST                 0x10
-#define        EVT_BCU_FULL                    0x11
-#define        EVT_BCU_DRAIN                   0x12
-#define        EVT_BCU_ECC_NO_ELOG             0x14
-#define        EVT_BCU_1_BIT_ERR               0x15
-#define        EVT_RMW                         0x16
-/* EVT_CCNT is not hardware defined */
-#define EVT_CCNT                       0xFE
-#define EVT_UNUSED                     0xFF
-
-struct pmu_counter {
-       volatile unsigned long ovf;
-       unsigned long reset_counter;
-};
-
-enum { CCNT, PMN0, PMN1, PMN2, PMN3, MAX_COUNTERS };
-
-static struct pmu_counter results[MAX_COUNTERS];
-
-/*
- * There are two versions of the PMU in current XScale processors
- * with differing register layouts and number of performance counters.
- * e.g. IOP32x is xsc1 whilst IOP33x is xsc2.
- * We detect which register layout to use in xscale_detect_pmu()
- */
-enum { PMU_XSC1, PMU_XSC2 };
-
-struct pmu_type {
-       int id;
-       char *name;
-       int num_counters;
-       unsigned int int_enable;
-       unsigned int cnt_ovf[MAX_COUNTERS];
-       unsigned int int_mask[MAX_COUNTERS];
-};
-
-static struct pmu_type pmu_parms[] = {
-       {
-               .id             = PMU_XSC1,
-               .name           = "arm/xscale1",
-               .num_counters   = 3,
-               .int_mask       = { [PMN0] = 0x10, [PMN1] = 0x20,
-                                   [CCNT] = 0x40 },
-               .cnt_ovf        = { [CCNT] = 0x400, [PMN0] = 0x100,
-                                   [PMN1] = 0x200},
-       },
-       {
-               .id             = PMU_XSC2,
-               .name           = "arm/xscale2",
-               .num_counters   = 5,
-               .int_mask       = { [CCNT] = 0x01, [PMN0] = 0x02,
-                                   [PMN1] = 0x04, [PMN2] = 0x08,
-                                   [PMN3] = 0x10 },
-               .cnt_ovf        = { [CCNT] = 0x01, [PMN0] = 0x02,
-                                   [PMN1] = 0x04, [PMN2] = 0x08,
-                                   [PMN3] = 0x10 },
-       },
-};
-
-static struct pmu_type *pmu;
-
-static void write_pmnc(u32 val)
-{
-       if (pmu->id == PMU_XSC1) {
-               /* upper 4bits and 7, 11 are write-as-0 */
-               val &= 0xffff77f;
-               __asm__ __volatile__ ("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
-       } else {
-               /* bits 4-23 are write-as-0, 24-31 are write ignored */
-               val &= 0xf;
-               __asm__ __volatile__ ("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
-       }
-}
-
-static u32 read_pmnc(void)
-{
-       u32 val;
-
-       if (pmu->id == PMU_XSC1)
-               __asm__ __volatile__ ("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
-       else {
-               __asm__ __volatile__ ("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
-               /* bits 1-2 and 4-23 are read-unpredictable */
-               val &= 0xff000009;
-       }
-
-       return val;
-}
-
-static u32 __xsc1_read_counter(int counter)
-{
-       u32 val = 0;
-
-       switch (counter) {
-       case CCNT:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
-               break;
-       case PMN0:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
-               break;
-       case PMN1:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
-               break;
-       }
-       return val;
-}
-
-static u32 __xsc2_read_counter(int counter)
-{
-       u32 val = 0;
-
-       switch (counter) {
-       case CCNT:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
-               break;
-       case PMN0:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
-               break;
-       case PMN1:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
-               break;
-       case PMN2:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
-               break;
-       case PMN3:
-               __asm__ __volatile__ ("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
-               break;
-       }
-       return val;
-}
-
-static u32 read_counter(int counter)
-{
-       u32 val;
-
-       if (pmu->id == PMU_XSC1)
-               val = __xsc1_read_counter(counter);
-       else
-               val = __xsc2_read_counter(counter);
-
-       return val;
-}
-
-static void __xsc1_write_counter(int counter, u32 val)
-{
-       switch (counter) {
-       case CCNT:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
-               break;
-       case PMN0:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
-               break;
-       case PMN1:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
-               break;
-       }
-}
-
-static void __xsc2_write_counter(int counter, u32 val)
-{
-       switch (counter) {
-       case CCNT:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
-               break;
-       case PMN0:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
-               break;
-       case PMN1:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
-               break;
-       case PMN2:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
-               break;
-       case PMN3:
-               __asm__ __volatile__ ("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
-               break;
-       }
-}
-
-static void write_counter(int counter, u32 val)
-{
-       if (pmu->id == PMU_XSC1)
-               __xsc1_write_counter(counter, val);
-       else
-               __xsc2_write_counter(counter, val);
-}
-
-static int xscale_setup_ctrs(void)
-{
-       u32 evtsel, pmnc;
-       int i;
-
-       for (i = CCNT; i < MAX_COUNTERS; i++) {
-               if (counter_config[i].enabled)
-                       continue;
-
-               counter_config[i].event = EVT_UNUSED;
-       }
-
-       switch (pmu->id) {
-       case PMU_XSC1:
-               pmnc = (counter_config[PMN1].event << 20) | (counter_config[PMN0].event << 12);
-               pr_debug("xscale_setup_ctrs: pmnc: %#08x\n", pmnc);
-               write_pmnc(pmnc);
-               break;
-
-       case PMU_XSC2:
-               evtsel = counter_config[PMN0].event | (counter_config[PMN1].event << 8) |
-                       (counter_config[PMN2].event << 16) | (counter_config[PMN3].event << 24);
-
-               pr_debug("xscale_setup_ctrs: evtsel %#08x\n", evtsel);
-               __asm__ __volatile__ ("mcr p14, 0, %0, c8, c1, 0" : : "r" (evtsel));
-               break;
-       }
-
-       for (i = CCNT; i < MAX_COUNTERS; i++) {
-               if (counter_config[i].event == EVT_UNUSED) {
-                       counter_config[i].event = 0;
-                       pmu->int_enable &= ~pmu->int_mask[i];
-                       continue;
-               }
-
-               results[i].reset_counter = counter_config[i].count;
-               write_counter(i, -(u32)counter_config[i].count);
-               pmu->int_enable |= pmu->int_mask[i];
-               pr_debug("xscale_setup_ctrs: counter%d %#08x from %#08lx\n", i,
-                       read_counter(i), counter_config[i].count);
-       }
-
-       return 0;
-}
-
-static void inline __xsc1_check_ctrs(void)
-{
-       int i;
-       u32 pmnc = read_pmnc();
-
-       /* NOTE: there's an A stepping errata that states if an overflow */
-       /*       bit already exists and another occurs, the previous     */
-       /*       Overflow bit gets cleared. There's no workaround.       */
-       /*       Fixed in B stepping or later                            */
-
-       /* Write the value back to clear the overflow flags. Overflow */
-       /* flags remain in pmnc for use below */
-       write_pmnc(pmnc & ~PMU_ENABLE);
-
-       for (i = CCNT; i <= PMN1; i++) {
-               if (!(pmu->int_mask[i] & pmu->int_enable))
-                       continue;
-
-               if (pmnc & pmu->cnt_ovf[i])
-                       results[i].ovf++;
-       }
-}
-
-static void inline __xsc2_check_ctrs(void)
-{
-       int i;
-       u32 flag = 0, pmnc = read_pmnc();
-
-       pmnc &= ~PMU_ENABLE;
-       write_pmnc(pmnc);
-
-       /* read overflow flag register */
-       __asm__ __volatile__ ("mrc p14, 0, %0, c5, c1, 0" : "=r" (flag));
-
-       for (i = CCNT; i <= PMN3; i++) {
-               if (!(pmu->int_mask[i] & pmu->int_enable))
-                       continue;
-
-               if (flag & pmu->cnt_ovf[i])
-                       results[i].ovf++;
-       }
-
-       /* writeback clears overflow bits */
-       __asm__ __volatile__ ("mcr p14, 0, %0, c5, c1, 0" : : "r" (flag));
-}
-
-static irqreturn_t xscale_pmu_interrupt(int irq, void *arg)
-{
-       int i;
-       u32 pmnc;
-
-       if (pmu->id == PMU_XSC1)
-               __xsc1_check_ctrs();
-       else
-               __xsc2_check_ctrs();
-
-       for (i = CCNT; i < MAX_COUNTERS; i++) {
-               if (!results[i].ovf)
-                       continue;
-
-               write_counter(i, -(u32)results[i].reset_counter);
-               oprofile_add_sample(get_irq_regs(), i);
-               results[i].ovf--;
-       }
-
-       pmnc = read_pmnc() | PMU_ENABLE;
-       write_pmnc(pmnc);
-
-       return IRQ_HANDLED;
-}
-
-static const struct pmu_irqs *pmu_irqs;
-
-static void xscale_pmu_stop(void)
-{
-       u32 pmnc = read_pmnc();
-
-       pmnc &= ~PMU_ENABLE;
-       write_pmnc(pmnc);
-
-       free_irq(pmu_irqs->irqs[0], results);
-       release_pmu(pmu_irqs);
-       pmu_irqs = NULL;
-}
-
-static int xscale_pmu_start(void)
-{
-       int ret;
-       u32 pmnc;
-
-       pmu_irqs = reserve_pmu();
-       if (IS_ERR(pmu_irqs))
-               return PTR_ERR(pmu_irqs);
-
-       pmnc = read_pmnc();
-
-       ret = request_irq(pmu_irqs->irqs[0], xscale_pmu_interrupt,
-                         IRQF_DISABLED, "XScale PMU", (void *)results);
-
-       if (ret < 0) {
-               printk(KERN_ERR "oprofile: unable to request IRQ%d for XScale PMU\n",
-                      pmu_irqs->irqs[0]);
-               release_pmu(pmu_irqs);
-               pmu_irqs = NULL;
-               return ret;
-       }
-
-       if (pmu->id == PMU_XSC1)
-               pmnc |= pmu->int_enable;
-       else {
-               __asm__ __volatile__ ("mcr p14, 0, %0, c4, c1, 0" : : "r" (pmu->int_enable));
-               pmnc &= ~PMU_CNT64;
-       }
-
-       pmnc |= PMU_ENABLE;
-       write_pmnc(pmnc);
-       pr_debug("xscale_pmu_start: pmnc: %#08x mask: %08x\n", pmnc, pmu->int_enable);
-       return 0;
-}
-
-static int xscale_detect_pmu(void)
-{
-       int ret = 0;
-       u32 id;
-
-       id = (read_cpuid(CPUID_ID) >> 13) & 0x7;
-
-       switch (id) {
-       case 1:
-               pmu = &pmu_parms[PMU_XSC1];
-               break;
-       case 2:
-               pmu = &pmu_parms[PMU_XSC2];
-               break;
-       default:
-               ret = -ENODEV;
-               break;
-       }
-
-       if (!ret) {
-               op_xscale_spec.name = pmu->name;
-               op_xscale_spec.num_counters = pmu->num_counters;
-               pr_debug("xscale_detect_pmu: detected %s PMU\n", pmu->name);
-       }
-
-       return ret;
-}
-
-struct op_arm_model_spec op_xscale_spec = {
-       .init           = xscale_detect_pmu,
-       .setup_ctrs     = xscale_setup_ctrs,
-       .start          = xscale_pmu_start,
-       .stop           = xscale_pmu_stop,
-};
-
index 36bff03..69b09c1 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IOP32X) += time.o
 obj-$(CONFIG_ARCH_IOP32X) += io.o
 obj-$(CONFIG_ARCH_IOP32X) += cp6.o
 obj-$(CONFIG_ARCH_IOP32X) += adma.o
+obj-$(CONFIG_ARCH_IOP32X) += pmu.o
 
 # IOP33X
 obj-$(CONFIG_ARCH_IOP33X) += gpio.o
@@ -23,6 +24,7 @@ obj-$(CONFIG_ARCH_IOP33X) += time.o
 obj-$(CONFIG_ARCH_IOP33X) += io.o
 obj-$(CONFIG_ARCH_IOP33X) += cp6.o
 obj-$(CONFIG_ARCH_IOP33X) += adma.o
+obj-$(CONFIG_ARCH_IOP33X) += pmu.o
 
 # IOP13XX
 obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c
new file mode 100644 (file)
index 0000000..a2024b8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * PMU IRQ registration for the iop3xx xscale PMU families.
+ * Copyright (C) 2010 Will Deacon, ARM 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+
+static struct resource pmu_resource = {
+#ifdef CONFIG_ARCH_IOP32X
+       .start  = IRQ_IOP32X_CORE_PMU,
+       .end    = IRQ_IOP32X_CORE_PMU,
+#endif
+#ifdef CONFIG_ARCH_IOP33X
+       .start  = IRQ_IOP33X_CORE_PMU,
+       .end    = IRQ_IOP33X_CORE_PMU,
+#endif
+       .flags  = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+       .name           = "arm-pmu",
+       .id             = ARM_PMU_DEVICE_CPU,
+       .resource       = &pmu_resource,
+       .num_resources  = 1,
+};
+
+static int __init iop3xx_pmu_init(void)
+{
+       platform_device_register(&pmu_device);
+       return 0;
+}
+
+arch_initcall(iop3xx_pmu_init);
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
new file mode 100644 (file)
index 0000000..da92933
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
+
+/* Definitions for components on the Debug board */
+
+/* Base address of CPLD controller on the Debug board */
+#define DEBUG_BASE_ADDRESS             CS5_IO_ADDRESS(CS5_BASE_ADDR)
+
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR              CS5_BASE_ADDR
+
+/* CPLD config and interrupt base address */
+#define CPLD_ADDR                      (DEBUG_BASE_ADDRESS + 0x20000)
+
+/* LED switchs */
+#define CPLD_LED_REG                   (CPLD_ADDR + 0x00)
+/* buttons */
+#define CPLD_SWITCH_BUTTONS_REG        (EXPIO_ADDR + 0x08)
+/* status, interrupt */
+#define CPLD_INT_STATUS_REG            (CPLD_ADDR + 0x10)
+#define CPLD_INT_MASK_REG              (CPLD_ADDR + 0x38)
+#define CPLD_INT_RESET_REG             (CPLD_ADDR + 0x20)
+/* magic word for debug CPLD */
+#define CPLD_MAGIC_NUMBER1_REG         (CPLD_ADDR + 0x40)
+#define CPLD_MAGIC_NUMBER2_REG         (CPLD_ADDR + 0x48)
+/* CPLD code version */
+#define CPLD_CODE_VER_REG              (CPLD_ADDR + 0x50)
+/* magic word for debug CPLD */
+#define CPLD_MAGIC_NUMBER3_REG         (CPLD_ADDR + 0x58)
+/* module reset register */
+#define CPLD_MODULE_RESET_REG          (CPLD_ADDR + 0x60)
+/* CPU ID and Personality ID */
+#define CPLD_MCU_BOARD_ID_REG          (CPLD_ADDR + 0x68)
+
+/* CPLD IRQ line for external uart, external ethernet etc */
+#define EXPIO_PARENT_INT       IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
+
+#define MXC_EXP_IO_BASE                (MXC_BOARD_IRQ_START)
+#define MXC_IRQ_TO_EXPIO(irq)  ((irq) - MXC_EXP_IO_BASE)
+
+#define EXPIO_INT_ENET         (MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_XUART_A      (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_XUART_B      (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_BUTTON_A     (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_BUTTON_B     (MXC_EXP_IO_BASE + 4)
+
+#define MXC_MAX_EXP_IO_LINES   16
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
deleted file mode 100644 (file)
index 2bbd6ed..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
-
-/* Definitions for components on the Debug board */
-
-/* Base address of CPLD controller on the Debug board */
-#define DEBUG_BASE_ADDRESS             CS5_IO_ADDRESS(CS5_BASE_ADDR)
-
-/* LAN9217 ethernet base address */
-#define LAN9217_BASE_ADDR              CS5_BASE_ADDR
-
-/* CPLD config and interrupt base address */
-#define CPLD_ADDR                      (DEBUG_BASE_ADDRESS + 0x20000)
-
-/* LED switchs */
-#define CPLD_LED_REG                   (CPLD_ADDR + 0x00)
-/* buttons */
-#define CPLD_SWITCH_BUTTONS_REG        (EXPIO_ADDR + 0x08)
-/* status, interrupt */
-#define CPLD_INT_STATUS_REG            (CPLD_ADDR + 0x10)
-#define CPLD_INT_MASK_REG              (CPLD_ADDR + 0x38)
-#define CPLD_INT_RESET_REG             (CPLD_ADDR + 0x20)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER1_REG         (CPLD_ADDR + 0x40)
-#define CPLD_MAGIC_NUMBER2_REG         (CPLD_ADDR + 0x48)
-/* CPLD code version */
-#define CPLD_CODE_VER_REG              (CPLD_ADDR + 0x50)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER3_REG         (CPLD_ADDR + 0x58)
-/* module reset register */
-#define CPLD_MODULE_RESET_REG          (CPLD_ADDR + 0x60)
-/* CPU ID and Personality ID */
-#define CPLD_MCU_BOARD_ID_REG          (CPLD_ADDR + 0x68)
-
-/* CPLD IRQ line for external uart, external ethernet etc */
-#define EXPIO_PARENT_INT       IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
-
-#define MXC_EXP_IO_BASE                (MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_EXPIO(irq)  ((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_ENET         (MXC_EXP_IO_BASE + 0)
-#define EXPIO_INT_XUART_A      (MXC_EXP_IO_BASE + 1)
-#define EXPIO_INT_XUART_B      (MXC_EXP_IO_BASE + 2)
-#define EXPIO_INT_BUTTON_A     (MXC_EXP_IO_BASE + 3)
-#define EXPIO_INT_BUTTON_B     (MXC_EXP_IO_BASE + 4)
-
-#define MXC_MAX_EXP_IO_LINES   16
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
index 07be8ad..7c4870b 100644 (file)
 #define DMA_MODE_WRITE         1
 #define DMA_MODE_MASK          1
 
-#define DMA_BASE IO_ADDRESS(DMA_BASE_ADDR)
+#define MX1_DMA_REG(offset)    MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
+
+/* DMA Interrupt Mask Register */
+#define MX1_DMA_DIMR           MX1_DMA_REG(0x08)
+
+/* Channel Control Register */
+#define MX1_DMA_CCR(x)         MX1_DMA_REG(0x8c + ((x) << 6))
 
 #define IMX_DMA_MEMSIZE_32     (0 << 4)
 #define IMX_DMA_MEMSIZE_8      (1 << 4)
index 771532b..5aad344 100644 (file)
@@ -14,7 +14,7 @@
  * FB100000    70000000        1M      SPBA 0
  * FB000000    73F00000        1M      AIPS 1
  * FB200000    83F00000        1M      AIPS 2
- * FA100000    8FFFC000        16K     TZIC (interrupt controller)
+ *             8FFFC000        16K     TZIC (interrupt controller)
  *             90000000        256M    CSD0 SDRAM/DDR
  *             A0000000        256M    CSD1 SDRAM/DDR
  *             B0000000        128M    CS0 Flash
  *             C8000000        64M     CS3 Flash
  *             CC000000        32M     CS4 SRAM
  *             CE000000        32M     CS5 SRAM
- * F9000000    CFFF0000        64K     NFC (NAND Flash AXI)
+ *             CFFF0000        64K     NFC (NAND Flash AXI)
  *
  */
 
+/*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR            0x0
+#define MX51_IROM_SIZE                 SZ_64K
+
 /*
  * IRAM
  */
@@ -40,7 +46,6 @@
  * NFC
  */
 #define MX51_NFC_AXI_BASE_ADDR         0xCFFF0000      /* NAND flash AXI */
-#define MX51_NFC_AXI_BASE_ADDR_VIRT    0xF9000000
 #define MX51_NFC_AXI_SIZE              SZ_64K
 
 /*
@@ -49,9 +54,8 @@
 #define MX51_GPU_BASE_ADDR             0x20000000
 #define MX51_GPU2D_BASE_ADDR           0xD0000000
 
-#define MX51_TZIC_BASE_ADDR            0x8FFFC000
-#define MX51_TZIC_BASE_ADDR_VIRT       0xFA100000
-#define MX51_TZIC_SIZE                 SZ_16K
+#define MX51_TZIC_BASE_ADDR_TO1                0x8FFFC000
+#define MX51_TZIC_BASE_ADDR            0xE0000000
 
 #define MX51_DEBUG_BASE_ADDR           0x60000000
 #define MX51_DEBUG_BASE_ADDR_VIRT      0xFA200000
 #define MX51_IO_ADDRESS(x)                                     \
        (void __iomem *)                                        \
        (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :    \
-       MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) :     \
        MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :   \
        MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :   \
        MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :   \
-       MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) :   \
-       MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \
+       MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
        0xDEADBEEF)
 
 /*
 #define MX51_IRAM_IO_ADDRESS(x)  \
        (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
 
-#define MX51_TZIC_IO_ADDRESS(x)  \
-       (((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT)
-
 #define MX51_DEBUG_IO_ADDRESS(x)  \
        (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
 
 #define MX51_AIPS2_IO_ADDRESS(x)  \
        (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
 
-#define MX51_NFC_AXI_IO_ADDRESS(x) \
-       (((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT)
-
 #define MX51_IS_MEM_DEVICE_NONSHARED(x)                0
 
 /*
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 
-extern unsigned int system_rev;
-
-static inline unsigned int mx51_revision(void)
-{
-       return system_rev;
-}
+extern int mx51_revision(void);
 #endif
 
 #endif /*  __ASM_ARCH_MXC_MX51_H__ */
index 52e476a..b6d3d0f 100644 (file)
@@ -66,6 +66,7 @@ static inline void flush(void)
 #define MX2X_UART1_BASE_ADDR   0x1000a000
 #define MX3X_UART1_BASE_ADDR   0x43F90000
 #define MX3X_UART2_BASE_ADDR   0x43F94000
+#define MX51_UART1_BASE_ADDR   0x73fbc000
 
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
@@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
        case MACH_TYPE_MAGX_ZN5:
                uart_base = MX3X_UART2_BASE_ADDR;
                break;
+       case MACH_TYPE_MX51_BABBAGE:
+               uart_base = MX51_UART1_BASE_ADDR;
+               break;
        default:
                break;
        }
index 159daf5..5da3f97 100644 (file)
@@ -19,4 +19,9 @@ config HAS_MTU
          to multiple interrupt generating programmable
          32-bit free running decrementing counters.
 
+config NOMADIK_GPIO
+       bool
+       help
+         Support for the Nomadik GPIO controller.
+
 endif
index 37c7cdd..c335473 100644 (file)
@@ -3,3 +3,4 @@
 # Licensed under GPLv2
 
 obj-$(CONFIG_HAS_MTU)  += timer.o
+obj-$(CONFIG_NOMADIK_GPIO)     += gpio.o
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
new file mode 100644 (file)
index 0000000..5a6ef25
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * Generic GPIO driver for logic cells found in the Nomadik SoC
+ *
+ * Copyright (C) 2008,2009 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.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/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+/*
+ * The GPIO module in the Nomadik family of Systems-on-Chip is an
+ * AMBA device, managing 32 pins and alternate functions.  The logic block
+ * is currently only used in the Nomadik.
+ *
+ * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
+ */
+
+#define NMK_GPIO_PER_CHIP 32
+struct nmk_gpio_chip {
+       struct gpio_chip chip;
+       void __iomem *addr;
+       struct clk *clk;
+       unsigned int parent_irq;
+       spinlock_t lock;
+       /* Keep track of configured edges */
+       u32 edge_rising;
+       u32 edge_falling;
+};
+
+/* Mode functions */
+int nmk_gpio_set_mode(int gpio, int gpio_mode)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       unsigned long flags;
+       u32 afunc, bfunc, bit;
+
+       nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+       if (!nmk_chip)
+               return -EINVAL;
+
+       bit = 1 << (gpio - nmk_chip->chip.base);
+
+       spin_lock_irqsave(&nmk_chip->lock, flags);
+       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
+       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
+       if (gpio_mode & NMK_GPIO_ALT_A)
+               afunc |= bit;
+       if (gpio_mode & NMK_GPIO_ALT_B)
+               bfunc |= bit;
+       writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
+       writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+       spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(nmk_gpio_set_mode);
+
+int nmk_gpio_get_mode(int gpio)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       u32 afunc, bfunc, bit;
+
+       nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+       if (!nmk_chip)
+               return -EINVAL;
+
+       bit = 1 << (gpio - nmk_chip->chip.base);
+
+       afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
+       bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
+
+       return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
+}
+EXPORT_SYMBOL(nmk_gpio_get_mode);
+
+
+/* IRQ functions */
+static inline int nmk_gpio_get_bitmask(int gpio)
+{
+       return 1 << (gpio % 32);
+}
+
+static void nmk_gpio_irq_ack(unsigned int irq)
+{
+       int gpio;
+       struct nmk_gpio_chip *nmk_chip;
+
+       gpio = NOMADIK_IRQ_TO_GPIO(irq);
+       nmk_chip = get_irq_chip_data(irq);
+       if (!nmk_chip)
+               return;
+       writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
+}
+
+static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
+                                 int gpio, bool enable)
+{
+       u32 bitmask = nmk_gpio_get_bitmask(gpio);
+       u32 reg;
+
+       /* we must individually set/clear the two edges */
+       if (nmk_chip->edge_rising & bitmask) {
+               reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC);
+               if (enable)
+                       reg |= bitmask;
+               else
+                       reg &= ~bitmask;
+               writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC);
+       }
+       if (nmk_chip->edge_falling & bitmask) {
+               reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC);
+               if (enable)
+                       reg |= bitmask;
+               else
+                       reg &= ~bitmask;
+               writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC);
+       }
+}
+
+static void nmk_gpio_irq_modify(unsigned int irq, bool enable)
+{
+       int gpio;
+       struct nmk_gpio_chip *nmk_chip;
+       unsigned long flags;
+       u32 bitmask;
+
+       gpio = NOMADIK_IRQ_TO_GPIO(irq);
+       nmk_chip = get_irq_chip_data(irq);
+       bitmask = nmk_gpio_get_bitmask(gpio);
+       if (!nmk_chip)
+               return;
+
+       spin_lock_irqsave(&nmk_chip->lock, flags);
+       __nmk_gpio_irq_modify(nmk_chip, gpio, enable);
+       spin_unlock_irqrestore(&nmk_chip->lock, flags);
+}
+
+static void nmk_gpio_irq_mask(unsigned int irq)
+{
+       nmk_gpio_irq_modify(irq, false);
+};
+
+static void nmk_gpio_irq_unmask(unsigned int irq)
+{
+       nmk_gpio_irq_modify(irq, true);
+}
+
+static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
+{
+       bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED);
+       int gpio;
+       struct nmk_gpio_chip *nmk_chip;
+       unsigned long flags;
+       u32 bitmask;
+
+       gpio = NOMADIK_IRQ_TO_GPIO(irq);
+       nmk_chip = get_irq_chip_data(irq);
+       bitmask = nmk_gpio_get_bitmask(gpio);
+       if (!nmk_chip)
+               return -EINVAL;
+
+       if (type & IRQ_TYPE_LEVEL_HIGH)
+               return -EINVAL;
+       if (type & IRQ_TYPE_LEVEL_LOW)
+               return -EINVAL;
+
+       spin_lock_irqsave(&nmk_chip->lock, flags);
+
+       if (enabled)
+               __nmk_gpio_irq_modify(nmk_chip, gpio, false);
+
+       nmk_chip->edge_rising &= ~bitmask;
+       if (type & IRQ_TYPE_EDGE_RISING)
+               nmk_chip->edge_rising |= bitmask;
+
+       nmk_chip->edge_falling &= ~bitmask;
+       if (type & IRQ_TYPE_EDGE_FALLING)
+               nmk_chip->edge_falling |= bitmask;
+
+       if (enabled)
+               __nmk_gpio_irq_modify(nmk_chip, gpio, true);
+
+       spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+       return 0;
+}
+
+static struct irq_chip nmk_gpio_irq_chip = {
+       .name           = "Nomadik-GPIO",
+       .ack            = nmk_gpio_irq_ack,
+       .mask           = nmk_gpio_irq_mask,
+       .unmask         = nmk_gpio_irq_unmask,
+       .set_type       = nmk_gpio_irq_set_type,
+};
+
+static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       struct irq_chip *host_chip = get_irq_chip(irq);
+       unsigned int gpio_irq;
+       u32 pending;
+       unsigned int first_irq;
+
+       if (host_chip->mask_ack)
+               host_chip->mask_ack(irq);
+       else {
+               host_chip->mask(irq);
+               if (host_chip->ack)
+                       host_chip->ack(irq);
+       }
+
+       nmk_chip = get_irq_data(irq);
+       first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+       while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
+               gpio_irq = first_irq + __ffs(pending);
+               generic_handle_irq(gpio_irq);
+       }
+
+       host_chip->unmask(irq);
+}
+
+static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
+{
+       unsigned int first_irq;
+       int i;
+
+       first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+       for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
+               set_irq_chip(i, &nmk_gpio_irq_chip);
+               set_irq_handler(i, handle_edge_irq);
+               set_irq_flags(i, IRQF_VALID);
+               set_irq_chip_data(i, nmk_chip);
+               set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
+       }
+       set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
+       set_irq_data(nmk_chip->parent_irq, nmk_chip);
+       return 0;
+}
+
+/* I/O Functions */
+static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+
+       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+       return 0;
+}
+
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+                               int val)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+
+       writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+       return 0;
+}
+
+static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+       u32 bit = 1 << offset;
+
+       return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
+}
+
+static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
+                               int val)
+{
+       struct nmk_gpio_chip *nmk_chip =
+               container_of(chip, struct nmk_gpio_chip, chip);
+       u32 bit = 1 << offset;
+
+       if (val)
+               writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+       else
+               writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+/* This structure is replicated for each GPIO block allocated at probe time */
+static struct gpio_chip nmk_gpio_template = {
+       .direction_input        = nmk_gpio_make_input,
+       .get                    = nmk_gpio_get_input,
+       .direction_output       = nmk_gpio_make_output,
+       .set                    = nmk_gpio_set_output,
+       .ngpio                  = NMK_GPIO_PER_CHIP,
+       .can_sleep              = 0,
+};
+
+static int __init nmk_gpio_probe(struct platform_device *dev)
+{
+       struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
+       struct nmk_gpio_chip *nmk_chip;
+       struct gpio_chip *chip;
+       struct resource *res;
+       struct clk *clk;
+       int irq;
+       int ret;
+
+       if (!pdata)
+               return -ENODEV;
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENOENT;
+               goto out;
+       }
+
+       irq = platform_get_irq(dev, 0);
+       if (irq < 0) {
+               ret = irq;
+               goto out;
+       }
+
+       if (request_mem_region(res->start, resource_size(res),
+                              dev_name(&dev->dev)) == NULL) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       clk = clk_get(&dev->dev, NULL);
+       if (IS_ERR(clk)) {
+               ret = PTR_ERR(clk);
+               goto out_release;
+       }
+
+       clk_enable(clk);
+
+       nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
+       if (!nmk_chip) {
+               ret = -ENOMEM;
+               goto out_clk;
+       }
+       /*
+        * The virt address in nmk_chip->addr is in the nomadik register space,
+        * so we can simply convert the resource address, without remapping
+        */
+       nmk_chip->clk = clk;
+       nmk_chip->addr = io_p2v(res->start);
+       nmk_chip->chip = nmk_gpio_template;
+       nmk_chip->parent_irq = irq;
+       spin_lock_init(&nmk_chip->lock);
+
+       chip = &nmk_chip->chip;
+       chip->base = pdata->first_gpio;
+       chip->label = pdata->name;
+       chip->dev = &dev->dev;
+       chip->owner = THIS_MODULE;
+
+       ret = gpiochip_add(&nmk_chip->chip);
+       if (ret)
+               goto out_free;
+
+       platform_set_drvdata(dev, nmk_chip);
+
+       nmk_gpio_init_irq(nmk_chip);
+
+       dev_info(&dev->dev, "Bits %i-%i at address %p\n",
+                nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
+       return 0;
+
+out_free:
+       kfree(nmk_chip);
+out_clk:
+       clk_disable(clk);
+       clk_put(clk);
+out_release:
+       release_mem_region(res->start, resource_size(res));
+out:
+       dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
+                 pdata->first_gpio, pdata->first_gpio+31);
+       return ret;
+}
+
+static int __exit nmk_gpio_remove(struct platform_device *dev)
+{
+       struct nmk_gpio_chip *nmk_chip;
+       struct resource *res;
+
+       res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+
+       nmk_chip = platform_get_drvdata(dev);
+       gpiochip_remove(&nmk_chip->chip);
+       clk_disable(nmk_chip->clk);
+       clk_put(nmk_chip->clk);
+       kfree(nmk_chip);
+       release_mem_region(res->start, resource_size(res));
+       return 0;
+}
+
+
+static struct platform_driver nmk_gpio_driver = {
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "gpio",
+               },
+       .probe = nmk_gpio_probe,
+       .remove = __exit_p(nmk_gpio_remove),
+       .suspend = NULL, /* to be done */
+       .resume = NULL,
+};
+
+static int __init nmk_gpio_init(void)
+{
+       return platform_driver_register(&nmk_gpio_driver);
+}
+
+arch_initcall(nmk_gpio_init);
+
+MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
+MODULE_DESCRIPTION("Nomadik GPIO Driver");
+MODULE_LICENSE("GPL");
+
+
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
new file mode 100644 (file)
index 0000000..4200811
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Structures and registers for GPIO access in the Nomadik SoC
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ *     Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *
+ * 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_PLAT_GPIO_H
+#define __ASM_PLAT_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+/*
+ * These currently cause a function call to happen, they may be optimized
+ * if needed by adding cpu-specific defines to identify blocks
+ * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
+ */
+#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
+
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT   0x00
+#define NMK_GPIO_DATS  0x04
+#define NMK_GPIO_DATC  0x08
+#define NMK_GPIO_PDIS  0x0c
+#define NMK_GPIO_DIR   0x10
+#define NMK_GPIO_DIRS  0x14
+#define NMK_GPIO_DIRC  0x18
+#define NMK_GPIO_SLPC  0x1c
+#define NMK_GPIO_AFSLA 0x20
+#define NMK_GPIO_AFSLB 0x24
+
+#define NMK_GPIO_RIMSC 0x40
+#define NMK_GPIO_FIMSC 0x44
+#define NMK_GPIO_IS    0x48
+#define NMK_GPIO_IC    0x4c
+#define NMK_GPIO_RWIMSC        0x50
+#define NMK_GPIO_FWIMSC        0x54
+#define NMK_GPIO_WKS   0x58
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO      0
+#define NMK_GPIO_ALT_A 1
+#define NMK_GPIO_ALT_B 2
+#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
+extern int nmk_gpio_get_mode(int gpio);
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+       char *name;
+       int first_gpio;
+       int first_irq;
+};
+
+#endif /* __ASM_PLAT_GPIO_H */
index fa7cb3a..0ff3798 100644 (file)
@@ -2,7 +2,7 @@
  *  linux/arch/arm/mach-nomadik/timer.c
  *
  * Copyright (C) 2008 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
+ * Copyright (C) 2010 Alessandro Rubini
  *
  * 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 <plat/mtu.h>
 
-static u32     nmdk_count;             /* accumulated count */
-static u32     nmdk_cycle;             /* write-once */
-
-/* setup by the platform code */
-void __iomem *mtu_base;
+void __iomem *mtu_base; /* ssigned by machine code */
 
 /*
- * clocksource: the MTU device is a decrementing counters, so we negate
- * the value being read.
+ * Kernel assumes that sched_clock can be called early
+ * but the MTU may not yet be initialized.
  */
-static cycle_t nmdk_read_timer(struct clocksource *cs)
+static cycle_t nmdk_read_timer_dummy(struct clocksource *cs)
 {
-       u32 count = readl(mtu_base + MTU_VAL(0));
-       return nmdk_count + nmdk_cycle - count;
+       return 0;
+}
 
+/* clocksource: MTU decrements, so we negate the value being read. */
+static cycle_t nmdk_read_timer(struct clocksource *cs)
+{
+       return -readl(mtu_base + MTU_VAL(0));
 }
 
 static struct clocksource nmdk_clksrc = {
        .name           = "mtu_0",
-       .rating         = 120,
-       .read           = nmdk_read_timer,
+       .rating         = 200,
+       .read           = nmdk_read_timer_dummy,
+       .mask           = CLOCKSOURCE_MASK(32),
        .shift          = 20,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 /*
- * Clockevent device: currently only periodic mode is supported
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel. We accept that
+ * this wraps around for now, since it is just a relative time
+ * stamp. (Inspired by OMAP implementation.)
  */
+unsigned long long notrace sched_clock(void)
+{
+       return clocksource_cyc2ns(nmdk_clksrc.read(
+                                 &nmdk_clksrc),
+                                 nmdk_clksrc.mult,
+                                 nmdk_clksrc.shift);
+}
+
+/* Clockevent device: use one-shot mode */
 static void nmdk_clkevt_mode(enum clock_event_mode mode,
                             struct clock_event_device *dev)
 {
+       u32 cr;
+
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               /* count current value? */
-               writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
+               pr_err("%s: periodic mode not supported\n", __func__);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
-               BUG(); /* Not supported, yet */
-               /* FALLTHROUGH */
+               /* Load highest value, enable device, enable interrupts */
+               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);
+               break;
        case CLOCK_EVT_MODE_SHUTDOWN:
        case CLOCK_EVT_MODE_UNUSED:
-               writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
+               /* disable irq */
+               writel(0, mtu_base + MTU_IMSC);
                break;
        case CLOCK_EVT_MODE_RESUME:
                break;
        }
 }
 
+static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
+{
+       /* writing the value has immediate effect */
+       writel(evt, mtu_base + MTU_LR(1));
+       return 0;
+}
+
 static struct clock_event_device nmdk_clkevt = {
-       .name           = "mtu_0",
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .name           = "mtu_1",
+       .features       = CLOCK_EVT_FEAT_ONESHOT,
        .shift          = 32,
-       .rating         = 100,
+       .rating         = 200,
        .set_mode       = nmdk_clkevt_mode,
+       .set_next_event = nmdk_clkevt_next,
 };
 
 /*
- * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
- * as we are the only users of mtu0 by now.
+ * IRQ Handler for timer 1 of the MTU block.
  */
 static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
 {
-       /* ack: "interrupt clear register" */
-       writel(1 << 0, mtu_base + MTU_ICR);
-
-       /* we can't count lost ticks, unfortunately */
-       nmdk_count += nmdk_cycle;
-       nmdk_clkevt.event_handler(&nmdk_clkevt);
+       struct clock_event_device *evdev = dev_id;
 
+       writel(1 << 1, mtu_base + MTU_ICR); /* Interrupt clear reg */
+       evdev->event_handler(evdev);
        return IRQ_HANDLED;
 }
 
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
 static struct irqaction nmdk_timer_irq = {
        .name           = "Nomadik Timer Tick",
        .flags          = IRQF_DISABLED | IRQF_TIMER,
        .handler        = nmdk_timer_interrupt,
+       .dev_id         = &nmdk_clkevt,
 };
 
-static void nmdk_timer_reset(void)
-{
-       u32 cr;
-
-       writel(0, mtu_base + MTU_CR(0)); /* off */
-
-       /* configure load and background-load, and fire it up */
-       writel(nmdk_cycle, mtu_base + MTU_LR(0));
-       writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
-       cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
-       writel(cr, mtu_base + MTU_CR(0));
-       writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
-}
-
 void __init nmdk_timer_init(void)
 {
        unsigned long rate;
-       int bits;
-
-       rate = CLOCK_TICK_RATE; /* 2.4MHz */
-       nmdk_cycle = (rate + HZ/2) / HZ;
+       u32 cr = MTU_CRn_32BITS;;
+
+       /*
+        * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500:
+        * use a divide-by-16 counter if it's more than 16MHz
+        */
+       rate = CLOCK_TICK_RATE;
+       if (rate > 16 << 20) {
+               rate /= 16;
+               cr |= MTU_CRn_PRESCALE_16;
+       } else {
+               cr |= MTU_CRn_PRESCALE_1;
+       }
 
-       /* Init the timer and register clocksource */
-       nmdk_timer_reset();
+       /* Timer 0 is the free running clocksource */
+       writel(cr, mtu_base + MTU_CR(0));
+       writel(0, mtu_base + MTU_LR(0));
+       writel(0, mtu_base + MTU_BGLR(0));
+       writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
 
        nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
-       bits =  8*sizeof(nmdk_count);
-       nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
+       /* Now the scheduling clock is ready */
+       nmdk_clksrc.read = nmdk_read_timer;
 
        if (clocksource_register(&nmdk_clksrc))
-               printk(KERN_ERR "timer: failed to initialize clock "
-                       "source %s\n", nmdk_clksrc.name);
+               pr_err("timer: failed to initialize clock source %s\n",
+                      nmdk_clksrc.name);
+
+       /* Timer 1 is used for events, fix according to rate */
+       writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
+       nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+       nmdk_clkevt.max_delta_ns =
+               clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
+       nmdk_clkevt.min_delta_ns =
+               clockevent_delta2ns(0x00000002, &nmdk_clkevt);
+       nmdk_clkevt.cpumask     = cpumask_of(0);
 
        /* Register irq and clockevents */
        setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-       nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
-       nmdk_clkevt.cpumask = cpumask_of(0);
        clockevents_register_device(&nmdk_clkevt);
 }
index 088c1a0..f12f0e3 100644 (file)
@@ -44,9 +44,6 @@
 
 #define NO_LENGTH_CHECK 0xffffffff
 
-unsigned char omap_bootloader_tag[512];
-int omap_bootloader_tag_len;
-
 struct omap_board_config_kernel *omap_board_config;
 int omap_board_config_size;
 
@@ -100,10 +97,17 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 #include <linux/clocksource.h>
 
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
 #ifdef CONFIG_ARCH_OMAP16XX
 static cycle_t omap16xx_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
+       return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
 }
 #else
 #define omap16xx_32k_read      NULL
@@ -112,7 +116,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2420
 static cycle_t omap2420_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2420_32k_read      NULL
@@ -121,7 +125,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2430
 static cycle_t omap2430_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2430_32k_read      NULL
@@ -130,7 +134,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP3
 static cycle_t omap34xx_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap34xx_32k_read      NULL
@@ -139,7 +143,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP4
 static cycle_t omap44xx_32k_read(struct clocksource *cs)
 {
-       return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+       return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap44xx_32k_read      NULL
@@ -227,6 +231,8 @@ static int __init omap_init_clocksource_32k(void)
                clocksource_32k.mult = clocksource_hz2mult(32768,
                                            clocksource_32k.shift);
 
+               offset_32k = clocksource_32k.read(&clocksource_32k);
+
                if (clocksource_register(&clocksource_32k))
                        printk(err, clocksource_32k.name);
        }
index 5c6c342..1d95996 100644 (file)
@@ -937,6 +937,15 @@ void omap_start_dma(int lch)
 {
        u32 l;
 
+       /*
+        * The CPC/CDAC register needs to be initialized to zero
+        * before starting dma transfer.
+        */
+       if (cpu_is_omap15xx())
+               dma_write(0, CPC(lch));
+       else
+               dma_write(0, CDAC(lch));
+
        if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
                int next_lch, cur_lch;
                char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
index 76a347b..45a225d 100644 (file)
@@ -798,7 +798,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_MPUIO:
                reg += OMAP_MPUIO_GPIO_INT_EDGE;
                l = __raw_readl(reg);
-               if (trigger & IRQ_TYPE_EDGE_BOTH)
+               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 1 << gpio;
@@ -812,7 +812,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_GPIO_1510:
                reg += OMAP1510_GPIO_INT_CONTROL;
                l = __raw_readl(reg);
-               if (trigger & IRQ_TYPE_EDGE_BOTH)
+               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 1 << gpio;
@@ -846,7 +846,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
        case METHOD_GPIO_7XX:
                reg += OMAP7XX_GPIO_INT_CONTROL;
                l = __raw_readl(reg);
-               if (trigger & IRQ_TYPE_EDGE_BOTH)
+               if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
                        bank->toggle_mask |= 1 << gpio;
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        l |= 1 << gpio;
index b65088a..4017019 100644 (file)
 #define INT_34XX_MMC3_IRQ      94
 #define INT_34XX_GPT12_IRQ     95
 
-#define        INT_34XX_BENCH_MPU_EMUL 3
-
 #define INT_35XX_HECC0_IRQ             24
 #define INT_35XX_HECC1_IRQ             28
 #define INT_35XX_EMAC_C0_RXTHRESH_IRQ  67
index 3974835..7de903d 100644 (file)
@@ -59,7 +59,7 @@
 #define OMAP44XX_MCBSP1_BASE   0x49022000
 #define OMAP44XX_MCBSP2_BASE   0x49024000
 #define OMAP44XX_MCBSP3_BASE   0x49026000
-#define OMAP44XX_MCBSP4_BASE   0x48074000
+#define OMAP44XX_MCBSP4_BASE   0x48096000
 
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 
index 6ba88d2..f8efd54 100644 (file)
@@ -29,4 +29,11 @@ struct omap_nand_platform_data {
 /* size (4 KiB) for IO mapping */
 #define        NAND_IO_SIZE    SZ_4K
 
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
 extern int gpmc_nand_init(struct omap_nand_platform_data *d);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
+{
+       return 0;
+}
+#endif
index 2302474..b3ef1a7 100644 (file)
@@ -32,7 +32,7 @@
 #define OMAP4430_PRM_BASE              0x4a306000
 #define OMAP44XX_GPMC_BASE             0x50000000
 #define OMAP443X_SCM_BASE              0x4a002000
-#define OMAP443X_CTRL_BASE             OMAP443X_SCM_BASE
+#define OMAP443X_CTRL_BASE             0x4a100000
 #define OMAP44XX_IC_BASE               0x48200000
 #define OMAP44XX_IVA_INTC_BASE         0x40000000
 #define IRQ_SIR_IRQ                    0x0040
index 440b416..36d6ea5 100644 (file)
@@ -294,8 +294,8 @@ struct omap_hwmod_class_sysconfig {
        u16 rev_offs;
        u16 sysc_offs;
        u16 syss_offs;
+       u16 sysc_flags;
        u8 idlemodes;
-       u8 sysc_flags;
        u8 clockact;
        struct omap_hwmod_sysc_fields *sysc_fields;
 };
index 568578d..876ca8d 100644 (file)
@@ -46,7 +46,7 @@ struct ehci_hcd_omap_platform_data {
 struct omap_musb_board_data {
        u8      interface_type;
        u8      mode;
-       u     power;
+       u16     power;
 };
 
 enum musb_interface    {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
index b158e98..da53395 100644 (file)
@@ -1,3 +1,8 @@
 if PLAT_PXA
 
+config PXA_SSP
+       tristate
+       help
+         Enable support for PXA2xx SSP ports
+
 endif
index 0264bfb..6187edf 100644 (file)
@@ -2,10 +2,11 @@
 # Makefile for code common across different PXA processor families
 #
 
-obj-y  := dma.o
+obj-y  := dma.o pmu.o
 
 obj-$(CONFIG_GENERIC_GPIO)     += gpio.o
 obj-$(CONFIG_PXA3xx)           += mfp.o
 obj-$(CONFIG_ARCH_MMP)         += mfp.o
 
 obj-$(CONFIG_HAVE_PWM)         += pwm.o
+obj-$(CONFIG_PXA_SSP)          += ssp.o
index 742350e..2d3c19d 100644 (file)
@@ -245,7 +245,7 @@ static void pxa_dma_init_debugfs(void)
 
        dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
                             GFP_KERNEL);
-       if (!dbgfs_state)
+       if (!dbgfs_chan)
                goto err_alloc;
 
        chandir = debugfs_create_dir("channels", dbgfs_root);
index 857a683..9e604c8 100644 (file)
@@ -316,6 +316,13 @@ enum {
        MFP_PIN_PMIC_INT,
        MFP_PIN_RDY,
 
+       /* additional pins on MMP2 */
+       MFP_PIN_TWSI1_SCL,
+       MFP_PIN_TWSI1_SDA,
+       MFP_PIN_TWSI4_SCL,
+       MFP_PIN_TWSI4_SDA,
+       MFP_PIN_CLK_REQ,
+
        MFP_PIN_MAX,
 };
 
diff --git a/arch/arm/plat-pxa/include/plat/ssp.h b/arch/arm/plat-pxa/include/plat/ssp.h
new file mode 100644 (file)
index 0000000..fe43150
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *  ssp.h
+ *
+ *  Copyright (C) 2003 Russell King, 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 as
+ * published by the Free Software Foundation.
+ *
+ * This driver supports the following PXA CPU/SSP ports:-
+ *
+ *       PXA250     SSP
+ *       PXA255     SSP, NSSP
+ *       PXA26x     SSP, NSSP, ASSP
+ *       PXA27x     SSP1, SSP2, SSP3
+ *       PXA3xx     SSP1, SSP2, SSP3, SSP4
+ */
+
+#ifndef __ASM_ARCH_SSP_H
+#define __ASM_ARCH_SSP_H
+
+#include <linux/list.h>
+#include <linux/io.h>
+
+/*
+ * SSP Serial Port Registers
+ * PXA250, PXA255, PXA26x and PXA27x SSP controllers are all slightly different.
+ * PXA255, PXA26x and PXA27x have extra ports, registers and bits.
+ */
+
+#define SSCR0          (0x00)  /* SSP Control Register 0 */
+#define SSCR1          (0x04)  /* SSP Control Register 1 */
+#define SSSR           (0x08)  /* SSP Status Register */
+#define SSITR          (0x0C)  /* SSP Interrupt Test Register */
+#define SSDR           (0x10)  /* SSP Data Write/Data Read Register */
+
+#define SSTO           (0x28)  /* SSP Time Out Register */
+#define SSPSP          (0x2C)  /* SSP Programmable Serial Protocol */
+#define SSTSA          (0x30)  /* SSP Tx Timeslot Active */
+#define SSRSA          (0x34)  /* SSP Rx Timeslot Active */
+#define SSTSS          (0x38)  /* SSP Timeslot Status */
+#define SSACD          (0x3C)  /* SSP Audio Clock Divider */
+#define SSACDD         (0x40)  /* SSP Audio Clock Dither Divider */
+
+/* Common PXA2xx bits first */
+#define SSCR0_DSS      (0x0000000f)    /* Data Size Select (mask) */
+#define SSCR0_DataSize(x)  ((x) - 1)   /* Data Size Select [4..16] */
+#define SSCR0_FRF      (0x00000030)    /* FRame Format (mask) */
+#define SSCR0_Motorola (0x0 << 4)      /* Motorola's Serial Peripheral Interface (SPI) */
+#define SSCR0_TI       (0x1 << 4)      /* Texas Instruments' Synchronous Serial Protocol (SSP) */
+#define SSCR0_National (0x2 << 4)      /* National Microwire */
+#define SSCR0_ECS      (1 << 6)        /* External clock select */
+#define SSCR0_SSE      (1 << 7)        /* Synchronous Serial Port Enable */
+#define SSCR0_SCR(x)   ((x) << 8)      /* Serial Clock Rate (mask) */
+
+/* PXA27x, PXA3xx */
+#define SSCR0_EDSS     (1 << 20)       /* Extended data size select */
+#define SSCR0_NCS      (1 << 21)       /* Network clock select */
+#define SSCR0_RIM      (1 << 22)       /* Receive FIFO overrrun interrupt mask */
+#define SSCR0_TUM      (1 << 23)       /* Transmit FIFO underrun interrupt mask */
+#define SSCR0_FRDC     (0x07000000)    /* Frame rate divider control (mask) */
+#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */
+#define SSCR0_FPCKE    (1 << 29)       /* FIFO packing enable */
+#define SSCR0_ACS      (1 << 30)       /* Audio clock select */
+#define SSCR0_MOD      (1 << 31)       /* Mode (normal or network) */
+
+
+#define SSCR1_RIE      (1 << 0)        /* Receive FIFO Interrupt Enable */
+#define SSCR1_TIE      (1 << 1)        /* Transmit FIFO Interrupt Enable */
+#define SSCR1_LBM      (1 << 2)        /* Loop-Back Mode */
+#define SSCR1_SPO      (1 << 3)        /* Motorola SPI SSPSCLK polarity setting */
+#define SSCR1_SPH      (1 << 4)        /* Motorola SPI SSPSCLK phase setting */
+#define SSCR1_MWDS     (1 << 5)        /* Microwire Transmit Data Size */
+#define SSCR1_TFT      (0x000003c0)    /* Transmit FIFO Threshold (mask) */
+#define SSCR1_TxTresh(x) (((x) - 1) << 6) /* level [1..16] */
+#define SSCR1_RFT      (0x00003c00)    /* Receive FIFO Threshold (mask) */
+#define SSCR1_RxTresh(x) (((x) - 1) << 10) /* level [1..16] */
+
+#define SSSR_TNF       (1 << 2)        /* Transmit FIFO Not Full */
+#define SSSR_RNE       (1 << 3)        /* Receive FIFO Not Empty */
+#define SSSR_BSY       (1 << 4)        /* SSP Busy */
+#define SSSR_TFS       (1 << 5)        /* Transmit FIFO Service Request */
+#define SSSR_RFS       (1 << 6)        /* Receive FIFO Service Request */
+#define SSSR_ROR       (1 << 7)        /* Receive FIFO Overrun */
+
+
+/* extra bits in PXA255, PXA26x and PXA27x SSP ports */
+#define SSCR0_TISSP            (1 << 4)        /* TI Sync Serial Protocol */
+#define SSCR0_PSP              (3 << 4)        /* PSP - Programmable Serial Protocol */
+#define SSCR1_TTELP            (1 << 31)       /* TXD Tristate Enable Last Phase */
+#define SSCR1_TTE              (1 << 30)       /* TXD Tristate Enable */
+#define SSCR1_EBCEI            (1 << 29)       /* Enable Bit Count Error interrupt */
+#define SSCR1_SCFR             (1 << 28)       /* Slave Clock free Running */
+#define SSCR1_ECRA             (1 << 27)       /* Enable Clock Request A */
+#define SSCR1_ECRB             (1 << 26)       /* Enable Clock request B */
+#define SSCR1_SCLKDIR          (1 << 25)       /* Serial Bit Rate Clock Direction */
+#define SSCR1_SFRMDIR          (1 << 24)       /* Frame Direction */
+#define SSCR1_RWOT             (1 << 23)       /* Receive Without Transmit */
+#define SSCR1_TRAIL            (1 << 22)       /* Trailing Byte */
+#define SSCR1_TSRE             (1 << 21)       /* Transmit Service Request Enable */
+#define SSCR1_RSRE             (1 << 20)       /* Receive Service Request Enable */
+#define SSCR1_TINTE            (1 << 19)       /* Receiver Time-out Interrupt enable */
+#define SSCR1_PINTE            (1 << 18)       /* Peripheral Trailing Byte Interupt Enable */
+#define SSCR1_IFS              (1 << 16)       /* Invert Frame Signal */
+#define SSCR1_STRF             (1 << 15)       /* Select FIFO or EFWR */
+#define SSCR1_EFWR             (1 << 14)       /* Enable FIFO Write/Read */
+
+#define SSSR_BCE               (1 << 23)       /* Bit Count Error */
+#define SSSR_CSS               (1 << 22)       /* Clock Synchronisation Status */
+#define SSSR_TUR               (1 << 21)       /* Transmit FIFO Under Run */
+#define SSSR_EOC               (1 << 20)       /* End Of Chain */
+#define SSSR_TINT              (1 << 19)       /* Receiver Time-out Interrupt */
+#define SSSR_PINT              (1 << 18)       /* Peripheral Trailing Byte Interrupt */
+
+
+#define SSPSP_SCMODE(x)                ((x) << 0)      /* Serial Bit Rate Clock Mode */
+#define SSPSP_SFRMP            (1 << 2)        /* Serial Frame Polarity */
+#define SSPSP_ETDS             (1 << 3)        /* End of Transfer data State */
+#define SSPSP_STRTDLY(x)       ((x) << 4)      /* Start Delay */
+#define SSPSP_DMYSTRT(x)       ((x) << 7)      /* Dummy Start */
+#define SSPSP_SFRMDLY(x)       ((x) << 9)      /* Serial Frame Delay */
+#define SSPSP_SFRMWDTH(x)      ((x) << 16)     /* Serial Frame Width */
+#define SSPSP_DMYSTOP(x)       ((x) << 23)     /* Dummy Stop */
+#define SSPSP_FSRT             (1 << 25)       /* Frame Sync Relative Timing */
+
+/* PXA3xx */
+#define SSPSP_EDMYSTRT(x)      ((x) << 26)     /* Extended Dummy Start */
+#define SSPSP_EDMYSTOP(x)      ((x) << 28)     /* Extended Dummy Stop */
+#define SSPSP_TIMING_MASK      (0x7f8001f0)
+
+#define SSACD_SCDB             (1 << 3)        /* SSPSYSCLK Divider Bypass */
+#define SSACD_ACPS(x)          ((x) << 4)      /* Audio clock PLL select */
+#define SSACD_ACDS(x)          ((x) << 0)      /* Audio clock divider select */
+#define SSACD_SCDX8            (1 << 7)        /* SYSCLK division ratio select */
+
+enum pxa_ssp_type {
+       SSP_UNDEFINED = 0,
+       PXA25x_SSP,  /* pxa 210, 250, 255, 26x */
+       PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */
+       PXA27x_SSP,
+       PXA168_SSP,
+};
+
+struct ssp_device {
+       struct platform_device *pdev;
+       struct list_head        node;
+
+       struct clk      *clk;
+       void __iomem    *mmio_base;
+       unsigned long   phys_base;
+
+       const char      *label;
+       int             port_id;
+       int             type;
+       int             use_count;
+       int             irq;
+       int             drcmr_rx;
+       int             drcmr_tx;
+};
+
+/**
+ * pxa_ssp_write_reg - Write to a SSP register
+ *
+ * @dev: SSP device to access
+ * @reg: Register to write to
+ * @val: Value to be written.
+ */
+static inline void pxa_ssp_write_reg(struct ssp_device *dev, u32 reg, u32 val)
+{
+       __raw_writel(val, dev->mmio_base + reg);
+}
+
+/**
+ * pxa_ssp_read_reg - Read from a SSP register
+ *
+ * @dev: SSP device to access
+ * @reg: Register to read from
+ */
+static inline u32 pxa_ssp_read_reg(struct ssp_device *dev, u32 reg)
+{
+       return __raw_readl(dev->mmio_base + reg);
+}
+
+struct ssp_device *pxa_ssp_request(int port, const char *label);
+void pxa_ssp_free(struct ssp_device *);
+#endif /* __ASM_ARCH_SSP_H */
index be58f9f..b77e018 100644 (file)
@@ -110,6 +110,7 @@ static const unsigned long mfpr_lpm[] = {
        MFPR_LPM_PULL_LOW,
        MFPR_LPM_PULL_HIGH,
        MFPR_LPM_FLOAT,
+       MFPR_LPM_INPUT,
 };
 
 /* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
diff --git a/arch/arm/plat-pxa/pmu.c b/arch/arm/plat-pxa/pmu.c
new file mode 100644 (file)
index 0000000..267ceb6
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * PMU IRQ registration for the PXA xscale PMU families.
+ * Copyright (C) 2010 Will Deacon, ARM 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+
+static struct resource pmu_resource = {
+       .start  = IRQ_PMU,
+       .end    = IRQ_PMU,
+       .flags  = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+       .name           = "arm-pmu",
+       .id             = ARM_PMU_DEVICE_CPU,
+       .resource       = &pmu_resource,
+       .num_resources  = 1,
+};
+
+static int __init pxa_pmu_init(void)
+{
+       platform_device_register(&pmu_device);
+       return 0;
+}
+arch_initcall(pxa_pmu_init);
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
new file mode 100644 (file)
index 0000000..c6357e5
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ *  linux/arch/arm/mach-pxa/ssp.c
+ *
+ *  based on linux/arch/arm/mach-sa1100/ssp.c by Russell King
+ *
+ *  Copyright (C) 2003 Russell King.
+ *  Copyright (C) 2003 Wolfson Microelectronics PLC
+ *
+ * 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.
+ *
+ *  PXA2xx SSP driver.  This provides the generic core for simple
+ *  IO-based SSP applications and allows easy port setup for DMA access.
+ *
+ *  Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <plat/ssp.h>
+
+static DEFINE_MUTEX(ssp_lock);
+static LIST_HEAD(ssp_list);
+
+struct ssp_device *pxa_ssp_request(int port, const char *label)
+{
+       struct ssp_device *ssp = NULL;
+
+       mutex_lock(&ssp_lock);
+
+       list_for_each_entry(ssp, &ssp_list, node) {
+               if (ssp->port_id == port && ssp->use_count == 0) {
+                       ssp->use_count++;
+                       ssp->label = label;
+                       break;
+               }
+       }
+
+       mutex_unlock(&ssp_lock);
+
+       if (&ssp->node == &ssp_list)
+               return NULL;
+
+       return ssp;
+}
+EXPORT_SYMBOL(pxa_ssp_request);
+
+void pxa_ssp_free(struct ssp_device *ssp)
+{
+       mutex_lock(&ssp_lock);
+       if (ssp->use_count) {
+               ssp->use_count--;
+               ssp->label = NULL;
+       } else
+               dev_err(&ssp->pdev->dev, "device already free\n");
+       mutex_unlock(&ssp_lock);
+}
+EXPORT_SYMBOL(pxa_ssp_free);
+
+static int __devinit pxa_ssp_probe(struct platform_device *pdev)
+{
+       const struct platform_device_id *id = platform_get_device_id(pdev);
+       struct resource *res;
+       struct ssp_device *ssp;
+       int ret = 0;
+
+       ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
+       if (ssp == NULL) {
+               dev_err(&pdev->dev, "failed to allocate memory");
+               return -ENOMEM;
+       }
+       ssp->pdev = pdev;
+
+       ssp->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(ssp->clk)) {
+               ret = PTR_ERR(ssp->clk);
+               goto err_free;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
+               ret = -ENODEV;
+               goto err_free_clk;
+       }
+       ssp->drcmr_rx = res->start;
+
+       res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
+               ret = -ENODEV;
+               goto err_free_clk;
+       }
+       ssp->drcmr_tx = res->start;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no memory resource defined\n");
+               ret = -ENODEV;
+               goto err_free_clk;
+       }
+
+       res = request_mem_region(res->start, resource_size(res),
+                       pdev->name);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "failed to request memory resource\n");
+               ret = -EBUSY;
+               goto err_free_clk;
+       }
+
+       ssp->phys_base = res->start;
+
+       ssp->mmio_base = ioremap(res->start, resource_size(res));
+       if (ssp->mmio_base == NULL) {
+               dev_err(&pdev->dev, "failed to ioremap() registers\n");
+               ret = -ENODEV;
+               goto err_free_mem;
+       }
+
+       ssp->irq = platform_get_irq(pdev, 0);
+       if (ssp->irq < 0) {
+               dev_err(&pdev->dev, "no IRQ resource defined\n");
+               ret = -ENODEV;
+               goto err_free_io;
+       }
+
+       /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
+        * starts from 0, do a translation here
+        */
+       ssp->port_id = pdev->id + 1;
+       ssp->use_count = 0;
+       ssp->type = (int)id->driver_data;
+
+       mutex_lock(&ssp_lock);
+       list_add(&ssp->node, &ssp_list);
+       mutex_unlock(&ssp_lock);
+
+       platform_set_drvdata(pdev, ssp);
+       return 0;
+
+err_free_io:
+       iounmap(ssp->mmio_base);
+err_free_mem:
+       release_mem_region(res->start, resource_size(res));
+err_free_clk:
+       clk_put(ssp->clk);
+err_free:
+       kfree(ssp);
+       return ret;
+}
+
+static int __devexit pxa_ssp_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct ssp_device *ssp;
+
+       ssp = platform_get_drvdata(pdev);
+       if (ssp == NULL)
+               return -ENODEV;
+
+       iounmap(ssp->mmio_base);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, resource_size(res));
+
+       clk_put(ssp->clk);
+
+       mutex_lock(&ssp_lock);
+       list_del(&ssp->node);
+       mutex_unlock(&ssp_lock);
+
+       kfree(ssp);
+       return 0;
+}
+
+static const struct platform_device_id ssp_id_table[] = {
+       { "pxa25x-ssp",         PXA25x_SSP },
+       { "pxa25x-nssp",        PXA25x_NSSP },
+       { "pxa27x-ssp",         PXA27x_SSP },
+       { "pxa168-ssp",         PXA168_SSP },
+       { },
+};
+
+static struct platform_driver pxa_ssp_driver = {
+       .probe          = pxa_ssp_probe,
+       .remove         = __devexit_p(pxa_ssp_remove),
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "pxa2xx-ssp",
+       },
+       .id_table       = ssp_id_table,
+};
+
+static int __init pxa_ssp_init(void)
+{
+       return platform_driver_register(&pxa_ssp_driver);
+}
+
+static void __exit pxa_ssp_exit(void)
+{
+       platform_driver_unregister(&pxa_ssp_driver);
+}
+
+arch_initcall(pxa_ssp_init);
+module_exit(pxa_ssp_exit);
+
+MODULE_DESCRIPTION("PXA SSP driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
index 6e93ef8..984bf66 100644 (file)
@@ -9,6 +9,7 @@ config PLAT_S3C24XX
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
        select S3C_DEVICE_NAND
+       select S3C_GPIO_CFG_S3C24XX
        help
          Base platform code for any Samsung S3C24XX device
 
@@ -44,6 +45,12 @@ config S3C2410_CLOCK
          Clock code for the S3C2410, and similar processors which
          is currently includes the S3C2410, S3C2440, S3C2442.
 
+config S3C2443_CLOCK
+       bool
+       help
+         Clock code for the S3C2443 and similar processors, which includes
+         the S3C2416 and S3C2450.
+
 config S3C24XX_DCLK
        bool
        help
@@ -157,4 +164,9 @@ config S3C24XX_SIMTEC_AUDIO
        help
          Add audio devices for common Simtec S3C24XX boards
 
+config S3C2410_SETUP_TS
+       bool
+       help
+         Compile in platform device definition for Samsung TouchScreen.
+
 endif
index c2237c4..c2064c3 100644 (file)
@@ -30,6 +30,7 @@ obj-$(CONFIG_PM)              += pm.o
 obj-$(CONFIG_PM)               += irq-pm.o
 obj-$(CONFIG_PM)               += sleep.o
 obj-$(CONFIG_S3C2410_CLOCK)    += s3c2410-clock.o
+obj-$(CONFIG_S3C2443_CLOCK)    += s3c2443-clock.o
 obj-$(CONFIG_S3C2410_DMA)      += dma.o
 obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
 obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
@@ -37,6 +38,7 @@ obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
 
 # device specific setup and/or initialisation
 obj-$(CONFIG_ARCH_S3C2410)     += setup-i2c.o
+obj-$(CONFIG_S3C2410_SETUP_TS) += setup-ts.o
 
 # SPI gpio central GPIO functions
 
index 9e0e20a..7b44d0c 100644 (file)
@@ -42,6 +42,7 @@
 #include <plat/nand.h>
 
 #include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
 
@@ -185,10 +186,10 @@ void __init smdk_machine_init(void)
 {
        /* Configure the LEDs (even if we have no LED support)*/
 
-       s3c2410_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
-       s3c2410_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
+       s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
 
        s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
        s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
index 9ca64df..76d0858 100644 (file)
@@ -49,6 +49,7 @@
 #include <plat/s3c2400.h>
 #include <plat/s3c2410.h>
 #include <plat/s3c2412.h>
+#include <plat/s3c2416.h>
 #include <plat/s3c244x.h>
 #include <plat/s3c2443.h>
 
@@ -57,6 +58,7 @@
 static const char name_s3c2400[]  = "S3C2400";
 static const char name_s3c2410[]  = "S3C2410";
 static const char name_s3c2412[]  = "S3C2412";
+static const char name_s3c2416[]  = "S3C2416/S3C2450";
 static const char name_s3c2440[]  = "S3C2440";
 static const char name_s3c2442[]  = "S3C2442";
 static const char name_s3c2442b[]  = "S3C2442B";
@@ -137,6 +139,15 @@ static struct cpu_table cpu_ids[] __initdata = {
                .init           = s3c2412_init,
                .name           = name_s3c2412,
        },
+       {                       /* a strange version of the s3c2416 */
+               .idcode         = 0x32450003,
+               .idmask         = 0xffffffff,
+               .map_io         = s3c2416_map_io,
+               .init_clocks    = s3c2416_init_clocks,
+               .init_uarts     = s3c2416_init_uarts,
+               .init           = s3c2416_init,
+               .name           = name_s3c2416,
+       },
        {
                .idcode         = 0x32443001,
                .idmask         = 0xffffffff,
@@ -170,6 +181,16 @@ static struct map_desc s3c_iodesc[] __initdata = {
 
 static unsigned long s3c24xx_read_idcode_v5(void)
 {
+#if defined(CONFIG_CPU_S3C2416)
+       /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
+
+       u32 gs = __raw_readl(S3C24XX_GSTATUS1);
+
+       /* test for s3c2416 or similar device */
+       if ((gs >> 16) == 0x3245)
+               return gs;
+#endif
+
 #if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
        return __raw_readl(S3C2412_GSTATUS1);
 #else
index 9265f09..5858373 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -38,8 +39,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/regs-spi.h>
-
-#include <mach/ts.h>
+#include <plat/ts.h>
 
 /* Serial port registrations */
 
@@ -149,10 +149,14 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
 {
        struct s3c2410fb_mach_info *npd;
 
-       npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+       npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL);
        if (npd) {
-               memcpy(npd, pd, sizeof(*npd));
                s3c_device_lcd.dev.platform_data = npd;
+               npd->displays = kmemdup(pd->displays,
+                       sizeof(struct s3c2410fb_display) * npd->num_displays,
+                       GFP_KERNEL);
+               if (!npd->displays)
+                       printk(KERN_ERR "no memory for LCD display data\n");
        } else {
                printk(KERN_ERR "no memory for LCD platform data\n");
        }
@@ -338,14 +342,6 @@ struct platform_device s3c_device_adc = {
        .resource         = s3c_adc_resource,
 };
 
-/* HWMON */
-
-struct platform_device s3c_device_hwmon = {
-       .name           = "s3c-hwmon",
-       .id             = -1,
-       .dev.parent     = &s3c_device_adc.dev,
-};
-
 /* SDI */
 
 static struct resource s3c_sdi_resource[] = {
@@ -371,7 +367,7 @@ struct platform_device s3c_device_sdi = {
 
 EXPORT_SYMBOL(s3c_device_sdi);
 
-void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
+void __init s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata)
 {
        struct s3c24xx_mci_pdata *npd;
 
index 93827b3..6ad274e 100644 (file)
@@ -1104,7 +1104,7 @@ EXPORT_SYMBOL(s3c2410_dma_config);
  * devaddr:   physical address of the source
 */
 
-int s3c2410_dma_devconfig(int channel,
+int s3c2410_dma_devconfig(unsigned int channel,
                          enum s3c2410_dmasrc source,
                          unsigned long devaddr)
 {
index 5467470..2f3d7c0 100644 (file)
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/gpio.c
  *
- * Copyright (c) 2004-2005 Simtec Electronics
+ * Copyright (c) 2004-2010 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *
  * S3C24XX GPIO support
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/gpio.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
 
 #include <mach/regs-gpio.h>
 
-void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long mask;
-       unsigned long con;
-       unsigned long flags;
+#include <plat/gpio-core.h>
 
-       if (pin < S3C2410_GPIO_BANKB) {
-               mask = 1 << S3C2410_GPIO_OFFSET(pin);
-       } else {
-               mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
-       }
-
-       switch (function) {
-       case S3C2410_GPIO_LEAVE:
-               mask = 0;
-               function = 0;
-               break;
-
-       case S3C2410_GPIO_INPUT:
-       case S3C2410_GPIO_OUTPUT:
-       case S3C2410_GPIO_SFN2:
-       case S3C2410_GPIO_SFN3:
-               if (pin < S3C2410_GPIO_BANKB) {
-                       function -= 1;
-                       function &= 1;
-                       function <<= S3C2410_GPIO_OFFSET(pin);
-               } else {
-                       function &= 3;
-                       function <<= S3C2410_GPIO_OFFSET(pin)*2;
-               }
-       }
-
-       /* modify the specified register wwith IRQs off */
-
-       local_irq_save(flags);
-
-       con  = __raw_readl(base + 0x00);
-       con &= ~mask;
-       con |= function;
-
-       __raw_writel(con, base + 0x00);
-
-       local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
-
-unsigned int s3c2410_gpio_getcfg(unsigned int pin)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long val = __raw_readl(base);
-
-       if (pin < S3C2410_GPIO_BANKB) {
-               val >>= S3C2410_GPIO_OFFSET(pin);
-               val &= 1;
-               val += 1;
-       } else {
-               val >>= S3C2410_GPIO_OFFSET(pin)*2;
-               val &= 3;
-       }
-
-       return val | S3C2410_GPIO_INPUT;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getcfg);
+/* gpiolib wrappers until these are totally eliminated */
 
 void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-       unsigned long flags;
-       unsigned long up;
+       int ret;
 
-       if (pin < S3C2410_GPIO_BANKB)
-               return;
+       WARN_ON(to);    /* should be none of these left */
 
-       local_irq_save(flags);
-
-       up = __raw_readl(base + 0x08);
-       up &= ~(1L << offs);
-       up |= to << offs;
-       __raw_writel(up, base + 0x08);
+       if (!to) {
+               /* if pull is enabled, try first with up, and if that
+                * fails, try using down */
 
-       local_irq_restore(flags);
+               ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
+               if (ret)
+                       s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
+       } else {
+               s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
+       }
 }
-
 EXPORT_SYMBOL(s3c2410_gpio_pullup);
 
-int s3c2410_gpio_getpull(unsigned int pin)
-{
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-
-       if (pin < S3C2410_GPIO_BANKB)
-               return -EINVAL;
-
-       return (__raw_readl(base + 0x08) & (1L << offs)) ? 1 : 0;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getpull);
-
 void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
-       unsigned long flags;
-       unsigned long dat;
+       /* do this via gpiolib until all users removed */
 
-       local_irq_save(flags);
-
-       dat = __raw_readl(base + 0x04);
-       dat &= ~(1 << offs);
-       dat |= to << offs;
-       __raw_writel(dat, base + 0x04);
-
-       local_irq_restore(flags);
+       gpio_request(pin, "temporary");
+       gpio_set_value(pin, to);
+       gpio_free(pin);
 }
 
 EXPORT_SYMBOL(s3c2410_gpio_setpin);
 
 unsigned int s3c2410_gpio_getpin(unsigned int pin)
 {
-       void __iomem *base = S3C24XX_GPIO_BASE(pin);
-       unsigned long offs = S3C2410_GPIO_OFFSET(pin);
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long offs = pin - chip->chip.base;
 
-       return __raw_readl(base + 0x04) & (1<< offs);
+       return __raw_readl(chip->base + 0x04) & (1<< offs);
 }
 
 EXPORT_SYMBOL(s3c2410_gpio_getpin);
@@ -181,22 +94,3 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
 }
 
 EXPORT_SYMBOL(s3c2410_modify_misccr);
-
-int s3c2410_gpio_getirq(unsigned int pin)
-{
-       if (pin < S3C2410_GPF(0) || pin > S3C2410_GPG(15))
-               return -EINVAL; /* not valid interrupts */
-
-       if (pin < S3C2410_GPG(0) && pin > S3C2410_GPF(7))
-               return -EINVAL; /* not valid pin */
-
-       if (pin < S3C2410_GPF(4))
-               return (pin - S3C2410_GPF(0)) + IRQ_EINT0;
-
-       if (pin < S3C2410_GPG(0))
-               return (pin - S3C2410_GPF(4)) + IRQ_EINT4;
-
-       return (pin - S3C2410_GPG(0)) + IRQ_EINT8;
-}
-
-EXPORT_SYMBOL(s3c2410_gpio_getirq);
index 4f0f11a..4c0896f 100644 (file)
@@ -1,6 +1,6 @@
 /* linux/arch/arm/plat-s3c24xx/gpiolib.c
  *
- * Copyright (c) 2008 Simtec Electronics
+ * Copyright (c) 2008-2010 Simtec Electronics
  *     http://armlinux.simtec.co.uk/
  *     Ben Dooks <ben@simtec.co.uk>
  *
@@ -21,6 +21,8 @@
 #include <linux/gpio.h>
 
 #include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <plat/pm.h>
@@ -77,10 +79,21 @@ static int s3c24xx_gpiolib_bankg_toirq(struct gpio_chip *chip, unsigned offset)
        return IRQ_EINT8 + offset;
 }
 
+static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
+       .set_config     = s3c_gpio_setcfg_s3c24xx_a,
+       .get_config     = s3c_gpio_getcfg_s3c24xx_a,
+};
+
+struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
+       .set_config     = s3c_gpio_setcfg_s3c24xx,
+       .get_config     = s3c_gpio_getcfg_s3c24xx,
+};
+
 struct s3c_gpio_chip s3c24xx_gpios[] = {
        [0] = {
                .base   = S3C2410_GPACON,
                .pm     = __gpio_pm(&s3c_gpio_pm_1bit),
+               .config = &s3c24xx_gpiocfg_banka,
                .chip   = {
                        .base                   = S3C2410_GPA(0),
                        .owner                  = THIS_MODULE,
@@ -161,15 +174,58 @@ struct s3c_gpio_chip s3c24xx_gpios[] = {
                        .ngpio                  = 11,
                },
        },
+               /* GPIOS for the S3C2443 and later devices. */
+       {
+               .base   = S3C2440_GPJCON,
+               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
+               .chip   = {
+                       .base                   = S3C2410_GPJ(0),
+                       .owner                  = THIS_MODULE,
+                       .label                  = "GPIOJ",
+                       .ngpio                  = 16,
+               },
+       }, {
+               .base   = S3C2443_GPKCON,
+               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
+               .chip   = {
+                       .base                   = S3C2410_GPK(0),
+                       .owner                  = THIS_MODULE,
+                       .label                  = "GPIOK",
+                       .ngpio                  = 16,
+               },
+       }, {
+               .base   = S3C2443_GPLCON,
+               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
+               .chip   = {
+                       .base                   = S3C2410_GPL(0),
+                       .owner                  = THIS_MODULE,
+                       .label                  = "GPIOL",
+                       .ngpio                  = 15,
+               },
+       }, {
+               .base   = S3C2443_GPMCON,
+               .pm     = __gpio_pm(&s3c_gpio_pm_2bit),
+               .chip   = {
+                       .base                   = S3C2410_GPM(0),
+                       .owner                  = THIS_MODULE,
+                       .label                  = "GPIOM",
+                       .ngpio                  = 2,
+               },
+       },
 };
 
+
 static __init int s3c24xx_gpiolib_init(void)
 {
        struct s3c_gpio_chip *chip = s3c24xx_gpios;
        int gpn;
 
-       for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++)
+       for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
+               if (!chip->config)
+                       chip->config = &s3c24xx_gpiocfg_default;
+
                s3c_gpiolib_add(chip);
+       }
 
        return 0;
 }
index 7ea8bff..005729a 100644 (file)
@@ -35,3 +35,28 @@ s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
 
        return (unsigned int)fvco;
 }
+
+#define S3C2416_PLL_M_SHIFT    (14)
+#define S3C2416_PLL_P_SHIFT    (5)
+#define S3C2416_PLL_S_MASK     (7)
+#define S3C2416_PLL_M_MASK     ((1 << 10) - 1)
+#define S3C2416_PLL_P_MASK     (63)
+
+static inline unsigned int
+s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
+{
+       unsigned int m, p, s;
+       uint64_t fvco;
+
+       m = pllval >> S3C2416_PLL_M_SHIFT;
+       p = pllval >> S3C2416_PLL_P_SHIFT;
+
+       s = pllval & S3C2416_PLL_S_MASK;
+       m &= S3C2416_PLL_M_MASK;
+       p &= S3C2416_PLL_P_MASK;
+
+       fvco = (uint64_t)baseclk * m;
+       do_div(fvco, (p << s));
+
+       return (unsigned int)fvco;
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
new file mode 100644 (file)
index 0000000..dc3c090
--- /dev/null
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+ *
+ * Header file for s3c2416 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2416
+
+struct s3c2410_uartcfg;
+
+extern  int s3c2416_init(void);
+
+extern void s3c2416_map_io(void);
+
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2416_init_clocks(int xtal);
+
+extern  int s3c2416_baseclk_add(void);
+
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
index 815b107..a19715f 100644 (file)
@@ -30,3 +30,22 @@ extern  int s3c2443_baseclk_add(void);
 #define s3c2443_map_io NULL
 #define s3c2443_init NULL
 #endif
+
+/* common code used by s3c2443 and others.
+ * note, not to be used outside of arch/arm/mach-s3c* */
+
+struct clk;    /* some files don't need clk.h otherwise */
+
+typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
+typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
+
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
+
+extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
+
+extern struct clksrc_clk clk_epllref;
+extern struct clksrc_clk clk_esysclk;
+extern struct clksrc_clk clk_msysclk;
index 3620dd2..60627e6 100644 (file)
@@ -43,6 +43,7 @@
 
 #include <asm/mach/time.h>
 
+#include <plat/gpio-cfg.h>
 #include <plat/pm.h>
 
 #define PFX "s3c24xx-pm: "
@@ -90,22 +91,22 @@ static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
 {
        unsigned long irqstate;
        unsigned long pinstate;
-       int irq = s3c2410_gpio_getirq(pin);
+       int irq = gpio_to_irq(pin);
 
        if (irqoffs < 4)
                irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
        else
                irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
 
-       pinstate = s3c2410_gpio_getcfg(pin);
+       pinstate = s3c_gpio_getcfg(pin);
 
        if (!irqstate) {
                if (pinstate == S3C2410_GPIO_IRQ)
-                       S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+                       S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
        } else {
                if (pinstate == S3C2410_GPIO_IRQ) {
                        S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
-                       s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+                       s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
                }
        }
 }
index b61bdb7..9ecc5d9 100644 (file)
@@ -87,7 +87,7 @@ static int s3c2410_upll_enable(struct clk *clk, int enable)
 
 /* standard clock definitions */
 
-static struct clk init_clocks_disable[] = {
+static struct clk init_clocks_off[] = {
        {
                .name           = "nand",
                .id             = -1,
@@ -249,17 +249,8 @@ int __init s3c2410_baseclk_add(void)
 
        /* install (and disable) the clocks we do not need immediately */
 
-       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);
-               }
-
-               s3c2410_clkcon_enable(clkp, 0);
-       }
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
 
        /* show the clock-slow value */
 
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
new file mode 100644 (file)
index 0000000..461f070
--- /dev/null
@@ -0,0 +1,472 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control suport - common code
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+
+
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+       u32 ctrlbit = clk->ctrlbit;
+       u32 con = __raw_readl(reg);
+
+       if (enable)
+               con |= ctrlbit;
+       else
+               con &= ~ctrlbit;
+
+       __raw_writel(con, reg);
+       return 0;
+}
+
+int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+       return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+       return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+       return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
+}
+
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
+struct clk clk_mpllref = {
+       .name           = "mpllref",
+       .parent         = &clk_xtal,
+       .id             = -1,
+};
+
+static struct clk *clk_epllref_sources[] = {
+       [0] = &clk_mpllref,
+       [1] = &clk_mpllref,
+       [2] = &clk_xtal,
+       [3] = &clk_ext,
+};
+
+struct clksrc_clk clk_epllref = {
+       .clk    = {
+               .name           = "epllref",
+               .id             = -1,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_epllref_sources,
+               .nr_sources = ARRAY_SIZE(clk_epllref_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
+};
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static struct clk *clk_sysclk_sources[] = {
+       [0] = &clk_epllref.clk,
+       [1] = &clk_epll,
+};
+
+struct clksrc_clk clk_esysclk = {
+       .clk    = {
+               .name           = "esysclk",
+               .parent         = &clk_epll,
+               .id             = -1,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_sysclk_sources,
+               .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+       unsigned long parent_rate = clk_get_rate(clk->parent);
+       unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+       div  &= S3C2443_CLKDIV0_EXTDIV_MASK;
+       div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1);       /* x2 */
+
+       return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+       .name           = "mdivclk",
+       .parent         = &clk_mpllref,
+       .id             = -1,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2443_getrate_mdivclk,
+       },
+};
+
+static struct clk *clk_msysclk_sources[] = {
+       [0] = &clk_mpllref,
+       [1] = &clk_mpll,
+       [2] = &clk_mdivclk,
+       [3] = &clk_mpllref,
+};
+
+struct clksrc_clk clk_msysclk = {
+       .clk    = {
+               .name           = "msysclk",
+               .parent         = &clk_xtal,
+               .id             = -1,
+       },
+       .sources = &(struct clksrc_sources) {
+               .sources = clk_msysclk_sources,
+               .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+       },
+       .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
+};
+
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+       clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+       clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+       return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+       .name           = "prediv",
+       .id             = -1,
+       .parent         = &clk_msysclk.clk,
+       .ops            = &(struct clk_ops) {
+               .get_rate       = s3c2443_prediv_getrate,
+       },
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static struct clksrc_clk clk_usb_bus_host = {
+       .clk    = {
+               .name           = "usb-bus-host-parent",
+               .id             = -1,
+               .parent         = &clk_esysclk.clk,
+               .ctrlbit        = S3C2443_SCLKCON_USBHOST,
+               .enable         = s3c2443_clkcon_enable_s,
+       },
+       .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+/* common clksrc clocks */
+
+static struct clksrc_clk clksrc_clks[] = {
+       {
+               /* ART baud-rate clock sourced from esysclk via a divisor */
+               .clk    = {
+                       .name           = "uartclk",
+                       .id             = -1,
+                       .parent         = &clk_esysclk.clk,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+       }, {
+               /* camera interface bus-clock, divided down from esysclk */
+               .clk    = {
+                       .name           = "camif-upll", /* same as 2440 name */
+                       .id             = -1,
+                       .parent         = &clk_esysclk.clk,
+                       .ctrlbit        = S3C2443_SCLKCON_CAMCLK,
+                       .enable         = s3c2443_clkcon_enable_s,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
+       }, {
+               .clk    = {
+                       .name           = "display-if",
+                       .id             = -1,
+                       .parent         = &clk_esysclk.clk,
+                       .ctrlbit        = S3C2443_SCLKCON_DISPCLK,
+                       .enable         = s3c2443_clkcon_enable_s,
+               },
+               .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
+       },
+};
+
+
+static struct clk init_clocks_off[] = {
+       {
+               .name           = "adc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_ADC,
+       }, {
+               .name           = "i2c",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_IIC,
+       }
+};
+
+static struct clk init_clocks[] = {
+       {
+               .name           = "dma",
+               .id             = 0,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA0,
+       }, {
+               .name           = "dma",
+               .id             = 1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA1,
+       }, {
+               .name           = "dma",
+               .id             = 2,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA2,
+       }, {
+               .name           = "dma",
+               .id             = 3,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA3,
+       }, {
+               .name           = "dma",
+               .id             = 4,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA4,
+       }, {
+               .name           = "dma",
+               .id             = 5,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_DMA5,
+       }, {
+               .name           = "hsmmc",
+               .id             = 0,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_HSMMC,
+       }, {
+               .name           = "gpio",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_GPIO,
+       }, {
+               .name           = "usb-host",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBH,
+       }, {
+               .name           = "usb-device",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_USBD,
+       }, {
+               .name           = "lcd",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_LCDC,
+
+       }, {
+               .name           = "timers",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_PWMT,
+       }, {
+               .name           = "cfc",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_CFC,
+       }, {
+               .name           = "ssmc",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_SSMC,
+       }, {
+               .name           = "uart",
+               .id             = 0,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART0,
+       }, {
+               .name           = "uart",
+               .id             = 1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART1,
+       }, {
+               .name           = "uart",
+               .id             = 2,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART2,
+       }, {
+               .name           = "uart",
+               .id             = 3,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_UART3,
+       }, {
+               .name           = "rtc",
+               .id             = -1,
+               .parent         = &clk_p,
+               .enable         = s3c2443_clkcon_enable_p,
+               .ctrlbit        = S3C2443_PCLKCON_RTC,
+       }, {
+               .name           = "watchdog",
+               .id             = -1,
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_WDT,
+       }, {
+               .name           = "ac97",
+               .id             = -1,
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_AC97,
+       }, {
+               .name           = "nand",
+               .id             = -1,
+               .parent         = &clk_h,
+       }, {
+               .name           = "usb-bus-host",
+               .id             = -1,
+               .parent         = &clk_usb_bus_host.clk,
+       }
+};
+
+static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
+{
+       clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
+
+       return clkcon0 + 1;
+}
+
+/* EPLLCON compatible enough to get on/off information */
+
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
+                                                  fdiv_fn get_fdiv)
+{
+       unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+       unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+       struct clk *xtal_clk;
+       unsigned long xtal;
+       unsigned long pll;
+       unsigned long fclk;
+       unsigned long hclk;
+       unsigned long pclk;
+       int ptr;
+
+       xtal_clk = clk_get(NULL, "xtal");
+       xtal = clk_get_rate(xtal_clk);
+       clk_put(xtal_clk);
+
+       pll = get_mpll(mpllcon, xtal);
+       clk_msysclk.clk.rate = pll;
+
+       fclk = pll / get_fdiv(clkdiv0);
+       hclk = s3c2443_prediv_getrate(&clk_prediv);
+       hclk /= s3c2443_get_hdiv(clkdiv0);
+       pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+       s3c24xx_setup_clocks(fclk, hclk, pclk);
+
+       printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+              (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+              print_mhz(pll), print_mhz(fclk),
+              print_mhz(hclk), print_mhz(pclk));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+               s3c_set_clksrc(&clksrc_clks[ptr], true);
+
+       /* ensure usb bus clock is within correct rate of 48MHz */
+
+       if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
+               printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+               clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
+       }
+
+       printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+              (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+              print_mhz(clk_get_rate(&clk_epll)),
+              print_mhz(clk_get_rate(&clk_usb_bus)));
+}
+
+static struct clk *clks[] __initdata = {
+       &clk_prediv,
+       &clk_mpllref,
+       &clk_mdivclk,
+       &clk_ext,
+       &clk_epll,
+       &clk_usb_bus,
+};
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+       &clk_usb_bus_host,
+       &clk_epllref,
+       &clk_esysclk,
+       &clk_msysclk,
+};
+
+void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+                                      fdiv_fn get_fdiv)
+{
+       int ptr;
+
+       /* s3c2443 parents h and p clocks from prediv */
+       clk_h.parent = &clk_prediv;
+       clk_p.parent = &clk_prediv;
+
+       clk_usb_bus.parent = &clk_usb_bus_host.clk;
+       clk_epll.parent = &clk_epllref.clk;
+
+       s3c24xx_register_baseclocks(xtal);
+       s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+       for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+               s3c_register_clksrc(clksrcs[ptr], 1);
+
+       s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
+       s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+       /* See s3c2443/etc notes on disabling clocks at init time */
+       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+       s3c2443_common_setup_clocks(get_mpll, get_fdiv);
+}
index 71a6acc..9e90a7c 100644 (file)
 
 struct platform_device;
 
+#include <plat/gpio-cfg.h>
 #include <plat/iic.h>
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 
 void s3c_i2c0_cfg_gpio(struct platform_device *dev)
 {
-       s3c2410_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
-       s3c2410_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
+       s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
+       s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
 }
diff --git a/arch/arm/plat-s3c24xx/setup-ts.c b/arch/arm/plat-s3c24xx/setup-ts.c
new file mode 100644 (file)
index 0000000..ed26386
--- /dev/null
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s3c24xx/setup-ts.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *                     http://www.samsung.com/
+ *
+ * Based on S3C24XX setup for i2c device
+ *
+ * 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/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+/**
+ * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems
+ *
+ * Configure the GPIO for the S3C2410 system, where we have external FETs
+ * connected to the device (later systems such as the S3C2440 integrate
+ * these into the device).
+ */
+void s3c24xx_ts_cfg_gpio(struct platform_device *dev)
+{
+       s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
+       s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
+}
index da7a617..9793544 100644 (file)
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
                                          int enable)
 {
        if (enable) {
-               s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
-               s3c2410_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
-               s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
+               s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
+               s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
+               s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
                s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
                s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
        } else {
-               s3c2410_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
-               s3c2410_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
-               s3c2410_gpio_pullup(S3C2410_GPE(11), 1);
-               s3c2410_gpio_pullup(S3C2410_GPE(12), 1);
-               s3c2410_gpio_pullup(S3C2410_GPE(13), 1);
+               s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
        }
 }
index 89fcf53..db9e9e4 100644 (file)
@@ -23,16 +23,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
 
        printk(KERN_INFO "%s(%d)\n", __func__, enable);
        if (enable) {
-               s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
-               s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
-               s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
+               s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
+               s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
+               s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
                s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
                s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
        } else {
-               s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
-               s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
-               s3c2410_gpio_pullup(S3C2410_GPD(10), 1);
-               s3c2410_gpio_pullup(S3C2410_GPD(9), 1);
-               s3c2410_gpio_pullup(S3C2410_GPD(8), 1);
+               s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
        }
 }
index 86b9edc..8ea663a 100644 (file)
@@ -21,16 +21,16 @@ void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
                                       int enable)
 {
        if (enable) {
-               s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
-               s3c2410_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
-               s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
+               s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
+               s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
+               s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
                s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
                s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
        } else {
-               s3c2410_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
-               s3c2410_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
-               s3c2410_gpio_pullup(S3C2410_GPG(5), 1);
-               s3c2410_gpio_pullup(S3C2410_GPG(6), 1);
-               s3c2410_gpio_pullup(S3C2410_GPG(7), 1);
+               s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
+               s3c_gpio_cfgpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
+               s3c_gpio_cfgpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
        }
 }
index d400a6a..92bd756 100644 (file)
@@ -13,6 +13,7 @@ config PLAT_S5P
        select NO_IOPORT
        select ARCH_REQUIRE_GPIOLIB
        select S3C_GPIO_TRACK
+       select S5P_GPIO_DRVSTR
        select SAMSUNG_GPIOLIB_4BIT
        select S3C_GPIO_CFG_S3C64XX
        select S3C_GPIO_PULL_UPDOWN
index a7c54b3..0ec09a9 100644 (file)
@@ -16,4 +16,3 @@ obj-y                         += dev-uart.o
 obj-y                          += cpu.o
 obj-y                          += clock.o
 obj-y                          += irq.o
-obj-y                          += setup-i2c0.o
index aa96e33..24a931f 100644 (file)
@@ -33,7 +33,12 @@ struct clk clk_ext_xtal_mux = {
        .id             = -1,
 };
 
-static struct clk s5p_clk_27m = {
+struct clk clk_xusbxti = {
+       .name           = "xusbxti",
+       .id             = -1,
+};
+
+struct clk s5p_clk_27m = {
        .name           = "clk_27m",
        .id             = -1,
        .rate           = 27000000,
@@ -69,6 +74,13 @@ struct clk clk_fout_epll = {
        .ctrlbit        = (1 << 31),
 };
 
+/* VPLL clock output */
+struct clk clk_fout_vpll = {
+       .name           = "fout_vpll",
+       .id             = -1,
+       .ctrlbit        = (1 << 31),
+};
+
 /* ARM clock */
 struct clk clk_arm = {
        .name           = "armclk",
@@ -133,6 +145,7 @@ static struct clk *s5p_clks[] __initdata = {
        &clk_fout_apll,
        &clk_fout_mpll,
        &clk_fout_epll,
+       &clk_fout_vpll,
        &clk_arm,
        &clk_vpll,
 };
index 42e757f..9ff3d71 100644 (file)
@@ -79,7 +79,7 @@
 #define S5P_IRQ_VIC2(x)                (S5P_VIC2_BASE + (x))
 #define S5P_IRQ_VIC3(x)                (S5P_VIC3_BASE + (x))
 
-#define S5P_TIMER_IRQ(x)       S5P_IRQ(11 + (x))
+#define S5P_TIMER_IRQ(x)       (11 + (x))
 
 #define IRQ_TIMER0             S5P_TIMER_IRQ(0)
 #define IRQ_TIMER1             S5P_TIMER_IRQ(1)
index d48325b..7db3227 100644 (file)
@@ -81,3 +81,25 @@ static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
 
        return result;
 }
+
+#define PLL65XX_MDIV_MASK      (0x3FF)
+#define PLL65XX_PDIV_MASK      (0x3F)
+#define PLL65XX_SDIV_MASK      (0x7)
+#define PLL65XX_MDIV_SHIFT     (16)
+#define PLL65XX_PDIV_SHIFT     (8)
+#define PLL65XX_SDIV_SHIFT     (0)
+
+static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
+{
+       u32 mdiv, pdiv, sdiv;
+       u64 fvco = baseclk;
+
+       mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
index 56fb8b4..09418b1 100644 (file)
 #define clk_fin_mpll clk_ext_xtal_mux
 #define clk_fin_epll clk_ext_xtal_mux
 #define clk_fin_vpll clk_ext_xtal_mux
+#define clk_fin_hpll clk_ext_xtal_mux
 
 extern struct clk clk_ext_xtal_mux;
+extern struct clk clk_xusbxti;
 extern struct clk clk_48m;
+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_vpll;
 extern struct clk clk_arm;
 extern struct clk clk_vpll;
 
diff --git a/arch/arm/plat-s5p/setup-i2c0.c b/arch/arm/plat-s5p/setup-i2c0.c
deleted file mode 100644 (file)
index 67a66e0..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* linux/arch/arm/plat-s5p/setup-i2c0.c
- *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * I2C0 GPIO configuration.
- *
- * Based on plat-s3c64xx/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
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/iic.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-       /* Will be populated later */
-}
index c7ccdf2..c7bd2bb 100644 (file)
@@ -16,9 +16,10 @@ config PLAT_S5PC1XX
        select SAMSUNG_IRQ_VIC_TIMER
        select S3C_GPIO_TRACK
        select S3C_GPIO_PULL_UPDOWN
+       select S5P_GPIO_DRVSTR
        select S3C_GPIO_CFG_S3C24XX
        select S3C_GPIO_CFG_S3C64XX
-       select S5P_GPIO_CFG_S5PC1XX
+       select SAMSUNG_GPIOLIB_4BIT
        help
          Base platform code for any Samsung S5PC1XX device
 
@@ -38,25 +39,6 @@ config CPU_S5PC100_CLOCK
 
 # platform specific device setup
 
-config S5PC1XX_SETUP_FB_24BPP
-       bool
-       help
-          Common setup code for S5PC1XX with an 24bpp RGB display helper.
-
-config S5PC1XX_SETUP_I2C0
-       bool
-       default y
-       help
-         Common setup code for i2c bus 0.
-
-         Note, currently since i2c0 is always compiled, this setup helper
-         is always compiled with it.
-
-config S5PC1XX_SETUP_I2C1
-       bool
-       help
-         Common setup code for i2c bus 1.
-
 config S5PC1XX_SETUP_SDHCI_GPIO
        bool
        help
index 278f268..9ce6409 100644 (file)
@@ -13,9 +13,8 @@ obj-                          :=
 
 obj-y                          += dev-uart.o
 obj-y                          += cpu.o
-obj-y                          += irq.o irq-gpio.o irq-eint.o
+obj-y                          += irq.o
 obj-y                          += clock.o
-obj-y                          += gpiolib.o
 
 # CPU support
 
@@ -24,8 +23,4 @@ obj-$(CONFIG_CPU_S5PC100_CLOCK)       += s5pc100-clock.o
 
 # Device setup
 
-obj-$(CONFIG_S5P_GPIO_CFG_S5PC1XX) += gpio-config.o
-obj-$(CONFIG_S5PC1XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
-obj-$(CONFIG_S5PC1XX_SETUP_I2C0) += setup-i2c0.o
-obj-$(CONFIG_S5PC1XX_SETUP_I2C1) += setup-i2c1.o
 obj-$(CONFIG_S5PC1XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/plat-s5pc1xx/gpio-config.c b/arch/arm/plat-s5pc1xx/gpio-config.c
deleted file mode 100644 (file)
index a4f67e8..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/gpio-config.c
- *
- * Copyright 2009 Samsung Electronics
- *
- * S5PC1XX GPIO Configuration.
- *
- * Based on plat-s3c64xx/gpio-config.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg-s5pc1xx.h>
-
-s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       void __iomem *reg;
-       int shift = off * 2;
-       u32 drvstr;
-
-       if (!chip)
-               return -EINVAL;
-
-       reg = chip->base + 0x0C;
-
-       drvstr = __raw_readl(reg);
-       drvstr = 0xffff & (0x3 << shift);
-       drvstr = drvstr >> shift;
-
-       return (__force s5p_gpio_drvstr_t)drvstr;
-}
-EXPORT_SYMBOL(s5p_gpio_get_drvstr);
-
-int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
-                       s5p_gpio_drvstr_t drvstr)
-{
-       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
-       void __iomem *reg;
-       int shift = off * 2;
-       u32 tmp;
-
-       if (!chip)
-               return -EINVAL;
-
-       reg = chip->base + 0x0C;
-
-       tmp = __raw_readl(reg);
-       tmp |= drvstr << shift;
-
-       __raw_writel(tmp, reg);
-
-       return 0;
-}
-EXPORT_SYMBOL(s5p_gpio_set_drvstr);
diff --git a/arch/arm/plat-s5pc1xx/gpiolib.c b/arch/arm/plat-s5pc1xx/gpiolib.c
deleted file mode 100644 (file)
index 1ffc57a..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * arch/arm/plat-s5pc1xx/gpiolib.c
- *
- *  Copyright 2009 Samsung Electronics Co
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S5PC1XX - 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 <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <plat/regs-gpio.h>
-
-/* S5PC100 GPIO bank summary:
- *
- * Bank        GPIOs   Style   INT Type
- * A0  8       4Bit    GPIO_INT0
- * A1  5       4Bit    GPIO_INT1
- * B   8       4Bit    GPIO_INT2
- * C   5       4Bit    GPIO_INT3
- * D   7       4Bit    GPIO_INT4
- * E0  8       4Bit    GPIO_INT5
- * E1  6       4Bit    GPIO_INT6
- * F0  8       4Bit    GPIO_INT7
- * F1  8       4Bit    GPIO_INT8
- * F2  8       4Bit    GPIO_INT9
- * F3  4       4Bit    GPIO_INT10
- * G0  8       4Bit    GPIO_INT11
- * G1  3       4Bit    GPIO_INT12
- * G2  7       4Bit    GPIO_INT13
- * G3  7       4Bit    GPIO_INT14
- * H0  8       4Bit    WKUP_INT
- * H1  8       4Bit    WKUP_INT
- * H2  8       4Bit    WKUP_INT
- * H3  8       4Bit    WKUP_INT
- * I   8       4Bit    GPIO_INT15
- * J0  8       4Bit    GPIO_INT16
- * J1  5       4Bit    GPIO_INT17
- * J2  8       4Bit    GPIO_INT18
- * J3  8       4Bit    GPIO_INT19
- * J4  4       4Bit    GPIO_INT20
- * K0  8       4Bit    None
- * K1  6       4Bit    None
- * K2  8       4Bit    None
- * K3  8       4Bit    None
- * L0  8       4Bit    None
- * L1  8       4Bit    None
- * L2  8       4Bit    None
- * L3  8       4Bit    None
- */
-
-#define OFF_GPCON      (0x00)
-#define OFF_GPDAT      (0x04)
-
-#define con_4bit_shift(__off) ((__off) * 4)
-
-#if 1
-#define gpio_dbg(x...) do { } while (0)
-#else
-#define gpio_dbg(x...) printk(KERN_DEBUG x)
-#endif
-
-/* The s5pc1xx_gpiolib routines are to control the gpio banks where
- * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
- * following example:
- *
- * base + 0x00: Control register, 4 bits per gpio
- *             gpio n: 4 bits starting at (4*n)
- *             0000 = input, 0001 = output, others mean special-function
- * base + 0x04: Data register, 1 bit per gpio
- *             bit n: data bit n
- *
- * Note, since the data register is one bit per gpio and is at base + 0x4
- * we can use s3c_gpiolib_get and s3c_gpiolib_set to change the state of
- * the output.
- */
-
-static int s5pc1xx_gpiolib_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long con;
-
-       con = __raw_readl(base + OFF_GPCON);
-       con &= ~(0xf << con_4bit_shift(offset));
-       __raw_writel(con, base + OFF_GPCON);
-
-       gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
-
-       return 0;
-}
-
-static int s5pc1xx_gpiolib_output(struct gpio_chip *chip,
-                                      unsigned offset, int value)
-{
-       struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
-       void __iomem *base = ourchip->base;
-       unsigned long con;
-       unsigned long dat;
-
-       con = __raw_readl(base + OFF_GPCON);
-       con &= ~(0xf << con_4bit_shift(offset));
-       con |= 0x1 << con_4bit_shift(offset);
-
-       dat = __raw_readl(base + OFF_GPDAT);
-       if (value)
-               dat |= 1 << offset;
-       else
-               dat &= ~(1 << offset);
-
-       __raw_writel(dat, base + OFF_GPDAT);
-       __raw_writel(con, base + OFF_GPCON);
-       __raw_writel(dat, base + OFF_GPDAT);
-
-       gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
-
-       return 0;
-}
-
-static int s5pc1xx_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-       return S3C_IRQ_GPIO(chip->base + offset);
-}
-
-static int s5pc1xx_gpiolib_to_eint(struct gpio_chip *chip, unsigned int offset)
-{
-       int base;
-
-       base = chip->base - S5PC100_GPH0(0);
-       if (base == 0)
-               return IRQ_EINT(offset);
-       base = chip->base - S5PC100_GPH1(0);
-       if (base == 0)
-               return IRQ_EINT(8 + offset);
-       base = chip->base - S5PC100_GPH2(0);
-       if (base == 0)
-               return IRQ_EINT(16 + offset);
-       base = chip->base - S5PC100_GPH3(0);
-       if (base == 0)
-               return IRQ_EINT(24 + offset);
-       return -EINVAL;
-}
-
-static struct s3c_gpio_cfg gpio_cfg = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_eint = {
-       .cfg_eint       = 0xf,
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-       .set_config     = s3c_gpio_setcfg_s3c64xx_4bit,
-       .set_pull       = s3c_gpio_setpull_updown,
-       .get_pull       = s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
-       {
-               .base   = S5PC100_GPA0_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPA0(0),
-                       .ngpio  = S5PC100_GPIO_A0_NR,
-                       .label  = "GPA0",
-               },
-       }, {
-               .base   = S5PC100_GPA1_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPA1(0),
-                       .ngpio  = S5PC100_GPIO_A1_NR,
-                       .label  = "GPA1",
-               },
-       }, {
-               .base   = S5PC100_GPB_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPB(0),
-                       .ngpio  = S5PC100_GPIO_B_NR,
-                       .label  = "GPB",
-               },
-       }, {
-               .base   = S5PC100_GPC_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPC(0),
-                       .ngpio  = S5PC100_GPIO_C_NR,
-                       .label  = "GPC",
-               },
-       }, {
-               .base   = S5PC100_GPD_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPD(0),
-                       .ngpio  = S5PC100_GPIO_D_NR,
-                       .label  = "GPD",
-               },
-       }, {
-               .base   = S5PC100_GPE0_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPE0(0),
-                       .ngpio  = S5PC100_GPIO_E0_NR,
-                       .label  = "GPE0",
-               },
-       }, {
-               .base   = S5PC100_GPE1_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPE1(0),
-                       .ngpio  = S5PC100_GPIO_E1_NR,
-                       .label  = "GPE1",
-               },
-       }, {
-               .base   = S5PC100_GPF0_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPF0(0),
-                       .ngpio  = S5PC100_GPIO_F0_NR,
-                       .label  = "GPF0",
-               },
-       }, {
-               .base   = S5PC100_GPF1_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPF1(0),
-                       .ngpio  = S5PC100_GPIO_F1_NR,
-                       .label  = "GPF1",
-               },
-       }, {
-               .base   = S5PC100_GPF2_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPF2(0),
-                       .ngpio  = S5PC100_GPIO_F2_NR,
-                       .label  = "GPF2",
-               },
-       }, {
-               .base   = S5PC100_GPF3_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPF3(0),
-                       .ngpio  = S5PC100_GPIO_F3_NR,
-                       .label  = "GPF3",
-               },
-       }, {
-               .base   = S5PC100_GPG0_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPG0(0),
-                       .ngpio  = S5PC100_GPIO_G0_NR,
-                       .label  = "GPG0",
-               },
-       }, {
-               .base   = S5PC100_GPG1_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPG1(0),
-                       .ngpio  = S5PC100_GPIO_G1_NR,
-                       .label  = "GPG1",
-               },
-       }, {
-               .base   = S5PC100_GPG2_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPG2(0),
-                       .ngpio  = S5PC100_GPIO_G2_NR,
-                       .label  = "GPG2",
-               },
-       }, {
-               .base   = S5PC100_GPG3_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPG3(0),
-                       .ngpio  = S5PC100_GPIO_G3_NR,
-                       .label  = "GPG3",
-               },
-       }, {
-               .base   = S5PC100_GPH0_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH0(0),
-                       .ngpio  = S5PC100_GPIO_H0_NR,
-                       .label  = "GPH0",
-               },
-       }, {
-               .base   = S5PC100_GPH1_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH1(0),
-                       .ngpio  = S5PC100_GPIO_H1_NR,
-                       .label  = "GPH1",
-               },
-       }, {
-               .base   = S5PC100_GPH2_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH2(0),
-                       .ngpio  = S5PC100_GPIO_H2_NR,
-                       .label  = "GPH2",
-               },
-       }, {
-               .base   = S5PC100_GPH3_BASE,
-               .config = &gpio_cfg_eint,
-               .chip   = {
-                       .base   = S5PC100_GPH3(0),
-                       .ngpio  = S5PC100_GPIO_H3_NR,
-                       .label  = "GPH3",
-               },
-       }, {
-               .base   = S5PC100_GPI_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPI(0),
-                       .ngpio  = S5PC100_GPIO_I_NR,
-                       .label  = "GPI",
-               },
-       }, {
-               .base   = S5PC100_GPJ0_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPJ0(0),
-                       .ngpio  = S5PC100_GPIO_J0_NR,
-                       .label  = "GPJ0",
-               },
-       }, {
-               .base   = S5PC100_GPJ1_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPJ1(0),
-                       .ngpio  = S5PC100_GPIO_J1_NR,
-                       .label  = "GPJ1",
-               },
-       }, {
-               .base   = S5PC100_GPJ2_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPJ2(0),
-                       .ngpio  = S5PC100_GPIO_J2_NR,
-                       .label  = "GPJ2",
-               },
-       }, {
-               .base   = S5PC100_GPJ3_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPJ3(0),
-                       .ngpio  = S5PC100_GPIO_J3_NR,
-                       .label  = "GPJ3",
-               },
-       }, {
-               .base   = S5PC100_GPJ4_BASE,
-               .config = &gpio_cfg,
-               .chip   = {
-                       .base   = S5PC100_GPJ4(0),
-                       .ngpio  = S5PC100_GPIO_J4_NR,
-                       .label  = "GPJ4",
-               },
-       }, {
-               .base   = S5PC100_GPK0_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK0(0),
-                       .ngpio  = S5PC100_GPIO_K0_NR,
-                       .label  = "GPK0",
-               },
-       }, {
-               .base   = S5PC100_GPK1_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK1(0),
-                       .ngpio  = S5PC100_GPIO_K1_NR,
-                       .label  = "GPK1",
-               },
-       }, {
-               .base   = S5PC100_GPK2_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK2(0),
-                       .ngpio  = S5PC100_GPIO_K2_NR,
-                       .label  = "GPK2",
-               },
-       }, {
-               .base   = S5PC100_GPK3_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPK3(0),
-                       .ngpio  = S5PC100_GPIO_K3_NR,
-                       .label  = "GPK3",
-               },
-       }, {
-               .base   = S5PC100_GPL0_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL0(0),
-                       .ngpio  = S5PC100_GPIO_L0_NR,
-                       .label  = "GPL0",
-               },
-       }, {
-               .base   = S5PC100_GPL1_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL1(0),
-                       .ngpio  = S5PC100_GPIO_L1_NR,
-                       .label  = "GPL1",
-               },
-       }, {
-               .base   = S5PC100_GPL2_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL2(0),
-                       .ngpio  = S5PC100_GPIO_L2_NR,
-                       .label  = "GPL2",
-               },
-       }, {
-               .base   = S5PC100_GPL3_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL3(0),
-                       .ngpio  = S5PC100_GPIO_L3_NR,
-                       .label  = "GPL3",
-               },
-       }, {
-               .base   = S5PC100_GPL4_BASE,
-               .config = &gpio_cfg_noint,
-               .chip   = {
-                       .base   = S5PC100_GPL4(0),
-                       .ngpio  = S5PC100_GPIO_L4_NR,
-                       .label  = "GPL4",
-               },
-       },
-};
-
-/* FIXME move from irq-gpio.c */
-extern struct irq_chip s5pc1xx_gpioint;
-extern void s5pc1xx_irq_gpioint_handler(unsigned int irq, struct irq_desc *desc);
-
-static __init void s5pc1xx_gpiolib_link(struct s3c_gpio_chip *chip)
-{
-       chip->chip.direction_input = s5pc1xx_gpiolib_input;
-       chip->chip.direction_output = s5pc1xx_gpiolib_output;
-       chip->pm = __gpio_pm(&s3c_gpio_pm_4bit);
-
-       /* Interrupt */
-       if (chip->config == &gpio_cfg) {
-               int i, irq;
-
-               chip->chip.to_irq = s5pc1xx_gpiolib_to_irq;
-
-               for (i = 0;  i < chip->chip.ngpio; i++) {
-                       irq = S3C_IRQ_GPIO_BASE + chip->chip.base + i;
-                       set_irq_chip(irq, &s5pc1xx_gpioint);
-                       set_irq_data(irq, &chip->chip);
-                       set_irq_handler(irq, handle_level_irq);
-                       set_irq_flags(irq, IRQF_VALID);
-               }
-       } else if (chip->config == &gpio_cfg_eint)
-               chip->chip.to_irq = s5pc1xx_gpiolib_to_eint;
-}
-
-static __init void s5pc1xx_gpiolib_add(struct s3c_gpio_chip *chips,
-                                      int nr_chips,
-                                      void (*fn)(struct s3c_gpio_chip *))
-{
-       for (; nr_chips > 0; nr_chips--, chips++) {
-               if (fn)
-                       (fn)(chips);
-               s3c_gpiolib_add(chips);
-       }
-}
-
-static __init int s5pc1xx_gpiolib_init(void)
-{
-       struct s3c_gpio_chip *chips;
-       int nr_chips;
-
-               chips = s5pc100_gpio_chips;
-               nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
-
-       s5pc1xx_gpiolib_add(chips, nr_chips, s5pc1xx_gpiolib_link);
-       /* Interrupt */
-       set_irq_chained_handler(IRQ_GPIOINT, s5pc1xx_irq_gpioint_handler);
-
-       return 0;
-}
-core_initcall(s5pc1xx_gpiolib_init);
diff --git a/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h b/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg-s5pc1xx.h
deleted file mode 100644 (file)
index 72ad59f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/include/plat/gpio-cfg.h
- *
- * Copyright 2009 Samsung Electronic
- *
- * S5PC1XX Platform - GPIO pin 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.
-*/
-
-/* This file contains the necessary definitions to get the basic gpio
- * pin configuration done such as setting a pin to input or output or
- * changing the pull-{up,down} configurations.
- */
-
-#ifndef __GPIO_CFG_S5PC1XX_H
-#define __GPIO_CFG_S5PC1XX_H __FILE__
-
-typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
-
-#define S5P_GPIO_DRVSTR_LV1    0x00
-#define S5P_GPIO_DRVSTR_LV2    0x01
-#define S5P_GPIO_DRVSTR_LV3    0x10
-#define S5P_GPIO_DRVSTR_LV4    0x11
-
-extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin, unsigned int off);
-
-extern int s5p_gpio_set_drvstr(unsigned int pin, unsigned int off,
-                       s5p_gpio_drvstr_t drvstr);
-
-#endif /* __GPIO_CFG_S5PC1XX_H */
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h b/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
deleted file mode 100644 (file)
index 43c7bc8..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/include/plat/regs-gpio.h
- *
- * Copyright 2009 Samsung Electronics Co.
- *      Byungho Min <bhmin@samsung.com>
- *
- * S5PC1XX - GPIO register definitions
- */
-
-#ifndef __ASM_PLAT_S5PC1XX_REGS_GPIO_H
-#define __ASM_PLAT_S5PC1XX_REGS_GPIO_H __FILE__
-
-#include <mach/map.h>
-
-/* S5PC100 */
-#define S5PC100_GPIO_BASE      S5PC1XX_VA_GPIO
-#define S5PC100_GPA0_BASE      (S5PC100_GPIO_BASE + 0x0000)
-#define S5PC100_GPA1_BASE      (S5PC100_GPIO_BASE + 0x0020)
-#define S5PC100_GPB_BASE       (S5PC100_GPIO_BASE + 0x0040)
-#define S5PC100_GPC_BASE       (S5PC100_GPIO_BASE + 0x0060)
-#define S5PC100_GPD_BASE       (S5PC100_GPIO_BASE + 0x0080)
-#define S5PC100_GPE0_BASE      (S5PC100_GPIO_BASE + 0x00A0)
-#define S5PC100_GPE1_BASE      (S5PC100_GPIO_BASE + 0x00C0)
-#define S5PC100_GPF0_BASE      (S5PC100_GPIO_BASE + 0x00E0)
-#define S5PC100_GPF1_BASE      (S5PC100_GPIO_BASE + 0x0100)
-#define S5PC100_GPF2_BASE      (S5PC100_GPIO_BASE + 0x0120)
-#define S5PC100_GPF3_BASE      (S5PC100_GPIO_BASE + 0x0140)
-#define S5PC100_GPG0_BASE      (S5PC100_GPIO_BASE + 0x0160)
-#define S5PC100_GPG1_BASE      (S5PC100_GPIO_BASE + 0x0180)
-#define S5PC100_GPG2_BASE      (S5PC100_GPIO_BASE + 0x01A0)
-#define S5PC100_GPG3_BASE      (S5PC100_GPIO_BASE + 0x01C0)
-#define S5PC100_GPH0_BASE      (S5PC100_GPIO_BASE + 0x0C00)
-#define S5PC100_GPH1_BASE      (S5PC100_GPIO_BASE + 0x0C20)
-#define S5PC100_GPH2_BASE      (S5PC100_GPIO_BASE + 0x0C40)
-#define S5PC100_GPH3_BASE      (S5PC100_GPIO_BASE + 0x0C60)
-#define S5PC100_GPI_BASE       (S5PC100_GPIO_BASE + 0x01E0)
-#define S5PC100_GPJ0_BASE      (S5PC100_GPIO_BASE + 0x0200)
-#define S5PC100_GPJ1_BASE      (S5PC100_GPIO_BASE + 0x0220)
-#define S5PC100_GPJ2_BASE      (S5PC100_GPIO_BASE + 0x0240)
-#define S5PC100_GPJ3_BASE      (S5PC100_GPIO_BASE + 0x0260)
-#define S5PC100_GPJ4_BASE      (S5PC100_GPIO_BASE + 0x0280)
-#define S5PC100_GPK0_BASE      (S5PC100_GPIO_BASE + 0x02A0)
-#define S5PC100_GPK1_BASE      (S5PC100_GPIO_BASE + 0x02C0)
-#define S5PC100_GPK2_BASE      (S5PC100_GPIO_BASE + 0x02E0)
-#define S5PC100_GPK3_BASE      (S5PC100_GPIO_BASE + 0x0300)
-#define S5PC100_GPL0_BASE      (S5PC100_GPIO_BASE + 0x0320)
-#define S5PC100_GPL1_BASE      (S5PC100_GPIO_BASE + 0x0340)
-#define S5PC100_GPL2_BASE      (S5PC100_GPIO_BASE + 0x0360)
-#define S5PC100_GPL3_BASE      (S5PC100_GPIO_BASE + 0x0380)
-#define S5PC100_GPL4_BASE      (S5PC100_GPIO_BASE + 0x03A0)
-#define S5PC100_EINT_BASE      (S5PC100_GPIO_BASE + 0x0E00)
-
-#define S5PC100_UHOST          (S5PC100_GPIO_BASE + 0x0B68)
-#define S5PC100_PDNEN          (S5PC100_GPIO_BASE + 0x0F80)
-
-/* PDNEN */
-#define S5PC100_PDNEN_CFG_PDNEN        (1 << 1)
-#define S5PC100_PDNEN_CFG_AUTO (0 << 1)
-#define S5PC100_PDNEN_POWERDOWN        (1 << 0)
-#define S5PC100_PDNEN_NORMAL   (0 << 0)
-
-/* Common part */
-/* External interrupt base is same at both s5pc100 and s5pc110 */
-#define S5PC1XX_EINT_BASE      (S5PC100_EINT_BASE)
-
-#define S5PC100_GPx_INPUT(__gpio)      (0x0 << ((__gpio) * 4))
-#define S5PC100_GPx_OUTPUT(__gpio)     (0x1 << ((__gpio) * 4))
-#define S5PC100_GPx_CONMASK(__gpio)    (0xf << ((__gpio) * 4))
-
-#endif /* __ASM_PLAT_S5PC1XX_REGS_GPIO_H */
-
diff --git a/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c b/arch/arm/plat-s5pc1xx/setup-fb-24bpp.c
deleted file mode 100644 (file)
index 1a63768..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * linux/arch/arm/plat-s5pc100/setup-fb-24bpp.c
- *
- * Copyright 2009 Samsung Electronics
- *
- * Base S5PC1XX setup information for 24bpp LCD framebuffer
- *
- * 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/fb.h>
-#include <linux/gpio.h>
-
-#include <mach/regs-fb.h>
-#include <mach/map.h>
-#include <plat/fb.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-s5pc1xx.h>
-
-#define DISR_OFFSET    0x7008
-
-void s5pc100_fb_gpio_setup_24bpp(void)
-{
-       unsigned int gpio = 0;
-
-       for (gpio = S5PC100_GPF0(0); gpio <= S5PC100_GPF0(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S5PC100_GPF1(0); gpio <= S5PC100_GPF1(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S5PC100_GPF2(0); gpio <= S5PC100_GPF2(7); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-
-       for (gpio = S5PC100_GPF3(0); gpio <= S5PC100_GPF3(3); gpio++) {
-               s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
-               s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
-       }
-}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c
deleted file mode 100644 (file)
index 5e4a7c3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c
- *
- * Copyright 2009 Samsung Electronics Co.
- *     Byungho Min <bhmin@samsung.com>
- *
- * Base S5PC1XX I2C bus 0 gpio configuration
- *
- * Based on plat-s3c64xx/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
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgpin(S5PC100_GPD(3), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(3), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PC100_GPD(4), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(4), S3C_GPIO_PULL_UP);
-}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c
deleted file mode 100644 (file)
index a0a8b4a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
- *
- * Copyright 2009 Samsung Electronics Co.
- *     Byungho Min <bhmin@samsung.com>
- *
- * Base S5PC1XX I2C bus 1 gpio configuration
- *
- * Based on plat-s3c64xx/setup-i2c1.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <linux/gpio.h>
-#include <plat/iic.h>
-#include <plat/gpio-cfg.h>
-
-void s3c_i2c1_cfg_gpio(struct platform_device *dev)
-{
-       s3c_gpio_cfgpin(S5PC100_GPD(5), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(5), S3C_GPIO_PULL_UP);
-       s3c_gpio_cfgpin(S5PC100_GPD(6), S3C_GPIO_SFN(2));
-       s3c_gpio_setpull(S5PC100_GPD(6), S3C_GPIO_PULL_UP);
-}
index d552c65..229919e 100644 (file)
@@ -90,12 +90,6 @@ config S3C_GPIO_CFG_S3C64XX
          Internal configuration to enable S3C64XX style GPIO configuration
          functions.
 
-config S5P_GPIO_CFG_S5PC1XX
-       bool
-       help
-         Internal configuration to enable S5PC1XX style GPIO configuration
-         functions.
-
 config S3C_GPIO_PULL_UPDOWN
        bool
        help
@@ -111,6 +105,12 @@ config S3C_GPIO_PULL_UP
        help
          Internal configuration to enable the correct GPIO pull helper
 
+config S5P_GPIO_DRVSTR
+       bool
+       help
+         Internal configuration to get and set correct GPIO driver strength
+         helper
+
 config SAMSUNG_GPIO_EXTRA
        int "Number of additional GPIO pins"
        default 0
@@ -160,6 +160,11 @@ config S3C_DEV_HSMMC2
        help
          Compile in platform device definitions for HSMMC channel 2
 
+config S3C_DEV_HWMON
+       bool
+       help
+           Compile in platform device definitions for HWMON
+
 config S3C_DEV_I2C1
        bool
        help
@@ -185,12 +190,27 @@ config S3C_DEV_NAND
        help
          Compile in platform device definition for NAND controller
 
+config S3C_DEV_RTC
+       bool
+       help
+         Complie in platform device definition for RTC
+
+config SAMSUNG_DEV_ADC
+       bool
+       help
+         Compile in platform device definition for ADC controller
+
 config S3C64XX_DEV_SPI
        bool
        help
          Compile in platform device definitions for S3C64XX's type
          SPI controllers.
 
+config SAMSUNG_DEV_TS
+       bool
+       help
+           Common in platform device definitions for touchscreen device
+
 # DMA
 
 config S3C_DMA
@@ -198,6 +218,12 @@ config S3C_DMA
        help
          Internal configuration for S3C DMA core
 
+config S3C_PL330_DMA
+       bool
+       select PL330
+       help
+         S3C DMA API Driver for PL330 DMAC.
+
 comment "Power management"
 
 config SAMSUNG_PM_DEBUG
index 22c89d0..4828849 100644 (file)
@@ -33,6 +33,7 @@ obj-$(CONFIG_S3C_ADC) += adc.o
 obj-$(CONFIG_S3C_DEV_HSMMC)    += dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)   += dev-hsmmc1.o
 obj-$(CONFIG_S3C_DEV_HSMMC2)   += dev-hsmmc2.o
+obj-$(CONFIG_S3C_DEV_HWMON)    += dev-hwmon.o
 obj-y                          += dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)     += dev-i2c1.o
 obj-$(CONFIG_S3C_DEV_FB)       += dev-fb.o
@@ -40,11 +41,17 @@ obj-y                               += dev-uart.o
 obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
 obj-$(CONFIG_S3C_DEV_USB_HSOTG)        += dev-usb-hsotg.o
 obj-$(CONFIG_S3C_DEV_NAND)     += dev-nand.o
+obj-$(CONFIG_S3C_DEV_RTC)      += dev-rtc.o
+
+obj-$(CONFIG_SAMSUNG_DEV_ADC)  += dev-adc.o
+obj-$(CONFIG_SAMSUNG_DEV_TS)   += dev-ts.o
 
 # DMA support
 
 obj-$(CONFIG_S3C_DMA)          += dma.o
 
+obj-$(CONFIG_S3C_PL330_DMA)    += s3c-pl330.o
+
 # PM support
 
 obj-$(CONFIG_PM)               += pm.o
index 1b25c9d..8bf79f3 100644 (file)
@@ -376,6 +376,21 @@ void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
        }
 }
 
+/**
+ * s3c_disable_clocks() - disable an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * for internal use only at initialisation time. disable the clocks in the
+ * @clkp array.
+ */
+
+void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
+{
+       for (; nr_clks > 0; nr_clks--, clkp++)
+               (clkp->enable)(clkp, 0);
+}
+
 /* initalise all the clocks */
 
 int __init s3c24xx_register_baseclocks(unsigned long xtal)
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
new file mode 100644 (file)
index 0000000..9d903d4
--- /dev/null
@@ -0,0 +1,46 @@
+/* linux/arch/arm/plat-samsung/dev-adc.c
+ *
+ * Copyright 2010 Maurus Cuelenaere
+ *
+ * S3C64xx series device definition for ADC device
+ *
+ * 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/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/adc.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_adc_resource[] = {
+       [0] = {
+               .start = SAMSUNG_PA_ADC,
+               .end   = SAMSUNG_PA_ADC + SZ_256 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TC,
+               .end   = IRQ_TC,
+               .flags = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start = IRQ_ADC,
+               .end   = IRQ_ADC,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_adc = {
+       .name           = "samsung-adc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_adc_resource),
+       .resource       = s3c_adc_resource,
+};
index 002a15f..bf60204 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <mach/irqs.h>
 #include <mach/map.h>
-#include <mach/regs-fb.h>
 
 #include <plat/fb.h>
 #include <plat/devs.h>
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
new file mode 100644 (file)
index 0000000..b3ffb95
--- /dev/null
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-samsung/dev-hwmon.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Adapted for HWMON by Maurus Cuelenaere
+ *
+ * Samsung series device definition for HWMON
+ *
+ * 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/platform_device.h>
+
+#include <plat/devs.h>
+#include <plat/hwmon.h>
+
+struct platform_device s3c_device_hwmon = {
+       .name           = "s3c-hwmon",
+       .id             = -1,
+       .dev.parent     = &s3c_device_adc.dev,
+};
+
+void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd)
+{
+       struct s3c_hwmon_pdata *npd;
+
+       if (!pd) {
+               printk(KERN_ERR "%s: no platform data\n", __func__);
+               return;
+       }
+
+       npd = kmemdup(pd, sizeof(struct s3c_hwmon_pdata), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+       s3c_device_hwmon.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c
new file mode 100644 (file)
index 0000000..bf4e226
--- /dev/null
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-samsung/dev-rtc.c
+ *
+ * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_rtc_resource[] = {
+       [0] = {
+               .start  = S3C_PA_RTC,
+               .end    = S3C_PA_RTC + 0xff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = IRQ_RTC_ALARM,
+               .end    = IRQ_RTC_ALARM,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start  = IRQ_RTC_TIC,
+               .end    = IRQ_RTC_TIC,
+               .flags  = IORESOURCE_IRQ
+       }
+};
+
+struct platform_device s3c_device_rtc = {
+       .name           = "s3c64xx-rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_rtc_resource),
+       .resource       = s3c_rtc_resource,
+};
+EXPORT_SYMBOL(s3c_device_rtc);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
new file mode 100644 (file)
index 0000000..236ef84
--- /dev/null
@@ -0,0 +1,61 @@
+/* linux/arch/arm/mach-s3c64xx/dev-ts.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Adapted by Maurus Cuelenaere for s3c64xx
+ *
+ * S3C64XX series device definition for touchscreen device
+ *
+ * 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/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/ts.h>
+
+static struct resource s3c_ts_resource[] = {
+       [0] = {
+               .start = SAMSUNG_PA_ADC,
+               .end   = SAMSUNG_PA_ADC + SZ_256 - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = IRQ_TC,
+               .end   = IRQ_TC,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device s3c_device_ts = {
+       .name           = "s3c64xx-ts",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(s3c_ts_resource),
+       .resource       = s3c_ts_resource,
+};
+
+void __init s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *pd)
+{
+       struct s3c2410_ts_mach_info *npd;
+
+       if (!pd) {
+               printk(KERN_ERR "%s: no platform data\n", __func__);
+               return;
+       }
+
+       npd = kmemdup(pd, sizeof(struct s3c2410_ts_mach_info), GFP_KERNEL);
+       if (!npd)
+               printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+
+       s3c_device_ts.dev.platform_data = npd;
+}
+EXPORT_SYMBOL(s3c24xx_ts_set_platdata);
index 44a84e8..57b68a5 100644 (file)
@@ -1,7 +1,7 @@
 /* linux/arch/arm/plat-s3c/gpio-config.c
  *
  * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
+ * Copyright 2008-2010 Simtec Electronics
  *     Ben Dooks <ben@simtec.co.uk>
  *     http://armlinux.simtec.co.uk/
  *
@@ -33,14 +33,34 @@ int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
 
        offset = pin - chip->chip.base;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(chip, flags);
        ret = s3c_gpio_do_setcfg(chip, offset, config);
-       local_irq_restore(flags);
+       s3c_gpio_unlock(chip, flags);
 
        return ret;
 }
 EXPORT_SYMBOL(s3c_gpio_cfgpin);
 
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned long flags;
+       unsigned ret = 0;
+       int offset;
+
+       if (chip) {
+               offset = pin - chip->chip.base;
+
+               s3c_gpio_lock(chip, flags);
+               ret = s3c_gpio_do_getcfg(chip, offset);
+               s3c_gpio_unlock(chip, flags);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+
 int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 {
        struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
@@ -52,17 +72,17 @@ int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
 
        offset = pin - chip->chip.base;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(chip, flags);
        ret = s3c_gpio_do_setpull(chip, offset, pull);
-       local_irq_restore(flags);
+       s3c_gpio_unlock(chip, flags);
 
        return ret;
 }
 EXPORT_SYMBOL(s3c_gpio_setpull);
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
-int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
-                                 unsigned int off, unsigned int cfg)
+int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+                             unsigned int off, unsigned int cfg)
 {
        void __iomem *reg = chip->base;
        unsigned int shift = off;
@@ -87,6 +107,19 @@ int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
        return 0;
 }
 
+unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+                                  unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off;
+       con &= 1;
+       con++;
+
+       return S3C_GPIO_SFN(con);
+}
+
 int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
                            unsigned int off, unsigned int cfg)
 {
@@ -109,6 +142,19 @@ int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
 
        return 0;
 }
+
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       u32 con;
+
+       con = __raw_readl(chip->base);
+       con >>= off * 2;
+       con &= 3;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
 #endif
 
 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
@@ -134,6 +180,25 @@ int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
 
        return 0;
 }
+
+unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+                                     unsigned int off)
+{
+       void __iomem *reg = chip->base;
+       unsigned int shift = (off & 7) * 4;
+       u32 con;
+
+       if (off < 8 && chip->chip.ngpio > 8)
+               reg -= 4;
+
+       con = __raw_readl(reg);
+       con >>= shift;
+       con &= 0xf;
+
+       /* this conversion works for IN and OUT as well as special mode */
+       return S3C_GPIO_SPECIAL(con);
+}
+
 #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
 
 #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
@@ -164,3 +229,83 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
        return (__force s3c_gpio_pull_t)pup;
 }
 #endif
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+                        unsigned int off, s3c_gpio_pull_t pull)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       pup = __raw_readl(reg);
+
+       if (pup == S3C_GPIO_PULL_UP)
+               pup &= ~(1 << off);
+       else if (pup == S3C_GPIO_PULL_NONE)
+               pup |= (1 << off);
+       else
+               return -EINVAL;
+
+       __raw_writel(pup, reg);
+       return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+                                    unsigned int off)
+{
+       void __iomem *reg = chip->base + 0x08;
+       u32 pup = __raw_readl(reg);
+
+       pup &= (1 << off);
+       return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP */
+
+#ifdef CONFIG_S5P_GPIO_DRVSTR
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned int off;
+       void __iomem *reg;
+       int shift;
+       u32 drvstr;
+
+       if (!chip)
+               return -EINVAL;
+
+       off = chip->chip.base - pin;
+       shift = off * 2;
+       reg = chip->base + 0x0C;
+
+       drvstr = __raw_readl(reg);
+       drvstr = 0xffff & (0x3 << shift);
+       drvstr = drvstr >> shift;
+
+       return (__force s5p_gpio_drvstr_t)drvstr;
+}
+EXPORT_SYMBOL(s5p_gpio_get_drvstr);
+
+int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
+{
+       struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+       unsigned int off;
+       void __iomem *reg;
+       int shift;
+       u32 tmp;
+
+       if (!chip)
+               return -EINVAL;
+
+       off = chip->chip.base - pin;
+       shift = off * 2;
+       reg = chip->base + 0x0C;
+
+       tmp = __raw_readl(reg);
+       tmp |= drvstr << shift;
+
+       __raw_writel(tmp, reg);
+
+       return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
+#endif /* CONFIG_S5P_GPIO_DRVSTR */
index 28d2ab8..b83a833 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
+#include <linux/spinlock.h>
 
 #include <plat/gpio-core.h>
 
@@ -52,14 +53,14 @@ static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
        unsigned long flags;
        unsigned long con;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(ourchip, flags);
 
        con = __raw_readl(base + 0x00);
        con &= ~(3 << (offset * 2));
 
        __raw_writel(con, base + 0x00);
 
-       local_irq_restore(flags);
+       s3c_gpio_unlock(ourchip, flags);
        return 0;
 }
 
@@ -72,7 +73,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
        unsigned long dat;
        unsigned long con;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(ourchip, flags);
 
        dat = __raw_readl(base + 0x04);
        dat &= ~(1 << offset);
@@ -87,7 +88,7 @@ static int s3c_gpiolib_output(struct gpio_chip *chip,
        __raw_writel(con, base + 0x00);
        __raw_writel(dat, base + 0x04);
 
-       local_irq_restore(flags);
+       s3c_gpio_unlock(ourchip, flags);
        return 0;
 }
 
@@ -99,7 +100,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
        unsigned long flags;
        unsigned long dat;
 
-       local_irq_save(flags);
+       s3c_gpio_lock(ourchip, flags);
 
        dat = __raw_readl(base + 0x04);
        dat &= ~(1 << offset);
@@ -107,7 +108,7 @@ static void s3c_gpiolib_set(struct gpio_chip *chip,
                dat |= 1 << offset;
        __raw_writel(dat, base + 0x04);
 
-       local_irq_restore(flags);
+       s3c_gpio_unlock(ourchip, flags);
 }
 
 static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
@@ -131,6 +132,8 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
        BUG_ON(!gc->label);
        BUG_ON(!gc->ngpio);
 
+       spin_lock_init(&chip->lock);
+
        if (!gc->direction_input)
                gc->direction_input = s3c_gpiolib_input;
        if (!gc->direction_output)
index 60b6269..0fbcd0e 100644 (file)
@@ -74,6 +74,7 @@ extern struct clk clk_ext;
 extern struct clk clk_h2;
 extern struct clk clk_27m;
 extern struct clk clk_48m;
+extern struct clk clk_xusbxti;
 
 extern int clk_default_setrate(struct clk *clk, unsigned long rate);
 extern struct clk_ops clk_ops_def_setrate;
@@ -91,6 +92,7 @@ extern int s3c24xx_register_clock(struct clk *clk);
 extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
 
 extern void s3c_register_clocks(struct clk *clk, int nr_clks);
+extern void s3c_disable_clocks(struct clk *clkp, int nr_clks);
 
 extern int s3c24xx_register_baseclocks(unsigned long xtal);
 
index d316b4a..6412933 100644 (file)
@@ -73,11 +73,15 @@ extern struct sys_timer s3c24xx_timer;
 extern struct sysdev_class s3c2410_sysclass;
 extern struct sysdev_class s3c2410a_sysclass;
 extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2416_sysclass;
 extern struct sysdev_class s3c2440_sysclass;
 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 s5p6442_sysclass;
+extern struct sysdev_class s5pv210_sysclass;
 
 extern void (*s5pc1xx_idle)(void);
 
index 796d242..ef69e56 100644 (file)
@@ -64,6 +64,22 @@ extern struct platform_device s3c_device_nand;
 extern struct platform_device s3c_device_usbgadget;
 extern struct platform_device s3c_device_usb_hsotg;
 
+extern struct platform_device s5pv210_device_ac97;
+extern struct platform_device s5pv210_device_pcm0;
+extern struct platform_device s5pv210_device_pcm1;
+extern struct platform_device s5pv210_device_pcm2;
+extern struct platform_device s5pv210_device_iis0;
+extern struct platform_device s5pv210_device_iis1;
+extern struct platform_device s5pv210_device_iis2;
+
+extern struct platform_device s5p6442_device_pcm0;
+extern struct platform_device s5p6442_device_pcm1;
+extern struct platform_device s5p6442_device_iis0;
+extern struct platform_device s5p6442_device_iis1;
+
+extern struct platform_device s5p6440_device_pcm;
+extern struct platform_device s5p6440_device_iis;
+
 /* s3c2440 specific devices */
 
 #ifdef CONFIG_CPU_S3C2440
index 7584d75..2e8f8c6 100644 (file)
@@ -110,8 +110,8 @@ extern int s3c2410_dma_config(unsigned int channel, int xferunit);
  * configure the device we're talking to
 */
 
-extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
-                                unsigned long devaddr);
+extern int s3c2410_dma_devconfig(unsigned int channel,
+               enum s3c2410_dmasrc source, unsigned long devaddr);
 
 /* s3c2410_dma_getposition
  *
index ffc01a7..1f85649 100644 (file)
 #ifndef __PLAT_S3C_FB_H
 #define __PLAT_S3C_FB_H __FILE__
 
+/* S3C_FB_MAX_WIN
+ * Set to the maximum number of windows that any of the supported hardware
+ * can use. Since the platform data uses this for an array size, having it
+ * set to the maximum of any version of the hardware can do is safe.
+ */
+#define S3C_FB_MAX_WIN (5)
+
 /**
  * struct s3c_fb_pd_win - per window setup data
  * @win_mode: The display parameters to initialise (not for window 0)
index dda19da..3e21c75 100644 (file)
@@ -30,6 +30,12 @@ static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
        return (chip->config->set_config)(chip, off, config);
 }
 
+static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
+                                         unsigned int off)
+{
+       return (chip->config->get_config)(chip, off);
+}
+
 static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
                                      unsigned int off, s3c_gpio_pull_t pull)
 {
@@ -52,6 +58,18 @@ static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
 extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
                                   unsigned int off, unsigned int cfg);
 
+/**
+ * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
+ * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+                                    unsigned int off);
+
 /**
  * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
  * @chip: The gpio chip that is being configured.
@@ -65,6 +83,21 @@ extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
 extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
                                     unsigned int off, unsigned int cfg);
 
+
+/**
+ * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ * @sa s3c_gpio_getcfg_s3c64xx_4bit
+ */
+extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+                                         unsigned int off);
+
 /**
  * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
  * @chip: The gpio chip that is being configured.
@@ -85,6 +118,20 @@ extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
                                        unsigned int off, unsigned int cfg);
 
 
+/**
+ * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to s3c_gpio_setcfg_s3c64xx_4bit().
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ */
+extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+                                            unsigned int off);
+
 /* Pull-{up,down} resistor controls.
  *
  * S3C2410,S3C2440,S3C24A0 = Pull-UP,
@@ -145,6 +192,17 @@ extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
 extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
                                               unsigned int off);
 
+/**
+ * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-up resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1up.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+                                           unsigned int off);
+
 /**
  * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
  * @chip: The gpio chip that is being configured.
index 29cd6a8..34efdd2 100644 (file)
@@ -25,6 +25,7 @@
 #define __PLAT_GPIO_CFG_H __FILE__
 
 typedef unsigned int __bitwise__ s3c_gpio_pull_t;
+typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
 
 /* forward declaration if gpio-core.h hasn't been included */
 struct s3c_gpio_chip;
@@ -77,6 +78,17 @@ struct s3c_gpio_cfg {
  */
 extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
 
+/**
+ * s3c_gpio_getcfg - Read the current function for a GPIO pin
+ * @pin: The pin to read the configuration value for.
+ *
+ * Read the configuration state of the given @pin, returning a value that
+ * could be passed back to s3c_gpio_cfgpin().
+ *
+ * @sa s3c_gpio_cfgpin
+ */
+extern unsigned s3c_gpio_getcfg(unsigned int pin);
+
 /* Define values for the pull-{up,down} available for each gpio pin.
  *
  * These values control the state of the weak pull-{up,down} resistors
@@ -107,4 +119,33 @@ extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
 */
 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.
+ */
+#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)
+
+/**
+ * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the driver streght value for the specified pin.
+*/
+extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
+
+/**
+ * s3c_gpio_set_drvstr() - set the driver streght value of a gpio pin
+ * @pin: The pin number to configure the driver streght value
+ * @drvstr: The new value of the driver strength
+ *
+ * This function sets the driver strength value for the specified pin.
+ * It will return 0 if successfull, or a negative error code if the pin
+ * cannot support the requested setting.
+*/
+extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+
 #endif /* __PLAT_GPIO_CFG_H */
index 49ff406..f3a68d1 100644 (file)
@@ -44,16 +44,26 @@ struct s3c_gpio_cfg;
  * @chip: The chip structure to be exported via gpiolib.
  * @base: The base pointer to the gpio configuration registers.
  * @config: special function and pull-resistor control information.
+ * @lock: Lock for exclusive access to this gpio bank.
  * @pm_save: Save information for suspend/resume support.
  *
  * This wrapper provides the necessary information for the Samsung
  * specific gpios being registered with gpiolib.
+ *
+ * The lock protects each gpio bank from multiple access of the shared
+ * configuration registers, or from reading of data whilst another thread
+ * is writing to the register set.
+ *
+ * Each chip has its own lock to avoid any  contention between different
+ * CPU cores trying to get one lock for different GPIO banks, where each
+ * bank of GPIO has its own register space and configuration registers.
  */
 struct s3c_gpio_chip {
        struct gpio_chip        chip;
        struct s3c_gpio_cfg     *config;
        struct s3c_gpio_pm      *pm;
        void __iomem            *base;
+       spinlock_t               lock;
 #ifdef CONFIG_PM
        u32                     pm_save[4];
 #endif
@@ -108,6 +118,9 @@ extern void samsung_gpiolib_add_4bit2_chips(struct s3c_gpio_chip *chip,
 extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
 extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
 
+/* exported for core SoC support to change */
+extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
+
 #ifdef CONFIG_S3C_GPIO_TRACK
 extern struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
 
@@ -135,3 +148,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
 #define __gpio_pm(x) NULL
 
 #endif /* CONFIG_PM */
+
+/* locking wrappers to deal with multiple access to the same gpio bank */
+#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
index 1ba88ea..c167e44 100644 (file)
@@ -37,5 +37,15 @@ struct s3c_hwmon_pdata {
        struct s3c_hwmon_chcfg  *in[8];
 };
 
+/**
+ * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use with the S3C HWMON device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd);
+
 #endif /* __ASM_ARCH_ADC_HWMON_H */
 
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644 (file)
index 0000000..b8b7e1d
--- /dev/null
@@ -0,0 +1,51 @@
+/* arch/arm/plat-samsung/include/plat/pll6553x.h
+ *     partially from arch/arm/mach-s3c64xx/include/mach/pll.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *     http://armlinux.simtec.co.uk/
+ *
+ * Samsung PLL6553x PLL 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.
+*/
+
+/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
+
+#define PLL6553X_MDIV_MASK     ((1 << (23-16)) - 1)
+#define PLL6553X_PDIV_MASK     ((1 << (13-8)) - 1)
+#define PLL6553X_SDIV_MASK     ((1 << (2-0)) - 1)
+#define PLL6553X_MDIV_SHIFT    (16)
+#define PLL6553X_PDIV_SHIFT    (8)
+#define PLL6553X_SDIV_SHIFT    (0)
+#define PLL6553X_KDIV_MASK     (0xffff)
+
+static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
+                                            u32 pll0, u32 pll1)
+{
+       unsigned long result;
+       u32 mdiv, pdiv, sdiv, kdiv;
+       u64 tmp;
+
+       mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
+       pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
+       sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
+       kdiv = pll1 & PLL6553X_KDIV_MASK;
+
+       /* We need to multiple baseclk by mdiv (the integer part) and kdiv
+        * which is in 2^16ths, so shift mdiv up (does not overflow) and
+        * add kdiv before multiplying. The use of tmp is to avoid any
+        * overflows before shifting bac down into result when multipling
+        * by the mdiv and kdiv pair.
+        */
+
+       tmp = baseclk;
+       tmp *= (mdiv << 16) + kdiv;
+       do_div(tmp, (pdiv << sdiv));
+       result = tmp >> 16;
+
+       return result;
+}
diff --git a/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
new file mode 100644 (file)
index 0000000..5fe6721
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef        __S3C_DMA_PL330_H_
+#define        __S3C_DMA_PL330_H_
+
+#define S3C2410_DMAF_AUTOSTART         (1 << 0)
+#define S3C2410_DMAF_CIRCULAR          (1 << 1)
+
+/*
+ * PL330 can assign any channel to communicate with
+ * any of the peripherals attched to the DMAC.
+ * For the sake of consistency across client drivers,
+ * We keep the channel names unchanged and only add
+ * missing peripherals are added.
+ * Order is not important since S3C PL330 API driver
+ * use these just as IDs.
+ */
+enum dma_ch {
+       DMACH_UART0_RX,
+       DMACH_UART0_TX,
+       DMACH_UART1_RX,
+       DMACH_UART1_TX,
+       DMACH_UART2_RX,
+       DMACH_UART2_TX,
+       DMACH_UART3_RX,
+       DMACH_UART3_TX,
+       DMACH_IRDA,
+       DMACH_I2S0_RX,
+       DMACH_I2S0_TX,
+       DMACH_I2S0S_TX,
+       DMACH_I2S1_RX,
+       DMACH_I2S1_TX,
+       DMACH_I2S2_RX,
+       DMACH_I2S2_TX,
+       DMACH_SPI0_RX,
+       DMACH_SPI0_TX,
+       DMACH_SPI1_RX,
+       DMACH_SPI1_TX,
+       DMACH_SPI2_RX,
+       DMACH_SPI2_TX,
+       DMACH_AC97_MICIN,
+       DMACH_AC97_PCMIN,
+       DMACH_AC97_PCMOUT,
+       DMACH_EXTERNAL,
+       DMACH_PWM,
+       DMACH_SPDIF,
+       DMACH_HSI_RX,
+       DMACH_HSI_TX,
+       DMACH_PCM0_TX,
+       DMACH_PCM0_RX,
+       DMACH_PCM1_TX,
+       DMACH_PCM1_RX,
+       DMACH_PCM2_TX,
+       DMACH_PCM2_RX,
+       DMACH_MSM_REQ3,
+       DMACH_MSM_REQ2,
+       DMACH_MSM_REQ1,
+       DMACH_MSM_REQ0,
+       /* END Marker, also used to denote a reserved channel */
+       DMACH_MAX,
+};
+
+static inline bool s3c_dma_has_circular(void)
+{
+       return true;
+}
+
+#include <plat/dma.h>
+
+#endif /* __S3C_DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
new file mode 100644 (file)
index 0000000..bf5e2a9
--- /dev/null
@@ -0,0 +1,32 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __S3C_PL330_PDATA_H
+#define __S3C_PL330_PDATA_H
+
+#include <plat/s3c-dma-pl330.h>
+
+/*
+ * Every PL330 DMAC has max 32 peripheral interfaces,
+ * of which some may be not be really used in your
+ * DMAC's configuration.
+ * Populate this array of 32 peri i/fs with relevant
+ * channel IDs for used peri i/f and DMACH_MAX for
+ * those unused.
+ *
+ * The platforms just need to provide this info
+ * to the S3C DMA API driver for PL330.
+ */
+struct s3c_pl330_platdata {
+       enum dma_ch peri[32];
+};
+
+#endif /* __S3C_PL330_PDATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h
new file mode 100644 (file)
index 0000000..26fdb22
--- /dev/null
@@ -0,0 +1,25 @@
+/* arch/arm/plat-samsung/include/plat/ts.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * 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_TS_H
+#define __ASM_ARM_TS_H
+
+struct s3c2410_ts_mach_info {
+       int             delay;
+       int             presc;
+       int             oversampling_shift;
+       void    (*cfg_gpio)(struct platform_device *dev);
+};
+
+extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+
+/* defined by architecture to configure gpio */
+extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
+
+#endif /* __ASM_ARM_TS_H */
index 69a4c7f..d50ab9d 100644 (file)
@@ -329,7 +329,7 @@ void s3c_pm_save_gpios(void)
        struct s3c_gpio_chip *ourchip;
        unsigned int gpio_nr;
 
-       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
                ourchip = s3c_gpiolib_getchip(gpio_nr);
                if (!ourchip)
                        continue;
@@ -367,7 +367,7 @@ void s3c_pm_restore_gpios(void)
        struct s3c_gpio_chip *ourchip;
        unsigned int gpio_nr;
 
-       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END; gpio_nr++) {
+       for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
                ourchip = s3c_gpiolib_getchip(gpio_nr);
                if (!ourchip)
                        continue;
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
new file mode 100644 (file)
index 0000000..a91305a
--- /dev/null
@@ -0,0 +1,1224 @@
+/* linux/arch/arm/plat-samsung/s3c-pl330.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/pl330.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+/**
+ * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
+ * @busy_chan: Number of channels currently busy.
+ * @peri: List of IDs of peripherals this DMAC can work with.
+ * @node: To attach to the global list of DMACs.
+ * @pi: PL330 configuration info for the DMAC.
+ * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
+ */
+struct s3c_pl330_dmac {
+       unsigned                busy_chan;
+       enum dma_ch             *peri;
+       struct list_head        node;
+       struct pl330_info       *pi;
+       struct kmem_cache       *kmcache;
+};
+
+/**
+ * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
+ * @token: Xfer ID provided by the client.
+ * @node: To attach to the list of xfers on a channel.
+ * @px: Xfer for PL330 core.
+ * @chan: Owner channel of this xfer.
+ */
+struct s3c_pl330_xfer {
+       void                    *token;
+       struct list_head        node;
+       struct pl330_xfer       px;
+       struct s3c_pl330_chan   *chan;
+};
+
+/**
+ * struct s3c_pl330_chan - Logical channel to communicate with
+ *     a Physical peripheral.
+ * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
+ *     NULL if the channel is available to be acquired.
+ * @id: ID of the peripheral that this channel can communicate with.
+ * @options: Options specified by the client.
+ * @sdaddr: Address provided via s3c2410_dma_devconfig.
+ * @node: To attach to the global list of channels.
+ * @lrq: Pointer to the last submitted pl330_req to PL330 core.
+ * @xfer_list: To manage list of xfers enqueued.
+ * @req: Two requests to communicate with the PL330 engine.
+ * @callback_fn: Callback function to the client.
+ * @rqcfg: Channel configuration for the xfers.
+ * @xfer_head: Pointer to the xfer to be next excecuted.
+ * @dmac: Pointer to the DMAC that manages this channel, NULL if the
+ *     channel is available to be acquired.
+ * @client: Client of this channel. NULL if the
+ *     channel is available to be acquired.
+ */
+struct s3c_pl330_chan {
+       void                            *pl330_chan_id;
+       enum dma_ch                     id;
+       unsigned int                    options;
+       unsigned long                   sdaddr;
+       struct list_head                node;
+       struct pl330_req                *lrq;
+       struct list_head                xfer_list;
+       struct pl330_req                req[2];
+       s3c2410_dma_cbfn_t              callback_fn;
+       struct pl330_reqcfg             rqcfg;
+       struct s3c_pl330_xfer           *xfer_head;
+       struct s3c_pl330_dmac           *dmac;
+       struct s3c2410_dma_client       *client;
+};
+
+/* All DMACs in the platform */
+static LIST_HEAD(dmac_list);
+
+/* All channels to peripherals in the platform */
+static LIST_HEAD(chan_list);
+
+/*
+ * Since we add resources(DMACs and Channels) to the global pool,
+ * we need to guard access to the resources using a global lock
+ */
+static DEFINE_SPINLOCK(res_lock);
+
+/* Returns the channel with ID 'id' in the chan_list */
+static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
+{
+       struct s3c_pl330_chan *ch;
+
+       list_for_each_entry(ch, &chan_list, node)
+               if (ch->id == id)
+                       return ch;
+
+       return NULL;
+}
+
+/* Allocate a new channel with ID 'id' and add to chan_list */
+static void chan_add(const enum dma_ch id)
+{
+       struct s3c_pl330_chan *ch = id_to_chan(id);
+
+       /* Return if the channel already exists */
+       if (ch)
+               return;
+
+       ch = kmalloc(sizeof(*ch), GFP_KERNEL);
+       /* Return silently to work with other channels */
+       if (!ch)
+               return;
+
+       ch->id = id;
+       ch->dmac = NULL;
+
+       list_add_tail(&ch->node, &chan_list);
+}
+
+/* If the channel is not yet acquired by any client */
+static bool chan_free(struct s3c_pl330_chan *ch)
+{
+       if (!ch)
+               return false;
+
+       /* Channel points to some DMAC only when it's acquired */
+       return ch->dmac ? false : true;
+}
+
+/*
+ * Returns 0 is peripheral i/f is invalid or not present on the dmac.
+ * Index + 1, otherwise.
+ */
+static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
+{
+       enum dma_ch *id = dmac->peri;
+       int i;
+
+       /* Discount invalid markers */
+       if (ch_id == DMACH_MAX)
+               return 0;
+
+       for (i = 0; i < PL330_MAX_PERI; i++)
+               if (id[i] == ch_id)
+                       return i + 1;
+
+       return 0;
+}
+
+/* If all channel threads of the DMAC are busy */
+static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
+{
+       struct pl330_info *pi = dmac->pi;
+
+       return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
+}
+
+/*
+ * Returns the number of free channels that
+ * can be handled by this dmac only.
+ */
+static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
+{
+       enum dma_ch *id = dmac->peri;
+       struct s3c_pl330_dmac *d;
+       struct s3c_pl330_chan *ch;
+       unsigned found, count = 0;
+       enum dma_ch p;
+       int i;
+
+       for (i = 0; i < PL330_MAX_PERI; i++) {
+               p = id[i];
+               ch = id_to_chan(p);
+
+               if (p == DMACH_MAX || !chan_free(ch))
+                       continue;
+
+               found = 0;
+               list_for_each_entry(d, &dmac_list, node) {
+                       if (d != dmac && iface_of_dmac(d, ch->id)) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (!found)
+                       count++;
+       }
+
+       return count;
+}
+
+/*
+ * Measure of suitability of 'dmac' handling 'ch'
+ *
+ * 0 indicates 'dmac' can not handle 'ch' either
+ * because it is not supported by the hardware or
+ * because all dmac channels are currently busy.
+ *
+ * >0 vlaue indicates 'dmac' has the capability.
+ * The bigger the value the more suitable the dmac.
+ */
+#define MAX_SUIT       UINT_MAX
+#define MIN_SUIT       0
+
+static unsigned suitablility(struct s3c_pl330_dmac *dmac,
+               struct s3c_pl330_chan *ch)
+{
+       struct pl330_info *pi = dmac->pi;
+       enum dma_ch *id = dmac->peri;
+       struct s3c_pl330_dmac *d;
+       unsigned s;
+       int i;
+
+       s = MIN_SUIT;
+       /* If all the DMAC channel threads are busy */
+       if (dmac_busy(dmac))
+               return s;
+
+       for (i = 0; i < PL330_MAX_PERI; i++)
+               if (id[i] == ch->id)
+                       break;
+
+       /* If the 'dmac' can't talk to 'ch' */
+       if (i == PL330_MAX_PERI)
+               return s;
+
+       s = MAX_SUIT;
+       list_for_each_entry(d, &dmac_list, node) {
+               /*
+                * If some other dmac can talk to this
+                * peri and has some channel free.
+                */
+               if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
+                       s = 0;
+                       break;
+               }
+       }
+       if (s)
+               return s;
+
+       s = 100;
+
+       /* Good if free chans are more, bad otherwise */
+       s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
+
+       return s;
+}
+
+/* More than one DMAC may have capability to transfer data with the
+ * peripheral. This function assigns most suitable DMAC to manage the
+ * channel and hence communicate with the peripheral.
+ */
+static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
+{
+       struct s3c_pl330_dmac *d, *dmac = NULL;
+       unsigned sn, sl = MIN_SUIT;
+
+       list_for_each_entry(d, &dmac_list, node) {
+               sn = suitablility(d, ch);
+
+               if (sn == MAX_SUIT)
+                       return d;
+
+               if (sn > sl)
+                       dmac = d;
+       }
+
+       return dmac;
+}
+
+/* Acquire the channel for peripheral 'id' */
+static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
+{
+       struct s3c_pl330_chan *ch = id_to_chan(id);
+       struct s3c_pl330_dmac *dmac;
+
+       /* If the channel doesn't exist or is already acquired */
+       if (!ch || !chan_free(ch)) {
+               ch = NULL;
+               goto acq_exit;
+       }
+
+       dmac = map_chan_to_dmac(ch);
+       /* If couldn't map */
+       if (!dmac) {
+               ch = NULL;
+               goto acq_exit;
+       }
+
+       dmac->busy_chan++;
+       ch->dmac = dmac;
+
+acq_exit:
+       return ch;
+}
+
+/* Delete xfer from the queue */
+static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
+{
+       struct s3c_pl330_xfer *t;
+       struct s3c_pl330_chan *ch;
+       int found;
+
+       if (!xfer)
+               return;
+
+       ch = xfer->chan;
+
+       /* Make sure xfer is in the queue */
+       found = 0;
+       list_for_each_entry(t, &ch->xfer_list, node)
+               if (t == xfer) {
+                       found = 1;
+                       break;
+               }
+
+       if (!found)
+               return;
+
+       /* If xfer is last entry in the queue */
+       if (xfer->node.next == &ch->xfer_list)
+               t = list_entry(ch->xfer_list.next,
+                               struct s3c_pl330_xfer, node);
+       else
+               t = list_entry(xfer->node.next,
+                               struct s3c_pl330_xfer, node);
+
+       /* If there was only one node left */
+       if (t == xfer)
+               ch->xfer_head = NULL;
+       else if (ch->xfer_head == xfer)
+               ch->xfer_head = t;
+
+       list_del(&xfer->node);
+}
+
+/* Provides pointer to the next xfer in the queue.
+ * If CIRCULAR option is set, the list is left intact,
+ * otherwise the xfer is removed from the list.
+ * Forced delete 'pluck' can be set to override the CIRCULAR option.
+ */
+static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
+               int pluck)
+{
+       struct s3c_pl330_xfer *xfer = ch->xfer_head;
+
+       if (!xfer)
+               return NULL;
+
+       /* If xfer is last entry in the queue */
+       if (xfer->node.next == &ch->xfer_list)
+               ch->xfer_head = list_entry(ch->xfer_list.next,
+                                       struct s3c_pl330_xfer, node);
+       else
+               ch->xfer_head = list_entry(xfer->node.next,
+                                       struct s3c_pl330_xfer, node);
+
+       if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
+               del_from_queue(xfer);
+
+       return xfer;
+}
+
+static inline void add_to_queue(struct s3c_pl330_chan *ch,
+               struct s3c_pl330_xfer *xfer, int front)
+{
+       struct pl330_xfer *xt;
+
+       /* If queue empty */
+       if (ch->xfer_head == NULL)
+               ch->xfer_head = xfer;
+
+       xt = &ch->xfer_head->px;
+       /* If the head already submitted (CIRCULAR head) */
+       if (ch->options & S3C2410_DMAF_CIRCULAR &&
+               (xt == ch->req[0].x || xt == ch->req[1].x))
+               ch->xfer_head = xfer;
+
+       /* If this is a resubmission, it should go at the head */
+       if (front) {
+               ch->xfer_head = xfer;
+               list_add(&xfer->node, &ch->xfer_list);
+       } else {
+               list_add_tail(&xfer->node, &ch->xfer_list);
+       }
+}
+
+static inline void _finish_off(struct s3c_pl330_xfer *xfer,
+               enum s3c2410_dma_buffresult res, int ffree)
+{
+       struct s3c_pl330_chan *ch;
+
+       if (!xfer)
+               return;
+
+       ch = xfer->chan;
+
+       /* Do callback */
+       if (ch->callback_fn)
+               ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
+
+       /* Force Free or if buffer is not needed anymore */
+       if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
+               kmem_cache_free(ch->dmac->kmcache, xfer);
+}
+
+static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
+               struct pl330_req *r)
+{
+       struct s3c_pl330_xfer *xfer;
+       int ret = 0;
+
+       /* If already submitted */
+       if (r->x)
+               return 0;
+
+       xfer = get_from_queue(ch, 0);
+       if (xfer) {
+               r->x = &xfer->px;
+
+               /* Use max bandwidth for M<->M xfers */
+               if (r->rqtype == MEMTOMEM) {
+                       struct pl330_info *pi = xfer->chan->dmac->pi;
+                       int burst = 1 << ch->rqcfg.brst_size;
+                       u32 bytes = r->x->bytes;
+                       int bl;
+
+                       bl = pi->pcfg.data_bus_width / 8;
+                       bl *= pi->pcfg.data_buf_dep;
+                       bl /= burst;
+
+                       /* src/dst_burst_len can't be more than 16 */
+                       if (bl > 16)
+                               bl = 16;
+
+                       while (bl > 1) {
+                               if (!(bytes % (bl * burst)))
+                                       break;
+                               bl--;
+                       }
+
+                       ch->rqcfg.brst_len = bl;
+               } else {
+                       ch->rqcfg.brst_len = 1;
+               }
+
+               ret = pl330_submit_req(ch->pl330_chan_id, r);
+
+               /* If submission was successful */
+               if (!ret) {
+                       ch->lrq = r; /* latest submitted req */
+                       return 0;
+               }
+
+               r->x = NULL;
+
+               /* If both of the PL330 ping-pong buffers filled */
+               if (ret == -EAGAIN) {
+                       dev_err(ch->dmac->pi->dev, "%s:%d!\n",
+                               __func__, __LINE__);
+                       /* Queue back again */
+                       add_to_queue(ch, xfer, 1);
+                       ret = 0;
+               } else {
+                       dev_err(ch->dmac->pi->dev, "%s:%d!\n",
+                               __func__, __LINE__);
+                       _finish_off(xfer, S3C2410_RES_ERR, 0);
+               }
+       }
+
+       return ret;
+}
+
+static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
+       struct pl330_req *r, enum pl330_op_err err)
+{
+       unsigned long flags;
+       struct s3c_pl330_xfer *xfer;
+       struct pl330_xfer *xl = r->x;
+       enum s3c2410_dma_buffresult res;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       r->x = NULL;
+
+       s3c_pl330_submit(ch, r);
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       /* Map result to S3C DMA API */
+       if (err == PL330_ERR_NONE)
+               res = S3C2410_RES_OK;
+       else if (err == PL330_ERR_ABORT)
+               res = S3C2410_RES_ABORT;
+       else
+               res = S3C2410_RES_ERR;
+
+       /* If last request had some xfer */
+       if (xl) {
+               xfer = container_of(xl, struct s3c_pl330_xfer, px);
+               _finish_off(xfer, res, 0);
+       } else {
+               dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
+                       __func__, __LINE__);
+       }
+}
+
+static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
+{
+       struct pl330_req *r = token;
+       struct s3c_pl330_chan *ch = container_of(r,
+                                       struct s3c_pl330_chan, req[0]);
+       s3c_pl330_rq(ch, r, err);
+}
+
+static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
+{
+       struct pl330_req *r = token;
+       struct s3c_pl330_chan *ch = container_of(r,
+                                       struct s3c_pl330_chan, req[1]);
+       s3c_pl330_rq(ch, r, err);
+}
+
+/* Release an acquired channel */
+static void chan_release(struct s3c_pl330_chan *ch)
+{
+       struct s3c_pl330_dmac *dmac;
+
+       if (chan_free(ch))
+               return;
+
+       dmac = ch->dmac;
+       ch->dmac = NULL;
+       dmac->busy_chan--;
+}
+
+int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
+{
+       struct s3c_pl330_xfer *xfer;
+       enum pl330_chan_op pl330op;
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int idx, ret;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto ctrl_exit;
+       }
+
+       switch (op) {
+       case S3C2410_DMAOP_START:
+               /* Make sure both reqs are enqueued */
+               idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+               s3c_pl330_submit(ch, &ch->req[idx]);
+               s3c_pl330_submit(ch, &ch->req[1 - idx]);
+               pl330op = PL330_OP_START;
+               break;
+
+       case S3C2410_DMAOP_STOP:
+               pl330op = PL330_OP_ABORT;
+               break;
+
+       case S3C2410_DMAOP_FLUSH:
+               pl330op = PL330_OP_FLUSH;
+               break;
+
+       case S3C2410_DMAOP_PAUSE:
+       case S3C2410_DMAOP_RESUME:
+       case S3C2410_DMAOP_TIMEOUT:
+       case S3C2410_DMAOP_STARTED:
+               spin_unlock_irqrestore(&res_lock, flags);
+               return 0;
+
+       default:
+               spin_unlock_irqrestore(&res_lock, flags);
+               return -EINVAL;
+       }
+
+       ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
+
+       if (pl330op == PL330_OP_START) {
+               spin_unlock_irqrestore(&res_lock, flags);
+               return ret;
+       }
+
+       idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+       /* Abort the current xfer */
+       if (ch->req[idx].x) {
+               xfer = container_of(ch->req[idx].x,
+                               struct s3c_pl330_xfer, px);
+
+               /* Drop xfer during FLUSH */
+               if (pl330op == PL330_OP_FLUSH)
+                       del_from_queue(xfer);
+
+               ch->req[idx].x = NULL;
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT,
+                               pl330op == PL330_OP_FLUSH ? 1 : 0);
+               spin_lock_irqsave(&res_lock, flags);
+       }
+
+       /* Flush the whole queue */
+       if (pl330op == PL330_OP_FLUSH) {
+
+               if (ch->req[1 - idx].x) {
+                       xfer = container_of(ch->req[1 - idx].x,
+                                       struct s3c_pl330_xfer, px);
+
+                       del_from_queue(xfer);
+
+                       ch->req[1 - idx].x = NULL;
+
+                       spin_unlock_irqrestore(&res_lock, flags);
+                       _finish_off(xfer, S3C2410_RES_ABORT, 1);
+                       spin_lock_irqsave(&res_lock, flags);
+               }
+
+               /* Finish off the remaining in the queue */
+               xfer = ch->xfer_head;
+               while (xfer) {
+
+                       del_from_queue(xfer);
+
+                       spin_unlock_irqrestore(&res_lock, flags);
+                       _finish_off(xfer, S3C2410_RES_ABORT, 1);
+                       spin_lock_irqsave(&res_lock, flags);
+
+                       xfer = ch->xfer_head;
+               }
+       }
+
+ctrl_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+int s3c2410_dma_enqueue(enum dma_ch id, void *token,
+                       dma_addr_t addr, int size)
+{
+       struct s3c_pl330_chan *ch;
+       struct s3c_pl330_xfer *xfer;
+       unsigned long flags;
+       int idx, ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       /* Error if invalid or free channel */
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto enq_exit;
+       }
+
+       /* Error if size is unaligned */
+       if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
+               ret = -EINVAL;
+               goto enq_exit;
+       }
+
+       xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
+       if (!xfer) {
+               ret = -ENOMEM;
+               goto enq_exit;
+       }
+
+       xfer->token = token;
+       xfer->chan = ch;
+       xfer->px.bytes = size;
+       xfer->px.next = NULL; /* Single request */
+
+       /* For S3C DMA API, direction is always fixed for all xfers */
+       if (ch->req[0].rqtype == MEMTODEV) {
+               xfer->px.src_addr = addr;
+               xfer->px.dst_addr = ch->sdaddr;
+       } else {
+               xfer->px.src_addr = ch->sdaddr;
+               xfer->px.dst_addr = addr;
+       }
+
+       add_to_queue(ch, xfer, 0);
+
+       /* Try submitting on either request */
+       idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+       if (!ch->req[idx].x)
+               s3c_pl330_submit(ch, &ch->req[idx]);
+       else
+               s3c_pl330_submit(ch, &ch->req[1 - idx]);
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       if (ch->options & S3C2410_DMAF_AUTOSTART)
+               s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
+
+       return 0;
+
+enq_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+int s3c2410_dma_request(enum dma_ch id,
+                       struct s3c2410_dma_client *client,
+                       void *dev)
+{
+       struct s3c_pl330_dmac *dmac;
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = chan_acquire(id);
+       if (!ch) {
+               ret = -EBUSY;
+               goto req_exit;
+       }
+
+       dmac = ch->dmac;
+
+       ch->pl330_chan_id = pl330_request_channel(dmac->pi);
+       if (!ch->pl330_chan_id) {
+               chan_release(ch);
+               ret = -EBUSY;
+               goto req_exit;
+       }
+
+       ch->client = client;
+       ch->options = 0; /* Clear any option */
+       ch->callback_fn = NULL; /* Clear any callback */
+       ch->lrq = NULL;
+
+       ch->rqcfg.brst_size = 2; /* Default word size */
+       ch->rqcfg.swap = SWAP_NO;
+       ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
+       ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
+       ch->rqcfg.privileged = 0;
+       ch->rqcfg.insnaccess = 0;
+
+       /* Set invalid direction */
+       ch->req[0].rqtype = DEVTODEV;
+       ch->req[1].rqtype = ch->req[0].rqtype;
+
+       ch->req[0].cfg = &ch->rqcfg;
+       ch->req[1].cfg = ch->req[0].cfg;
+
+       ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
+       ch->req[1].peri = ch->req[0].peri;
+
+       ch->req[0].token = &ch->req[0];
+       ch->req[0].xfer_cb = s3c_pl330_rq0;
+       ch->req[1].token = &ch->req[1];
+       ch->req[1].xfer_cb = s3c_pl330_rq1;
+
+       ch->req[0].x = NULL;
+       ch->req[1].x = NULL;
+
+       /* Reset xfer list */
+       INIT_LIST_HEAD(&ch->xfer_list);
+       ch->xfer_head = NULL;
+
+req_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
+{
+       struct s3c_pl330_chan *ch;
+       struct s3c_pl330_xfer *xfer;
+       unsigned long flags;
+       int ret = 0;
+       unsigned idx;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch))
+               goto free_exit;
+
+       /* Refuse if someone else wanted to free the channel */
+       if (ch->client != client) {
+               ret = -EBUSY;
+               goto free_exit;
+       }
+
+       /* Stop any active xfer, Flushe the queue and do callbacks */
+       pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
+
+       /* Abort the submitted requests */
+       idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+       if (ch->req[idx].x) {
+               xfer = container_of(ch->req[idx].x,
+                               struct s3c_pl330_xfer, px);
+
+               ch->req[idx].x = NULL;
+               del_from_queue(xfer);
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT, 1);
+               spin_lock_irqsave(&res_lock, flags);
+       }
+
+       if (ch->req[1 - idx].x) {
+               xfer = container_of(ch->req[1 - idx].x,
+                               struct s3c_pl330_xfer, px);
+
+               ch->req[1 - idx].x = NULL;
+               del_from_queue(xfer);
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT, 1);
+               spin_lock_irqsave(&res_lock, flags);
+       }
+
+       /* Pluck and Abort the queued requests in order */
+       do {
+               xfer = get_from_queue(ch, 1);
+
+               spin_unlock_irqrestore(&res_lock, flags);
+               _finish_off(xfer, S3C2410_RES_ABORT, 1);
+               spin_lock_irqsave(&res_lock, flags);
+       } while (xfer);
+
+       ch->client = NULL;
+
+       pl330_release_channel(ch->pl330_chan_id);
+
+       ch->pl330_chan_id = NULL;
+
+       chan_release(ch);
+
+free_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+int s3c2410_dma_config(enum dma_ch id, int xferunit)
+{
+       struct s3c_pl330_chan *ch;
+       struct pl330_info *pi;
+       unsigned long flags;
+       int i, dbwidth, ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto cfg_exit;
+       }
+
+       pi = ch->dmac->pi;
+       dbwidth = pi->pcfg.data_bus_width / 8;
+
+       /* Max size of xfer can be pcfg.data_bus_width */
+       if (xferunit > dbwidth) {
+               ret = -EINVAL;
+               goto cfg_exit;
+       }
+
+       i = 0;
+       while (xferunit != (1 << i))
+               i++;
+
+       /* If valid value */
+       if (xferunit == (1 << i))
+               ch->rqcfg.brst_size = i;
+       else
+               ret = -EINVAL;
+
+cfg_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+/* Options that are supported by this driver */
+#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
+
+int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
+{
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
+               ret = -EINVAL;
+       else
+               ch->options = options;
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_setflags);
+
+int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
+{
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch))
+               ret = -EINVAL;
+       else
+               ch->callback_fn = rtn;
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
+                         unsigned long address)
+{
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       ch = id_to_chan(id);
+
+       if (!ch || chan_free(ch)) {
+               ret = -EINVAL;
+               goto devcfg_exit;
+       }
+
+       switch (source) {
+       case S3C2410_DMASRC_HW: /* P->M */
+               ch->req[0].rqtype = DEVTOMEM;
+               ch->req[1].rqtype = DEVTOMEM;
+               ch->rqcfg.src_inc = 0;
+               ch->rqcfg.dst_inc = 1;
+               break;
+       case S3C2410_DMASRC_MEM: /* M->P */
+               ch->req[0].rqtype = MEMTODEV;
+               ch->req[1].rqtype = MEMTODEV;
+               ch->rqcfg.src_inc = 1;
+               ch->rqcfg.dst_inc = 0;
+               break;
+       default:
+               ret = -EINVAL;
+               goto devcfg_exit;
+       }
+
+       ch->sdaddr = address;
+
+devcfg_exit:
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
+{
+       struct s3c_pl330_chan *ch = id_to_chan(id);
+       struct pl330_chanstatus status;
+       int ret;
+
+       if (!ch || chan_free(ch))
+               return -EINVAL;
+
+       ret = pl330_chan_status(ch->pl330_chan_id, &status);
+       if (ret < 0)
+               return ret;
+
+       *src = status.src_addr;
+       *dst = status.dst_addr;
+
+       return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+static irqreturn_t pl330_irq_handler(int irq, void *data)
+{
+       if (pl330_update(data))
+               return IRQ_HANDLED;
+       else
+               return IRQ_NONE;
+}
+
+static int pl330_probe(struct platform_device *pdev)
+{
+       struct s3c_pl330_dmac *s3c_pl330_dmac;
+       struct s3c_pl330_platdata *pl330pd;
+       struct pl330_info *pl330_info;
+       struct resource *res;
+       int i, ret, irq;
+
+       pl330pd = pdev->dev.platform_data;
+
+       /* Can't do without the list of _32_ peripherals */
+       if (!pl330pd || !pl330pd->peri) {
+               dev_err(&pdev->dev, "platform data missing!\n");
+               return -ENODEV;
+       }
+
+       pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
+       if (!pl330_info)
+               return -ENOMEM;
+
+       pl330_info->pl330_data = NULL;
+       pl330_info->dev = &pdev->dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               ret = -ENODEV;
+               goto probe_err1;
+       }
+
+       request_mem_region(res->start, resource_size(res), pdev->name);
+
+       pl330_info->base = ioremap(res->start, resource_size(res));
+       if (!pl330_info->base) {
+               ret = -ENXIO;
+               goto probe_err2;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+               goto probe_err3;
+       }
+
+       ret = request_irq(irq, pl330_irq_handler, 0,
+                       dev_name(&pdev->dev), pl330_info);
+       if (ret)
+               goto probe_err4;
+
+       ret = pl330_add(pl330_info);
+       if (ret)
+               goto probe_err5;
+
+       /* Allocate a new DMAC */
+       s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
+       if (!s3c_pl330_dmac) {
+               ret = -ENOMEM;
+               goto probe_err6;
+       }
+
+       /* Hook the info */
+       s3c_pl330_dmac->pi = pl330_info;
+
+       /* No busy channels */
+       s3c_pl330_dmac->busy_chan = 0;
+
+       s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
+                               sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
+
+       if (!s3c_pl330_dmac->kmcache) {
+               ret = -ENOMEM;
+               goto probe_err7;
+       }
+
+       /* Get the list of peripherals */
+       s3c_pl330_dmac->peri = pl330pd->peri;
+
+       /* Attach to the list of DMACs */
+       list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
+
+       /* Create a channel for each peripheral in the DMAC
+        * that is, if it doesn't already exist
+        */
+       for (i = 0; i < PL330_MAX_PERI; i++)
+               if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
+                       chan_add(s3c_pl330_dmac->peri[i]);
+
+       printk(KERN_INFO
+               "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
+       printk(KERN_INFO
+               "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
+               pl330_info->pcfg.data_buf_dep,
+               pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
+               pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
+
+       return 0;
+
+probe_err7:
+       kfree(s3c_pl330_dmac);
+probe_err6:
+       pl330_del(pl330_info);
+probe_err5:
+       free_irq(irq, pl330_info);
+probe_err4:
+probe_err3:
+       iounmap(pl330_info->base);
+probe_err2:
+       release_mem_region(res->start, resource_size(res));
+probe_err1:
+       kfree(pl330_info);
+
+       return ret;
+}
+
+static int pl330_remove(struct platform_device *pdev)
+{
+       struct s3c_pl330_dmac *dmac, *d;
+       struct s3c_pl330_chan *ch;
+       unsigned long flags;
+       int del, found;
+
+       if (!pdev->dev.platform_data)
+               return -EINVAL;
+
+       spin_lock_irqsave(&res_lock, flags);
+
+       found = 0;
+       list_for_each_entry(d, &dmac_list, node)
+               if (d->pi->dev == &pdev->dev) {
+                       found = 1;
+                       break;
+               }
+
+       if (!found) {
+               spin_unlock_irqrestore(&res_lock, flags);
+               return 0;
+       }
+
+       dmac = d;
+
+       /* Remove all Channels that are managed only by this DMAC */
+       list_for_each_entry(ch, &chan_list, node) {
+
+               /* Only channels that are handled by this DMAC */
+               if (iface_of_dmac(dmac, ch->id))
+                       del = 1;
+               else
+                       continue;
+
+               /* Don't remove if some other DMAC has it too */
+               list_for_each_entry(d, &dmac_list, node)
+                       if (d != dmac && iface_of_dmac(d, ch->id)) {
+                               del = 0;
+                               break;
+                       }
+
+               if (del) {
+                       spin_unlock_irqrestore(&res_lock, flags);
+                       s3c2410_dma_free(ch->id, ch->client);
+                       spin_lock_irqsave(&res_lock, flags);
+                       list_del(&ch->node);
+                       kfree(ch);
+               }
+       }
+
+       /* Remove the DMAC */
+       list_del(&dmac->node);
+       kfree(dmac);
+
+       spin_unlock_irqrestore(&res_lock, flags);
+
+       return 0;
+}
+
+static struct platform_driver pl330_driver = {
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "s3c-pl330",
+       },
+       .probe          = pl330_probe,
+       .remove         = pl330_remove,
+};
+
+static int __init pl330_init(void)
+{
+       return platform_driver_register(&pl330_driver);
+}
+module_init(pl330_init);
+
+static void __exit pl330_exit(void)
+{
+       platform_driver_unregister(&pl330_driver);
+       return;
+}
+module_exit(pl330_exit);
+
+MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
new file mode 100644 (file)
index 0000000..1bb3dbc
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# SPEAr Platform configuration file
+#
+
+if PLAT_SPEAR
+
+choice
+       prompt "ST SPEAr Family"
+       default ARCH_SPEAR3XX
+
+config ARCH_SPEAR3XX
+       bool "SPEAr3XX"
+       select ARM_VIC
+       select CPU_ARM926T
+       help
+         Supports for ARM's SPEAR3XX family
+
+config ARCH_SPEAR6XX
+       bool "SPEAr6XX"
+       select ARM_VIC
+       select CPU_ARM926T
+       help
+         Supports for ARM's SPEAR6XX family
+
+endchoice
+
+# Adding SPEAr machine specific configuration files
+source "arch/arm/mach-spear3xx/Kconfig"
+source "arch/arm/mach-spear6xx/Kconfig"
+
+endif
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
new file mode 100644 (file)
index 0000000..eb89540
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# SPEAr Platform specific Makefile
+#
+
+# Common support
+obj-y  := clock.o padmux.o time.o
+
+obj-$(CONFIG_ARCH_SPEAR3XX)    += shirq.o
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
new file mode 100644 (file)
index 0000000..ee4f90e
--- /dev/null
@@ -0,0 +1,435 @@
+/*
+ * arch/arm/plat-spear/clock.c
+ *
+ * Clock framework for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <mach/misc_regs.h>
+#include <plat/clock.h>
+
+static DEFINE_SPINLOCK(clocks_lock);
+static LIST_HEAD(root_clks);
+
+static void propagate_rate(struct list_head *);
+
+static int generic_clk_enable(struct clk *clk)
+{
+       unsigned int val;
+
+       if (!clk->en_reg)
+               return -EFAULT;
+
+       val = readl(clk->en_reg);
+       if (unlikely(clk->flags & RESET_TO_ENABLE))
+               val &= ~(1 << clk->en_reg_bit);
+       else
+               val |= 1 << clk->en_reg_bit;
+
+       writel(val, clk->en_reg);
+
+       return 0;
+}
+
+static void generic_clk_disable(struct clk *clk)
+{
+       unsigned int val;
+
+       if (!clk->en_reg)
+               return;
+
+       val = readl(clk->en_reg);
+       if (unlikely(clk->flags & RESET_TO_ENABLE))
+               val |= 1 << clk->en_reg_bit;
+       else
+               val &= ~(1 << clk->en_reg_bit);
+
+       writel(val, clk->en_reg);
+}
+
+/* generic clk ops */
+static struct clkops generic_clkops = {
+       .enable = generic_clk_enable,
+       .disable = generic_clk_disable,
+};
+
+/*
+ * clk_enable - inform the system when the clock source should be running.
+ * @clk: clock source
+ *
+ * If the clock can not be enabled/disabled, this should return success.
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       if (!clk || IS_ERR(clk))
+               return -EFAULT;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (clk->usage_count == 0) {
+               if (clk->ops && clk->ops->enable)
+                       ret = clk->ops->enable(clk);
+       }
+       clk->usage_count++;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/*
+ * clk_disable - inform the system when the clock source is no longer required.
+ * @clk: clock source
+ *
+ * Inform the system that a clock source is no longer required by
+ * a driver and may be shut down.
+ *
+ * Implementation detail: if the clock source is shared between
+ * multiple drivers, clk_enable() calls must be balanced by the
+ * same number of clk_disable() calls for the clock source to be
+ * disabled.
+ */
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (!clk || IS_ERR(clk))
+               return;
+
+       WARN_ON(clk->usage_count == 0);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       clk->usage_count--;
+       if (clk->usage_count == 0) {
+               if (clk->ops && clk->ops->disable)
+                       clk->ops->disable(clk);
+       }
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/**
+ * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
+ *              This is only valid once the clock source has been enabled.
+ * @clk: clock source
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+       unsigned long flags, rate;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       rate = clk->rate;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/**
+ * clk_set_parent - set the parent clock source for this clock
+ * @clk: clock source
+ * @parent: parent clock source
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       int i, found = 0, val = 0;
+       unsigned long flags;
+
+       if (!clk || IS_ERR(clk) || !parent || IS_ERR(parent))
+               return -EFAULT;
+       if (clk->usage_count)
+               return -EBUSY;
+       if (!clk->pclk_sel)
+               return -EPERM;
+       if (clk->pclk == parent)
+               return 0;
+
+       for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+               if (clk->pclk_sel->pclk_info[i].pclk == parent) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (!found)
+               return -EINVAL;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       /* reflect parent change in hardware */
+       val = readl(clk->pclk_sel->pclk_sel_reg);
+       val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
+       val |= clk->pclk_sel->pclk_info[i].pclk_mask << clk->pclk_sel_shift;
+       writel(val, clk->pclk_sel->pclk_sel_reg);
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       /* reflect parent change in software */
+       clk->recalc(clk);
+       propagate_rate(&clk->children);
+       return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* registers clock in platform clock framework */
+void clk_register(struct clk_lookup *cl)
+{
+       struct clk *clk = cl->clk;
+       unsigned long flags;
+
+       if (!clk || IS_ERR(clk))
+               return;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+
+       INIT_LIST_HEAD(&clk->children);
+       if (clk->flags & ALWAYS_ENABLED)
+               clk->ops = NULL;
+       else if (!clk->ops)
+               clk->ops = &generic_clkops;
+
+       /* root clock don't have any parents */
+       if (!clk->pclk && !clk->pclk_sel) {
+               list_add(&clk->sibling, &root_clks);
+               /* add clocks with only one parent to parent's children list */
+       } else if (clk->pclk && !clk->pclk_sel) {
+               list_add(&clk->sibling, &clk->pclk->children);
+       } else {
+               /* add clocks with > 1 parent to 1st parent's children list */
+               list_add(&clk->sibling,
+                        &clk->pclk_sel->pclk_info[0].pclk->children);
+       }
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       /* add clock to arm clockdev framework */
+       clkdev_add(cl);
+}
+
+/**
+ * propagate_rate - recalculate and propagate all clocks in list head
+ *
+ * Recalculates all root clocks in list head, which if the clock's .recalc is
+ * set correctly, should also propagate their rates.
+ */
+static void propagate_rate(struct list_head *lhead)
+{
+       struct clk *clkp, *_temp;
+
+       list_for_each_entry_safe(clkp, _temp, lhead, sibling) {
+               if (clkp->recalc)
+                       clkp->recalc(clkp);
+               propagate_rate(&clkp->children);
+       }
+}
+
+/* returns current programmed clocks clock info structure */
+static struct pclk_info *pclk_info_get(struct clk *clk)
+{
+       unsigned int mask, i;
+       unsigned long flags;
+       struct pclk_info *info = NULL;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       mask = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
+                       & clk->pclk_sel->pclk_sel_mask;
+
+       for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+               if (clk->pclk_sel->pclk_info[i].pclk_mask == mask)
+                       info = &clk->pclk_sel->pclk_info[i];
+       }
+       spin_unlock_irqrestore(&clocks_lock, flags);
+
+       return info;
+}
+
+/*
+ * Set pclk as cclk's parent and add clock sibling node to current parents
+ * children list
+ */
+static void change_parent(struct clk *cclk, struct clk *pclk)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       list_del(&cclk->sibling);
+       list_add(&cclk->sibling, &pclk->children);
+
+       cclk->pclk = pclk;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * calculates current programmed rate of pll1
+ *
+ * In normal mode
+ * rate = (2 * M[15:8] * Fin)/(N * 2^P)
+ *
+ * In Dithered mode
+ * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
+ */
+void pll1_clk_recalc(struct clk *clk)
+{
+       struct pll_clk_config *config = clk->private_data;
+       unsigned int num = 2, den = 0, val, mode = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) &
+               PLL_MODE_MASK;
+
+       val = readl(config->cfg_reg);
+       /* calculate denominator */
+       den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK;
+       den = 1 << den;
+       den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK;
+
+       /* calculate numerator & denominator */
+       if (!mode) {
+               /* Normal mode */
+               num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK;
+       } else {
+               /* Dithered mode */
+               num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK;
+               den *= 256;
+       }
+
+       clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/* calculates current programmed rate of ahb or apb bus */
+void bus_clk_recalc(struct clk *clk)
+{
+       struct bus_clk_config *config = clk->private_data;
+       unsigned int div;
+       unsigned long flags;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       div = ((readl(config->reg) >> config->shift) & config->mask) + 1;
+       clk->rate = (unsigned long)clk->pclk->rate / div;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * calculates current programmed rate of auxiliary synthesizers
+ * used by: UART, FIRDA
+ *
+ * Fout from synthesizer can be given from two equations:
+ * Fout1 = (Fin * X/Y)/2
+ * Fout2 = Fin * X/Y
+ *
+ * Selection of eqn 1 or 2 is programmed in register
+ */
+void aux_clk_recalc(struct clk *clk)
+{
+       struct aux_clk_config *config = clk->private_data;
+       struct pclk_info *pclk_info = NULL;
+       unsigned int num = 1, den = 1, val, eqn;
+       unsigned long flags;
+
+       /* get current programmed parent */
+       pclk_info = pclk_info_get(clk);
+       if (!pclk_info) {
+               spin_lock_irqsave(&clocks_lock, flags);
+               clk->pclk = NULL;
+               clk->rate = 0;
+               spin_unlock_irqrestore(&clocks_lock, flags);
+               return;
+       }
+
+       change_parent(clk, pclk_info->pclk);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (pclk_info->scalable) {
+               val = readl(config->synth_reg);
+
+               eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK;
+               if (eqn == AUX_EQ1_SEL)
+                       den *= 2;
+
+               /* calculate numerator */
+               num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK;
+
+               /* calculate denominator */
+               den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK;
+               val = (((clk->pclk->rate/10000) * num) / den) * 10000;
+       } else
+               val = clk->pclk->rate;
+
+       clk->rate = val;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * calculates current programmed rate of gpt synthesizers
+ * Fout from synthesizer can be given from below equations:
+ * Fout= Fin/((2 ^ (N+1)) * (M+1))
+ */
+void gpt_clk_recalc(struct clk *clk)
+{
+       struct aux_clk_config *config = clk->private_data;
+       struct pclk_info *pclk_info = NULL;
+       unsigned int div = 1, val;
+       unsigned long flags;
+
+       pclk_info = pclk_info_get(clk);
+       if (!pclk_info) {
+               spin_lock_irqsave(&clocks_lock, flags);
+               clk->pclk = NULL;
+               clk->rate = 0;
+               spin_unlock_irqrestore(&clocks_lock, flags);
+               return;
+       }
+
+       change_parent(clk, pclk_info->pclk);
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       if (pclk_info->scalable) {
+               val = readl(config->synth_reg);
+               div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK;
+               div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1);
+       }
+
+       clk->rate = (unsigned long)clk->pclk->rate / div;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/*
+ * Used for clocks that always have same value as the parent clock divided by a
+ * fixed divisor
+ */
+void follow_parent(struct clk *clk)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&clocks_lock, flags);
+       clk->rate = clk->pclk->rate;
+       spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+/**
+ * recalc_root_clocks - recalculate and propagate all root clocks
+ *
+ * Recalculates all root clocks (clocks with no parent), which if the
+ * clock's .recalc is set correctly, should also propagate their rates.
+ */
+void recalc_root_clocks(void)
+{
+       propagate_rate(&root_clks);
+}
diff --git a/arch/arm/plat-spear/include/plat/clkdev.h b/arch/arm/plat-spear/include/plat/clkdev.h
new file mode 100644 (file)
index 0000000..a2d0112
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-spear/include/plat/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_CLKDEV_H
+#define __PLAT_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* __PLAT_CLKDEV_H */
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
new file mode 100644 (file)
index 0000000..298bafc
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * arch/arm/plat-spear/include/plat/clock.h
+ *
+ * Clock framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_CLOCK_H
+#define __PLAT_CLOCK_H
+
+#include <linux/list.h>
+#include <asm/clkdev.h>
+#include <linux/types.h>
+
+/* clk structure flags */
+#define        ALWAYS_ENABLED          (1 << 0) /* clock always enabled */
+#define        RESET_TO_ENABLE         (1 << 1) /* reset register bit to enable clk */
+
+/**
+ * struct clkops - clock operations
+ * @enable: pointer to clock enable function
+ * @disable: pointer to clock disable function
+ */
+struct clkops {
+       int (*enable) (struct clk *);
+       void (*disable) (struct clk *);
+};
+
+/**
+ * struct pclk_info - parents info
+ * @pclk: pointer to parent clk
+ * @pclk_mask: value to be written for selecting this parent
+ * @scalable: Is parent scalable (1 - YES, 0 - NO)
+ */
+struct pclk_info {
+       struct clk *pclk;
+       u8 pclk_mask;
+       u8 scalable;
+};
+
+/**
+ * struct pclk_sel - parents selection configuration
+ * @pclk_info: pointer to array of parent clock info
+ * @pclk_count: number of parents
+ * @pclk_sel_reg: register for selecting a parent
+ * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also)
+ */
+struct pclk_sel {
+       struct pclk_info *pclk_info;
+       u8 pclk_count;
+       unsigned int *pclk_sel_reg;
+       unsigned int pclk_sel_mask;
+};
+
+/**
+ * struct clk - clock structure
+ * @usage_count: num of users who enabled this clock
+ * @flags: flags for clock properties
+ * @rate: programmed clock rate in Hz
+ * @en_reg: clk enable/disable reg
+ * @en_reg_bit: clk enable/disable bit
+ * @ops: clk enable/disable ops - generic_clkops selected if NULL
+ * @recalc: pointer to clock rate recalculate function
+ * @pclk: current parent clk
+ * @pclk_sel: pointer to parent selection structure
+ * @pclk_sel_shift: register shift for selecting parent of this clock
+ * @children: list for childrens or this clock
+ * @sibling: node for list of clocks having same parents
+ * @private_data: clock specific private data
+ */
+struct clk {
+       unsigned int usage_count;
+       unsigned int flags;
+       unsigned long rate;
+       unsigned int *en_reg;
+       u8 en_reg_bit;
+       const struct clkops *ops;
+       void (*recalc) (struct clk *);
+
+       struct clk *pclk;
+       struct pclk_sel *pclk_sel;
+       unsigned int pclk_sel_shift;
+
+       struct list_head children;
+       struct list_head sibling;
+       void *private_data;
+};
+
+/* pll configuration structure */
+struct pll_clk_config {
+       unsigned int *mode_reg;
+       unsigned int *cfg_reg;
+};
+
+/* ahb and apb bus configuration structure */
+struct bus_clk_config {
+       unsigned int *reg;
+       unsigned int mask;
+       unsigned int shift;
+};
+
+/*
+ * Aux clk configuration structure: applicable to GPT, UART and FIRDA
+ */
+struct aux_clk_config {
+       unsigned int *synth_reg;
+};
+
+/* platform specific clock functions */
+void clk_register(struct clk_lookup *cl);
+void recalc_root_clocks(void);
+
+/* clock recalc functions */
+void follow_parent(struct clk *clk);
+void pll1_clk_recalc(struct clk *clk);
+void bus_clk_recalc(struct clk *clk);
+void gpt_clk_recalc(struct clk *clk);
+void aux_clk_recalc(struct clk *clk);
+
+#endif /* __PLAT_CLOCK_H */
diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S
new file mode 100644 (file)
index 0000000..1670734
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/plat-spear/include/plat/debug-macro.S
+ *
+ * Debugging macro include header for spear platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/amba/serial.h>
+#include <mach/spear.h>
+
+               .macro  addruart, rx
+               mrc     p15, 0, \rx, c1, c0
+               tst     \rx, #1                                 @ MMU enabled?
+               moveq   \rx, =SPEAR_DBG_UART_BASE               @ Physical base
+               movne   \rx, =VA_SPEAR_DBG_UART_BASE            @ Virtual base
+               .endm
+
+               .macro  senduart, rd, rx
+               strb    \rd, [\rx, #UART01x_DR]                 @ ASC_TX_BUFFER
+               .endm
+
+               .macro  waituart, rd, rx
+1001:          ldr     \rd, [\rx, #UART01x_FR]                 @ FLAG REGISTER
+               tst     \rd, #UART01x_FR_TXFF                   @ TX_FULL
+               bne     1001b
+               .endm
+
+               .macro  busyuart, rd, rx
+1002:          ldr     \rd, [\rx, #UART01x_FR]                 @ FLAG REGISTER
+               tst     \rd, #UART011_FR_TXFE                   @ TX_EMPTY
+               beq     1002b
+               .endm
diff --git a/arch/arm/plat-spear/include/plat/gpio.h b/arch/arm/plat-spear/include/plat/gpio.h
new file mode 100644 (file)
index 0000000..b857c91
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-spear/include/plat/gpio.h
+ *
+ * GPIO macros for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#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
+
+#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-spear/include/plat/io.h b/arch/arm/plat-spear/include/plat/io.h
new file mode 100644 (file)
index 0000000..4d4ba82
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/plat-spear/include/plat/io.h
+ *
+ * IO definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_IO_H
+#define __PLAT_IO_H
+
+#define IO_SPACE_LIMIT         0xFFFFFFFF
+
+#define __io(a)                        __typesafe_io(a)
+#define __mem_pci(a)           (a)
+
+#endif /* __PLAT_IO_H */
diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h
new file mode 100644 (file)
index 0000000..27a4aba
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-spear/include/plat/memory.h
+ *
+ * Memory map for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_MEMORY_H
+#define __PLAT_MEMORY_H
+
+/* Physical DRAM offset */
+#define PHYS_OFFSET            UL(0x00000000)
+
+#endif /* __PLAT_MEMORY_H */
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
new file mode 100644 (file)
index 0000000..877f3ad
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/plat-spear/include/plat/padmux.h
+ *
+ * SPEAr platform specific gpio pads muxing file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_PADMUX_H
+#define __PLAT_PADMUX_H
+
+#include <linux/types.h>
+
+/*
+ * struct pmx_reg: configuration structure for mode reg and mux reg
+ *
+ * offset: offset of mode reg
+ * mask: mask of mode reg
+ */
+struct pmx_reg {
+       u32 offset;
+       u32 mask;
+};
+
+/*
+ * struct pmx_dev_mode: configuration structure every group of modes of a device
+ *
+ * ids: all modes for this configuration
+ * mask: mask for supported mode
+ */
+struct pmx_dev_mode {
+       u32 ids;
+       u32 mask;
+};
+
+/*
+ * struct pmx_mode: mode definition structure
+ *
+ * name: mode name
+ * mask: mode mask
+ */
+struct pmx_mode {
+       char *name;
+       u32 id;
+       u32 mask;
+};
+
+/*
+ * struct pmx_dev: device definition structure
+ *
+ * name: device name
+ * modes: device configuration array for different modes supported
+ * mode_count: size of modes array
+ * is_active: is peripheral active/enabled
+ * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg
+ */
+struct pmx_dev {
+       char *name;
+       struct pmx_dev_mode *modes;
+       u8 mode_count;
+       bool is_active;
+       bool enb_on_reset;
+};
+
+/*
+ * struct pmx_driver: driver definition structure
+ *
+ * mode: mode to be set
+ * devs: array of pointer to pmx devices
+ * devs_count: ARRAY_SIZE of devs
+ * base: base address of soc config registers
+ * mode_reg: structure of mode config register
+ * mux_reg: structure of device mux config register
+ */
+struct pmx_driver {
+       struct pmx_mode *mode;
+       struct pmx_dev **devs;
+       u8 devs_count;
+       u32 *base;
+       struct pmx_reg mode_reg;
+       struct pmx_reg mux_reg;
+};
+
+/* pmx functions */
+int pmx_register(struct pmx_driver *driver);
+
+#endif /* __PLAT_PADMUX_H */
diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h
new file mode 100644 (file)
index 0000000..03ed8b5
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/plat-spear/include/plat/shirq.h
+ *
+ * SPEAr platform shared irq layer header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_SHIRQ_H
+#define __PLAT_SHIRQ_H
+
+#include <linux/irq.h>
+#include <linux/types.h>
+
+/*
+ * struct shirq_dev_config: shared irq device configuration
+ *
+ * virq: virtual irq number of device
+ * enb_mask: enable mask of device
+ * status_mask: status mask of device
+ * clear_mask: clear mask of device
+ */
+struct shirq_dev_config {
+       u32 virq;
+       u32 enb_mask;
+       u32 status_mask;
+       u32 clear_mask;
+};
+
+/*
+ * struct shirq_regs: shared irq register configuration
+ *
+ * base: base address of shared irq register
+ * enb_reg: enable register offset
+ * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt
+ * status_reg: status register offset
+ * status_reg_mask: status register valid mask
+ * clear_reg: clear register offset
+ * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt
+ */
+struct shirq_regs {
+       void __iomem *base;
+       u32 enb_reg;
+       u32 reset_to_enb;
+       u32 status_reg;
+       u32 status_reg_mask;
+       u32 clear_reg;
+       u32 reset_to_clear;
+};
+
+/*
+ * struct spear_shirq: shared irq structure
+ *
+ * irq: hardware irq number
+ * dev_config: array of device config structures which are using "irq" line
+ * dev_count: size of dev_config array
+ * regs: register configuration for shared irq block
+ */
+struct spear_shirq {
+       u32 irq;
+       struct shirq_dev_config *dev_config;
+       u32 dev_count;
+       struct shirq_regs regs;
+};
+
+int spear_shirq_register(struct spear_shirq *shirq);
+
+#endif /* __PLAT_SHIRQ_H */
diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h
new file mode 100644 (file)
index 0000000..55a4e40
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/plat-spear/include/plat/system.h
+ *
+ * SPEAr platform specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_SYSTEM_H
+#define __PLAT_SYSTEM_H
+
+#include <asm/hardware/sp810.h>
+#include <linux/io.h>
+#include <mach/spear.h>
+
+static inline void arch_idle(void)
+{
+       /*
+        * This should do all the clock switching
+        * and wait for interrupt tricks
+        */
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+       if (mode == 's') {
+               /* software reset, Jump into ROM at address 0 */
+               cpu_reset(0);
+       } else {
+               /* hardware reset, Use on-chip reset capability */
+               sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
+       }
+}
+
+#endif /* __PLAT_SYSTEM_H */
diff --git a/arch/arm/plat-spear/include/plat/timex.h b/arch/arm/plat-spear/include/plat/timex.h
new file mode 100644 (file)
index 0000000..914d09d
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-spear/include/plat/timex.h
+ *
+ * SPEAr platform specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_TIMEX_H
+#define __PLAT_TIMEX_H
+
+#define CLOCK_TICK_RATE                        48000000
+
+#endif /* __PLAT_TIMEX_H */
diff --git a/arch/arm/plat-spear/include/plat/uncompress.h b/arch/arm/plat-spear/include/plat/uncompress.h
new file mode 100644 (file)
index 0000000..99ba678
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/plat-spear/include/plat/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/amba/serial.h>
+#include <mach/spear.h>
+
+#ifndef __PLAT_UNCOMPRESS_H
+#define __PLAT_UNCOMPRESS_H
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+       void __iomem *base = (void __iomem *)SPEAR_DBG_UART_BASE;
+
+       while (readl(base + UART01x_FR) & UART01x_FR_TXFF)
+               barrier();
+
+       writel(c, base + UART01x_DR);
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif /* __PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-spear/include/plat/vmalloc.h b/arch/arm/plat-spear/include/plat/vmalloc.h
new file mode 100644 (file)
index 0000000..09e9372
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-spear/include/plat/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_VMALLOC_H
+#define __PLAT_VMALLOC_H
+
+#define VMALLOC_END            0xF0000000
+
+#endif /* __PLAT_VMALLOC_H */
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
new file mode 100644 (file)
index 0000000..d2aab3a
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/plat-spear/include/plat/padmux.c
+ *
+ * SPEAr platform specific gpio pads muxing source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <plat/padmux.h>
+
+/*
+ * struct pmx: pmx definition structure
+ *
+ * base: base address of configuration registers
+ * mode_reg: mode configurations
+ * mux_reg: muxing configurations
+ * active_mode: pointer to current active mode
+ */
+struct pmx {
+       u32 base;
+       struct pmx_reg mode_reg;
+       struct pmx_reg mux_reg;
+       struct pmx_mode *active_mode;
+};
+
+static struct pmx *pmx;
+
+/**
+ * pmx_mode_set - Enables an multiplexing mode
+ * @mode - pointer to pmx mode
+ *
+ * It will set mode of operation in hardware.
+ * Returns -ve on Err otherwise 0
+ */
+static int pmx_mode_set(struct pmx_mode *mode)
+{
+       u32 val;
+
+       if (!mode->name)
+               return -EFAULT;
+
+       pmx->active_mode = mode;
+
+       val = readl(pmx->base + pmx->mode_reg.offset);
+       val &= ~pmx->mode_reg.mask;
+       val |= mode->mask & pmx->mode_reg.mask;
+       writel(val, pmx->base + pmx->mode_reg.offset);
+
+       return 0;
+}
+
+/**
+ * pmx_devs_enable - Enables list of devices
+ * @devs - pointer to pmx device array
+ * @count - number of devices to enable
+ *
+ * It will enable pads for all required peripherals once and only once.
+ * If peripheral is not supported by current mode then request is rejected.
+ * Conflicts between peripherals are not handled and peripherals will be
+ * enabled in the order they are present in pmx_dev array.
+ * In case of conflicts last peripheral enalbed will be present.
+ * Returns -ve on Err otherwise 0
+ */
+static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
+{
+       u32 val, i, mask;
+
+       if (!count)
+               return -EINVAL;
+
+       val = readl(pmx->base + pmx->mux_reg.offset);
+       for (i = 0; i < count; i++) {
+               u8 j = 0;
+
+               if (!devs[i]->name || !devs[i]->modes) {
+                       printk(KERN_ERR "padmux: dev name or modes is null\n");
+                       continue;
+               }
+               /* check if peripheral exists in active mode */
+               if (pmx->active_mode) {
+                       bool found = false;
+                       for (j = 0; j < devs[i]->mode_count; j++) {
+                               if (devs[i]->modes[j].ids &
+                                               pmx->active_mode->id) {
+                                       found = true;
+                                       break;
+                               }
+                       }
+                       if (found == false) {
+                               printk(KERN_ERR "%s device not available in %s"\
+                                               "mode\n", devs[i]->name,
+                                               pmx->active_mode->name);
+                               continue;
+                       }
+               }
+
+               /* enable peripheral */
+               mask = devs[i]->modes[j].mask & pmx->mux_reg.mask;
+               if (devs[i]->enb_on_reset)
+                       val &= ~mask;
+               else
+                       val |= mask;
+
+               devs[i]->is_active = true;
+       }
+       writel(val, pmx->base + pmx->mux_reg.offset);
+       kfree(pmx);
+
+       /* this will ensure that multiplexing can't be changed now */
+       pmx = (struct pmx *)-1;
+
+       return 0;
+}
+
+/**
+ * pmx_register - registers a platform requesting pad mux feature
+ * @driver - pointer to driver structure containing driver specific parameters
+ *
+ * Also this must be called only once. This will allocate memory for pmx
+ * structure, will call pmx_mode_set, will call pmx_devs_enable.
+ * Returns -ve on Err otherwise 0
+ */
+int pmx_register(struct pmx_driver *driver)
+{
+       int ret = 0;
+
+       if (pmx)
+               return -EPERM;
+       if (!driver->base || !driver->devs)
+               return -EFAULT;
+
+       pmx = kzalloc(sizeof(*pmx), GFP_KERNEL);
+       if (!pmx)
+               return -ENOMEM;
+
+       pmx->base = (u32)driver->base;
+       pmx->mode_reg.offset = driver->mode_reg.offset;
+       pmx->mode_reg.mask = driver->mode_reg.mask;
+       pmx->mux_reg.offset = driver->mux_reg.offset;
+       pmx->mux_reg.mask = driver->mux_reg.mask;
+
+       /* choose mode to enable */
+       if (driver->mode) {
+               ret = pmx_mode_set(driver->mode);
+               if (ret)
+                       goto pmx_fail;
+       }
+       ret = pmx_devs_enable(driver->devs, driver->devs_count);
+       if (ret)
+               goto pmx_fail;
+
+       return 0;
+
+pmx_fail:
+       return ret;
+}
diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c
new file mode 100644 (file)
index 0000000..2172d69
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/plat-spear/shirq.c
+ *
+ * SPEAr platform shared irq layer source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <plat/shirq.h>
+
+struct spear_shirq *shirq;
+static DEFINE_SPINLOCK(lock);
+
+static void shirq_irq_mask(unsigned irq)
+{
+       struct spear_shirq *shirq = get_irq_chip_data(irq);
+       u32 val, id = irq - shirq->dev_config[0].virq;
+       unsigned long flags;
+
+       if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+               return;
+
+       spin_lock_irqsave(&lock, flags);
+       val = readl(shirq->regs.base + shirq->regs.enb_reg);
+       if (shirq->regs.reset_to_enb)
+               val |= shirq->dev_config[id].enb_mask;
+       else
+               val &= ~(shirq->dev_config[id].enb_mask);
+       writel(val, shirq->regs.base + shirq->regs.enb_reg);
+       spin_unlock_irqrestore(&lock, flags);
+}
+
+static void shirq_irq_unmask(unsigned irq)
+{
+       struct spear_shirq *shirq = get_irq_chip_data(irq);
+       u32 val, id = irq - shirq->dev_config[0].virq;
+       unsigned long flags;
+
+       if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+               return;
+
+       spin_lock_irqsave(&lock, flags);
+       val = readl(shirq->regs.base + shirq->regs.enb_reg);
+       if (shirq->regs.reset_to_enb)
+               val &= ~(shirq->dev_config[id].enb_mask);
+       else
+               val |= shirq->dev_config[id].enb_mask;
+       writel(val, shirq->regs.base + shirq->regs.enb_reg);
+       spin_unlock_irqrestore(&lock, flags);
+}
+
+static struct irq_chip shirq_chip = {
+       .name           = "spear_shirq",
+       .ack            = shirq_irq_mask,
+       .mask           = shirq_irq_mask,
+       .unmask         = shirq_irq_unmask,
+};
+
+static void shirq_handler(unsigned irq, struct irq_desc *desc)
+{
+       u32 i, val, mask;
+       struct spear_shirq *shirq = get_irq_data(irq);
+
+       desc->chip->ack(irq);
+       while ((val = readl(shirq->regs.base + shirq->regs.status_reg) &
+                               shirq->regs.status_reg_mask)) {
+               for (i = 0; (i < shirq->dev_count) && val; i++) {
+                       if (!(shirq->dev_config[i].status_mask & val))
+                               continue;
+
+                       generic_handle_irq(shirq->dev_config[i].virq);
+
+                       /* clear interrupt */
+                       val &= ~shirq->dev_config[i].status_mask;
+                       if ((shirq->regs.clear_reg == -1) ||
+                                       shirq->dev_config[i].clear_mask == -1)
+                               continue;
+                       mask = readl(shirq->regs.base + shirq->regs.clear_reg);
+                       if (shirq->regs.reset_to_clear)
+                               mask &= ~shirq->dev_config[i].clear_mask;
+                       else
+                               mask |= shirq->dev_config[i].clear_mask;
+                       writel(mask, shirq->regs.base + shirq->regs.clear_reg);
+               }
+       }
+       desc->chip->unmask(irq);
+}
+
+int spear_shirq_register(struct spear_shirq *shirq)
+{
+       int i;
+
+       if (!shirq || !shirq->dev_config || !shirq->regs.base)
+               return -EFAULT;
+
+       if (!shirq->dev_count)
+               return -EINVAL;
+
+       set_irq_chained_handler(shirq->irq, shirq_handler);
+       for (i = 0; i < shirq->dev_count; i++) {
+               set_irq_chip(shirq->dev_config[i].virq, &shirq_chip);
+               set_irq_handler(shirq->dev_config[i].virq, handle_simple_irq);
+               set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID);
+               set_irq_chip_data(shirq->dev_config[i].virq, shirq);
+       }
+
+       set_irq_data(shirq->irq, shirq);
+       return 0;
+}
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
new file mode 100644 (file)
index 0000000..a1025d3
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * arch/arm/plat-spear/time.c
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Shiraz Hashim<shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/spear.h>
+#include <mach/generic.h>
+
+/*
+ * We would use TIMER0 and TIMER1 as clockevent and clocksource.
+ * Timer0 and Timer1 both belong to same gpt block in cpu subbsystem. Further
+ * they share same functional clock. Any change in one's functional clock will
+ * also affect other timer.
+ */
+
+#define CLKEVT 0       /* gpt0, channel0 as clockevent */
+#define CLKSRC 1       /* gpt0, channel1 as clocksource */
+
+/* Register offsets, x is channel number */
+#define CR(x)          ((x) * 0x80 + 0x80)
+#define IR(x)          ((x) * 0x80 + 0x84)
+#define LOAD(x)                ((x) * 0x80 + 0x88)
+#define COUNT(x)       ((x) * 0x80 + 0x8C)
+
+/* Reg bit definitions */
+#define CTRL_INT_ENABLE                0x0100
+#define CTRL_ENABLE            0x0020
+#define CTRL_ONE_SHOT          0x0010
+
+#define CTRL_PRESCALER1                0x0
+#define CTRL_PRESCALER2                0x1
+#define CTRL_PRESCALER4                0x2
+#define CTRL_PRESCALER8                0x3
+#define CTRL_PRESCALER16       0x4
+#define CTRL_PRESCALER32       0x5
+#define CTRL_PRESCALER64       0x6
+#define CTRL_PRESCALER128      0x7
+#define CTRL_PRESCALER256      0x8
+
+#define INT_STATUS             0x1
+
+static __iomem void *gpt_base;
+static struct clk *gpt_clk;
+
+static void clockevent_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *clk_event_dev);
+static int clockevent_next_event(unsigned long evt,
+                                struct clock_event_device *clk_event_dev);
+
+/*
+ * Following clocksource_set_clock and clockevent_set_clock picked
+ * from arch/mips/kernel/time.c
+ */
+
+void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
+{
+       u64 temp;
+       u32 shift;
+
+       /* Find a shift value */
+       for (shift = 32; shift > 0; shift--) {
+               temp = (u64) NSEC_PER_SEC << shift;
+               do_div(temp, clock);
+               if ((temp >> 32) == 0)
+                       break;
+       }
+       cs->shift = shift;
+       cs->mult = (u32) temp;
+}
+
+void __init clockevent_set_clock(struct clock_event_device *cd,
+       unsigned int clock)
+{
+       u64 temp;
+       u32 shift;
+
+       /* Find a shift value */
+       for (shift = 32; shift > 0; shift--) {
+               temp = (u64) clock << shift;
+               do_div(temp, NSEC_PER_SEC);
+               if ((temp >> 32) == 0)
+                       break;
+       }
+       cd->shift = shift;
+       cd->mult = (u32) temp;
+}
+
+static cycle_t clocksource_read_cycles(struct clocksource *cs)
+{
+       return (cycle_t) readw(gpt_base + COUNT(CLKSRC));
+}
+
+static struct clocksource clksrc = {
+       .name = "tmr1",
+       .rating = 200,          /* its a pretty decent clock */
+       .read = clocksource_read_cycles,
+       .mask = 0xFFFF,         /* 16 bits */
+       .mult = 0,              /* to be computed */
+       .shift = 0,             /* to be computed */
+       .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void spear_clocksource_init(void)
+{
+       u32 tick_rate;
+       u16 val;
+
+       /* program the prescaler (/256)*/
+       writew(CTRL_PRESCALER256, gpt_base + CR(CLKSRC));
+
+       /* find out actual clock driving Timer */
+       tick_rate = clk_get_rate(gpt_clk);
+       tick_rate >>= CTRL_PRESCALER256;
+
+       writew(0xFFFF, gpt_base + LOAD(CLKSRC));
+
+       val = readw(gpt_base + CR(CLKSRC));
+       val &= ~CTRL_ONE_SHOT;  /* autoreload mode */
+       val |= CTRL_ENABLE ;
+       writew(val, gpt_base + CR(CLKSRC));
+
+       clocksource_set_clock(&clksrc, tick_rate);
+
+       /* register the clocksource */
+       clocksource_register(&clksrc);
+}
+
+static struct clock_event_device clkevt = {
+       .name = "tmr0",
+       .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_mode = clockevent_set_mode,
+       .set_next_event = clockevent_next_event,
+       .shift = 0,     /* to be computed */
+};
+
+static void clockevent_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *clk_event_dev)
+{
+       u32 period;
+       u16 val;
+
+       /* stop the timer */
+       val = readw(gpt_base + CR(CLKEVT));
+       val &= ~CTRL_ENABLE;
+       writew(val, gpt_base + CR(CLKEVT));
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               period = clk_get_rate(gpt_clk) / HZ;
+               period >>= CTRL_PRESCALER16;
+               writew(period, gpt_base + LOAD(CLKEVT));
+
+               val = readw(gpt_base + CR(CLKEVT));
+               val &= ~CTRL_ONE_SHOT;
+               val |= CTRL_ENABLE | CTRL_INT_ENABLE;
+               writew(val, gpt_base + CR(CLKEVT));
+
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               val = readw(gpt_base + CR(CLKEVT));
+               val |= CTRL_ONE_SHOT;
+               writew(val, gpt_base + CR(CLKEVT));
+
+               break;
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+
+               break;
+       default:
+               pr_err("Invalid mode requested\n");
+               break;
+       }
+}
+
+static int clockevent_next_event(unsigned long cycles,
+                                struct clock_event_device *clk_event_dev)
+{
+       u16 val;
+
+       writew(cycles, gpt_base + LOAD(CLKEVT));
+
+       val = readw(gpt_base + CR(CLKEVT));
+       val |= CTRL_ENABLE | CTRL_INT_ENABLE;
+       writew(val, gpt_base + CR(CLKEVT));
+
+       return 0;
+}
+
+static irqreturn_t spear_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = &clkevt;
+
+       writew(INT_STATUS, gpt_base + IR(CLKEVT));
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction spear_timer_irq = {
+       .name = "timer",
+       .flags = IRQF_DISABLED | IRQF_TIMER,
+       .handler = spear_timer_interrupt
+};
+
+static void __init spear_clockevent_init(void)
+{
+       u32 tick_rate;
+
+       /* program the prescaler */
+       writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT));
+
+       tick_rate = clk_get_rate(gpt_clk);
+       tick_rate >>= CTRL_PRESCALER16;
+
+       clockevent_set_clock(&clkevt, tick_rate);
+
+       clkevt.max_delta_ns = clockevent_delta2ns(0xfff0,
+                       &clkevt);
+       clkevt.min_delta_ns = clockevent_delta2ns(3, &clkevt);
+
+       clkevt.cpumask = cpumask_of(0);
+
+       clockevents_register_device(&clkevt);
+
+       setup_irq(SPEAR_GPT0_CHAN0_IRQ, &spear_timer_irq);
+}
+
+void __init spear_setup_timer(void)
+{
+       struct clk *pll3_clk;
+
+       if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
+               pr_err("%s:cannot get IO addr\n", __func__);
+               return;
+       }
+
+       gpt_base = (void __iomem *)ioremap(SPEAR_GPT0_BASE, SZ_1K);
+       if (!gpt_base) {
+               pr_err("%s:ioremap failed for gpt\n", __func__);
+               goto err_mem;
+       }
+
+       gpt_clk = clk_get_sys("gpt0", NULL);
+       if (!gpt_clk) {
+               pr_err("%s:couldn't get clk for gpt\n", __func__);
+               goto err_iomap;
+       }
+
+       pll3_clk = clk_get(NULL, "pll3_48m_clk");
+       if (!pll3_clk) {
+               pr_err("%s:couldn't get PLL3 as parent for gpt\n", __func__);
+               goto err_iomap;
+       }
+
+       clk_set_parent(gpt_clk, pll3_clk);
+
+       spear_clockevent_init();
+       spear_clocksource_init();
+
+       return;
+
+err_iomap:
+       iounmap(gpt_base);
+
+err_mem:
+       release_mem_region(SPEAR_GPT0_BASE, SZ_1K);
+}
+
+struct sys_timer spear_sys_timer = {
+       .init = spear_setup_timer,
+};
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
new file mode 100644 (file)
index 0000000..9b1a668
--- /dev/null
@@ -0,0 +1,4 @@
+obj-y  := clock.o
+obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
+obj-$(CONFIG_ARCH_REALVIEW) += sched-clock.o
+obj-$(CONFIG_ARCH_VERSATILE) += sched-clock.o
diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c
new file mode 100644 (file)
index 0000000..5c8b656
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/plat-versatile/clock.c
+ *
+ *  Copyright (C) 2004 ARM Limited.
+ *  Written by Deep Blue Solutions Limited.
+ *
+ * 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/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <asm/hardware/icst.h>
+
+#include <mach/clkdev.h>
+
+int clk_enable(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       long ret = -EIO;
+       if (clk->ops && clk->ops->round)
+               ret = clk->ops->round(clk, rate);
+       return ret;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       int ret = -EIO;
+       if (clk->ops && clk->ops->set)
+               ret = clk->ops->set(clk, rate);
+       return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+long icst_clk_round(struct clk *clk, unsigned long rate)
+{
+       struct icst_vco vco;
+       vco = icst_hz_to_vco(clk->params, rate);
+       return icst_hz(clk->params, vco);
+}
+EXPORT_SYMBOL(icst_clk_round);
+
+int icst_clk_set(struct clk *clk, unsigned long rate)
+{
+       struct icst_vco vco;
+
+       vco = icst_hz_to_vco(clk->params, rate);
+       clk->rate = icst_hz(clk->params, vco);
+       clk->ops->setvco(clk, vco);
+
+       return 0;
+}
+EXPORT_SYMBOL(icst_clk_set);
diff --git a/arch/arm/plat-versatile/include/plat/clock.h b/arch/arm/plat-versatile/include/plat/clock.h
new file mode 100644 (file)
index 0000000..3cfb024
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef PLAT_CLOCK_H
+#define PLAT_CLOCK_H
+
+#include <asm/hardware/icst.h>
+
+struct clk_ops {
+       long    (*round)(struct clk *, unsigned long);
+       int     (*set)(struct clk *, unsigned long);
+       void    (*setvco)(struct clk *, struct icst_vco);
+};
+
+int icst_clk_set(struct clk *, unsigned long);
+long icst_clk_round(struct clk *, unsigned long);
+
+#endif
diff --git a/arch/arm/plat-versatile/include/plat/timer-sp.h b/arch/arm/plat-versatile/include/plat/timer-sp.h
new file mode 100644 (file)
index 0000000..21e75e3
--- /dev/null
@@ -0,0 +1,2 @@
+void sp804_clocksource_init(void __iomem *);
+void sp804_clockevents_init(void __iomem *, unsigned int);
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
new file mode 100644 (file)
index 0000000..9768cf7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  linux/arch/arm/plat-versatile/sched-clock.c
+ *
+ *  Copyright (C) 1999 - 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/cnt32_to_63.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#ifdef VERSATILE_SYS_BASE
+#define REFCOUNTER     (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)
+#endif
+
+#ifdef REALVIEW_SYS_BASE
+#define REFCOUNTER     (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
+#endif
+
+/*
+ * This is the Realview and Versatile sched_clock implementation.  This
+ * has a resolution of 41.7ns, and a maximum value of about 35583 days.
+ *
+ * The return value is guaranteed to be monotonic in that range as
+ * long as there is always less than 89 seconds between successive
+ * calls to this function.
+ */
+unsigned long long sched_clock(void)
+{
+       unsigned long long v = cnt32_to_63(readl(REFCOUNTER));
+
+       /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */
+       v *= 125<<1;
+       do_div(v, 3<<1);
+
+       return v;
+}
diff --git a/arch/arm/plat-versatile/timer-sp.c b/arch/arm/plat-versatile/timer-sp.c
new file mode 100644 (file)
index 0000000..fb0d1c2
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  linux/arch/arm/plat-versatile/timer-sp.c
+ *
+ *  Copyright (C) 1999 - 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/arm_timer.h>
+
+#include <plat/timer-sp.h>
+
+/*
+ * These timers are currently always setup to be clocked at 1MHz.
+ */
+#define TIMER_FREQ_KHZ (1000)
+#define TIMER_RELOAD   (TIMER_FREQ_KHZ * 1000 / HZ)
+
+static void __iomem *clksrc_base;
+
+static cycle_t sp804_read(struct clocksource *cs)
+{
+       return ~readl(clksrc_base + TIMER_VALUE);
+}
+
+static struct clocksource clocksource_sp804 = {
+       .name           = "timer3",
+       .rating         = 200,
+       .read           = sp804_read,
+       .mask           = CLOCKSOURCE_MASK(32),
+       .shift          = 20,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sp804_clocksource_init(void __iomem *base)
+{
+       struct clocksource *cs = &clocksource_sp804;
+
+       clksrc_base = base;
+
+       /* setup timer 0 as free-running clocksource */
+       writel(0, clksrc_base + TIMER_CTRL);
+       writel(0xffffffff, clksrc_base + TIMER_LOAD);
+       writel(0xffffffff, clksrc_base + TIMER_VALUE);
+       writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+               clksrc_base + TIMER_CTRL);
+
+       cs->mult = clocksource_khz2mult(TIMER_FREQ_KHZ, cs->shift);
+       clocksource_register(cs);
+}
+
+
+static void __iomem *clkevt_base;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       /* clear the interrupt */
+       writel(1, clkevt_base + TIMER_INTCLR);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static void sp804_set_mode(enum clock_event_mode mode,
+       struct clock_event_device *evt)
+{
+       unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE;
+
+       writel(ctrl, clkevt_base + TIMER_CTRL);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD);
+               ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+               /* period set, and timer enabled in 'next_event' hook */
+               ctrl |= TIMER_CTRL_ONESHOT;
+               break;
+
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       default:
+               break;
+       }
+
+       writel(ctrl, clkevt_base + TIMER_CTRL);
+}
+
+static int sp804_set_next_event(unsigned long next,
+       struct clock_event_device *evt)
+{
+       unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+       writel(next, clkevt_base + TIMER_LOAD);
+       writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+       return 0;
+}
+
+static struct clock_event_device sp804_clockevent = {
+       .name           = "timer0",
+       .shift          = 32,
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .set_mode       = sp804_set_mode,
+       .set_next_event = sp804_set_next_event,
+       .rating         = 300,
+       .cpumask        = cpu_all_mask,
+};
+
+static struct irqaction sp804_timer_irq = {
+       .name           = "timer",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = sp804_timer_interrupt,
+       .dev_id         = &sp804_clockevent,
+};
+
+void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq)
+{
+       struct clock_event_device *evt = &sp804_clockevent;
+
+       clkevt_base = base;
+
+       evt->irq = timer_irq;
+       evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift);
+       evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
+       evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
+
+       setup_irq(timer_irq, &sp804_timer_irq);
+       clockevents_register_device(evt);
+}
index 1536f17..8f10d24 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Sat Mar 20 15:35:41 2010
+# Last update: Sat May 1 10:36:42 2010
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -2749,3 +2749,58 @@ stamp9g45                MACH_STAMP9G45          STAMP9G45               2761
 h6053                  MACH_H6053              H6053                   2762
 smint01                        MACH_SMINT01            SMINT01                 2763
 prtlvt2                        MACH_PRTLVT2            PRTLVT2                 2764
+ap420                  MACH_AP420              AP420                   2765
+htcshift               MACH_HTCSHIFT           HTCSHIFT                2766
+davinci_dm365_fc       MACH_DAVINCI_DM365_FC   DAVINCI_DM365_FC        2767
+msm8x55_surf           MACH_MSM8X55_SURF       MSM8X55_SURF            2768
+msm8x55_ffa            MACH_MSM8X55_FFA        MSM8X55_FFA             2769
+esl_vamana             MACH_ESL_VAMANA         ESL_VAMANA              2770
+sbc35                  MACH_SBC35              SBC35                   2771
+mpx6446                        MACH_MPX6446            MPX6446                 2772
+oreo_controller                MACH_OREO_CONTROLLER    OREO_CONTROLLER         2773
+kopin_models           MACH_KOPIN_MODELS       KOPIN_MODELS            2774
+ttc_vision2            MACH_TTC_VISION2        TTC_VISION2             2775
+cns3420vb              MACH_CNS3420VB          CNS3420VB               2776
+lpc2                   MACH_LPC2               LPC2                    2777
+olympus                        MACH_OLYMPUS            OLYMPUS                 2778
+vortex                 MACH_VORTEX             VORTEX                  2779
+s5pc200                        MACH_S5PC200            S5PC200                 2780
+ecucore_9263           MACH_ECUCORE_9263       ECUCORE_9263            2781
+smdkc200               MACH_SMDKC200           SMDKC200                2782
+emsiso_sx27            MACH_EMSISO_SX27        EMSISO_SX27             2783
+apx_som9g45_ek         MACH_APX_SOM9G45_EK     APX_SOM9G45_EK          2784
+songshan               MACH_SONGSHAN           SONGSHAN                2785
+tianshan               MACH_TIANSHAN           TIANSHAN                2786
+vpx500                 MACH_VPX500             VPX500                  2787
+am3517sam              MACH_AM3517SAM          AM3517SAM               2788
+skat91_sim508          MACH_SKAT91_SIM508      SKAT91_SIM508           2789
+skat91_s3e             MACH_SKAT91_S3E         SKAT91_S3E              2790
+omap4_panda            MACH_OMAP4_PANDA        OMAP4_PANDA             2791
+df7220                 MACH_DF7220             DF7220                  2792
+nemini                 MACH_NEMINI             NEMINI                  2793
+t8200                  MACH_T8200              T8200                   2794
+apf51                  MACH_APF51              APF51                   2795
+dr_rc_unit             MACH_DR_RC_UNIT         DR_RC_UNIT              2796
+bordeaux               MACH_BORDEAUX           BORDEAUX                2797
+catania_b              MACH_CATANIA_B          CATANIA_B               2798
+mx51_ocean             MACH_MX51_OCEAN         MX51_OCEAN              2799
+ti8168evm              MACH_TI8168EVM          TI8168EVM               2800
+neocoreomap            MACH_NEOCOREOMAP        NEOCOREOMAP             2801
+withings_wbp           MACH_WITHINGS_WBP       WITHINGS_WBP            2802
+dbps                   MACH_DBPS               DBPS                    2803
+sbc9261                        MACH_SBC9261            SBC9261                 2804
+pcbfp0001              MACH_PCBFP0001          PCBFP0001               2805
+speedy                 MACH_SPEEDY             SPEEDY                  2806
+chrysaor               MACH_CHRYSAOR           CHRYSAOR                2807
+tango                  MACH_TANGO              TANGO                   2808
+synology_dsx11         MACH_SYNOLOGY_DSX11     SYNOLOGY_DSX11          2809
+hanlin_v3ext           MACH_HANLIN_V3EXT       HANLIN_V3EXT            2810
+hanlin_v5              MACH_HANLIN_V5          HANLIN_V5               2811
+hanlin_v3plus          MACH_HANLIN_V3PLUS      HANLIN_V3PLUS           2812
+iriver_story           MACH_IRIVER_STORY       IRIVER_STORY            2813
+irex_iliad             MACH_IREX_ILIAD         IREX_ILIAD              2814
+irex_dr1000            MACH_IREX_DR1000        IREX_DR1000             2815
+teton_bga              MACH_TETON_BGA          TETON_BGA               2816
+snapper9g45            MACH_SNAPPER9G45        SNAPPER9G45             2817
+tam3517                        MACH_TAM3517            TAM3517                 2818
+pdc100                 MACH_PDC100             PDC100                  2819
index a420cb9..315a540 100644 (file)
@@ -428,26 +428,6 @@ static void vfp_pm_init(void)
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
 
-/*
- * Synchronise the hardware VFP state of a thread other than current with the
- * saved one. This function is used by the ptrace mechanism.
- */
-#ifdef CONFIG_SMP
-void vfp_sync_hwstate(struct thread_info *thread)
-{
-}
-
-void vfp_flush_hwstate(struct thread_info *thread)
-{
-       /*
-        * On SMP systems, the VFP state is automatically saved at every
-        * context switch. We mark the thread VFP state as belonging to a
-        * non-existent CPU so that the saved one will be reloaded when
-        * needed.
-        */
-       thread->vfpstate.hard.cpu = NR_CPUS;
-}
-#else
 void vfp_sync_hwstate(struct thread_info *thread)
 {
        unsigned int cpu = get_cpu();
@@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
                last_VFP_context[cpu] = NULL;
        }
 
+#ifdef CONFIG_SMP
+       /*
+        * For SMP we still have to take care of the case where the thread
+        * migrates to another CPU and then back to the original CPU on which
+        * the last VFP user is still the same thread. Mark the thread VFP
+        * state as belonging to a non-existent CPU so that the saved one will
+        * be reloaded in the above case.
+        */
+       thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
        put_cpu();
 }
-#endif
 
 #include <linux/smp.h>
 
index b131c27..bbce6a1 100644 (file)
@@ -19,7 +19,7 @@
 
 #define ATOMIC_INIT(i)  { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 /*
index dd5b882..5e73c25 100644 (file)
@@ -28,7 +28,7 @@ static struct pt_regs *get_user_regs(struct task_struct *tsk)
                                  THREAD_SIZE - sizeof(struct pt_regs));
 }
 
-static void user_enable_single_step(struct task_struct *tsk)
+void user_enable_single_step(struct task_struct *tsk)
 {
        pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
                 tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr);
index f27aa3b..668ed28 100644 (file)
@@ -110,17 +110,17 @@ static struct clock_event_device comparator = {
        .set_mode       = comparator_mode,
 };
 
+void read_persistent_clock(struct timespec *ts)
+{
+       ts->tv_sec = mktime(2007, 1, 1, 0, 0, 0);
+       ts->tv_nsec = 0;
+}
+
 void __init time_init(void)
 {
        unsigned long counter_hz;
        int ret;
 
-       xtime.tv_sec = mktime(2007, 1, 1, 0, 0, 0);
-       xtime.tv_nsec = 0;
-
-       set_normalized_timespec(&wall_to_monotonic,
-                               -xtime.tv_sec, -xtime.tv_nsec);
-
        /* figure rate for counter */
        counter_hz = clk_get_rate(boot_cpu_data.clk);
        counter.mult = clocksource_hz2mult(counter_hz, counter.shift);
index cb7a01d..8c9a43d 100644 (file)
@@ -353,9 +353,15 @@ void bfin_coretmr_clockevent_init(void)
 #endif /* CONFIG_TICKSOURCE_CORETMR */
 
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
        time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
+       ts->tv_sec = secs_since_1970;
+       ts->tv_nsec = 0;
+}
+
+void __init time_init(void)
+{
 
 #ifdef CONFIG_RTC_DRV_BFIN
        /* [#2663] hack to filter junk RTC values that would cause
@@ -368,11 +374,6 @@ void __init time_init(void)
        }
 #endif
 
-       /* Initialize xtime. From now on, xtime is updated with timer interrupts */
-       xtime.tv_sec = secs_since_1970;
-       xtime.tv_nsec = 0;
-       set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
-
        bfin_cs_cycles_init();
        bfin_cs_gptimer0_init();
 
index 13c1ee3..c911361 100644 (file)
@@ -112,11 +112,6 @@ u32 arch_gettimeoffset(void)
 }
 #endif
 
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
-       return 0;
-}
-
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
@@ -126,29 +121,8 @@ __attribute__((l1_text))
 #endif
 irqreturn_t timer_interrupt(int irq, void *dummy)
 {
-       /* last time the cmos clock got updated */
-       static long last_rtc_update;
-
        write_seqlock(&xtime_lock);
        do_timer(1);
-
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        */
-       if (ntp_synced() &&
-           xtime.tv_sec > last_rtc_update + 660 &&
-           (xtime.tv_nsec / NSEC_PER_USEC) >=
-           500000 - ((unsigned)TICK_SIZE) / 2
-           && (xtime.tv_nsec / NSEC_PER_USEC) <=
-           500000 + ((unsigned)TICK_SIZE) / 2) {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else
-                       /* Do it again in 60s. */
-                       last_rtc_update = xtime.tv_sec - 600;
-       }
        write_sequnlock(&xtime_lock);
 
 #ifdef CONFIG_IPIPE
@@ -161,10 +135,15 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
        return IRQ_HANDLED;
 }
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
        time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */
+       ts->tv_sec = secs_since_1970;
+       ts->tv_nsec = 0;
+}
 
+void __init time_init(void)
+{
 #ifdef CONFIG_RTC_DRV_BFIN
        /* [#2663] hack to filter junk RTC values that would cause
         * userspace to have to deal with time values greater than
@@ -176,11 +155,5 @@ void __init time_init(void)
        }
 #endif
 
-       /* Initialize xtime. From now on, xtime is updated with timer interrupts */
-       xtime.tv_sec = secs_since_1970;
-       xtime.tv_nsec = 0;
-
-       wall_to_monotonic.tv_sec = -xtime.tv_sec;
-
        time_sched_init(timer_interrupt);
 }
index 059eac6..e25bf44 100644 (file)
@@ -23,6 +23,9 @@ config RWSEM_XCHGADD_ALGORITHM
 config GENERIC_TIME
        def_bool y
 
+config GENERIC_CMOS_UPDATE
+       def_bool y
+
 config ARCH_USES_GETTIMEOFFSET
        def_bool y
 
index 31ca141..30adae5 100644 (file)
@@ -26,7 +26,6 @@
 /* it will make jiffies at 96 hz instead of 100 hz though */
 #undef USE_CASCADE_TIMERS
 
-extern void update_xtime_from_cmos(void);
 extern int set_rtc_mmss(unsigned long nowtime);
 extern int have_rtc;
 
@@ -188,8 +187,6 @@ stop_watchdog(void)
 #endif 
 }
 
-/* last time the cmos clock got updated */
-static long last_rtc_update = 0;
 
 /*
  * timer_interrupt() needs to keep up the real-time clock,
@@ -232,24 +229,6 @@ timer_interrupt(int irq, void *dev_id)
        do_timer(1);
        
         cris_do_profile(regs); /* Save profiling information */
-
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        *
-        * The division here is not time critical since it will run once in 
-        * 11 minutes
-        */
-       if (ntp_synced() &&
-           xtime.tv_sec > last_rtc_update + 660 &&
-           (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 &&
-           (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else
-                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-       }
         return IRQ_HANDLED;
 }
 
@@ -274,22 +253,10 @@ time_init(void)
         */
        loops_per_usec = 50;
 
-       if(RTC_INIT() < 0) {
-               /* no RTC, start at 1980 */
-               xtime.tv_sec = 0;
-               xtime.tv_nsec = 0;
+       if(RTC_INIT() < 0)
                have_rtc = 0;
-       } else {                
-               /* get the current time */
+       else
                have_rtc = 1;
-               update_xtime_from_cmos();
-       }
-
-       /*
-        * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
-        * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
-        */
-       set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
 
        /* Setup the etrax timers
         * Base frequency is 25000 hz, divider 250 -> 100 HZ
index b1920d8..1ee0e10 100644 (file)
@@ -44,7 +44,6 @@ unsigned long timer_regs[NR_CPUS] =
 #endif
 };
 
-extern void update_xtime_from_cmos(void);
 extern int set_rtc_mmss(unsigned long nowtime);
 extern int have_rtc;
 
@@ -198,9 +197,6 @@ handle_watchdog_bite(struct pt_regs* regs)
 #endif
 }
 
-/* Last time the cmos clock got updated. */
-static long last_rtc_update = 0;
-
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick.
@@ -238,25 +234,6 @@ timer_interrupt(int irq, void *dev_id)
 
        /* Call the real timer interrupt handler */
        do_timer(1);
-
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        *
-        * The division here is not time critical since it will run once in
-        * 11 minutes
-        */
-       if ((time_status & STA_UNSYNC) == 0 &&
-           xtime.tv_sec > last_rtc_update + 660 &&
-           (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 &&
-           (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else
-                       /* Do it again in 60 s */
-                       last_rtc_update = xtime.tv_sec - 600;
-       }
         return IRQ_HANDLED;
 }
 
@@ -309,23 +286,10 @@ time_init(void)
         */
        loops_per_usec = 50;
 
-       if(RTC_INIT() < 0) {
-               /* No RTC, start at 1980 */
-               xtime.tv_sec = 0;
-               xtime.tv_nsec = 0;
+       if(RTC_INIT() < 0)
                have_rtc = 0;
-       } else {
-               /* Get the current time */
+       else
                have_rtc = 1;
-               update_xtime_from_cmos();
-       }
-
-       /*
-        * Initialize wall_to_monotonic such that adding it to
-        * xtime will yield zero, the tv_nsec field must be normalized
-        * (i.e., 0 <= nsec < NSEC_PER_SEC).
-        */
-       set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
 
        /* Start CPU local timer. */
        cris_timer_init();
index a6aca81..88dc9b9 100644 (file)
@@ -15,7 +15,7 @@
 
 #define ATOMIC_INIT(i)  { (i) }
 
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 #define atomic_set(v,i) (((v)->counter) = (i))
 
 /* These should be written in asm but we do it in C for now. */
index a05dd31..c72730d 100644 (file)
@@ -98,6 +98,8 @@ unsigned long
 get_cmos_time(void)
 {
        unsigned int year, mon, day, hour, min, sec;
+       if(!have_rtc)
+               return 0;
 
        sec = CMOS_READ(RTC_SECONDS);
        min = CMOS_READ(RTC_MINUTES);
@@ -119,19 +121,19 @@ get_cmos_time(void)
        return mktime(year, mon, day, hour, min, sec);
 }
 
-/* update xtime from the CMOS settings. used when /dev/rtc gets a SET_TIME.
- * TODO: this doesn't reset the fancy NTP phase stuff as do_settimeofday does.
- */
 
-void
-update_xtime_from_cmos(void)
+int update_persistent_clock(struct timespec now)
 {
-       if(have_rtc) {
-               xtime.tv_sec = get_cmos_time();
-               xtime.tv_nsec = 0;
-       }
+       return set_rtc_mmss(now.tv_sec);
 }
 
+void read_persistent_clock(struct timespec *ts)
+{
+       ts->tv_sec = get_cmos_time();
+       ts->tv_nsec = 0;
+}
+
+
 extern void cris_profile_sample(struct pt_regs* regs);
 
 void
index 00a57af..fae32c7 100644 (file)
@@ -36,7 +36,7 @@
 #define smp_mb__after_atomic_inc()     barrier()
 
 #define ATOMIC_INIT(i)         { (i) }
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = (i))
 
 #ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
index fb0ce75..0ddbbae 100644 (file)
@@ -48,20 +48,12 @@ static struct irqaction timer_irq  = {
        .name = "timer",
 };
 
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
-       return -1;
-}
-
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
 static irqreturn_t timer_interrupt(int irq, void *dummy)
 {
-       /* last time the cmos clock got updated */
-       static long last_rtc_update = 0;
-
        profile_tick(CPU_PROFILING);
        /*
         * Here we are in the timer irq handler. We just have irqs locally
@@ -74,22 +66,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy)
 
        do_timer(1);
 
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        */
-       if (ntp_synced() &&
-           xtime.tv_sec > last_rtc_update + 660 &&
-           (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
-           (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2
-           ) {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else
-                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-       }
-
 #ifdef CONFIG_HEARTBEAT
        static unsigned short n;
        n++;
@@ -119,7 +95,8 @@ void time_divisor_init(void)
        __set_TCSR_DATA(0, base >> 8);
 }
 
-void time_init(void)
+
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned int year, mon, day, hour, min, sec;
 
@@ -135,9 +112,12 @@ void time_init(void)
 
        if ((year += 1900) < 1970)
                year += 100;
-       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-       xtime.tv_nsec = 0;
+       ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+       ts->tv_nsec = 0;
+}
 
+void time_init(void)
+{
        /* install scheduling interrupt handler */
        setup_irq(IRQ_CPU_TIMER0, &timer_irq);
 
index 33c8c0f..e936804 100644 (file)
@@ -10,7 +10,7 @@
 
 #define ATOMIC_INIT(i) { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 #include <asm/system.h>
index 7f2d6cf..165005a 100644 (file)
@@ -41,7 +41,7 @@ void h8300_timer_tick(void)
        update_process_times(user_mode(get_irq_regs()));
 }
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned int year, mon, day, hour, min, sec;
 
@@ -56,8 +56,12 @@ void __init time_init(void)
 #endif
        if ((year += 1900) < 1970)
                year += 100;
-       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-       xtime.tv_nsec = 0;
+       ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+       ts->tv_nsec = 0;
+}
+
+void __init time_init(void)
+{
 
        h8300_timer_setup();
 }
index 4d4f418..9676100 100644 (file)
@@ -59,9 +59,6 @@ config NEED_DMA_MAP_STATE
 config SWIOTLB
        bool
 
-config IOMMU_HELPER
-       bool
-
 config GENERIC_LOCKBREAK
        def_bool n
 
index e14c492..4ce8d13 100644 (file)
@@ -2046,13 +2046,13 @@ acpi_sba_ioc_add(struct acpi_device *device)
        struct ioc *ioc;
        acpi_status status;
        u64 hpa, length;
-       struct acpi_device_info *dev_info;
+       struct acpi_device_info *adi;
 
        status = hp_acpi_csr_space(device->handle, &hpa, &length);
        if (ACPI_FAILURE(status))
                return 1;
 
-       status = acpi_get_object_info(device->handle, &dev_info);
+       status = acpi_get_object_info(device->handle, &adi);
        if (ACPI_FAILURE(status))
                return 1;
 
@@ -2060,13 +2060,13 @@ acpi_sba_ioc_add(struct acpi_device *device)
         * For HWP0001, only SBA appears in ACPI namespace.  It encloses the PCI
         * root bridges, and its CSR space includes the IOC function.
         */
-       if (strncmp("HWP0001", dev_info->hardware_id.string, 7) == 0) {
+       if (strncmp("HWP0001", adi->hardware_id.string, 7) == 0) {
                hpa += ZX1_IOC_OFFSET;
                /* zx1 based systems default to kernel page size iommu pages */
                if (!iovp_shift)
                        iovp_shift = min(PAGE_SHIFT, 16);
        }
-       kfree(dev_info);
+       kfree(adi);
 
        /*
         * default anything not caught above or specified on cmdline to 4k
index 88405cb..4e19484 100644 (file)
@@ -21,8 +21,8 @@
 #define ATOMIC_INIT(i)         ((atomic_t) { (i) })
 #define ATOMIC64_INIT(i)       ((atomic64_t) { (i) })
 
-#define atomic_read(v)         ((v)->counter)
-#define atomic64_read(v)       ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 #define atomic_set(v,i)                (((v)->counter) = (i))
 #define atomic64_set(v,i)      (((v)->counter) = (i))
index 6ebc229..9da3df6 100644 (file)
@@ -437,17 +437,18 @@ __fls (unsigned long x)
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
  */
-static __inline__ unsigned long
-hweight64 (unsigned long x)
+static __inline__ unsigned long __arch_hweight64(unsigned long x)
 {
        unsigned long result;
        result = ia64_popcnt(x);
        return result;
 }
 
-#define hweight32(x)   (unsigned int) hweight64((x) & 0xfffffffful)
-#define hweight16(x)   (unsigned int) hweight64((x) & 0xfffful)
-#define hweight8(x)    (unsigned int) hweight64((x) & 0xfful)
+#define __arch_hweight32(x) ((unsigned int) __arch_hweight64((x) & 0xfffffffful))
+#define __arch_hweight16(x) ((unsigned int) __arch_hweight64((x) & 0xfffful))
+#define __arch_hweight8(x)  ((unsigned int) __arch_hweight64((x) & 0xfful))
+
+#include <asm-generic/bitops/const_hweight.h>
 
 #endif /* __KERNEL__ */
 
index f2ca320..e0de617 100644 (file)
 
 static inline int pfn_to_nid(unsigned long pfn)
 {
-#ifdef CONFIG_NUMA
        extern int paddr_to_nid(unsigned long);
        int nid = paddr_to_nid(pfn << PAGE_SHIFT);
        if (nid < 0)
                return 0;
        else
                return nid;
-#else
-       return 0;
-#endif
 }
 
 #ifdef CONFIG_IA64_DIG /* DIG systems are small */
index 4d1a7e9..c6c90f3 100644 (file)
@@ -785,6 +785,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
        return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+       if (isa_irq >= 16)
+               return -1;
+       *gsi = isa_irq;
+       return 0;
+}
+
 /*
  *  ACPI based hotplug CPU support
  */
index b0b4e6e..22f6152 100644 (file)
@@ -113,7 +113,7 @@ processor_get_freq (
        dprintk("processor_get_freq\n");
 
        saved_mask = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
        if (smp_processor_id() != cpu)
                goto migrate_end;
 
@@ -121,7 +121,7 @@ processor_get_freq (
        ret = processor_get_pstate(&value);
 
        if (ret) {
-               set_cpus_allowed(current, saved_mask);
+               set_cpus_allowed_ptr(current, &saved_mask);
                printk(KERN_WARNING "get performance failed with error %d\n",
                       ret);
                ret = 0;
@@ -131,7 +131,7 @@ processor_get_freq (
        ret = (clock_freq*1000);
 
 migrate_end:
-       set_cpus_allowed(current, saved_mask);
+       set_cpus_allowed_ptr(current, &saved_mask);
        return ret;
 }
 
@@ -151,7 +151,7 @@ processor_set_freq (
        dprintk("processor_set_freq\n");
 
        saved_mask = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
        if (smp_processor_id() != cpu) {
                retval = -EAGAIN;
                goto migrate_end;
@@ -208,7 +208,7 @@ processor_set_freq (
        retval = 0;
 
 migrate_end:
-       set_cpus_allowed(current, saved_mask);
+       set_cpus_allowed_ptr(current, &saved_mask);
        return (retval);
 }
 
index 6404793..f14c35f 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/threads.h>
 #include <linux/bitops.h>
 #include <linux/irq.h>
+#include <linux/ratelimit.h>
 
 #include <asm/delay.h>
 #include <asm/intrinsics.h>
@@ -467,13 +468,9 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
                sp = ia64_getreg(_IA64_REG_SP);
 
                if ((sp - bsp) < 1024) {
-                       static unsigned char count;
-                       static long last_time;
+                       static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
 
-                       if (time_after(jiffies, last_time + 5 * HZ))
-                               count = 0;
-                       if (++count < 5) {
-                               last_time = jiffies;
+                       if (__ratelimit(&ratelimit)) {
                                printk("ia64_handle_irq: DANGER: less than "
                                       "1KB of free stack space!!\n"
                                       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
index e6676fc..aa8b5fa 100644 (file)
@@ -404,10 +404,9 @@ static void
 call_on_cpu(int cpu, void (*fn)(void *), void *arg)
 {
        cpumask_t save_cpus_allowed = current->cpus_allowed;
-       cpumask_t new_cpus_allowed = cpumask_of_cpu(cpu);
-       set_cpus_allowed(current, new_cpus_allowed);
+       set_cpus_allowed_ptr(current, cpumask_of(cpu));
        (*fn)(arg);
-       set_cpus_allowed(current, save_cpus_allowed);
+       set_cpus_allowed_ptr(current, &save_cpus_allowed);
 }
 
 static void
index 47a1927..653b3c4 100644 (file)
@@ -430,18 +430,16 @@ static int __init rtc_init(void)
 }
 module_init(rtc_init);
 
+void read_persistent_clock(struct timespec *ts)
+{
+       efi_gettimeofday(ts);
+}
+
 void __init
 time_init (void)
 {
        register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction);
-       efi_gettimeofday(&xtime);
        ia64_init_itm();
-
-       /*
-        * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
-        * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
-        */
-       set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
 }
 
 /*
index 28f299d..0baa1bb 100644 (file)
@@ -361,12 +361,12 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
                return 0;
 
        oldmask = current->cpus_allowed;
-       retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
+       retval = set_cpus_allowed_ptr(current, cpumask_of(cpu));
        if (unlikely(retval))
                return retval;
 
        retval = cpu_cache_sysfs_init(cpu);
-       set_cpus_allowed(current, oldmask);
+       set_cpus_allowed_ptr(current, &oldmask);
        if (unlikely(retval < 0))
                return retval;
 
index 776dd40..622772b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
+#include <linux/ratelimit.h>
 
 #include <asm/intrinsics.h>
 #include <asm/processor.h>
@@ -1283,24 +1284,9 @@ emulate_store_float (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
 /*
  * Make sure we log the unaligned access, so that user/sysadmin can notice it and
  * eventually fix the program.  However, we don't want to do that for every access so we
- * pace it with jiffies.  This isn't really MP-safe, but it doesn't really have to be
- * either...
+ * pace it with jiffies.
  */
-static int
-within_logging_rate_limit (void)
-{
-       static unsigned long count, last_time;
-
-       if (time_after(jiffies, last_time + 5 * HZ))
-               count = 0;
-       if (count < 5) {
-               last_time = jiffies;
-               count++;
-               return 1;
-       }
-       return 0;
-
-}
+static DEFINE_RATELIMIT_STATE(logging_rate_limit, 5 * HZ, 5);
 
 void
 ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
@@ -1337,7 +1323,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
 
                if (!no_unaligned_warning &&
                    !(current->thread.flags & IA64_THREAD_UAC_NOPRINT) &&
-                   within_logging_rate_limit())
+                   __ratelimit(&logging_rate_limit))
                {
                        char buf[200];  /* comm[] is at most 16 bytes... */
                        size_t len;
@@ -1370,7 +1356,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                        }
                }
        } else {
-               if (within_logging_rate_limit()) {
+               if (__ratelimit(&logging_rate_limit)) {
                        printk(KERN_WARNING "kernel unaligned access to 0x%016lx, ip=0x%016lx\n",
                               ifa, regs->cr_iip + ipsr->ri);
                        if (unaligned_dump_stack)
index 73c5c2b..7f3c0a2 100644 (file)
@@ -1802,7 +1802,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 {
        struct kvm_memory_slot *memslot;
        int r, i;
-       long n, base;
+       long base;
+       unsigned long n;
        unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base +
                        offsetof(struct kvm_vm_data, kvm_mem_dirty_log));
 
@@ -1815,7 +1816,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
        base = memslot->base_gfn / BITS_PER_LONG;
 
        for (i = 0; i < n/sizeof(long); ++i) {
@@ -1831,7 +1832,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                struct kvm_dirty_log *log)
 {
        int r;
-       int n;
+       unsigned long n;
        struct kvm_memory_slot *memslot;
        int is_dirty = 0;
 
@@ -1850,7 +1851,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        if (is_dirty) {
                kvm_flush_remote_tlbs(kvm);
                memslot = &kvm->memslots->memslots[log->slot];
-               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               n = kvm_dirty_bitmap_bytes(memslot);
                memset(memslot->dirty_bitmap, 0, n);
        }
        r = 0;
index 19261a9..0799fea 100644 (file)
@@ -148,7 +148,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
        if ((vma->vm_flags & mask) != mask)
                goto bad_area;
 
-  survive:
        /*
         * If for any reason at all we couldn't handle the fault, make
         * sure we exit gracefully rather than endlessly redo the
@@ -276,13 +275,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 
   out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_global_init(current)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
-       printk(KERN_CRIT "VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
-       goto no_context;
+       if (!user_mode(regs))
+               goto no_context;
+       pagefault_out_of_memory();
 }
index 55ac3c4..f6c1c5f 100644 (file)
@@ -629,9 +629,9 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
                else {
                        /* migrate the task before calling SAL */ 
                        save_allowed = current->cpus_allowed;
-                       set_cpus_allowed(current, cpumask_of_cpu(cpu));
+                       set_cpus_allowed_ptr(current, cpumask_of(cpu));
                        sn_hwperf_call_sal(op_info);
-                       set_cpus_allowed(current, save_allowed);
+                       set_cpus_allowed_ptr(current, &save_allowed);
                }
        }
        r = op_info->ret;
index 63f0cf0..d44a51e 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Atomically reads the value of @v.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
index 9cedcef..bda8682 100644 (file)
@@ -105,24 +105,6 @@ u32 arch_gettimeoffset(void)
        return elapsed_time * 1000;
 }
 
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you won't notice until after reboot!
- */
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
-       return 0;
-}
-
-/* last time the cmos clock got updated */
-static long last_rtc_update = 0;
-
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
@@ -138,23 +120,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
 #ifndef CONFIG_SMP
        update_process_times(user_mode(get_irq_regs()));
 #endif
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        */
-       write_seqlock(&xtime_lock);
-       if (ntp_synced()
-               && xtime.tv_sec > last_rtc_update + 660
-               && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
-               && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2)
-       {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else    /* do it again in 60 s */
-                       last_rtc_update = xtime.tv_sec - 600;
-       }
-       write_sequnlock(&xtime_lock);
        /* As we return to user mode fire off the other CPU schedulers..
           this is basically because we don't yet share IRQ's around.
           This message is rigged to be safe on the 386 - basically it's
@@ -174,7 +139,7 @@ static struct irqaction irq0 = {
        .name = "MFT2",
 };
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
        unsigned int epoch, year, mon, day, hour, min, sec;
 
@@ -194,11 +159,13 @@ void __init time_init(void)
                epoch = 1952;
        year += epoch;
 
-       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-       xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-       set_normalized_timespec(&wall_to_monotonic,
-               -xtime.tv_sec, -xtime.tv_nsec);
+       ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+       ts->tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+}
 
+
+void __init time_init(void)
+{
 #if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
        || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
        || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
index 6a0d765..11dd30b 100644 (file)
@@ -2,6 +2,6 @@
 # Makefile for Linux arch/m68k/amiga source directory
 #
 
-obj-y          := config.o amiints.o cia.o chipram.o amisound.o
+obj-y          := config.o amiints.o cia.o chipram.o amisound.o platform.o
 
 obj-$(CONFIG_AMIGA_PCMCIA)     += pcmcia.o
diff --git a/arch/m68k/amiga/platform.c b/arch/m68k/amiga/platform.c
new file mode 100644 (file)
index 0000000..38f18bf
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (C) 2007-2009 Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/zorro.h>
+
+#include <asm/amigahw.h>
+
+
+#ifdef CONFIG_ZORRO
+
+static const struct resource zorro_resources[] __initconst = {
+       /* Zorro II regions (on Zorro II/III) */
+       {
+               .name   = "Zorro II exp",
+               .start  = 0x00e80000,
+               .end    = 0x00efffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "Zorro II mem",
+               .start  = 0x00200000,
+               .end    = 0x009fffff,
+               .flags  = IORESOURCE_MEM,
+       },
+       /* Zorro III regions (on Zorro III only) */
+       {
+               .name   = "Zorro III exp",
+               .start  = 0xff000000,
+               .end    = 0xffffffff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .name   = "Zorro III cfg",
+               .start  = 0x40000000,
+               .end    = 0x7fffffff,
+               .flags  = IORESOURCE_MEM,
+       }
+};
+
+
+static int __init amiga_init_bus(void)
+{
+       if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
+               return -ENODEV;
+
+       platform_device_register_simple("amiga-zorro", -1, zorro_resources,
+                                       AMIGAHW_PRESENT(ZORRO3) ? 4 : 2);
+       return 0;
+}
+
+subsys_initcall(amiga_init_bus);
+
+#endif /* CONFIG_ZORRO */
+
+
+static int __init amiga_init_devices(void)
+{
+       if (!MACH_IS_AMIGA)
+               return -ENODEV;
+
+       /* video hardware */
+       if (AMIGAHW_PRESENT(AMI_VIDEO))
+               platform_device_register_simple("amiga-video", -1, NULL, 0);
+
+
+       /* sound hardware */
+       if (AMIGAHW_PRESENT(AMI_AUDIO))
+               platform_device_register_simple("amiga-audio", -1, NULL, 0);
+
+
+       /* storage interfaces */
+       if (AMIGAHW_PRESENT(AMI_FLOPPY))
+               platform_device_register_simple("amiga-floppy", -1, NULL, 0);
+
+       return 0;
+}
+
+device_initcall(amiga_init_devices);
index b46ea17..cb8617b 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/capability.h>
 #include <linux/fcntl.h>
 static unsigned char days_in_mo[] =
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
-static char rtc_status;
+static atomic_t rtc_status = ATOMIC_INIT(1);
 
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                    unsigned long arg)
+static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
        unsigned char msr;
@@ -132,29 +130,20 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 }
 
 /*
- *     We enforce only one user at a time here with the open/close.
- *     Also clear the previous interrupt data on an open, and clean
- *     up things on a close.
+ * We enforce only one user at a time here with the open/close.
  */
-
 static int rtc_open(struct inode *inode, struct file *file)
 {
-       lock_kernel();
-       if(rtc_status) {
-               unlock_kernel();
+       if (!atomic_dec_and_test(&rtc_status)) {
+               atomic_inc(&rtc_status);
                return -EBUSY;
        }
-
-       rtc_status = 1;
-       unlock_kernel();
        return 0;
 }
 
 static int rtc_release(struct inode *inode, struct file *file)
 {
-       lock_kernel();
-       rtc_status = 0;
-       unlock_kernel();
+       atomic_inc(&rtc_status);
        return 0;
 }
 
@@ -163,9 +152,9 @@ static int rtc_release(struct inode *inode, struct file *file)
  */
 
 static const struct file_operations rtc_fops = {
-       .ioctl =        rtc_ioctl,
-       .open =         rtc_open,
-       .release =      rtc_release,
+       .unlocked_ioctl = rtc_ioctl,
+       .open           = rtc_open,
+       .release        = rtc_release,
 };
 
 static struct miscdevice rtc_dev = {
index f5b3d09..7b98242 100644 (file)
@@ -1,4 +1,2 @@
 extern void hp300_sched_init(irq_handler_t vector);
-extern unsigned long hp300_gettimeoffset (void);
-
-
+extern unsigned long hp300_gettimeoffset(void);
index 88b7af2..6a223b3 100644 (file)
@@ -15,7 +15,7 @@
 
 #define ATOMIC_INIT(i) { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 static inline void atomic_add(int i, atomic_t *v)
@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new)
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 {
        char c;
-       __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
+       __asm__ __volatile__("subl %2,%1; seq %0"
+                            : "=d" (c), "+m" (*v)
+                            : "id" (i));
        return c != 0;
 }
 
 static inline int atomic_add_negative(int i, atomic_t *v)
 {
        char c;
-       __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
+       __asm__ __volatile__("addl %2,%1; smi %0"
+                            : "=d" (c), "+m" (*v)
+                            : "id" (i));
        return c != 0;
 }
 
index 5674cb9..289310c 100644 (file)
@@ -15,7 +15,7 @@
 
 #define ATOMIC_INIT(i) { (i) }
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v, i)       (((v)->counter) = i)
 
 static __inline__ void atomic_add(int i, atomic_t *v)
index 9bde784..b4ecdaa 100644 (file)
@@ -365,6 +365,10 @@ static inline int minix_test_bit(int nr, const void *vaddr)
 #define ext2_set_bit_atomic(lock, nr, addr)    test_and_set_bit((nr) ^ 24, (unsigned long *)(addr))
 #define ext2_clear_bit(nr, addr)               __test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
 #define ext2_clear_bit_atomic(lock, nr, addr)  test_and_clear_bit((nr) ^ 24, (unsigned long *)(addr))
+#define ext2_find_next_zero_bit(addr, size, offset) \
+       generic_find_next_zero_le_bit((unsigned long *)addr, size, offset)
+#define ext2_find_next_bit(addr, size, offset) \
+       generic_find_next_le_bit((unsigned long *)addr, size, offset)
 
 static inline int ext2_test_bit(int nr, const void *vaddr)
 {
@@ -394,10 +398,9 @@ static inline int ext2_find_first_zero_bit(const void *vaddr, unsigned size)
        return (p - addr) * 32 + res;
 }
 
-static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size,
-                                         unsigned offset)
+static inline unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
+               unsigned long size, unsigned long offset)
 {
-       const unsigned long *addr = vaddr;
        const unsigned long *p = addr + (offset >> 5);
        int bit = offset & 31UL, res;
 
@@ -437,10 +440,9 @@ static inline int ext2_find_first_bit(const void *vaddr, unsigned size)
        return (p - addr) * 32 + res;
 }
 
-static inline int ext2_find_next_bit(const void *vaddr, unsigned size,
-                                    unsigned offset)
+static inline unsigned long generic_find_next_le_bit(const unsigned long *addr,
+               unsigned long size, unsigned long offset)
 {
-       const unsigned long *addr = vaddr;
        const unsigned long *p = addr + (offset >> 5);
        int bit = offset & 31UL, res;
 
index ef22938..01a8716 100644 (file)
@@ -212,5 +212,10 @@ struct mcf_platform_uart {
 #define        MCFUART_URF_RXS         0xc0            /* Receiver status */
 #endif
 
+#if defined(CONFIG_M5272)
+#define MCFUART_TXFIFOSIZE     25
+#else
+#define MCFUART_TXFIFOSIZE     1
+#endif
 /****************************************************************************/
 #endif /* mcfuart_h */
index 85c41b7..36265cc 100644 (file)
@@ -1,26 +1,12 @@
 #ifndef _M68K_PARAM_H
 #define _M68K_PARAM_H
 
-#ifdef __KERNEL__
-# define HZ            CONFIG_HZ       /* Internal kernel timer frequency */
-# define USER_HZ       100             /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
 #ifdef __uClinux__
 #define EXEC_PAGESIZE  4096
 #else
 #define EXEC_PAGESIZE  8192
 #endif
 
-#ifndef NOGROUP
-#define NOGROUP                (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64      /* max length of hostname */
+#include <asm-generic/param.h>
 
 #endif /* _M68K_PARAM_H */
index 1320eaa..a29dd74 100644 (file)
@@ -17,13 +17,11 @@ struct sigcontext {
 #ifndef __uClinux__
 # ifdef __mcoldfire__
        unsigned long  sc_fpregs[2][2]; /* room for two fp registers */
-       unsigned long  sc_fpcntl[3];
-       unsigned char  sc_fpstate[16+6*8];
 # else
        unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
+# endif
        unsigned long  sc_fpcntl[3];
        unsigned char  sc_fpstate[216];
-# endif
 #endif
 };
 
index 17dc2a3..4926b38 100644 (file)
@@ -73,21 +73,24 @@ static irqreturn_t timer_interrupt(int irq, void *dummy)
        return IRQ_HANDLED;
 }
 
-void __init time_init(void)
+void read_persistent_clock(struct timespec *ts)
 {
        struct rtc_time time;
+       ts->tv_sec = 0;
+       ts->tv_nsec = 0;
 
        if (mach_hwclk) {
                mach_hwclk(0, &time);
 
                if ((time.tm_year += 1900) < 1970)
                        time.tm_year += 100;
-               xtime.tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
+               ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
                                      time.tm_hour, time.tm_min, time.tm_sec);
-               xtime.tv_nsec = 0;
        }
-       wall_to_monotonic.tv_sec = -xtime.tv_sec;
+}
 
+void __init time_init(void)
+{
        mach_sched_init(timer_interrupt);
 }
 
index aacd6d1..ada4f4c 100644 (file)
@@ -455,7 +455,7 @@ static inline void access_error040(struct frame *fp)
 
                if (do_page_fault(&fp->ptregs, addr, errorcode)) {
 #ifdef DEBUG
-                       printk("do_page_fault() !=0 \n");
+                       printk("do_page_fault() !=0\n");
 #endif
                        if (user_mode(&fp->ptregs)){
                                /* delay writebacks after signal delivery */
index 0356da9..1c16b1b 100644 (file)
@@ -148,7 +148,7 @@ static void mac_cache_card_flush(int writeback)
 void __init config_mac(void)
 {
        if (!MACH_IS_MAC)
-               printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n");
+               printk(KERN_ERR "ERROR: no Mac, but config_mac() called!!\n");
 
        mach_sched_init = mac_sched_init;
        mach_init_IRQ = mac_init_IRQ;
@@ -867,7 +867,7 @@ static void __init mac_identify(void)
         */
        iop_preinit();
 
-       printk(KERN_INFO "Detected Macintosh model: %d \n", model);
+       printk(KERN_INFO "Detected Macintosh model: %d\n", model);
 
        /*
         * Report booter data:
@@ -878,12 +878,12 @@ static void __init mac_identify(void)
                mac_bi_data.videoaddr, mac_bi_data.videorow,
                mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF,
                mac_bi_data.dimensions >> 16);
-       printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n",
+       printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx\n",
                mac_bi_data.videological, mac_orig_videoaddr,
                mac_bi_data.sccbase);
-       printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n",
+       printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx\n",
                mac_bi_data.boottime, mac_bi_data.gmtbias);
-       printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n",
+       printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx\n",
                mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize);
 
        iop_init();
index d0e35cf..a96394a 100644 (file)
@@ -154,7 +154,6 @@ good_area:
         * the fault.
         */
 
- survive:
        fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
 #ifdef DEBUG
        printk("handle_mm_fault returns %d\n",fault);
@@ -180,15 +179,10 @@ good_area:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_global_init(current)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
-
-       printk("VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
+       if (!user_mode(regs))
+               goto no_context;
+       pagefault_out_of_memory();
+       return 0;
 
 no_context:
        current->thread.signo = SIGBUS;
index 8da9c25..11ac6f6 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/capability.h>
 #include <linux/fcntl.h>
@@ -36,8 +35,7 @@ static const unsigned char days_in_mo[] =
 
 static atomic_t rtc_ready = ATOMIC_INIT(1);
 
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                    unsigned long arg)
+static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE;
        unsigned long flags;
@@ -120,22 +118,15 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 }
 
 /*
- *     We enforce only one user at a time here with the open/close.
- *     Also clear the previous interrupt data on an open, and clean
- *     up things on a close.
+ * We enforce only one user at a time here with the open/close.
  */
-
 static int rtc_open(struct inode *inode, struct file *file)
 {
-       lock_kernel();
        if( !atomic_dec_and_test(&rtc_ready) )
        {
                atomic_inc( &rtc_ready );
-               unlock_kernel();
                return -EBUSY;
        }
-       unlock_kernel();
-
        return 0;
 }
 
@@ -150,9 +141,9 @@ static int rtc_release(struct inode *inode, struct file *file)
  */
 
 static const struct file_operations rtc_fops = {
-       .ioctl =        rtc_ioctl,
-       .open =         rtc_open,
-       .release =      rtc_release,
+       .unlocked_ioctl = rtc_ioctl,
+       .open           = rtc_open,
+       .release        = rtc_release,
 };
 
 static struct miscdevice rtc_dev=
index 31ab3f0..ad10fec 100644 (file)
@@ -126,7 +126,7 @@ static void q40_reset(void)
 {
         halted = 1;
         printk("\n\n*******************************************\n"
-               "Called q40_reset : press the RESET button!! \n"
+               "Called q40_reset : press the RESET button!!\n"
                "*******************************************\n");
        Q40_LED_ON();
        while (1)
index ce404bc..1404257 100644 (file)
@@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x)                := $(call cc-option,-mcpu=5208,-m5200)
 cflags-$(CONFIG_M523x)         := $(call cc-option,-mcpu=523x,-m5307)
 cflags-$(CONFIG_M5249)         := $(call cc-option,-mcpu=5249,-m5200)
 cflags-$(CONFIG_M5271)         := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5271,-m5200)
+cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5272,-m5307)
 cflags-$(CONFIG_M5275)         := $(call cc-option,-mcpu=5275,-m5307)
 cflags-$(CONFIG_M528x)         := $(call cc-option,-m528x,-m5307)
 cflags-$(CONFIG_M5307)         := $(call cc-option,-m5307,-m5200)
index 56043ad..aff6f57 100644 (file)
@@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal)
        trap #0
 
 ENTRY(ret_from_user_rt_signal)
-       move #__NR_rt_sigreturn,%d0
+       movel #__NR_rt_sigreturn,%d0
        trap #0
 
index 1143f77..6f22970 100644 (file)
@@ -107,7 +107,6 @@ void init_IRQ(void)
        _ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
        _ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
        _ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
-       _ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
        _ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
        _ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
        _ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
index 6fced1f..3c91cf6 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc6
-# Wed Feb  3 10:02:59 2010
+# Linux kernel version: 2.6.34-rc6
+# Thu May  6 11:22:14 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -22,8 +22,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_PCI is not set
-CONFIG_NO_DMA=y
 CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -56,7 +54,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -106,6 +103,8 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -245,13 +244,20 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Bus Options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -341,7 +347,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
 CONFIG_OF_DEVICE=y
+CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -370,6 +378,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -383,9 +392,30 @@ CONFIG_NETDEVICES=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_ETHOC is not set
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -394,6 +424,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851_MLL is not set
 CONFIG_XILINX_EMACLITE=y
@@ -444,6 +475,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -471,6 +503,12 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -502,6 +540,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -572,6 +611,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -595,6 +635,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=y
 CONFIG_CIFS_STATS=y
 CONFIG_CIFS_STATS2=y
@@ -696,6 +737,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_OBJECTS is not set
 CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
@@ -741,6 +783,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
@@ -862,5 +905,6 @@ CONFIG_ZLIB_INFLATE=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
index ce2da53..dd3a494 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc6
-# Wed Feb  3 10:03:21 2010
+# Linux kernel version: 2.6.34-rc6
+# Thu May  6 11:25:12 2010
 #
 CONFIG_MICROBLAZE=y
 # CONFIG_SWAP is not set
@@ -22,8 +22,6 @@ CONFIG_GENERIC_CSUM=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-# CONFIG_PCI is not set
-CONFIG_NO_DMA=y
 CONFIG_DTC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -58,7 +56,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -96,6 +93,8 @@ CONFIG_SLAB=y
 # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -209,11 +208,14 @@ CONFIG_PROC_DEVICETREE=y
 #
 # Advanced setup
 #
+# CONFIG_ADVANCED_OPTIONS is not set
 
 #
 # Default settings for advanced configuration options are used
 #
+CONFIG_LOWMEM_SIZE=0x30000000
 CONFIG_KERNEL_START=0x90000000
+CONFIG_TASK_SIZE=0x80000000
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -235,13 +237,20 @@ CONFIG_BINFMT_FLAT=y
 # CONFIG_BINFMT_SHARED_FLAT is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Bus Options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -413,6 +422,7 @@ CONFIG_MTD_UCLINUX=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -442,6 +452,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -458,6 +469,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
+# CONFIG_ETHOC is not set
 # CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
@@ -466,6 +478,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
 # CONFIG_KS8851_MLL is not set
 # CONFIG_XILINX_EMACLITE is not set
@@ -516,6 +529,7 @@ CONFIG_SERIAL_UARTLITE=y
 CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -544,6 +558,12 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
@@ -593,6 +613,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -661,6 +682,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -689,6 +711,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -733,6 +756,7 @@ CONFIG_DEBUG_OBJECTS_TIMERS=y
 # CONFIG_DEBUG_OBJECTS_WORK is not set
 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -758,6 +782,7 @@ CONFIG_DEBUG_SG=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -782,6 +807,7 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_EARLY_PRINTK=y
 # CONFIG_HEART_BEAT is not set
@@ -901,5 +927,6 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
index e522108..4efe96a 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/registers.h>
 
-#define L1_CACHE_SHIFT 2
+#define L1_CACHE_SHIFT 5
 /* word-granular cache in microblaze */
 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
 
index 08c073b..0d73d0c 100644 (file)
 #define MAX_DMA_ADDRESS (CONFIG_KERNEL_START + memory_size - 1)
 #endif
 
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy     (0)
+#endif
+
 #endif /* _ASM_MICROBLAZE_DMA_H */
index 90731df..4c7b5d0 100644 (file)
@@ -64,12 +64,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
 void die(const char *str, struct pt_regs *fp, long err);
 void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);
 
-#ifdef CONFIG_MMU
-void __bug(const char *file, int line, void *data);
-int bad_trap(int trap_num, struct pt_regs *regs);
-int debug_trap(struct pt_regs *regs);
-#endif /* CONFIG_MMU */
-
 #if defined(CONFIG_KGDB)
 void (*debugger)(struct pt_regs *regs);
 int (*debugger_bpt)(struct pt_regs *regs);
index e45a6ee..00b5398 100644 (file)
@@ -139,8 +139,6 @@ static inline void writel(unsigned int v, volatile void __iomem *addr)
 
 #ifdef CONFIG_MMU
 
-#define mm_ptov(addr)          ((void *)__phys_to_virt(addr))
-#define mm_vtop(addr)          ((unsigned long)__virt_to_phys(addr))
 #define phys_to_virt(addr)     ((void *)__phys_to_virt(addr))
 #define virt_to_phys(addr)     ((unsigned long)__virt_to_phys(addr))
 #define virt_to_bus(addr)      ((unsigned long)__virt_to_phys(addr))
index 2dd1d04..de493f8 100644 (file)
@@ -31,6 +31,9 @@
 
 #ifndef __ASSEMBLY__
 
+/* MS be sure that SLAB allocates aligned objects */
+#define ARCH_KMALLOC_MINALIGN  L1_CACHE_BYTES
+
 #define PAGE_UP(addr)  (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
 #define PAGE_DOWN(addr)        ((addr)&(~((PAGE_SIZE)-1)))
 
@@ -70,14 +73,7 @@ typedef unsigned long pte_basic_t;
 
 #endif /* CONFIG_MMU */
 
-#  ifndef CONFIG_MMU
-#  define copy_page(to, from)                  memcpy((to), (from), PAGE_SIZE)
-#  define get_user_page(vaddr)                 __get_free_page(GFP_KERNEL)
-#  define free_user_page(page, addr)           free_page(addr)
-#  else /* CONFIG_MMU */
-extern void copy_page(void *to, void *from);
-#  endif /* CONFIG_MMU */
-
+# define copy_page(to, from)                   memcpy((to), (from), PAGE_SIZE)
 # define clear_page(pgaddr)                    memset((pgaddr), 0, PAGE_SIZE)
 
 # define clear_user_page(pgaddr, vaddr, page)  memset((pgaddr), 0, PAGE_SIZE)
index bdd65aa..5a388ee 100644 (file)
@@ -94,14 +94,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #define HAVE_PCI_LEGACY        1
 
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME)         (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)        do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME)           (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
-
 /* The PCI address space does equal the physical memory
  * address space (no IOMMU).  The IDE and SCSI device layers use
  * this boolean for bounce buffer decisions.
index f44b0d6..c614a89 100644 (file)
@@ -108,21 +108,7 @@ extern inline void free_pgd_slow(pgd_t *pgd)
 #define pmd_alloc_one_fast(mm, address)        ({ BUG(); ((pmd_t *)1); })
 #define pmd_alloc_one(mm, address)     ({ BUG(); ((pmd_t *)2); })
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-               unsigned long address)
-{
-       pte_t *pte;
-       extern void *early_get_page(void);
-       if (mem_init_done) {
-               pte = (pte_t *)__get_free_page(GFP_KERNEL |
-                                       __GFP_REPEAT | __GFP_ZERO);
-       } else {
-               pte = (pte_t *)early_get_page();
-               if (pte)
-                       clear_page(pte);
-       }
-       return pte;
-}
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
 
 static inline struct page *pte_alloc_one(struct mm_struct *mm,
                unsigned long address)
index dd2bb60..ca2d928 100644 (file)
@@ -511,15 +511,6 @@ static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
-/*
- * When flushing the tlb entry for a page, we also need to flush the hash
- * table entry.  flush_hash_page is assembler (for speed) in hashtable.S.
- */
-extern int flush_hash_page(unsigned context, unsigned long va, pte_t *ptep);
-
-/* Add an HPTE to the hash table */
-extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep);
-
 /*
  * Encode and decode a swap entry.
  * Note that the bits we use in a PTE for representing a swap entry
@@ -533,15 +524,7 @@ extern void add_hash_page(unsigned context, unsigned long va, pte_t *ptep);
 #define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) >> 2 })
 #define __swp_entry_to_pte(x)  ((pte_t) { (x).val << 2 })
 
-
-/* CONFIG_APUS */
-/* For virtual address to physical address conversion */
-extern void cache_clear(__u32 addr, int length);
-extern void cache_push(__u32 addr, int length);
-extern int mm_end_of_chunk(unsigned long addr, int len);
 extern unsigned long iopa(unsigned long addr);
-/* extern unsigned long mm_ptov(unsigned long addr) \
-       __attribute__ ((const)); TBD */
 
 /* Values for nocacheflag and cmode */
 /* These are not used by the APUS kernel_map, but prevents
@@ -552,18 +535,6 @@ extern unsigned long iopa(unsigned long addr);
 #define        IOMAP_NOCACHE_NONSER    2
 #define        IOMAP_NO_COPYBACK       3
 
-/*
- * Map some physical address range into the kernel address space.
- */
-extern unsigned long kernel_map(unsigned long paddr, unsigned long size,
-                               int nocacheflag, unsigned long *memavailp);
-
-/*
- * Set cache mode of (kernel space) address range.
- */
-extern void kernel_set_cachemode(unsigned long address, unsigned long size,
-                               unsigned int cmode);
-
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define kern_addr_valid(addr)  (1)
 
@@ -577,10 +548,6 @@ extern void kernel_set_cachemode(unsigned long address, unsigned long size,
 void do_page_fault(struct pt_regs *regs, unsigned long address,
                   unsigned long error_code);
 
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-                            unsigned int size, int flags);
-
-void __init adjust_total_lowmem(void);
 void mapin_ram(void);
 int map_page(unsigned long va, phys_addr_t pa, int flags);
 
@@ -601,7 +568,7 @@ void __init *early_get_page(void);
 extern unsigned long ioremap_bot, ioremap_base;
 
 void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
-void consistent_free(void *vaddr);
+void consistent_free(size_t size, void *vaddr);
 void consistent_sync(void *vaddr, size_t size, int direction);
 void consistent_sync_page(struct page *page, unsigned long offset,
        size_t size, int direction);
index 446bec2..26460d1 100644 (file)
@@ -182,6 +182,39 @@ extern long __user_bad(void);
  * Returns zero on success, or -EFAULT on error.
  * On error, the variable @x is set to zero.
  */
+#define get_user(x, ptr)                                               \
+       __get_user_check((x), (ptr), sizeof(*(ptr)))
+
+#define __get_user_check(x, ptr, size)                                 \
+({                                                                     \
+       unsigned long __gu_val = 0;                                     \
+       const typeof(*(ptr)) __user *__gu_addr = (ptr);                 \
+       int __gu_err = 0;                                               \
+                                                                       \
+       if (access_ok(VERIFY_READ, __gu_addr, size)) {                  \
+               switch (size) {                                         \
+               case 1:                                                 \
+                       __get_user_asm("lbu", __gu_addr, __gu_val,      \
+                                      __gu_err);                       \
+                       break;                                          \
+               case 2:                                                 \
+                       __get_user_asm("lhu", __gu_addr, __gu_val,      \
+                                      __gu_err);                       \
+                       break;                                          \
+               case 4:                                                 \
+                       __get_user_asm("lw", __gu_addr, __gu_val,       \
+                                      __gu_err);                       \
+                       break;                                          \
+               default:                                                \
+                       __gu_err = __user_bad();                        \
+                       break;                                          \
+               }                                                       \
+       } else {                                                        \
+               __gu_err = -EFAULT;                                     \
+       }                                                               \
+       x = (typeof(*(ptr)))__gu_val;                                   \
+       __gu_err;                                                       \
+})
 
 #define __get_user(x, ptr)                                             \
 ({                                                                     \
@@ -206,12 +239,6 @@ extern long __user_bad(void);
 })
 
 
-#define get_user(x, ptr)                                               \
-({                                                                     \
-       access_ok(VERIFY_READ, (ptr), sizeof(*(ptr)))                   \
-               ? __get_user((x), (ptr)) : -EFAULT;                     \
-})
-
 #define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)     \
 ({                                                             \
        __asm__ __volatile__ (                                  \
@@ -266,6 +293,42 @@ extern long __user_bad(void);
  *
  * Returns zero on success, or -EFAULT on error.
  */
+#define put_user(x, ptr)                                               \
+       __put_user_check((x), (ptr), sizeof(*(ptr)))
+
+#define __put_user_check(x, ptr, size)                                 \
+({                                                                     \
+       typeof(*(ptr)) __pu_val;                                        \
+       typeof(*(ptr)) __user *__pu_addr = (ptr);                       \
+       int __pu_err = 0;                                               \
+                                                                       \
+       __pu_val = (x);                                                 \
+       if (access_ok(VERIFY_WRITE, __pu_addr, size)) {                 \
+               switch (size) {                                         \
+               case 1:                                                 \
+                       __put_user_asm("sb", __pu_addr, __pu_val,       \
+                                      __pu_err);                       \
+                       break;                                          \
+               case 2:                                                 \
+                       __put_user_asm("sh", __pu_addr, __pu_val,       \
+                                      __pu_err);                       \
+                       break;                                          \
+               case 4:                                                 \
+                       __put_user_asm("sw", __pu_addr, __pu_val,       \
+                                      __pu_err);                       \
+                       break;                                          \
+               case 8:                                                 \
+                       __put_user_asm_8(__pu_addr, __pu_val, __pu_err);\
+                       break;                                          \
+               default:                                                \
+                       __pu_err = __user_bad();                        \
+                       break;                                          \
+               }                                                       \
+       } else {                                                        \
+               __pu_err = -EFAULT;                                     \
+       }                                                               \
+       __pu_err;                                                       \
+})
 
 #define __put_user(x, ptr)                                             \
 ({                                                                     \
@@ -290,18 +353,6 @@ extern long __user_bad(void);
        __gu_err;                                                       \
 })
 
-#ifndef CONFIG_MMU
-
-#define put_user(x, ptr)       __put_user((x), (ptr))
-
-#else /* CONFIG_MMU */
-
-#define put_user(x, ptr)                                               \
-({                                                                     \
-       access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr)))                  \
-               ? __put_user((x), (ptr)) : -EFAULT;                     \
-})
-#endif /* CONFIG_MMU */
 
 /* copy_to_from_user */
 #define __copy_from_user(to, from, n)  \
index 0071260..c1b459c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/hardirq.h>
 #include <linux/thread_info.h>
 #include <linux/kbuild.h>
+#include <asm/cpuinfo.h>
 
 int main(int argc, char *argv[])
 {
index f04d8a8..109876e 100644 (file)
@@ -96,13 +96,16 @@ static inline void __disable_dcache_nomsr(void)
 }
 
 
-/* Helper macro for computing the limits of cache range loops */
+/* Helper macro for computing the limits of cache range loops
+ *
+ * End address can be unaligned which is OK for C implementation.
+ * ASM implementation align it in ASM macros
+ */
 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)   \
 do {                                                                   \
        int align = ~(cache_line_length - 1);                           \
        end = min(start + cache_size, end);                             \
        start &= align;                                                 \
-       end = ((end & align) + cache_line_length);                      \
 } while (0);
 
 /*
@@ -111,9 +114,9 @@ do {                                                                        \
  */
 #define CACHE_ALL_LOOP(cache_size, line_length, op)                    \
 do {                                                                   \
-       unsigned int len = cache_size;                                  \
+       unsigned int len = cache_size - line_length;                    \
        int step = -line_length;                                        \
-       BUG_ON(step >= 0);                                              \
+       WARN_ON(step >= 0);                                             \
                                                                        \
        __asm__ __volatile__ (" 1:      " #op " %0, r0;                 \
                                        bgtid   %0, 1b;                 \
@@ -122,26 +125,22 @@ do {                                                                      \
                                        : "memory");                    \
 } while (0);
 
-
-#define CACHE_ALL_LOOP2(cache_size, line_length, op)                   \
-do {                                                                   \
-       unsigned int len = cache_size;                                  \
-       int step = -line_length;                                        \
-       BUG_ON(step >= 0);                                              \
-                                                                       \
-       __asm__ __volatile__ (" 1:      " #op " r0, %0;                 \
-                                       bgtid   %0, 1b;                 \
-                                       addk    %0, %0, %1;             \
-                                       " : : "r" (len), "r" (step)     \
-                                       : "memory");                    \
-} while (0);
-
-/* for wdc.flush/clear */
+/* Used for wdc.flush/clear which can use rB for offset which is not possible
+ * to use for simple wdc or wic.
+ *
+ * start address is cache aligned
+ * end address is not aligned, if end is aligned then I have to substract
+ * cacheline length because I can't flush/invalidate the next cacheline.
+ * If is not, I align it because I will flush/invalidate whole line.
+ */
 #define CACHE_RANGE_LOOP_2(start, end, line_length, op)                        \
 do {                                                                   \
        int step = -line_length;                                        \
-       int count = end - start;                                        \
-       BUG_ON(count <= 0);                                             \
+       int align = ~(line_length - 1);                                 \
+       int count;                                                      \
+       end = ((end & align) == end) ? end - line_length : end & align; \
+       count = end - start;                                            \
+       WARN_ON(count < 0);                                             \
                                                                        \
        __asm__ __volatile__ (" 1:      " #op " %0, %1;                 \
                                        bgtid   %1, 1b;                 \
@@ -154,7 +153,9 @@ do {                                                                        \
 #define CACHE_RANGE_LOOP_1(start, end, line_length, op)                        \
 do {                                                                   \
        int volatile temp;                                              \
-       BUG_ON(end - start <= 0);                                       \
+       int align = ~(line_length - 1);                                 \
+       end = ((end & align) == end) ? end - line_length : end & align; \
+       WARN_ON(end - start < 0);                                       \
                                                                        \
        __asm__ __volatile__ (" 1:      " #op " %1, r0;                 \
                                        cmpu    %0, %1, %2;             \
@@ -360,8 +361,12 @@ static void __invalidate_dcache_all_noirq_wt(void)
 #endif
 }
 
-/* FIXME this is weird - should be only wdc but not work
- * MS: I am getting bus errors and other weird things */
+/* FIXME It is blindly invalidation as is expected
+ * but can't be called on noMMU in microblaze_cache_init below
+ *
+ * MS: noMMU kernel won't boot if simple wdc is used
+ * The reason should be that there are discared data which kernel needs
+ */
 static void __invalidate_dcache_all_wb(void)
 {
 #ifndef ASM_LOOP
@@ -369,12 +374,12 @@ static void __invalidate_dcache_all_wb(void)
 #endif
        pr_debug("%s\n", __func__);
 #ifdef ASM_LOOP
-       CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
-                                       wdc.clear)
+       CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
+                                       wdc)
 #else
        for (i = 0; i < cpuinfo.dcache_size;
                 i += cpuinfo.dcache_line_length)
-                       __asm__ __volatile__ ("wdc.clear        %0, r0;" \
+                       __asm__ __volatile__ ("wdc      %0, r0;" \
                                        : : "r" (i));
 #endif
 }
@@ -393,7 +398,7 @@ static void __invalidate_dcache_range_wb(unsigned long start,
 #ifdef ASM_LOOP
        CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.clear);
 #else
-       for (i = start; i < end; i += cpuinfo.icache_line_length)
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
                __asm__ __volatile__ ("wdc.clear        %0, r0;"        \
                                : : "r" (i));
 #endif
@@ -413,7 +418,7 @@ static void __invalidate_dcache_range_nomsr_wt(unsigned long start,
 #ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 #else
-       for (i = start; i < end; i += cpuinfo.icache_line_length)
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
                __asm__ __volatile__ ("wdc      %0, r0;"        \
                                : : "r" (i));
 #endif
@@ -437,7 +442,7 @@ static void __invalidate_dcache_range_msr_irq_wt(unsigned long start,
 #ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 #else
-       for (i = start; i < end; i += cpuinfo.icache_line_length)
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
                __asm__ __volatile__ ("wdc      %0, r0;"        \
                                : : "r" (i));
 #endif
@@ -465,7 +470,7 @@ static void __invalidate_dcache_range_nomsr_irq(unsigned long start,
 #ifdef ASM_LOOP
        CACHE_RANGE_LOOP_1(start, end, cpuinfo.dcache_line_length, wdc);
 #else
-       for (i = start; i < end; i += cpuinfo.icache_line_length)
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
                __asm__ __volatile__ ("wdc      %0, r0;"        \
                                : : "r" (i));
 #endif
@@ -504,7 +509,7 @@ static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
 #ifdef ASM_LOOP
        CACHE_RANGE_LOOP_2(start, end, cpuinfo.dcache_line_length, wdc.flush);
 #else
-       for (i = start; i < end; i += cpuinfo.icache_line_length)
+       for (i = start; i < end; i += cpuinfo.dcache_line_length)
                __asm__ __volatile__ ("wdc.flush        %0, r0;"        \
                                : : "r" (i));
 #endif
@@ -650,7 +655,11 @@ void microblaze_cache_init(void)
                        }
                }
        }
-       invalidate_dcache();
+/* FIXME Invalidation is done in U-BOOT
+ * WT cache: Data is already written to main memory
+ * WB cache: Discard data on noMMU which caused that kernel doesn't boot
+ */
+       /* invalidate_dcache(); */
        enable_dcache();
 
        invalidate_icache();
index 0c912b2..4216eb1 100644 (file)
@@ -98,15 +98,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 
        if (cpuinfo.use_icache)
                count += seq_printf(m,
-                               "Icache:\t\t%ukB\n",
-                               cpuinfo.icache_size >> 10);
+                               "Icache:\t\t%ukB\tline length:\t%dB\n",
+                               cpuinfo.icache_size >> 10,
+                               cpuinfo.icache_line_length);
        else
                count += seq_printf(m, "Icache:\t\tno\n");
 
        if (cpuinfo.use_dcache) {
                count += seq_printf(m,
-                               "Dcache:\t\t%ukB\n",
-                               cpuinfo.dcache_size >> 10);
+                               "Dcache:\t\t%ukB\tline length:\t%dB\n",
+                               cpuinfo.dcache_size >> 10,
+                               cpuinfo.dcache_line_length);
                if (cpuinfo.dcache_wb)
                        count += seq_printf(m, "\t\twrite-back\n");
                else
index ce72dd4..9dcd90b 100644 (file)
@@ -74,7 +74,7 @@ static void dma_direct_free_coherent(struct device *dev, size_t size,
                              void *vaddr, dma_addr_t dma_handle)
 {
 #ifdef NOT_COHERENT_CACHE
-       consistent_free(vaddr);
+       consistent_free(size, vaddr);
 #else
        free_pages((unsigned long)vaddr, get_order(size));
 #endif
index 391d619..8cc18cd 100644 (file)
@@ -476,6 +476,8 @@ ENTRY(ret_from_fork)
        nop
 
 work_pending:
+       enable_irq
+
        andi    r11, r19, _TIF_NEED_RESCHED
        beqi    r11, 1f
        bralid  r15, schedule
index d9f70f8..02cbdfe 100644 (file)
@@ -121,7 +121,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
                }
                printk(KERN_WARNING "Divide by zero exception " \
                                                        "in kernel mode.\n");
-               die("Divide by exception", regs, SIGBUS);
+               die("Divide by zero exception", regs, SIGBUS);
                break;
        case MICROBLAZE_FPU_EXCEPTION:
                pr_debug(KERN_WARNING "FPU exception\n");
index da6a5f5..1bf7398 100644 (file)
@@ -28,6 +28,7 @@
  * for more details.
  */
 
+#include <linux/init.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
@@ -49,7 +50,7 @@ swapper_pg_dir:
 
 #endif /* CONFIG_MMU */
 
-       .text
+       __HEAD
 ENTRY(_start)
 #if CONFIG_KERNEL_BASE_ADDR == 0
        brai    TOPHYS(real_start)
index 6f39e2c..8f120ac 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/ftrace.h>
 #include <linux/kernel.h>
 #include <linux/hardirq.h>
 #include <linux/interrupt.h>
@@ -32,7 +33,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
 
 static u32 concurrent_irq;
 
-void do_IRQ(struct pt_regs *regs)
+void __irq_entry do_IRQ(struct pt_regs *regs)
 {
        unsigned int irq;
        struct pt_regs *old_regs = set_irq_regs(regs);
index bc4dcb7..ff85f77 100644 (file)
@@ -52,3 +52,14 @@ EXPORT_SYMBOL_GPL(_ebss);
 extern void _mcount(void);
 EXPORT_SYMBOL(_mcount);
 #endif
+
+/*
+ * Assembly functions that may be used (directly or indirectly) by modules
+ */
+EXPORT_SYMBOL(__copy_tofrom_user);
+EXPORT_SYMBOL(__strncpy_user);
+
+#ifdef CONFIG_OPT_LIB_ASM
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+#endif
index 7cf8649..0fb5fc6 100644 (file)
@@ -93,39 +93,3 @@ early_console_reg_tlb_alloc:
        nop
 
        .size  early_console_reg_tlb_alloc, . - early_console_reg_tlb_alloc
-
-/*
- * Copy a whole page (4096 bytes).
- */
-#define COPY_16_BYTES          \
-       lwi     r7, r6, 0;      \
-       lwi     r8, r6, 4;      \
-       lwi     r9, r6, 8;      \
-       lwi     r10, r6, 12;    \
-       swi     r7, r5, 0;      \
-       swi     r8, r5, 4;      \
-       swi     r9, r5, 8;      \
-       swi     r10, r5, 12
-
-
-/* FIXME DCACHE_LINE_BYTES (CONFIG_XILINX_MICROBLAZE0_DCACHE_LINE_LEN * 4)*/
-#define DCACHE_LINE_BYTES (4 * 4)
-
-.globl copy_page;
-.type  copy_page, @function
-.align 4;
-copy_page:
-       ori     r11, r0, (PAGE_SIZE/DCACHE_LINE_BYTES) - 1
-_copy_page_loop:
-       COPY_16_BYTES
-#if DCACHE_LINE_BYTES >= 32
-       COPY_16_BYTES
-#endif
-       addik   r6, r6, DCACHE_LINE_BYTES
-       addik   r5, r5, DCACHE_LINE_BYTES
-       bneid   r11, _copy_page_loop
-       addik   r11, r11, -1
-       rtsd    r15, 8
-       nop
-
-       .size  copy_page, . - copy_page
index cbecf11..0e73f66 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/string.h>
 
 #include <asm/pgtable.h>
+#include <asm/cacheflush.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -151,6 +152,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
 int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
                struct module *module)
 {
+       flush_dcache();
        return 0;
 }
 
index 5e4570e..75e4920 100644 (file)
@@ -95,37 +95,3 @@ void dump_stack(void)
        show_stack(NULL, NULL);
 }
 EXPORT_SYMBOL(dump_stack);
-
-#ifdef CONFIG_MMU
-void __bug(const char *file, int line, void *data)
-{
-       if (data)
-               printk(KERN_CRIT "kernel BUG at %s:%d (data = %p)!\n",
-                       file, line, data);
-       else
-               printk(KERN_CRIT "kernel BUG at %s:%d!\n", file, line);
-
-       machine_halt();
-}
-
-int bad_trap(int trap_num, struct pt_regs *regs)
-{
-       printk(KERN_CRIT
-               "unimplemented trap %d called at 0x%08lx, pid %d!\n",
-               trap_num, regs->pc, current->pid);
-       return -ENOSYS;
-}
-
-int debug_trap(struct pt_regs *regs)
-{
-       int i;
-       printk(KERN_CRIT "debug trap\n");
-       for (i = 0; i < 32; i++) {
-               /* printk("r%i:%08X\t",i,regs->gpr[i]); */
-               if ((i % 4) == 3)
-                       printk(KERN_CRIT "\n");
-       }
-       printk(KERN_CRIT "pc:%08lX\tmsr:%08lX\n", regs->pc, regs->msr);
-       return -ENOSYS;
-}
-#endif
index 5ef619a..db72d71 100644 (file)
@@ -24,7 +24,8 @@ SECTIONS {
        .text : AT(ADDR(.text) - LOAD_OFFSET) {
                _text = . ;
                _stext = . ;
-               *(.text .text.*)
+               HEAD_TEXT
+               TEXT_TEXT
                *(.fixup)
                EXIT_TEXT
                EXIT_CALL
index f956e24..5a59dad 100644 (file)
 #include <linux/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/cpuinfo.h>
+#include <asm/tlbflush.h>
 
 #ifndef CONFIG_MMU
-
 /* I have to use dcache values because I can't relate on ram size */
-#define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
+# define UNCACHED_SHADOW_MASK (cpuinfo.dcache_high - cpuinfo.dcache_base + 1)
+#endif
 
 /*
  * Consistent memory allocators. Used for DMA devices that want to
  */
 void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
 {
-       struct page *page, *end, *free;
-       unsigned long order;
-       void *ret, *virt;
-
-       if (in_interrupt())
-               BUG();
-
-       size = PAGE_ALIGN(size);
-       order = get_order(size);
-
-       page = alloc_pages(gfp, order);
-       if (!page)
-               goto no_page;
-
-       /* We could do with a page_to_phys and page_to_bus here. */
-       virt = page_address(page);
-       ret = ioremap(virt_to_phys(virt), size);
-       if (!ret)
-               goto no_remap;
-
-       /*
-        * Here's the magic!  Note if the uncached shadow is not implemented,
-        * it's up to the calling code to also test that condition and make
-        * other arranegments, such as manually flushing the cache and so on.
-        */
-#ifdef CONFIG_XILINX_UNCACHED_SHADOW
-       ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
-#endif
-       /* dma_handle is same as physical (shadowed) address */
-       *dma_handle = (dma_addr_t)ret;
-
-       /*
-        * free wasted pages.  We skip the first page since we know
-        * that it will have count = 1 and won't require freeing.
-        * We also mark the pages in use as reserved so that
-        * remap_page_range works.
-        */
-       page = virt_to_page(virt);
-       free = page + (size >> PAGE_SHIFT);
-       end  = page + (1 << order);
-
-       for (; page < end; page++) {
-               init_page_count(page);
-               if (page >= free)
-                       __free_page(page);
-               else
-                       SetPageReserved(page);
-       }
-
-       return ret;
-no_remap:
-       __free_pages(page, order);
-no_page:
-       return NULL;
-}
-
-#else
+       unsigned long order, vaddr;
+       void *ret;
+       unsigned int i, err = 0;
+       struct page *page, *end;
 
-void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
-{
-       int order, err, i;
-       unsigned long page, va, flags;
+#ifdef CONFIG_MMU
        phys_addr_t pa;
        struct vm_struct *area;
-       void     *ret;
+       unsigned long va;
+#endif
 
        if (in_interrupt())
                BUG();
@@ -133,71 +79,133 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
        size = PAGE_ALIGN(size);
        order = get_order(size);
 
-       page = __get_free_pages(gfp, order);
-       if (!page) {
-               BUG();
+       vaddr = __get_free_pages(gfp, order);
+       if (!vaddr)
                return NULL;
-       }
 
        /*
         * we need to ensure that there are no cachelines in use,
         * or worse dirty in this area.
         */
-       flush_dcache_range(virt_to_phys(page), virt_to_phys(page) + size);
+       flush_dcache_range(virt_to_phys((void *)vaddr),
+                                       virt_to_phys((void *)vaddr) + size);
 
+#ifndef CONFIG_MMU
+       ret = (void *)vaddr;
+       /*
+        * Here's the magic!  Note if the uncached shadow is not implemented,
+        * it's up to the calling code to also test that condition and make
+        * other arranegments, such as manually flushing the cache and so on.
+        */
+# ifdef CONFIG_XILINX_UNCACHED_SHADOW
+       ret = (void *)((unsigned) ret | UNCACHED_SHADOW_MASK);
+# endif
+       if ((unsigned int)ret > cpuinfo.dcache_base &&
+                               (unsigned int)ret < cpuinfo.dcache_high)
+               printk(KERN_WARNING
+                       "ERROR: Your cache coherent area is CACHED!!!\n");
+
+       /* dma_handle is same as physical (shadowed) address */
+       *dma_handle = (dma_addr_t)ret;
+#else
        /* Allocate some common virtual space to map the new pages. */
        area = get_vm_area(size, VM_ALLOC);
-       if (area == NULL) {
-               free_pages(page, order);
+       if (!area) {
+               free_pages(vaddr, order);
                return NULL;
        }
        va = (unsigned long) area->addr;
        ret = (void *)va;
 
        /* This gives us the real physical address of the first page. */
-       *dma_handle = pa = virt_to_bus((void *)page);
-
-       /* MS: This is the whole magic - use cache inhibit pages */
-       flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
+       *dma_handle = pa = virt_to_bus((void *)vaddr);
+#endif
 
        /*
-        * Set refcount=1 on all pages in an order>0
-        * allocation so that vfree() will actually
-        * free all pages that were allocated.
+        * free wasted pages.  We skip the first page since we know
+        * that it will have count = 1 and won't require freeing.
+        * We also mark the pages in use as reserved so that
+        * remap_page_range works.
         */
-       if (order > 0) {
-               struct page *rpage = virt_to_page(page);
-               for (i = 1; i < (1 << order); i++)
-                       init_page_count(rpage+i);
+       page = virt_to_page(vaddr);
+       end = page + (1 << order);
+
+       split_page(page, order);
+
+       for (i = 0; i < size && err == 0; i += PAGE_SIZE) {
+#ifdef CONFIG_MMU
+               /* MS: This is the whole magic - use cache inhibit pages */
+               err = map_page(va + i, pa + i, _PAGE_KERNEL | _PAGE_NO_CACHE);
+#endif
+
+               SetPageReserved(page);
+               page++;
        }
 
-       err = 0;
-       for (i = 0; i < size && err == 0; i += PAGE_SIZE)
-               err = map_page(va+i, pa+i, flags);
+       /* Free the otherwise unused pages. */
+       while (page < end) {
+               __free_page(page);
+               page++;
+       }
 
        if (err) {
-               vfree((void *)va);
+               free_pages(vaddr, order);
                return NULL;
        }
 
        return ret;
 }
-#endif /* CONFIG_MMU */
 EXPORT_SYMBOL(consistent_alloc);
 
 /*
  * free page(s) as defined by the above mapping.
  */
-void consistent_free(void *vaddr)
+void consistent_free(size_t size, void *vaddr)
 {
+       struct page *page;
+
        if (in_interrupt())
                BUG();
 
+       size = PAGE_ALIGN(size);
+
+#ifndef CONFIG_MMU
        /* Clear SHADOW_MASK bit in address, and free as per usual */
-#ifdef CONFIG_XILINX_UNCACHED_SHADOW
+# ifdef CONFIG_XILINX_UNCACHED_SHADOW
        vaddr = (void *)((unsigned)vaddr & ~UNCACHED_SHADOW_MASK);
+# endif
+       page = virt_to_page(vaddr);
+
+       do {
+               ClearPageReserved(page);
+               __free_page(page);
+               page++;
+       } while (size -= PAGE_SIZE);
+#else
+       do {
+               pte_t *ptep;
+               unsigned long pfn;
+
+               ptep = pte_offset_kernel(pmd_offset(pgd_offset_k(
+                                               (unsigned int)vaddr),
+                                       (unsigned int)vaddr),
+                               (unsigned int)vaddr);
+               if (!pte_none(*ptep) && pte_present(*ptep)) {
+                       pfn = pte_pfn(*ptep);
+                       pte_clear(&init_mm, (unsigned int)vaddr, ptep);
+                       if (pfn_valid(pfn)) {
+                               page = pfn_to_page(pfn);
+
+                               ClearPageReserved(page);
+                               __free_page(page);
+                       }
+               }
+               vaddr += PAGE_SIZE;
+       } while (size -= PAGE_SIZE);
+
+       /* flush tlb */
+       flush_tlb_all();
 #endif
-       vfree(vaddr);
 }
 EXPORT_SYMBOL(consistent_free);
 
@@ -221,7 +229,7 @@ void consistent_sync(void *vaddr, size_t size, int direction)
        case PCI_DMA_NONE:
                BUG();
        case PCI_DMA_FROMDEVICE:        /* invalidate only */
-               flush_dcache_range(start, end);
+               invalidate_dcache_range(start, end);
                break;
        case PCI_DMA_TODEVICE:          /* writeback only */
                flush_dcache_range(start, end);
index 7af87f4..bab9229 100644 (file)
@@ -273,16 +273,11 @@ bad_area_nosemaphore:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (current->pid == 1) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
        up_read(&mm->mmap_sem);
-       printk(KERN_WARNING "VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_exit(SIGKILL);
-       bad_page_fault(regs, address, SIGKILL);
+       if (!user_mode(regs))
+               bad_page_fault(regs, address, SIGKILL);
+       else
+               pagefault_out_of_memory();
        return;
 
 do_sigbus:
index f42c2dd..cca3579 100644 (file)
@@ -47,6 +47,7 @@ unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
 unsigned long memory_end; /* due to mm/nommu.c */
 unsigned long memory_size;
+EXPORT_SYMBOL(memory_size);
 
 /*
  * paging_init() sets up the page tables - in fact we've already done this.
index d31312c..59bf233 100644 (file)
@@ -42,6 +42,7 @@
 
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
+EXPORT_SYMBOL(ioremap_bot);
 
 /* The maximum lowmem defaults to 768Mb, but this can be configured to
  * another value.
@@ -161,24 +162,6 @@ int map_page(unsigned long va, phys_addr_t pa, int flags)
        return err;
 }
 
-void __init adjust_total_lowmem(void)
-{
-/* TBD */
-#if 0
-       unsigned long max_low_mem = MAX_LOW_MEM;
-
-       if (total_lowmem > max_low_mem) {
-               total_lowmem = max_low_mem;
-#ifndef CONFIG_HIGHMEM
-               printk(KERN_INFO "Warning, memory limited to %ld Mb, use "
-                               "CONFIG_HIGHMEM to reach %ld Mb\n",
-                               max_low_mem >> 20, total_memory >> 20);
-               total_memory = total_lowmem;
-#endif /* CONFIG_HIGHMEM */
-       }
-#endif
-}
-
 /*
  * Map in all of physical memory starting at CONFIG_KERNEL_START.
  */
@@ -206,24 +189,6 @@ void __init mapin_ram(void)
 /* is x a power of 2? */
 #define is_power_of_2(x)       ((x) != 0 && (((x) & ((x) - 1)) == 0))
 
-/*
- * Set up a mapping for a block of I/O.
- * virt, phys, size must all be page-aligned.
- * This should only be called before ioremap is called.
- */
-void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
-                            unsigned int size, int flags)
-{
-       int i;
-
-       if (virt > CONFIG_KERNEL_START && virt < ioremap_bot)
-               ioremap_bot = ioremap_base = virt;
-
-       /* Put it in the page tables. */
-       for (i = 0; i < size; i += PAGE_SIZE)
-               map_page(virt + i, phys + i, flags);
-}
-
 /* Scan the real Linux page tables and return a PTE pointer for
  * a virtual address in a context.
  * Returns true (1) if PTE was found, zero otherwise.  The pointer to
@@ -274,3 +239,18 @@ unsigned long iopa(unsigned long addr)
 
        return pa;
 }
+
+__init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+               unsigned long address)
+{
+       pte_t *pte;
+       if (mem_init_done) {
+               pte = (pte_t *)__get_free_page(GFP_KERNEL |
+                                       __GFP_REPEAT | __GFP_ZERO);
+       } else {
+               pte = (pte_t *)early_get_page();
+               if (pte)
+                       clear_page(pte);
+       }
+       return pte;
+}
index 740bb32..9cb782b 100644 (file)
@@ -1025,7 +1025,7 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
 
        struct pci_dev *dev = bus->self;
 
-       for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+       pci_bus_for_each_resource(bus, res, i) {
                res = bus->resource[i];
                if (!res)
                        continue;
@@ -1131,21 +1131,20 @@ static int skip_isa_ioresource_align(struct pci_dev *dev)
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res,
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
                                resource_size_t size, resource_size_t align)
 {
        struct pci_dev *dev = data;
+       resource_size_t start = res->start;
 
        if (res->flags & IORESOURCE_IO) {
-               resource_size_t start = res->start;
-
                if (skip_isa_ioresource_align(dev))
-                       return;
-               if (start & 0x300) {
+                       return start;
+               if (start & 0x300)
                        start = (start + 0x3ff) & ~0x3ff;
-                       res->start = start;
-               }
        }
+
+       return start;
 }
 EXPORT_SYMBOL(pcibios_align_resource);
 
@@ -1228,7 +1227,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus)
        pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
                 pci_domain_nr(bus), bus->number);
 
-       for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+       pci_bus_for_each_resource(bus, res, i) {
                res = bus->resource[i];
                if (!res || !res->flags
                    || res->start > res->end || res->parent)
@@ -1508,7 +1507,7 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
        pci_bus_add_devices(bus);
 
        /* Fixup EEH */
-       eeh_add_device_tree_late(bus);
+       /* eeh_add_device_tree_late(bus); */
 }
 EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
 
index 29e8692..7e6fd1c 100644 (file)
@@ -49,7 +49,7 @@ config AR7
          family: TNETD7100, 7200 and 7300.
 
 config BCM47XX
-       bool "BCM47XX based boards"
+       bool "Broadcom BCM47XX based boards"
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
@@ -509,6 +509,7 @@ config SIBYTE_SWARM
        bool "Sibyte BCM91250A-SWARM"
        select BOOT_ELF32
        select DMA_COHERENT
+       select HAVE_PATA_PLATFORM
        select NR_CPUS_DEFAULT_2
        select SIBYTE_SB1250
        select SWAP_IO_SPACE
@@ -523,6 +524,7 @@ config SIBYTE_LITTLESUR
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
+       select HAVE_PATA_PLATFORM
        select NR_CPUS_DEFAULT_2
        select SIBYTE_SB1250
        select SWAP_IO_SPACE
@@ -1305,6 +1307,33 @@ config CPU_CAVIUM_OCTEON
 
 endchoice
 
+if CPU_LOONGSON2F
+config CPU_NOP_WORKAROUNDS
+       bool
+
+config CPU_JUMP_WORKAROUNDS
+       bool
+
+config CPU_LOONGSON2F_WORKAROUNDS
+       bool "Loongson 2F Workarounds"
+       default y
+       select CPU_NOP_WORKAROUNDS
+       select CPU_JUMP_WORKAROUNDS
+       help
+         Loongson 2F01 / 2F02 processors have the NOP & JUMP issues which
+         require workarounds.  Without workarounds the system may hang
+         unexpectedly.  For more information please refer to the gas
+         -mfix-loongson2f-nop and -mfix-loongson2f-jump options.
+
+         Loongson 2F03 and later have fixed these issues and no workarounds
+         are needed.  The workarounds have no significant side effect on them
+         but may decrease the performance of the system so this option should
+         be disabled unless the kernel is intended to be run on 2F01 or 2F02
+         systems.
+
+         If unsure, please say Y.
+endif # CPU_LOONGSON2F
+
 config SYS_SUPPORTS_ZBOOT
        bool
        select HAVE_KERNEL_GZIP
index 2f2eac2..0b9c01a 100644 (file)
@@ -136,6 +136,19 @@ cflags-$(CONFIG_CPU_LOONGSON2E) += \
        $(call cc-option,-march=loongson2e,-march=r4600)
 cflags-$(CONFIG_CPU_LOONGSON2F) += \
        $(call cc-option,-march=loongson2f,-march=r4600)
+# enable the workarounds for loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+  else
+    cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+  endif
+  ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+    $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+  else
+    cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+  endif
+endif
 
 cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
                        -Wa,-mips32 -Wa,--trap
index 379536e..8876195 100644 (file)
@@ -60,58 +60,22 @@ void __init board_setup(void)
        wmb();
 }
 
-/* use the hexleds to count the number of times the cpu has entered
- * wait, the dots to indicate whether the CPU is currently idle or
- * active (dots off = sleeping, dots on = working) for cases where
- * the number doesn't change for a long(er) period of time.
- */
-static void db1200_wait(void)
-{
-       __asm__("       .set    push                    \n"
-               "       .set    mips3                   \n"
-               "       .set    noreorder               \n"
-               "       cache   0x14, 0(%0)             \n"
-               "       cache   0x14, 32(%0)            \n"
-               "       cache   0x14, 64(%0)            \n"
-               /* dots off: we're about to call wait */
-               "       lui     $26, 0xb980             \n"
-               "       ori     $27, $0, 3              \n"
-               "       sb      $27, 0x18($26)          \n"
-               "       sync                            \n"
-               "       nop                             \n"
-               "       wait                            \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               /* dots on: there's work to do, increment cntr */
-               "       lui     $26, 0xb980             \n"
-               "       sb      $0, 0x18($26)           \n"
-               "       lui     $26, 0xb9c0             \n"
-               "       lb      $27, 0($26)             \n"
-               "       addiu   $27, $27, 1             \n"
-               "       sb      $27, 0($26)             \n"
-               "       sync                            \n"
-               "       .set    pop                     \n"
-               : : "r" (db1200_wait));
-}
-
 static int __init db1200_arch_init(void)
 {
        /* GPIO7 is low-level triggered CPLD cascade */
        set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
        bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
 
-       /* do not autoenable these: CPLD has broken edge int handling,
-        * and the CD handler setup requires manual enabling to work
-        * around that.
+       /* insert/eject pairs: one of both is always screaming.  To avoid
+        * issues they must not be automatically enabled when initially
+        * requested.
         */
        irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
        irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
-
-       if (cpu_wait)
-               cpu_wait = db1200_wait;
+       irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN;
+       irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN;
+       irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN;
+       irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN;
 
        return 0;
 }
index 246df7a..2fafc78 100644 (file)
@@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
                .on     = vlynq_on,
                .off    = vlynq_off,
        },
-       .reset_bit      = 26,
+       .reset_bit      = 16,
        .gpio_bit       = 19,
 };
 
@@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
        }
 
        if (ar7_has_high_cpmac()) {
+               res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
                if (!res) {
                        cpmac_get_mac(1, cpmac_high_data.dev_addr);
 
index ea17941..8dba8cf 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/addrspace.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
        .name                           = "96338GW",
        .expected_cpu_id                = 0x6338,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .enet0 = {
                .force_speed_100        = 1,
@@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
        .name                           = "96338W",
        .expected_cpu_id                = 0x6338,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .enet0 = {
                .force_speed_100        = 1,
@@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
 static struct board_info __initdata board_96345gw2 = {
        .name                           = "96345GW2",
        .expected_cpu_id                = 0x6345,
+
+       .has_uart0                      = 1,
 };
 #endif
 
@@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
        .name                           = "96348R",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_pci                        = 1,
 
@@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
        .name                           = "96348GW-10",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
        .name                           = "96348GW-11",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
        .name                           = "96348GW",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = {
        .name                           = "F@ST2404",
        .expected_cpu_id                = 0x6348,
 
-       .has_enet0                      = 1,
-       .has_enet1                      = 1,
-       .has_pci                        = 1,
+       .has_uart0                      = 1,
+        .has_enet0                     = 1,
+        .has_enet1                     = 1,
+        .has_pci                       = 1,
 
        .enet0 = {
                .has_phy                = 1,
@@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
        .has_ehci0                      = 1,
 };
 
+static struct board_info __initdata board_rta1025w_16 = {
+       .name                           = "RTA1025W_16",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+};
+
+
 static struct board_info __initdata board_DV201AMR = {
        .name                           = "DV201AMR",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_pci                        = 1,
        .has_ohci0                      = 1,
 
@@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
        .name                           = "96348GW-A",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
        .name                           = "96358VW",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
        .name                           = "96358VW2",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
        .name                           = "AGPF-S0",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
        .has_ohci0 = 1,
        .has_ehci0 = 1,
 };
+
+static struct board_info __initdata board_DWVS0 = {
+       .name                           = "DWV-S0",
+       .expected_cpu_id                = 0x6358,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0                      = 1,
+};
 #endif
 
 /*
@@ -552,15 +607,87 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
        &board_FAST2404,
        &board_DV201AMR,
        &board_96348gw_a,
+       &board_rta1025w_16,
 #endif
 
 #ifdef CONFIG_BCM63XX_CPU_6358
        &board_96358vw,
        &board_96358vw2,
        &board_AGPFS0,
+       &board_DWVS0,
 #endif
 };
 
+/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+       .revision               = 0x02,
+       .board_rev              = 0x17,
+       .country_code           = 0x0,
+       .ant_available_bg       = 0x3,
+       .pa0b0                  = 0x15ae,
+       .pa0b1                  = 0xfa85,
+       .pa0b2                  = 0xfe8d,
+       .pa1b0                  = 0xffff,
+       .pa1b1                  = 0xffff,
+       .pa1b2                  = 0xffff,
+       .gpio0                  = 0xff,
+       .gpio1                  = 0xff,
+       .gpio2                  = 0xff,
+       .gpio3                  = 0xff,
+       .maxpwr_bg              = 0x004c,
+       .itssi_bg               = 0x00,
+       .boardflags_lo          = 0x2848,
+       .boardflags_hi          = 0x0000,
+};
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+       return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+       u8 *p;
+       int count;
+
+       if (mac_addr_used >= nvram.mac_addr_count) {
+               printk(KERN_ERR PFX "not enough mac address\n");
+               return -ENODEV;
+       }
+
+       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+       p = mac + ETH_ALEN - 1;
+       count = mac_addr_used;
+
+       while (count--) {
+               do {
+                       (*p)++;
+                       if (*p != 0)
+                               break;
+                       p--;
+               } while (p != mac);
+       }
+
+       if (p == mac) {
+               printk(KERN_ERR PFX "unable to fetch mac address\n");
+               return -ENODEV;
+       }
+
+       mac_addr_used++;
+       return 0;
+}
+
 /*
  * early init callback, read nvram data from flash and checksum it
  */
@@ -659,6 +786,17 @@ void __init board_prom_init(void)
        }
 
        bcm_gpio_writel(val, GPIO_MODE_REG);
+
+       /* Generate MAC address for WLAN and
+        * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+                       printk(KERN_ERR "failed to register fallback SPROM\n");
+       }
+#endif
 }
 
 /*
@@ -676,49 +814,6 @@ void __init board_setup(void)
                panic("unexpected CPU for bcm963xx board");
 }
 
-/*
- * return board name for /proc/cpuinfo
- */
-const char *board_get_name(void)
-{
-       return board.name;
-}
-
-/*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
-       u8 *p;
-       int count;
-
-       if (mac_addr_used >= nvram.mac_addr_count) {
-               printk(KERN_ERR PFX "not enough mac address\n");
-               return -ENODEV;
-       }
-
-       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-       p = mac + ETH_ALEN - 1;
-       count = mac_addr_used;
-
-       while (count--) {
-               do {
-                       (*p)++;
-                       if (*p != 0)
-                               break;
-                       p--;
-               } while (p != mac);
-       }
-
-       if (p == mac) {
-               printk(KERN_ERR PFX "unable to fetch mac address\n");
-               return -ENODEV;
-       }
-
-       mac_addr_used++;
-       return 0;
-}
-
 static struct mtd_partition mtd_partitions[] = {
        {
                .name           = "cfe",
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
        },
 };
 
-/*
- * Register a sane SPROMv2 to make the on-board
- * bcm4318 WLAN work
- */
-#ifdef CONFIG_SSB_PCIHOST
-static struct ssb_sprom bcm63xx_sprom = {
-       .revision               = 0x02,
-       .board_rev              = 0x17,
-       .country_code           = 0x0,
-       .ant_available_bg       = 0x3,
-       .pa0b0                  = 0x15ae,
-       .pa0b1                  = 0xfa85,
-       .pa0b2                  = 0xfe8d,
-       .pa1b0                  = 0xffff,
-       .pa1b1                  = 0xffff,
-       .pa1b2                  = 0xffff,
-       .gpio0                  = 0xff,
-       .gpio1                  = 0xff,
-       .gpio2                  = 0xff,
-       .gpio3                  = 0xff,
-       .maxpwr_bg              = 0x004c,
-       .itssi_bg               = 0x00,
-       .boardflags_lo          = 0x2848,
-       .boardflags_hi          = 0x0000,
-};
-#endif
-
 static struct gpio_led_platform_data bcm63xx_led_data;
 
 static struct platform_device bcm63xx_gpio_leds = {
@@ -792,6 +860,12 @@ int __init board_register_devices(void)
 {
        u32 val;
 
+       if (board.has_uart0)
+               bcm63xx_uart_register(0);
+
+       if (board.has_uart1)
+               bcm63xx_uart_register(1);
+
        if (board.has_pccard)
                bcm63xx_pcmcia_register();
 
@@ -806,17 +880,6 @@ int __init board_register_devices(void)
        if (board.has_dsp)
                bcm63xx_dsp_register(&board.dsp);
 
-       /* Generate MAC address for WLAN and
-        * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
-       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
-               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-                       printk(KERN_ERR "failed to register fallback SPROM\n");
-       }
-#endif
-
        /* read base address of boot chip select (0) */
        if (BCMCPU_IS_6345())
                val = 0x1fc00000;
index 70378bb..cbb7caf 100644 (file)
@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
        [RSET_TIMER]            = BCM_6338_TIMER_BASE,
        [RSET_WDT]              = BCM_6338_WDT_BASE,
        [RSET_UART0]            = BCM_6338_UART0_BASE,
+       [RSET_UART1]            = BCM_6338_UART1_BASE,
        [RSET_GPIO]             = BCM_6338_GPIO_BASE,
        [RSET_SPI]              = BCM_6338_SPI_BASE,
        [RSET_OHCI0]            = BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
        [RSET_TIMER]            = BCM_6345_TIMER_BASE,
        [RSET_WDT]              = BCM_6345_WDT_BASE,
        [RSET_UART0]            = BCM_6345_UART0_BASE,
+       [RSET_UART1]            = BCM_6345_UART1_BASE,
        [RSET_GPIO]             = BCM_6345_GPIO_BASE,
        [RSET_SPI]              = BCM_6345_SPI_BASE,
        [RSET_UDC0]             = BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
        [RSET_TIMER]            = BCM_6348_TIMER_BASE,
        [RSET_WDT]              = BCM_6348_WDT_BASE,
        [RSET_UART0]            = BCM_6348_UART0_BASE,
+       [RSET_UART1]            = BCM_6348_UART1_BASE,
        [RSET_GPIO]             = BCM_6348_GPIO_BASE,
        [RSET_SPI]              = BCM_6348_SPI_BASE,
        [RSET_OHCI0]            = BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
        [RSET_TIMER]            = BCM_6358_TIMER_BASE,
        [RSET_WDT]              = BCM_6358_WDT_BASE,
        [RSET_UART0]            = BCM_6358_UART0_BASE,
+       [RSET_UART1]            = BCM_6358_UART1_BASE,
        [RSET_GPIO]             = BCM_6358_GPIO_BASE,
        [RSET_SPI]              = BCM_6358_SPI_BASE,
        [RSET_OHCI0]            = BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
 static const int bcm96358_irqs[] = {
        [IRQ_TIMER]             = BCM_6358_TIMER_IRQ,
        [IRQ_UART0]             = BCM_6358_UART0_IRQ,
+       [IRQ_UART1]             = BCM_6358_UART1_IRQ,
        [IRQ_DSL]               = BCM_6358_DSL_IRQ,
        [IRQ_ENET0]             = BCM_6358_ENET0_IRQ,
        [IRQ_ENET1]             = BCM_6358_ENET1_IRQ,
index b051946..c2963da 100644 (file)
 #include <linux/platform_device.h>
 #include <bcm63xx_cpu.h>
 
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
        {
-               .start          = -1, /* filled at runtime */
-               .end            = -1, /* filled at runtime */
+               /* start & end filled at runtime */
                .flags          = IORESOURCE_MEM,
        },
        {
-               .start          = -1, /* filled at runtime */
+               /* start filled at runtime */
                .flags          = IORESOURCE_IRQ,
        },
 };
 
-static struct platform_device bcm63xx_uart_device = {
-       .name           = "bcm63xx_uart",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(uart_resources),
-       .resource       = uart_resources,
+static struct resource uart1_resources[] = {
+       {
+               /* start & end filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               /* start filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bcm63xx_uart_devices[] = {
+       {
+               .name           = "bcm63xx_uart",
+               .id             = 0,
+               .num_resources  = ARRAY_SIZE(uart0_resources),
+               .resource       = uart0_resources,
+       },
+
+       {
+               .name           = "bcm63xx_uart",
+               .id             = 1,
+               .num_resources  = ARRAY_SIZE(uart1_resources),
+               .resource       = uart1_resources,
+       }
 };
 
-int __init bcm63xx_uart_register(void)
+int __init bcm63xx_uart_register(unsigned int id)
 {
-       uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
-       uart_resources[0].end = uart_resources[0].start;
-       uart_resources[0].end += RSET_UART_SIZE - 1;
-       uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
-       return platform_device_register(&bcm63xx_uart_device);
+       if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+               return -ENODEV;
+
+       if (id == 1 && !BCMCPU_IS_6358())
+               return -ENODEV;
+
+       if (id == 0) {
+               uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+               uart0_resources[0].end = uart0_resources[0].start +
+                       RSET_UART_SIZE - 1;
+               uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+       }
+
+       if (id == 1) {
+               uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+               uart1_resources[0].end = uart1_resources[0].start +
+                       RSET_UART_SIZE - 1;
+               uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+       }
+
+       return platform_device_register(&bcm63xx_uart_devices[id]);
 }
-arch_initcall(bcm63xx_uart_register);
index 87ca390..315bc7f 100644 (file)
@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
 
 int __init bcm63xx_gpio_init(void)
 {
+       gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+       gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
        bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
        pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 
        return gpiochip_add(&bcm63xx_gpio_chip);
 }
-
-arch_initcall(bcm63xx_gpio_init);
index b321d3b..9a06fa9 100644 (file)
@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
 extern void pci_console_init(const char *arg);
 #endif
 
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
        write_octeon_c0_dcacheerr(0);
 }
 
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
-       /*
-        * The config has selected to wire the reserve32 memory for all
-        * userspace applications. We need to put a wired TLB entry in for each
-        * 512MB of reserve32 memory. We only handle double 256MB pages here,
-        * so reserve32 must be multiple of 512MB.
-        */
-       uint32_t size = CONFIG_CAVIUM_RESERVE32;
-       uint32_t entrylo0 =
-               0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
-       uint32_t entrylo1 = entrylo0 + (256 << 14);
-       uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
-       while (size >= 512) {
-#if 0
-               pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
-                       smp_processor_id(), entryhi);
-#endif
-               add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
-               entrylo0 += 512 << 14;
-               entrylo1 += 512 << 14;
-               entryhi += 512 << 20;
-               size -= 512;
-       }
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-       on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
 /**
  * Reboot Octeon
  *
@@ -294,18 +243,6 @@ static void octeon_halt(void)
        octeon_kill_core(NULL);
 }
 
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
-       /* Nothing special here, but we are required to have one */
-}
-
-#endif
-
 /**
  * Handle all the error condition interrupts that might occur.
  *
@@ -502,25 +439,13 @@ void __init prom_init(void)
         * memory when it is getting memory from the
         * bootloader. Later, after the memory allocations are
         * complete, the reserve32 will be freed.
-        */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-       if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
-               pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
-                      "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
-                      "is set\n");
-       else
-               addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
-                                                       0, 0, 512 << 20,
-                                                       "CAVIUM_RESERVE32", 0);
-#else
-       /*
+        *
         * Allocate memory for RESERVED32 aligned on 2MB boundary. This
         * is in case we later use hugetlb entries with it.
         */
        addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
                                                0, 0, 2 << 20,
                                                "CAVIUM_RESERVE32", 0);
-#endif
        if (addr < 0)
                pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
        else
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
                panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
        }
 #endif
-
-       /* This call is here so that it is performed after any TLB
-          initializations. It needs to be after these in case the
-          CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
-       octeon_hal_setup_reserved32();
 }
index 51e9802..6d99b9d 100644 (file)
@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
        uint32_t avail_coremask;
        struct cvmx_bootmem_named_block_desc *block_desc;
 
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
-       /* Disable the watchdog */
-       cvmx_ciu_wdogx_t ciu_wdog;
-       ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
-       ciu_wdog.s.mode = 0;
-       cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
        while (per_cpu(cpu_state, cpu) != CPU_DEAD)
                cpu_relax();
 
index 7fee027..6389ca0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc6
-# Sun May 31 20:17:18 2009
+# Linux kernel version: 2.6.34-rc2
+# Tue Mar 23 10:36:32 2010
 #
 CONFIG_MIPS=y
 
@@ -9,13 +9,14 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
 CONFIG_BCM63XX=y
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
 # CONFIG_NEC_MARKEINS is not set
@@ -26,6 +27,7 @@ CONFIG_BCM63XX=y
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -45,13 +47,17 @@ CONFIG_BCM63XX=y
 # CONFIG_WR_PPMC is not set
 # CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
 # CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 
 #
 # CPU support
 #
+CONFIG_BCM63XX_CPU_6338=y
+CONFIG_BCM63XX_CPU_6345=y
 CONFIG_BCM63XX_CPU_6348=y
 CONFIG_BCM63XX_CPU_6358=y
 CONFIG_BOARD_BCM963XX=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -69,10 +75,8 @@ CONFIG_CEVT_R4K=y
 CONFIG_CSRC_R4K_LIB=y
 CONFIG_CSRC_R4K=y
 CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_GPIO=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -85,7 +89,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 CONFIG_CPU_MIPS32_R1=y
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -128,7 +133,7 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -146,9 +151,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 # CONFIG_HIGH_RES_TIMERS is not set
@@ -170,6 +174,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -189,15 +194,12 @@ CONFIG_LOCALVERSION=""
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
 # CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -205,11 +207,11 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -223,6 +225,10 @@ CONFIG_BASE_FULL=y
 # CONFIG_EVENTFD is not set
 # CONFIG_SHMEM is not set
 # CONFIG_AIO is not set
+
+#
+# Kernel Performance Events And Counters
+#
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_PCI_QUIRKS=y
 # CONFIG_SLUB_DEBUG is not set
@@ -231,14 +237,17 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -246,14 +255,41 @@ CONFIG_BLOCK=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
 # CONFIG_DEFAULT_DEADLINE is not set
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -263,15 +299,12 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=y
 
 #
@@ -295,6 +328,7 @@ CONFIG_TRAD_SIGNALS=y
 #
 # Power management options
 #
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PM is not set
 CONFIG_NET=y
@@ -333,6 +367,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -347,6 +382,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -359,7 +395,27 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_CFG80211=y
+CONFIG_NL80211_TESTMODE=y
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=y
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUG_MENU is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -471,6 +527,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -484,13 +541,16 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -529,6 +589,7 @@ CONFIG_MII=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
 # CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
@@ -541,17 +602,48 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_ATL2 is not set
 CONFIG_BCM63XX_ENET=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_MWL8K is not set
+# CONFIG_ATH_COMMON is not set
+CONFIG_B43=y
+CONFIG_B43_PCI_AUTOSELECT=y
+CONFIG_B43_PCICORE_AUTOSELECT=y
+# CONFIG_B43_PCMCIA is not set
+CONFIG_B43_PIO=y
+# CONFIG_B43_PHY_LP is not set
+CONFIG_B43_LEDS=y
+# CONFIG_B43_DEBUG is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLWIFI is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -574,6 +666,7 @@ CONFIG_BCM63XX_ENET=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -607,6 +700,7 @@ CONFIG_BCM63XX_ENET=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_SERIAL_BCM63XX=y
 CONFIG_SERIAL_BCM63XX_CONSOLE=y
 # CONFIG_UNIX98_PTYS is not set
@@ -629,6 +723,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 # CONFIG_GPIO_SYSFS is not set
@@ -636,6 +735,8 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -644,16 +745,21 @@ CONFIG_GPIOLIB=y
 #
 # PCI GPIO expanders:
 #
+# CONFIG_GPIO_CS5535 is not set
 # CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
 
 #
 # SPI GPIO expanders:
 #
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -662,15 +768,16 @@ CONFIG_SSB_POSSIBLE=y
 #
 CONFIG_SSB=y
 CONFIG_SSB_SPROM=y
+CONFIG_SSB_BLOCKIO=y
 CONFIG_SSB_PCIHOST_POSSIBLE=y
 CONFIG_SSB_PCIHOST=y
-# CONFIG_SSB_B43_PCI_BRIDGE is not set
+CONFIG_SSB_B43_PCI_BRIDGE=y
 CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
 # CONFIG_SSB_PCMCIAHOST is not set
 # CONFIG_SSB_SILENT is not set
 # CONFIG_SSB_DEBUG is not set
 CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
-# CONFIG_SSB_DRIVER_PCICORE is not set
+CONFIG_SSB_DRIVER_PCICORE=y
 # CONFIG_SSB_DRIVER_MIPS is not set
 
 #
@@ -680,27 +787,15 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGA_ARB is not set
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -710,11 +805,7 @@ CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
 #
 # Display device support
 #
-CONFIG_DISPLAY_SUPPORT=y
-
-#
-# Display hardware drivers
-#
+# CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -741,13 +832,14 @@ CONFIG_USB=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
-CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_HCD_SSB is not set
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
@@ -796,7 +888,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -807,8 +898,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -819,7 +910,29 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
@@ -827,6 +940,10 @@ CONFIG_RTC_LIB=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -838,12 +955,16 @@ CONFIG_RTC_LIB=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-# CONFIG_FILE_LOCKING is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FILE_LOCKING is not set
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
@@ -875,8 +996,6 @@ CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
 CONFIG_MISC_FILESYSTEMS=y
@@ -888,6 +1007,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -898,7 +1018,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -906,7 +1025,46 @@ CONFIG_MISC_FILESYSTEMS=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
 
 #
@@ -918,29 +1076,23 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_FTRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_CMDLINE_OVERRIDE is not set
@@ -951,8 +1103,108 @@ CONFIG_CMDLINE="console=ttyS0,115200"
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=y
+# CONFIG_CRYPTO_HW is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index c2f06e3..0583bb2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Wed Jul  2 17:02:55 2008
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr  3 16:32:11 2010
 #
 CONFIG_MIPS=y
 
@@ -9,20 +9,25 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_NEC_MARKEINS is not set
 # CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -36,10 +41,13 @@ CONFIG_MIPS=y
 # CONFIG_SIBYTE_SENTOSA is not set
 CONFIG_SIBYTE_BIGSUR=y
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
 # CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 CONFIG_SIBYTE_BCM1x80=y
 CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_1 is not set
@@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_4 is not set
 # CONFIG_CPU_SB1_PASS_2_112x is not set
 # CONFIG_CPU_SB1_PASS_3 is not set
-# CONFIG_SIMULATION is not set
 # CONFIG_SB1_CEX_ALWAYS_FATAL is not set
 # CONFIG_SB1_CERR_STALL is not set
-CONFIG_SIBYTE_CFE=y
 # CONFIG_SIBYTE_CFE_CONSOLE is not set
 # CONFIG_SIBYTE_BUS_WATCHER is not set
 # CONFIG_SIBYTE_TBPROF is not set
 CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_CEVT_BCM1480=y
 CONFIG_CSRC_BCM1480=y
 CONFIG_CFE=y
 CONFIG_DMA_COHERENT=y
-CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -88,7 +93,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
+# CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_SYS_HAS_CPU_SB1=y
 CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -123,11 +131,13 @@ CONFIG_64BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -142,18 +152,17 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS_DEFAULT_4=y
 CONFIG_NR_CPUS=4
-# CONFIG_MIPS_CMP is not set
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +184,7 @@ CONFIG_SECCOMP=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -188,6 +198,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_TASKSTATS=y
@@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -222,29 +249,36 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_PCSPKR_PLATFORM is not set
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -252,26 +286,52 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 CONFIG_ZONE_DMA32=y
 # CONFIG_PCCARD is not set
@@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
@@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y
 #
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
 CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
 # CONFIG_IPV6_MROUTE is not set
+CONFIG_NETLABEL=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP_DCCP is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
 # CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
+CONFIG_SCTP_HMAC_SHA1=y
+# CONFIG_SCTP_HMAC_MD5 is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -482,26 +570,47 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -513,9 +622,12 @@ CONFIG_FIB_RULES=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 CONFIG_SGI_IOC4=m
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+CONFIG_EEPROM_MAX6875=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_AMD74XX is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
 CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
@@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_BLK_DEV_IDE_SWARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -645,27 +770,36 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -676,9 +810,15 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 CONFIG_SATA_SIL24=y
@@ -700,6 +840,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 CONFIG_PATA_SIL680=y
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -774,6 +921,9 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -783,23 +933,33 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
+CONFIG_MDIO=m
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_CHELSIO_T3=m
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 CONFIG_NETXEN_NIC=m
 # CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 # CONFIG_NOZOMI is not set
 
@@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
@@ -923,89 +1098,99 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-CONFIG_I2C_SIBYTE=y
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
 
 #
-# Miscellaneous I2C Chip support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_LEGACY=y
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-CONFIG_SENSORS_PCF8591=y
-CONFIG_EEPROM_MAX6875=y
-# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+CONFIG_I2C_SIBYTE=y
+# CONFIG_I2C_STUB is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
 #
 # File systems
 #
 CONFIG_EXT2_FS=m
 CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
 CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=m
+CONFIG_JBD2=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=m
 CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ECRYPT_FS is not set
@@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1133,16 +1349,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1205,12 +1422,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
 # CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_SB1XXX_CORELIS is not set
@@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y
 #
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+# CONFIG_SECURITY_PATH is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m
 #
 CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_CTR=m
-# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
 
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
 CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 1dd74fb..9252d9b 100644 (file)
 #include <asm/siginfo.h>
 
 struct mips_abi {
-       int (* const setup_frame)(struct k_sigaction * ka,
+       int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
                                  struct pt_regs *regs, int signr,
                                  sigset_t *set);
-       int (* const setup_rt_frame)(struct k_sigaction * ka,
+       const unsigned long     signal_return_offset;
+       int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
                               struct pt_regs *regs, int signr,
                               sigset_t *set, siginfo_t *info);
+       const unsigned long     rt_signal_return_offset;
        const unsigned long     restart;
 };
 
index 519197e..59dc0c7 100644 (file)
@@ -29,7 +29,7 @@
  *
  * Atomically reads the value of @v.
  */
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 
 /*
  * atomic_set - set atomic variable
@@ -410,7 +410,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
  * @v: pointer of type atomic64_t
  *
  */
-#define atomic64_read(v)       ((v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 /*
  * atomic64_set - set atomic variable
index ed9aaaa..2d28017 100644 (file)
@@ -16,7 +16,7 @@
 ({                                                                     \
        __typeof(*(m)) __ret;                                           \
                                                                        \
-       if (kernel_uses_llsc && R10000_LLSC_WAR) {                              \
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {                      \
                __asm__ __volatile__(                                   \
                "       .set    push                            \n"     \
                "       .set    noat                            \n"     \
index e53d7be..ea77a42 100644 (file)
@@ -310,6 +310,7 @@ do {                                                                        \
 
 #endif /* CONFIG_64BIT */
 
+struct pt_regs;
 struct task_struct;
 
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
@@ -367,4 +368,8 @@ extern const char *__elf_platform;
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #endif
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+                                      int uses_interp);
 #endif /* _ASM_ELF_H */
index aecada6..3b40927 100644 (file)
@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 
 #define MIPS_FPU_EMU_INC_STATS(M)                                      \
-       cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+do {                                                                   \
+       preempt_disable();                                              \
+       __local_inc(&__get_cpu_var(fpuemustats).M);                     \
+       preempt_enable();                                               \
+} while (0)
 
 #else
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
index 032ca73..48bb823 100644 (file)
@@ -12,7 +12,7 @@
 #define PIT_CH0                        0x40
 #define PIT_CH2                        0x42
 
-extern spinlock_t i8253_lock;
+extern raw_spinlock_t i8253_lock;
 
 extern void setup_pit_timer(void);
 
index b12c4ac..96a2391 100644 (file)
@@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
        RSET_TIMER,
        RSET_WDT,
        RSET_UART0,
+       RSET_UART1,
        RSET_GPIO,
        RSET_SPI,
        RSET_UDC0,
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
 #define BCM_6338_TIMER_BASE            (0xfffe0200)
 #define BCM_6338_WDT_BASE              (0xfffe021c)
 #define BCM_6338_UART0_BASE            (0xfffe0300)
+#define BCM_6338_UART1_BASE            (0xdeadbeef)
 #define BCM_6338_GPIO_BASE             (0xfffe0400)
 #define BCM_6338_SPI_BASE              (0xfffe0c00)
 #define BCM_6338_UDC0_BASE             (0xdeadbeef)
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_TIMER_BASE            (0xfffe0200)
 #define BCM_6345_WDT_BASE              (0xfffe021c)
 #define BCM_6345_UART0_BASE            (0xfffe0300)
+#define BCM_6345_UART1_BASE            (0xdeadbeef)
 #define BCM_6345_GPIO_BASE             (0xfffe0400)
 #define BCM_6345_SPI_BASE              (0xdeadbeef)
 #define BCM_6345_UDC0_BASE             (0xdeadbeef)
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
 #define BCM_6348_TIMER_BASE            (0xfffe0200)
 #define BCM_6348_WDT_BASE              (0xfffe021c)
 #define BCM_6348_UART0_BASE            (0xfffe0300)
+#define BCM_6348_UART1_BASE            (0xdeadbeef)
 #define BCM_6348_GPIO_BASE             (0xfffe0400)
 #define BCM_6348_SPI_BASE              (0xfffe0c00)
 #define BCM_6348_UDC0_BASE             (0xfffe1000)
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
 #define BCM_6358_TIMER_BASE            (0xfffe0040)
 #define BCM_6358_WDT_BASE              (0xfffe005c)
 #define BCM_6358_UART0_BASE            (0xfffe0100)
+#define BCM_6358_UART1_BASE            (0xfffe0120)
 #define BCM_6358_GPIO_BASE             (0xfffe0080)
 #define BCM_6358_SPI_BASE              (0xdeadbeef)
 #define BCM_6358_UDC0_BASE             (0xfffe0800)
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6338_WDT_BASE;
        case RSET_UART0:
                return BCM_6338_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6338_UART1_BASE;
        case RSET_GPIO:
                return BCM_6338_GPIO_BASE;
        case RSET_SPI:
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6345_WDT_BASE;
        case RSET_UART0:
                return BCM_6345_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6345_UART1_BASE;
        case RSET_GPIO:
                return BCM_6345_GPIO_BASE;
        case RSET_SPI:
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6348_WDT_BASE;
        case RSET_UART0:
                return BCM_6348_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6348_UART1_BASE;
        case RSET_GPIO:
                return BCM_6348_GPIO_BASE;
        case RSET_SPI:
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6358_WDT_BASE;
        case RSET_UART0:
                return BCM_6358_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6358_UART1_BASE;
        case RSET_GPIO:
                return BCM_6358_GPIO_BASE;
        case RSET_SPI:
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 enum bcm63xx_irq {
        IRQ_TIMER = 0,
        IRQ_UART0,
+       IRQ_UART1,
        IRQ_DSL,
        IRQ_ENET0,
        IRQ_ENET1,
@@ -510,6 +524,7 @@ enum bcm63xx_irq {
  */
 #define BCM_6358_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
 #define BCM_6358_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ             (IRQ_INTERNAL_BASE + 3)
 #define BCM_6358_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_ENET1_IRQ             (IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
new file mode 100644 (file)
index 0000000..23c705b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */
index 76a0b72..43d4da0 100644 (file)
@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
        switch (bcm63xx_get_cpu_id()) {
        case BCM6358_CPU_ID:
                return 40;
+       case BCM6338_CPU_ID:
+               return 8;
+       case BCM6345_CPU_ID:
+               return 16;
        case BCM6348_CPU_ID:
        default:
                return 37;
index 6479090..474daaa 100644 (file)
@@ -45,6 +45,8 @@ struct board_info {
        unsigned int    has_ohci0:1;
        unsigned int    has_ehci0:1;
        unsigned int    has_dsp:1;
+       unsigned int    has_uart0:1;
+       unsigned int    has_uart1:1;
 
        /* ethernet config */
        struct bcm63xx_enet_platform_data enet0;
index 71742ba..f453c01 100644 (file)
@@ -24,7 +24,7 @@
 #define cpu_has_smartmips              0
 #define cpu_has_vtag_icache            0
 
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
 #define cpu_has_dc_aliases             0
 #endif
 
index 1cf7b14..fcdbe3a 100644 (file)
@@ -307,7 +307,7 @@ extern unsigned long _loongson_addrwincfg_base;
  */
 #define LOONGSON_ADDRWIN_CFG(s, d, w, src, dst, size) do {\
        s##_WIN##w##_BASE = (src); \
-       s##_WIN##w##_MMAP = (src) | ADDRWIN_MAP_DST_##d; \
+       s##_WIN##w##_MMAP = (dst) | ADDRWIN_MAP_DST_##d; \
        s##_WIN##w##_MASK = ~(size-1); \
 } while (0)
 
index 7950ef4..743385d 100644 (file)
 #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
     defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
 
-#define BCM1250_M3_WAR 1
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
 #define SIBYTE_1956_WAR        1
 
 #else
index 49382d5..c6e3c93 100644 (file)
 #define FPU_CSR_COND6   0x40000000      /* $fcc6 */
 #define FPU_CSR_COND7   0x80000000      /* $fcc7 */
 
+/*
+ * Bits 18 - 20 of the FPU Status Register will be read as 0,
+ * and should be written as zero.
+ */
+#define FPU_CSR_RSVD   0x001c0000
+
 /*
  * X the exception cause indicator
  * E the exception enable
 #define FPU_CSR_UDF_S   0x00000008
 #define FPU_CSR_INE_S   0x00000004
 
-/* rounding mode */
+/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
+#define FPU_CSR_RM     0x00000003
 #define FPU_CSR_RN      0x0     /* nearest */
 #define FPU_CSR_RZ      0x1     /* towards zero */
 #define FPU_CSR_RU      0x2     /* towards +Infinity */
index 4063edd..c436138 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __ASM_MMU_H
 #define __ASM_MMU_H
 
-typedef unsigned long mm_context_t[NR_CPUS];
+typedef struct {
+       unsigned long asid[NR_CPUS];
+       void *vdso;
+} mm_context_t;
 
 #endif /* __ASM_MMU_H */
index 145bb81..d959273 100644 (file)
@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
 
 #endif
 
-#define cpu_context(cpu, mm)   ((mm)->context[cpu])
+#define cpu_context(cpu, mm)   ((mm)->context.asid[cpu])
 #define cpu_asid(cpu, mm)      (cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)                (cpu_data[cpu].asid_cache)
 
index ac32572..a16beaf 100644 (file)
@@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE +    \
+                                                               PHYS_OFFSET)
+#define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET -    \
+                                                               PHYS_OFFSET)
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
index 26dc69d..1be4b0f 100644 (file)
 #endif
 #define FIRST_USER_ADDRESS     0UL
 
-#define VMALLOC_START          MAP_BASE
+/*
+ * TLB refill handlers also map the vmalloc area into xuseg.  Avoid
+ * the first couple of pages so NULL pointer dereferences will still
+ * reliably trap.
+ */
+#define VMALLOC_START          (MAP_BASE + (2 * PAGE_SIZE))
 #define VMALLOC_END    \
-       (VMALLOC_START + \
+       (MAP_BASE + \
         min(PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
             (1UL << cpu_vmbits)) - (1UL << 32))
 
index 087a888..ab38791 100644 (file)
@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
 #ifdef CONFIG_32BIT
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
 #define TASK_SIZE      0x7fff8000UL
-#define STACK_TOP      TASK_SIZE
+#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
 #define TASK_SIZE32    0x7fff8000UL
 #define TASK_SIZE      0x10000000000UL
 #define STACK_TOP      \
-      (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+       (((test_thread_flag(TIF_32BIT_ADDR) ?                           \
+          TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
index ce47118..cdc6a46 100644 (file)
@@ -142,9 +142,9 @@ extern int ptrace_set_watch_regs(struct task_struct *child,
 
 extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
 
-extern NORET_TYPE void die(const char *, const struct pt_regs *) ATTRIB_NORET;
+extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
 
-static inline void die_if_kernel(const char *str, const struct pt_regs *regs)
+static inline void die_if_kernel(const char *str, struct pt_regs *regs)
 {
        if (unlikely(!user_mode(regs)))
                die(str, regs);
index 3b6da33..58730c5 100644 (file)
                .endm
 #else
                .macro  get_saved_sp    /* Uniprocessor variation */
+#ifdef CONFIG_CPU_JUMP_WORKAROUNDS
+               /*
+                * Clear BTB (branch target buffer), forbid RAS (return address
+                * stack) to workaround the Out-of-order Issue in Loongson2F
+                * via its diagnostic register.
+                */
+               move    k0, ra
+               jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             move    ra, k0
+               li      k0, 3
+               mtc0    k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
                lui     k1, %hi(kernelsp)
 #else
index b99bd07..697e40c 100644 (file)
@@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
 Ip_u1u2u3(_mfc0);
 Ip_u1u2u3(_mtc0);
 Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
 Ip_u2s3u1(_pref);
 Ip_0(_rfe);
 Ip_u2s3u1(_sc);
@@ -102,6 +103,7 @@ Ip_0(_tlbwr);
 Ip_u3u1u2(_xor);
 Ip_u2u1u3(_xori);
 Ip_u2u1msbu3(_dins);
+Ip_u1(_syscall);
 
 /* Handle labels. */
 struct uasm_label {
@@ -165,6 +167,24 @@ static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
 #define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
 #define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
 
+static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
+                                   unsigned int a2, unsigned int a3)
+{
+       if (a3 < 32)
+               uasm_i_dsrl(p, a1, a2, a3);
+       else
+               uasm_i_dsrl32(p, a1, a2, a3 - 32);
+}
+
+static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
+                                   unsigned int a2, unsigned int a3)
+{
+       if (a3 < 32)
+               uasm_i_dsll(p, a1, a2, a3);
+       else
+               uasm_i_dsll32(p, a1, a2, a3 - 32);
+}
+
 /* Handle relocations. */
 struct uasm_reloc {
        u32 *addr;
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
new file mode 100644 (file)
index 0000000..cca56aa
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+       u32 signal_trampoline[2];
+       u32 rt_signal_trampoline[2];
+};
+#else  /* !CONFIG_32BIT */
+struct mips_vdso {
+       u32 o32_signal_trampoline[2];
+       u32 o32_rt_signal_trampoline[2];
+       u32 rt_signal_trampoline[2];
+       u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */
index 7043f6b..0d0f054 100644 (file)
@@ -76,15 +76,9 @@ void __init plat_mem_setup(void)
 
 #ifdef CONFIG_VT
        screen_info = (struct screen_info) {
-               0, 0,           /* orig-x, orig-y */
-               0,              /* unused */
-               0,              /* orig_video_page */
-               0,              /* orig_video_mode */
-               160,            /* orig_video_cols */
-               0, 0, 0,        /* unused, ega_bx, unused */
-               64,             /* orig_video_lines */
-               0,              /* orig_video_isVGA */
-               16              /* orig_video_points */
+               .orig_video_cols        = 160,
+               .orig_video_lines       = 64,
+               .orig_video_points      = 16,
        };
 #endif
 
index ef20957..7a6ac50 100644 (file)
@@ -6,7 +6,7 @@ extra-y         := head.o init_task.o vmlinux.lds
 
 obj-y          += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
                   ptrace.o reset.o setup.o signal.o syscall.o \
-                  time.o topology.o traps.o unaligned.o watch.o
+                  time.o topology.o traps.o unaligned.o watch.o vdso.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
index d7ca256..cefc6e2 100644 (file)
@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
        spin_unlock_irqrestore(&loongson2_wait_lock, flags);
 }
 EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");
index ed5c441..9479406 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/io.h>
 #include <asm/time.h>
 
-DEFINE_SPINLOCK(i8253_lock);
+DEFINE_RAW_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
 /*
@@ -26,7 +26,7 @@ EXPORT_SYMBOL(i8253_lock);
 static void init_pit_timer(enum clock_event_mode mode,
                           struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
 
        switch(mode) {
        case CLOCK_EVT_MODE_PERIODIC:
@@ -55,7 +55,7 @@ static void init_pit_timer(enum clock_event_mode mode,
                /* Nothing to do here */
                break;
        }
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 }
 
 /*
@@ -65,10 +65,10 @@ static void init_pit_timer(enum clock_event_mode mode,
  */
 static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        outb_p(delta & 0xff , PIT_CH0); /* LSB */
        outb(delta >> 8 , PIT_CH0);     /* MSB */
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 
        return 0;
 }
@@ -137,7 +137,7 @@ static cycle_t pit_read(struct clocksource *cs)
        static int old_count;
        static u32 old_jifs;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        /*
         * Although our caller may have the read side of xtime_lock,
         * this is now a seqlock, and we are cheating in this routine
@@ -183,7 +183,7 @@ static cycle_t pit_read(struct clocksource *cs)
        old_count = count;
        old_jifs = jifs;
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        count = (LATCH - 1) - count;
 
index 463b71b..9996094 100644 (file)
@@ -63,8 +63,13 @@ void __noreturn cpu_idle(void)
 
                        smtc_idle_loop_hook();
 #endif
-                       if (cpu_wait)
+
+                       if (cpu_wait) {
+                               /* Don't trace irqs off for idle */
+                               stop_critical_timings();
                                (*cpu_wait)();
+                               start_critical_timings();
+                       }
                }
 #ifdef CONFIG_HOTPLUG_CPU
                if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
index 44337ba..a5297e2 100644 (file)
@@ -385,7 +385,7 @@ EXPORT(sysn32_call_table)
        PTR     sys_fchmodat
        PTR     sys_faccessat
        PTR     compat_sys_pselect6
-       PTR     sys_ppoll                       /* 6265 */
+       PTR     compat_sys_ppoll                /* 6265 */
        PTR     sys_unshare
        PTR     sys_splice
        PTR     sys_sync_file_range
index 6c8e8c4..10263b4 100644 (file)
  */
 extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
                                 size_t frame_size);
-/*
- * install trampoline code to get back from the sig handler
- */
-extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
-
 /* Check and clear pending FPU exceptions in saved CSR */
 extern int fpcsr_pending(unsigned int __user *fpcsr);
 
index d0c68b5..2099d5a 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe {
        u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
+       u32 sf_pad[2];          /* Was: signal trampoline */
        struct sigcontext sf_sc;
        sigset_t sf_mask;
 };
 
 struct rt_sigframe {
        u32 rs_ass[4];          /* argument save space for o32 */
-       u32 rs_code[2];         /* signal trampoline */
+       u32 rs_pad[2];          /* Was: signal trampoline */
        struct siginfo rs_info;
        struct ucontext rs_uc;
 };
 
-#else
-
-struct sigframe {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext sf_sc;        /* hw context */
-       sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-struct rt_sigframe {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
-       struct siginfo rs_info;
-       struct ucontext rs_uc;
-       u32 rs_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-#endif
-
 /*
  * Helper routines
  */
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
        return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 }
 
-int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
-{
-       int err;
-
-       /*
-        * Set up the return code ...
-        *
-        *         li      v0, __NR__foo_sigreturn
-        *         syscall
-        */
-
-       err = __put_user(0x24020000 + syscall, tramp + 0);
-       err |= __put_user(0x0000000c         , tramp + 1);
-       if (ICACHE_REFILLS_WORKAROUND_WAR) {
-               err |= __put_user(0, tramp + 2);
-               err |= __put_user(0, tramp + 3);
-               err |= __put_user(0, tramp + 4);
-               err |= __put_user(0, tramp + 5);
-               err |= __put_user(0, tramp + 6);
-               err |= __put_user(0, tramp + 7);
-       }
-       flush_cache_sigtramp((unsigned long) tramp);
-
-       return err;
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -484,8 +432,8 @@ badframe:
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+                      struct pt_regs *regs, int signr, sigset_t *set)
 {
        struct sigframe __user *frame;
        int err = 0;
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
-
        err |= setup_sigcontext(regs, &frame->sf_sc);
        err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
        if (err)
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->sf_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -529,8 +475,9 @@ give_sigsegv:
 }
 #endif
 
-static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+                         struct pt_regs *regs, int signr, sigset_t *set,
+                         siginfo_t *info)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
-
        /* Create siginfo.  */
        err |= copy_siginfo_to_user(&frame->rs_info, info);
 
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -590,8 +535,11 @@ give_sigsegv:
 struct mips_abi mips_abi = {
 #ifdef CONFIG_TRAD_SIGNALS
        .setup_frame    = setup_frame,
+       .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
 #endif
        .setup_rt_frame = setup_rt_frame,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, rt_signal_trampoline),
        .restart        = __NR_restart_syscall
 };
 
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 {
        int ret;
+       struct mips_abi *abi = current->thread.abi;
+       void *vdso = current->mm->context.vdso;
 
        switch(regs->regs[0]) {
        case ERESTART_RESTARTBLOCK:
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        regs->regs[0] = 0;              /* Don't deal with this again.  */
 
        if (sig_uses_siginfo(ka))
-               ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+               ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+                                         ka, regs, sig, oldset, info);
        else
-               ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+               ret = abi->setup_frame(vdso + abi->signal_return_offset,
+                                      ka, regs, sig, oldset);
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
index 03abaf0..a0ed0e0 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/system.h>
 #include <asm/fpu.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_O32_sigreturn             4119
-#define __NR_O32_rt_sigreturn          4193
 #define __NR_O32_restart_syscall        4253
 
 /* 32-bit compatibility types */
@@ -77,47 +76,20 @@ struct ucontext32 {
        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe32 {
        u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
+       u32 sf_pad[2];          /* Was: signal trampoline */
        struct sigcontext32 sf_sc;
        compat_sigset_t sf_mask;
 };
 
 struct rt_sigframe32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_code[2];                 /* signal trampoline */
+       u32 rs_pad[2];                  /* Was: signal trampoline */
        compat_siginfo_t rs_info;
        struct ucontext32 rs_uc;
 };
 
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe32 {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext32 sf_sc;      /* hw context */
-       compat_sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-struct rt_sigframe32 {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
-       compat_siginfo_t rs_info;
-       struct ucontext32 rs_uc;
-       u32 rs_code[8] __attribute__((aligned(32)));    /* signal trampoline */
-};
-
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 /*
  * sigcontext handlers
  */
@@ -598,8 +570,8 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+                         struct pt_regs *regs, int signr, sigset_t *set)
 {
        struct sigframe32 __user *frame;
        int err = 0;
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
-
        err |= setup_sigcontext32(regs, &frame->sf_sc);
        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->sf_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -644,8 +614,9 @@ give_sigsegv:
        return -EFAULT;
 }
 
-static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+                            struct pt_regs *regs, int signr, sigset_t *set,
+                            siginfo_t *info)
 {
        struct rt_sigframe32 __user *frame;
        int err = 0;
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
-
        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -709,7 +678,11 @@ give_sigsegv:
  */
 struct mips_abi mips_abi_32 = {
        .setup_frame    = setup_frame_32,
+       .signal_return_offset =
+               offsetof(struct mips_vdso, o32_signal_trampoline),
        .setup_rt_frame = setup_rt_frame_32,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, o32_rt_signal_trampoline),
        .restart        = __NR_O32_restart_syscall
 };
 
index bb277e8..2c5df81 100644 (file)
 #include <asm/fpu.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_N32_rt_sigreturn          6211
 #define __NR_N32_restart_syscall       6214
 
 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -67,27 +67,13 @@ struct ucontextn32 {
        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct rt_sigframe_n32 {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_code[2];                 /* signal trampoline */
-       struct compat_siginfo rs_info;
-       struct ucontextn32 rs_uc;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
 struct rt_sigframe_n32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
+       u32 rs_pad[2];                  /* Was: signal trampoline */
        struct compat_siginfo rs_info;
        struct ucontextn32 rs_uc;
-       u32 rs_code[8] ____cacheline_aligned;           /* signal trampoline */
 };
 
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -173,7 +159,7 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
        struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
        struct rt_sigframe_n32 __user *frame;
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
-
        /* Create siginfo.  */
        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -235,5 +219,7 @@ give_sigsegv:
 
 struct mips_abi mips_abi_n32 = {
        .setup_rt_frame = setup_rt_frame_n32,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, n32_rt_signal_trampoline),
        .restart        = __NR_N32_restart_syscall
 };
index 25e825a..a95dea5 100644 (file)
@@ -182,7 +182,7 @@ static int vpemask[2][8] = {
        {0, 0, 0, 0, 0, 0, 0, 1}
 };
 int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
 static int clock_hang_reported[NR_CPUS];
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
index 9587abc..dd81b0f 100644 (file)
@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
        int do_color_align;
        unsigned long task_size;
 
-       task_size = STACK_TOP;
+#ifdef CONFIG_32BIT
+       task_size = TASK_SIZE;
+#else /* Must be CONFIG_64BIT*/
+       task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
+#endif
 
        if (len > task_size)
                return -ENOMEM;
index 4e00f9b..d612c6d 100644 (file)
@@ -352,9 +352,10 @@ void show_registers(const struct pt_regs *regs)
 
 static DEFINE_SPINLOCK(die_lock);
 
-void __noreturn die(const char * str, const struct pt_regs * regs)
+void __noreturn die(const char * str, struct pt_regs * regs)
 {
        static int die_counter;
+       int sig = SIGSEGV;
 #ifdef CONFIG_MIPS_MT_SMTC
        unsigned long dvpret = dvpe();
 #endif /* CONFIG_MIPS_MT_SMTC */
@@ -365,6 +366,10 @@ void __noreturn die(const char * str, const struct pt_regs * regs)
 #ifdef CONFIG_MIPS_MT_SMTC
        mips_mt_regdump(dvpret);
 #endif /* CONFIG_MIPS_MT_SMTC */
+
+       if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
+               sig = 0;
+
        printk("%s[#%d]:\n", str, ++die_counter);
        show_registers(regs);
        add_taint(TAINT_DIE);
@@ -379,7 +384,7 @@ void __noreturn die(const char * str, const struct pt_regs * regs)
                panic("Fatal exception");
        }
 
-       do_exit(SIGSEGV);
+       do_exit(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
@@ -1557,12 +1562,7 @@ static char panic_null_cerr[] __cpuinitdata =
 void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
        unsigned long size)
 {
-#ifdef CONFIG_32BIT
-       unsigned long uncached_ebase = KSEG1ADDR(ebase);
-#endif
-#ifdef CONFIG_64BIT
-       unsigned long uncached_ebase = TO_UNCAC(ebase);
-#endif
+       unsigned long uncached_ebase = CKSEG1ADDR(ebase);
 
        if (!addr)
                panic(panic_null_cerr);
@@ -1599,7 +1599,7 @@ void __init trap_init(void)
                ebase = (unsigned long)
                        __alloc_bootmem(size, 1 << fls(size), 0);
        } else {
-               ebase = CAC_BASE;
+               ebase = CKSEG0;
                if (cpu_has_mips_r2)
                        ebase += (read_c0_ebase() & 0x3ffff000);
        }
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
new file mode 100644 (file)
index 0000000..b773c11
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn             4119
+#define __NR_O32_rt_sigreturn          4193
+#define __NR_N32_rt_sigreturn          6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+       uasm_i_addiu(&tramp, 2, 0, sigreturn);  /* li v0, sigreturn */
+       uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+       struct mips_vdso *vdso;
+
+       vdso_page = alloc_page(GFP_KERNEL);
+       if (!vdso_page)
+               panic("Cannot allocate vdso");
+
+       vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+       if (!vdso)
+               panic("Cannot map vdso");
+       clear_page(vdso);
+
+       install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+       install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+       install_trampoline(vdso->n32_rt_signal_trampoline,
+                          __NR_N32_rt_sigreturn);
+       install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+       install_trampoline(vdso->o32_rt_signal_trampoline,
+                          __NR_O32_rt_sigreturn);
+#endif
+
+       vunmap(vdso);
+
+       pr_notice("init_vdso successfull\n");
+
+       return 0;
+}
+device_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+       return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+       int ret;
+       unsigned long addr;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+
+       addr = vdso_addr(mm->start_stack);
+
+       addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+       if (IS_ERR_VALUE(addr)) {
+               ret = addr;
+               goto up_fail;
+       }
+
+       ret = install_special_mapping(mm, addr, PAGE_SIZE,
+                                     VM_READ|VM_EXEC|
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+                                     VM_ALWAYSDUMP,
+                                     &vdso_page);
+
+       if (ret)
+               goto up_fail;
+
+       mm->context.vdso = (void *)addr;
+
+up_fail:
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+               return "[vdso]";
+       return NULL;
+}
index 6b3b1de..5995969 100644 (file)
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
 
 void __udelay(unsigned long us)
 {
-       unsigned int lpj = current_cpu_data.udelay_val;
+       unsigned int lpj = raw_current_cpu_data.udelay_val;
 
        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
 
 void __ndelay(unsigned long ns)
 {
-       unsigned int lpj = current_cpu_data.udelay_val;
+       unsigned int lpj = raw_current_cpu_data.udelay_val;
 
        __delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
index 3f19d1c..05909d5 100644 (file)
@@ -17,8 +17,7 @@ struct DWstruct {
 #error I feel sick.
 #endif
 
-typedef union
-{
+typedef union {
        struct DWstruct s;
        long long ll;
 } DWunion;
index 853f184..81fbe6b 100644 (file)
@@ -24,7 +24,7 @@ static const char *system_types[] = {
        [MACH_LEMOTE_FL2F]              "lemote-fuloong-2f-box",
        [MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
        [MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
-       [MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+       [MACH_DEXXON_GDIUM2F10]         "dexxon-gdium-2f",
        [MACH_LEMOTE_NAS]               "lemote-nas-2f",
        [MACH_LEMOTE_LL2F]              "lemote-lynloong-2f",
        [MACH_LOONGSON_END]             NULL,
index ec2f796..30eba60 100644 (file)
@@ -75,7 +75,7 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
        unsigned long end = offset + size;
 
        if (__uncached_access(file, offset)) {
-               if (((uca_start && offset) >= uca_start) &&
+               if (uca_start && (offset >= uca_start) &&
                    (end <= uca_end))
                        return __pgprot((pgprot_val(vma_prot) &
                                         ~_CACHE_MASK) |
@@ -96,7 +96,7 @@ static int __init find_vga_mem_init(void)
                return 0;
 
        for_each_pci_dev(dev) {
-               if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+               if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
                        for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
                                r = &dev->resource[idx];
                                if (!r->start && r->end)
index 4bd9c18..9e10d62 100644 (file)
 
 #include <loongson.h>
 
+static inline void loongson_reboot(void)
+{
+#ifndef CONFIG_CPU_JUMP_WORKAROUNDS
+       ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+#else
+       void (*func)(void);
+
+       func = (void *)ioremap_nocache(LOONGSON_BOOT_BASE, 4);
+
+       __asm__ __volatile__(
+       "       .set    noat                                            \n"
+       "       jr      %[func]                                         \n"
+       "       .set    at                                              \n"
+       : /* No outputs */
+       : [func] "r" (func));
+#endif
+}
+
 static void loongson_restart(char *command)
 {
        /* do preparation for reboot */
        mach_prepare_reboot();
 
        /* reboot via jumping to boot base address */
-       ((void (*)(void))ioremap_nocache(LOONGSON_BOOT_BASE, 4)) ();
+       loongson_reboot();
 }
 
 static void loongson_poweroff(void)
index 4cd2aa9..27d826b 100644 (file)
@@ -41,15 +41,12 @@ void __init plat_mem_setup(void)
        conswitchp = &vga_con;
 
        screen_info = (struct screen_info) {
-               0, 25,          /* orig-x, orig-y */
-                   0,          /* unused */
-                   0,          /* orig-video-page */
-                   0,          /* orig-video-mode */
-                   80,         /* orig-video-cols */
-                   0, 0, 0,    /* ega_ax, ega_bx, ega_cx */
-                   25,         /* orig-video-lines */
-                   VIDEO_TYPE_VGAC,    /* orig-video-isVGA */
-                   16          /* orig-video-points */
+               .orig_x                 = 0,
+               .orig_y                 = 25,
+               .orig_video_cols        = 80,
+               .orig_video_lines       = 25,
+               .orig_video_isVGA       = VIDEO_TYPE_VGAC,
+               .orig_video_points      = 16,
        };
 #elif defined(CONFIG_DUMMY_CONSOLE)
        conswitchp = &dummy_con;
index 882dfcd..1d8b4d2 100644 (file)
@@ -79,7 +79,7 @@ void mach_irq_dispatch(unsigned int pending)
        if (pending & CAUSEF_IP7)
                do_IRQ(LOONGSON_TIMER_IRQ);
        else if (pending & CAUSEF_IP6) {        /* North Bridge, Perf counter */
-#ifdef CONFIG_OPROFILE
+#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
                do_IRQ(LOONGSON2_PERFCNT_IRQ);
 #endif
                bonito_irqdispatch();
index 8f2f8e9..f2338d1 100644 (file)
@@ -78,6 +78,9 @@ DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 #define FPCREG_RID     0       /* $0  = revision id */
 #define FPCREG_CSR     31      /* $31 = csr */
 
+/* Determine rounding mode from the RM bits of the FCSR */
+#define modeindex(v) ((v) & FPU_CSR_RM)
+
 /* Convert Mips rounding mode (0..3) to IEEE library modes. */
 static const unsigned char ieee_rm[4] = {
        [FPU_CSR_RN] = IEEE754_RN,
@@ -384,10 +387,14 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                                        (void *) (xcp->cp0_epc),
                                        MIPSInst_RT(ir), value);
 #endif
-                               value &= (FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
-                               ctx->fcr31 &= ~(FPU_CSR_FLUSH | FPU_CSR_ALL_E | FPU_CSR_ALL_S | 0x03);
-                               /* convert to ieee library modes */
-                               ctx->fcr31 |= (value & ~0x3) | ieee_rm[value & 0x3];
+
+                               /*
+                                * Don't write reserved bits,
+                                * and convert to ieee library modes
+                                */
+                               ctx->fcr31 = (value &
+                                               ~(FPU_CSR_RSVD | FPU_CSR_RM)) |
+                                               ieee_rm[modeindex(value)];
                        }
                        if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {
                                return SIGFPE;
index be8627b..12af739 100644 (file)
@@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
 }
 
 unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
 
 static inline void setup_protection_map(void)
 {
index 0de0e41..86f004d 100644 (file)
 #include <asm/war.h>
 #include <asm/uasm.h>
 
+/*
+ * TLB load/store/modify handlers.
+ *
+ * Only the fastpath gets synthesized at runtime, the slowpath for
+ * do_page_fault remains normal asm.
+ */
+extern void tlb_do_page_fault_0(void);
+extern void tlb_do_page_fault_1(void);
+
+
 static inline int r45k_bvahwbug(void)
 {
        /* XXX: We should probe for the presence of this bug, but we don't. */
@@ -83,6 +93,7 @@ enum label_id {
        label_nopage_tlbm,
        label_smp_pgtable_change,
        label_r3000_write_probe_fail,
+       label_large_segbits_fault,
 #ifdef CONFIG_HUGETLB_PAGE
        label_tlb_huge_update,
 #endif
@@ -101,6 +112,7 @@ UASM_L_LA(_nopage_tlbs)
 UASM_L_LA(_nopage_tlbm)
 UASM_L_LA(_smp_pgtable_change)
 UASM_L_LA(_r3000_write_probe_fail)
+UASM_L_LA(_large_segbits_fault)
 #ifdef CONFIG_HUGETLB_PAGE
 UASM_L_LA(_tlb_huge_update)
 #endif
@@ -157,6 +169,10 @@ static u32 tlb_handler[128] __cpuinitdata;
 static struct uasm_label labels[128] __cpuinitdata;
 static struct uasm_reloc relocs[128] __cpuinitdata;
 
+#ifdef CONFIG_64BIT
+static int check_for_high_segbits __cpuinitdata;
+#endif
+
 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT
 /*
  * CONFIG_MIPS_PGD_C0_CONTEXT implies 64 bit and lack of pgd_current,
@@ -408,7 +424,7 @@ static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
                UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
        } else {
 #ifdef CONFIG_64BIT_PHYS_ADDR
-               uasm_i_dsrl(p, reg, reg, ilog2(_PAGE_GLOBAL));
+               uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));
 #else
                UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL));
 #endif
@@ -532,7 +548,24 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
         * The vmalloc handling is not in the hotpath.
         */
        uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-       uasm_il_bltz(p, r, tmp, label_vmalloc);
+
+       if (check_for_high_segbits) {
+               /*
+                * The kernel currently implicitely assumes that the
+                * MIPS SEGBITS parameter for the processor is
+                * (PGDIR_SHIFT+PGDIR_BITS) or less, and will never
+                * allocate virtual addresses outside the maximum
+                * range for SEGBITS = (PGDIR_SHIFT+PGDIR_BITS). But
+                * that doesn't prevent user code from accessing the
+                * higher xuseg addresses.  Here, we make sure that
+                * everything but the lower xuseg addresses goes down
+                * the module_alloc/vmalloc path.
+                */
+               uasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+               uasm_il_bnez(p, r, ptr, label_vmalloc);
+       } else {
+               uasm_il_bltz(p, r, tmp, label_vmalloc);
+       }
        /* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
@@ -549,14 +582,14 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
         * SMTC uses TCBind value as "CPU" index
         */
        uasm_i_mfc0(p, ptr, C0_TCBIND);
-       uasm_i_dsrl(p, ptr, ptr, 19);
+       uasm_i_dsrl_safe(p, ptr, ptr, 19);
 # else
        /*
         * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
         * stored in CONTEXT.
         */
        uasm_i_dmfc0(p, ptr, C0_CONTEXT);
-       uasm_i_dsrl(p, ptr, ptr, 23);
+       uasm_i_dsrl_safe(p, ptr, ptr, 23);
 # endif
        UASM_i_LA_mostly(p, tmp, pgdc);
        uasm_i_daddu(p, ptr, ptr, tmp);
@@ -569,44 +602,78 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 
        uasm_l_vmalloc_done(l, *p);
 
-       if (PGDIR_SHIFT - 3 < 32)               /* get pgd offset in bytes */
-               uasm_i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
-       else
-               uasm_i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+       /* get pgd offset in bytes */
+       uasm_i_dsrl_safe(p, tmp, tmp, PGDIR_SHIFT - 3);
 
        uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
        uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
 #ifndef __PAGETABLE_PMD_FOLDED
        uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
        uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
-       uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
+       uasm_i_dsrl_safe(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
        uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
        uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
 #endif
 }
 
+enum vmalloc64_mode {not_refill, refill};
 /*
  * BVADDR is the faulting address, PTR is scratch.
  * PTR will hold the pgd for vmalloc.
  */
 static void __cpuinit
 build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
-                       unsigned int bvaddr, unsigned int ptr)
+                       unsigned int bvaddr, unsigned int ptr,
+                       enum vmalloc64_mode mode)
 {
        long swpd = (long)swapper_pg_dir;
+       int single_insn_swpd;
+       int did_vmalloc_branch = 0;
+
+       single_insn_swpd = uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd);
 
        uasm_l_vmalloc(l, *p);
 
-       if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
-               uasm_il_b(p, r, label_vmalloc_done);
-               uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
-       } else {
-               UASM_i_LA_mostly(p, ptr, swpd);
-               uasm_il_b(p, r, label_vmalloc_done);
-               if (uasm_in_compat_space_p(swpd))
-                       uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
-               else
-                       uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+       if (mode == refill && check_for_high_segbits) {
+               if (single_insn_swpd) {
+                       uasm_il_bltz(p, r, bvaddr, label_vmalloc_done);
+                       uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+                       did_vmalloc_branch = 1;
+                       /* fall through */
+               } else {
+                       uasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);
+               }
+       }
+       if (!did_vmalloc_branch) {
+               if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
+                       uasm_il_b(p, r, label_vmalloc_done);
+                       uasm_i_lui(p, ptr, uasm_rel_hi(swpd));
+               } else {
+                       UASM_i_LA_mostly(p, ptr, swpd);
+                       uasm_il_b(p, r, label_vmalloc_done);
+                       if (uasm_in_compat_space_p(swpd))
+                               uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));
+                       else
+                               uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));
+               }
+       }
+       if (mode == refill && check_for_high_segbits) {
+               uasm_l_large_segbits_fault(l, *p);
+               /*
+                * We get here if we are an xsseg address, or if we are
+                * an xuseg address above (PGDIR_SHIFT+PGDIR_BITS) boundary.
+                *
+                * Ignoring xsseg (assume disabled so would generate
+                * (address errors?), the only remaining possibility
+                * is the upper xuseg addresses.  On processors with
+                * TLB_SEGBITS <= PGDIR_SHIFT+PGDIR_BITS, these
+                * addresses would have taken an address error. We try
+                * to mimic that here by taking a load/istream page
+                * fault.
+                */
+               UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
+               uasm_i_jr(p, ptr);
+               uasm_i_nop(p);
        }
 }
 
@@ -720,9 +787,9 @@ static void __cpuinit build_update_entries(u32 **p, unsigned int tmp,
                        UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
                        UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
                } else {
-                       uasm_i_dsrl(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
+                       uasm_i_dsrl_safe(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); /* convert to entrylo0 */
                        UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */
-                       uasm_i_dsrl(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
+                       uasm_i_dsrl_safe(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); /* convert to entrylo1 */
                }
                UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */
        } else {
@@ -788,10 +855,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
         * create the plain linear handler
         */
        if (bcm1250_m3_war()) {
-               UASM_i_MFC0(&p, K0, C0_BADVADDR);
-               UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+               unsigned int segbits = 44;
+
+               uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+               uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
                uasm_i_xor(&p, K0, K0, K1);
-               UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+               uasm_i_dsrl_safe(&p, K1, K0, 62);
+               uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+               uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+               uasm_i_or(&p, K0, K0, K1);
                uasm_il_bnez(&p, &r, K0, label_leave);
                /* No need for uasm_i_nop */
        }
@@ -820,7 +892,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 #endif
 
 #ifdef CONFIG_64BIT
-       build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
+       build_get_pgd_vmalloc64(&p, &l, &r, K0, K1, refill);
 #endif
 
        /*
@@ -929,15 +1001,6 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
        dump_handler((u32 *)ebase, 64);
 }
 
-/*
- * TLB load/store/modify handlers.
- *
- * Only the fastpath gets synthesized at runtime, the slowpath for
- * do_page_fault remains normal asm.
- */
-extern void tlb_do_page_fault_0(void);
-extern void tlb_do_page_fault_1(void);
-
 /*
  * 128 instructions for the fastpath handler is generous and should
  * never be exceeded.
@@ -1297,7 +1360,7 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l,
        uasm_i_eret(p); /* return from trap */
 
 #ifdef CONFIG_64BIT
-       build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
+       build_get_pgd_vmalloc64(p, l, r, tmp, ptr, not_refill);
 #endif
 }
 
@@ -1312,10 +1375,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
        memset(relocs, 0, sizeof(relocs));
 
        if (bcm1250_m3_war()) {
-               UASM_i_MFC0(&p, K0, C0_BADVADDR);
-               UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+               unsigned int segbits = 44;
+
+               uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+               uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
                uasm_i_xor(&p, K0, K0, K1);
-               UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+               uasm_i_dsrl_safe(&p, K1, K0, 62);
+               uasm_i_dsrl_safe(&p, K0, K0, 12 + 1);
+               uasm_i_dsll_safe(&p, K0, K0, 64 + 12 + 1 - segbits);
+               uasm_i_or(&p, K0, K0, K1);
                uasm_il_bnez(&p, &r, K0, label_leave);
                /* No need for uasm_i_nop */
        }
@@ -1516,6 +1584,10 @@ void __cpuinit build_tlb_refill_handler(void)
         */
        static int run_once = 0;
 
+#ifdef CONFIG_64BIT
+       check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3);
+#endif
+
        switch (current_cpu_type()) {
        case CPU_R2000:
        case CPU_R3000:
index 1581e98..611d564 100644 (file)
@@ -31,7 +31,8 @@ enum fields {
        BIMM = 0x040,
        JIMM = 0x080,
        FUNC = 0x100,
-       SET = 0x200
+       SET = 0x200,
+       SCIMM = 0x400
 };
 
 #define OP_MASK                0x3f
@@ -52,6 +53,8 @@ enum fields {
 #define FUNC_SH                0
 #define SET_MASK       0x7
 #define SET_SH         0
+#define SCIMM_MASK     0xfffff
+#define SCIMM_SH       6
 
 enum opcode {
        insn_invalid,
@@ -61,10 +64,10 @@ enum opcode {
        insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
        insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
        insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
-       insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+       insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
        insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
        insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
-       insn_dins
+       insn_dins, insn_syscall
 };
 
 struct insn {
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
        { insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
        { insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
+       { insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
        { insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
        { insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
@@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
        { insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
        { insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
        { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+       { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
        { insn_invalid, 0, 0 }
 };
 
@@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
        return (arg >> 2) & JIMM_MASK;
 }
 
+static inline __cpuinit u32 build_scimm(u32 arg)
+{
+       if (arg & ~SCIMM_MASK)
+               printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+       return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
 static inline __cpuinit u32 build_func(u32 arg)
 {
        if (arg & ~FUNC_MASK)
@@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
                op |= build_func(va_arg(ap, u32));
        if (ip->fields & SET)
                op |= build_set(va_arg(ap, u32));
+       if (ip->fields & SCIMM)
+               op |= build_scimm(va_arg(ap, u32));
        va_end(ap);
 
        **buf = op;
@@ -373,6 +388,7 @@ I_u2s3u1(_lw)
 I_u1u2u3(_mfc0)
 I_u1u2u3(_mtc0)
 I_u2u1u3(_ori)
+I_u3u1u2(_or)
 I_u2s3u1(_pref)
 I_0(_rfe)
 I_u2s3u1(_sc)
@@ -391,6 +407,7 @@ I_0(_tlbwr)
 I_u3u1u2(_xor)
 I_u2u1u3(_xori)
 I_u2u1msbu3(_dins);
+I_u1(_syscall);
 
 /* Handle labels. */
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
index 76bc3ec..fadd874 100644 (file)
@@ -20,6 +20,8 @@
  * Reset the PNX8550 board.
  *
  */
+#include <linux/kernel.h>
+
 #include <asm/reboot.h>
 #include <glb.h>
 
index 29e2326..fa3bf66 100644 (file)
@@ -122,7 +122,7 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
         */
 
        /* Check whether the irq belongs to me */
-       enabled = read_c0_perfcnt() & LOONGSON2_PERFCNT_INT_EN;
+       enabled = read_c0_perfctrl() & LOONGSON2_PERFCNT_INT_EN;
        if (!enabled)
                return IRQ_NONE;
        enabled = reg.cnt1_enabled | reg.cnt2_enabled;
index 2bb4057..d657ee0 100644 (file)
@@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
 };
 
 #ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
 void _rdmsr(u32 msr, u32 *hi, u32 *lo)
 {
        struct pci_bus bus = {
                .number = PCI_BUS_CS5536
        };
        u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&msr_lock, flags);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
        loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
        loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+       raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_rdmsr);
 
@@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
                .number = PCI_BUS_CS5536
        };
        u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&msr_lock, flags);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+       raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_wrmsr);
 #endif
index ada24e6..1711e8e 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/tty.h>
+#include <linux/vt.h>
 
 #include <asm/io.h>
 
@@ -254,7 +255,7 @@ static int __init sb1250_pcibios_init(void)
         * XXX ehs: Should this happen in PCI Device mode?
         */
        io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
-       sb1250_controller.io_map_base = io_map_base;
+       sb1250_controller.io_map_base = (unsigned long)io_map_base;
        set_io_port_base((unsigned long)io_map_base);
 
 #ifdef CONFIG_SIBYTE_HAS_LDT
index de6a0cc..911d399 100644 (file)
@@ -89,7 +89,7 @@ static void print_buserr(void)
 void ip22_be_interrupt(int irq)
 {
        const int field = 2 * sizeof(unsigned long);
-       const struct pt_regs *regs = get_irq_regs();
+       struct pt_regs *regs = get_irq_regs();
 
        save_and_clear_buserr();
        print_buserr();
index 30e12e2..88c684e 100644 (file)
@@ -453,7 +453,7 @@ mips_be_fatal:
 
 void ip22_be_interrupt(int irq)
 {
-       const struct pt_regs *regs = get_irq_regs();
+       struct pt_regs *regs = get_irq_regs();
 
        count_be_interrupt++;
 
index 0444da1..92da315 100644 (file)
@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
        return ret;
 }
 
+int sb1250_m3_workaround_needed(void)
+{
+       switch (soc_type) {
+       case K_SYS_SOC_TYPE_BCM1250:
+       case K_SYS_SOC_TYPE_BCM1250_ALT:
+       case K_SYS_SOC_TYPE_BCM1250_ALT2:
+       case K_SYS_SOC_TYPE_BCM1125:
+       case K_SYS_SOC_TYPE_BCM1125H:
+               return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+       default:
+               return 0;
+       }
+}
+
 static int __init setup_bcm112x(void)
 {
        int ret = 0;
index 5277aac..c308989 100644 (file)
@@ -145,15 +145,14 @@ void __init plat_mem_setup(void)
 
 #ifdef CONFIG_VT
        screen_info = (struct screen_info) {
-               0, 0,           /* orig-x, orig-y */
-               0,              /* unused */
-               52,             /* orig_video_page */
-               3,              /* orig_video_mode */
-               80,             /* orig_video_cols */
-               4626, 3, 9,     /* unused, ega_bx, unused */
-               25,             /* orig_video_lines */
-               0x22,           /* orig_video_isVGA */
-               16              /* orig_video_points */
+               .orig_video_page        = 52,
+               .orig_video_mode        = 3,
+               .orig_video_cols        = 80,
+               .flags                  = 12,
+               .orig_video_ega_bx      = 3,
+               .orig_video_lines       = 25,
+               .orig_video_isVGA       = 0x22,
+               .orig_video_points      = 16,
        };
        /* XXXKW for CFE, get lines/cols from environment */
 #endif
index 89faaca..1c4565a 100644 (file)
@@ -37,6 +37,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
 config GENERIC_CALIBRATE_DELAY
        def_bool y
 
+config GENERIC_CMOS_UPDATE
+        def_bool y
+
 config GENERIC_FIND_NEXT_BIT
        def_bool y
 
index 5bf5be9..e41222d 100644 (file)
@@ -31,7 +31,7 @@
  * Atomically reads the value of @v.  Note that the guaranteed
  * useful range of an atomic_t is only 24 bits.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
index 7978470..815a933 100644 (file)
@@ -26,17 +26,15 @@ static long last_rtc_update;
 /* time for RTC to update itself in ioclks */
 static unsigned long mn10300_rtc_update_period;
 
-/*
- * read the current RTC time
- */
-unsigned long __init get_initial_rtc_time(void)
+void read_persistent_clock(struct timespec *ts)
 {
        struct rtc_time tm;
 
        get_rtc_time(&tm);
 
-       return mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
+       ts->tv_sec = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday,
                      tm.tm_hour, tm.tm_min, tm.tm_sec);
+       ts->tv_nsec = 0;
 }
 
 /*
@@ -110,24 +108,9 @@ static int set_rtc_mmss(unsigned long nowtime)
        return retval;
 }
 
-void check_rtc_time(void)
+int update_persistent_clock(struct timespec now)
 {
-       /* the RTC clock just finished ticking over again this second
-        * - if we have an externally synchronized Linux clock, then update
-        *   RTC clock accordingly every ~11 minutes. set_rtc_mmss() has to be
-        *   called as close as possible to 500 ms before the new second starts.
-        */
-       if ((time_status & STA_UNSYNC) == 0 &&
-           xtime.tv_sec > last_rtc_update + 660 &&
-           xtime.tv_nsec / 1000 >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
-           xtime.tv_nsec / 1000 <= 500000 + ((unsigned) TICK_SIZE) / 2
-           ) {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else
-                       /* do it again in 60s */
-                       last_rtc_update = xtime.tv_sec - 600;
-       }
+       return set_rtc_mms(now.tv_sec);
 }
 
 /*
index 395caf0..8f7f6d2 100644 (file)
@@ -111,7 +111,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
                /* advance the kernel's time tracking system */
                profile_tick(CPU_PROFILING);
                do_timer(1);
-               check_rtc_time();
        }
 
        write_sequnlock(&xtime_lock);
@@ -139,9 +138,6 @@ void __init time_init(void)
               " (calibrated against RTC)\n",
               MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100);
 
-       xtime.tv_sec = get_initial_rtc_time();
-       xtime.tv_nsec = 0;
-
        mn10300_last_tsc = TMTSCBC;
 
        /* use timer 0 & 1 cascaded to tick at as close to HZ as possible */
index 716634d..f819559 100644 (file)
@@ -189,7 +189,7 @@ static __inline__ void atomic_set(atomic_t *v, int i)
 
 static __inline__ int atomic_read(const atomic_t *v)
 {
-       return v->counter;
+       return (*(volatile int *)&(v)->counter);
 }
 
 /* exported interface */
@@ -286,7 +286,7 @@ atomic64_set(atomic64_t *v, s64 i)
 static __inline__ s64
 atomic64_read(const atomic64_t *v)
 {
-       return v->counter;
+       return (*(volatile long *)&(v)->counter);
 }
 
 #define atomic64_add(i,v)      ((void)(__atomic64_add_return( ((s64)(i)),(v))))
index baa2bbb..04f1626 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:38 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -543,6 +537,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -579,6 +575,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -788,6 +786,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -836,6 +835,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -849,15 +849,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -883,10 +877,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -923,6 +918,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -971,18 +967,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -991,6 +990,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1083,7 +1083,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1096,7 +1095,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1259,6 +1257,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1285,6 +1284,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 8b1aa80..1843ee1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:14 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:39 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,7 +98,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -346,7 +346,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -387,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=y
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -539,6 +539,8 @@ CONFIG_MTD_UBI_DEBUG=y
 # CONFIG_MTD_UBI_DEBUG_MSG_EBA is not set
 # CONFIG_MTD_UBI_DEBUG_MSG_WL is not set
 # CONFIG_MTD_UBI_DEBUG_MSG_IO is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -563,6 +565,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -690,6 +693,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -720,6 +724,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -732,15 +737,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -765,18 +764,20 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -805,8 +806,6 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -887,6 +886,7 @@ CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -911,6 +911,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -976,6 +977,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_HAVE_FUNCTION_TRACER=y
index 2f2d985..78ae3bf 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:15 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -612,6 +609,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -772,6 +770,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -824,6 +823,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -836,6 +837,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -931,6 +933,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,6 +983,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -993,15 +997,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1044,10 +1042,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1086,6 +1085,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1134,21 +1134,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1157,6 +1160,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1289,7 +1293,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1302,7 +1305,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1341,6 +1343,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1511,6 +1514,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1537,6 +1541,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 633e611..cccb713 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:16 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:40 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -556,6 +550,8 @@ CONFIG_MTD_NAND_IDS=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -593,6 +589,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -612,6 +609,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -735,6 +733,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -837,6 +836,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -889,6 +889,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -901,6 +903,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -996,6 +999,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1045,6 +1049,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1058,15 +1063,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1109,10 +1108,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1151,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1199,21 +1200,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1226,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1354,7 +1359,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1367,7 +1371,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1406,6 +1409,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1576,6 +1580,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1602,6 +1607,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 0b4262b..74cb27a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:17 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:41 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -492,6 +488,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -509,6 +506,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -693,6 +691,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -705,6 +705,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -790,6 +791,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -839,6 +841,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -851,15 +854,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -885,10 +882,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -925,6 +923,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -967,18 +966,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -987,6 +989,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1171,6 +1174,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1197,6 +1201,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 155af00..10412a9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:18 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:42 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -325,6 +320,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -457,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -494,6 +490,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -514,6 +511,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -700,6 +698,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -712,6 +712,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -808,6 +809,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -859,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -872,15 +875,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -922,10 +919,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -964,6 +962,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1012,21 +1011,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1035,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1166,7 +1169,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1179,7 +1181,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1204,8 +1205,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_WBSD is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MMC_TIFM_SD is not set
 CONFIG_MMC_SPI=y
 # CONFIG_MMC_CB710 is not set
@@ -1298,6 +1297,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1324,6 +1324,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index ff45f49..7b31fc3 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:19 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:43 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -644,6 +641,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -767,6 +765,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -880,6 +879,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -892,6 +893,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -966,6 +968,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1015,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1028,15 +1032,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -1095,21 +1093,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1118,6 +1119,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1222,7 +1224,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1235,7 +1236,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1399,6 +1399,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1425,6 +1426,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 28d8ff3..41401a9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:20 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:44 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -540,6 +534,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -577,6 +573,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -596,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -756,6 +754,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -768,6 +768,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -842,6 +843,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -891,6 +893,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -904,15 +907,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -971,21 +968,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +994,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1098,7 +1099,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1111,7 +1111,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1275,6 +1274,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1301,6 +1301,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 6252ab5..dc176b6 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:45 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -580,6 +578,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -631,6 +630,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -643,6 +644,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -726,6 +728,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -774,6 +777,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -786,15 +790,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -820,10 +818,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -860,6 +859,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -902,18 +902,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -922,6 +925,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1106,6 +1110,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1132,6 +1137,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 7822737..f512972 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:21 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:46 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -334,7 +330,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -360,7 +355,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -538,6 +532,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -590,6 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -774,6 +772,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -786,6 +786,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -871,6 +872,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -920,6 +922,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -932,15 +935,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -966,10 +963,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1006,6 +1004,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1048,18 +1047,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1068,6 +1070,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1253,6 +1256,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1279,6 +1283,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 9451d6e..77abfe8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:23 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,14 +97,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -112,6 +106,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -323,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -336,7 +332,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -362,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -550,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -587,6 +583,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -606,6 +603,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -774,6 +772,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,6 +824,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -837,15 +837,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -876,14 +870,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -932,22 +930,27 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -956,6 +959,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1145,6 +1149,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1171,6 +1176,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index f67b70d..0cdb414 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:22 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:47 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -456,6 +450,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -491,6 +487,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -508,6 +505,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -631,6 +629,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -755,6 +754,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -767,6 +768,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -851,6 +853,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -901,6 +904,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +917,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -947,10 +945,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +986,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1029,18 +1029,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1049,6 +1052,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1175,6 +1179,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1201,6 +1206,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index a84fd11..e69ed1b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:24 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:48 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -124,7 +119,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -324,6 +319,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +331,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -361,7 +356,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -451,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -487,6 +483,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -504,6 +501,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -626,6 +624,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -850,6 +849,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -900,6 +900,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +914,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -947,10 +942,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +983,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1034,18 +1031,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1054,6 +1054,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1079,6 +1080,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1094,14 +1096,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1190,7 +1197,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1203,7 +1209,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1297,6 +1302,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1323,6 +1329,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 72c2067..56e3995 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:25 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:49 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,14 +96,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -111,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +118,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -322,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -333,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -359,7 +354,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -537,6 +531,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -573,6 +569,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -590,6 +587,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -812,6 +810,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -862,6 +861,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -875,15 +875,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -909,10 +903,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -949,6 +944,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -996,18 +992,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1016,6 +1015,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1140,7 +1140,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1153,7 +1152,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1245,6 +1243,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1271,6 +1270,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 21dad38..f67a8d1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:26 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:50 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,10 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -110,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -315,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -345,7 +349,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -522,6 +525,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -575,6 +580,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -701,6 +707,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -732,6 +739,7 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
 
 #
@@ -915,6 +923,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -937,6 +946,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1036,6 +1046,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 5db54cd..61b122a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:27 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:51 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -316,6 +315,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -346,7 +346,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -443,6 +442,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -477,6 +478,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -602,6 +604,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -788,6 +791,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -810,6 +814,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 76c7018..a5ceaa4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:28 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:52 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -358,7 +357,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -455,6 +453,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -500,6 +500,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -609,6 +610,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -621,6 +624,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -700,6 +704,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -733,7 +738,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -793,6 +800,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -801,6 +810,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -927,6 +937,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -949,6 +960,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index fab8ada..4adb4eb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:53 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -317,6 +316,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -327,7 +327,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -356,7 +355,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -453,6 +451,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -552,6 +552,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -657,6 +658,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -669,6 +672,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -753,6 +757,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -817,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -825,6 +831,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -951,6 +958,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -973,6 +981,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 8290385..3de8450 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -324,7 +324,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -352,7 +351,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -447,6 +445,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -491,6 +491,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -596,6 +597,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -608,6 +611,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -692,6 +696,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -756,6 +761,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -764,6 +770,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -856,6 +863,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -878,6 +886,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 2499b5b..bd467fe 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:30 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:54 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -314,6 +313,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -344,7 +344,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -441,6 +440,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -475,6 +476,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -600,6 +602,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -815,6 +818,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -837,6 +841,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index e2edb79..9803e03 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:31 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:55 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=16
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +318,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -329,7 +329,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -355,7 +354,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -554,6 +552,8 @@ CONFIG_MTD_NAND_SOCRATES=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_SPI=y
@@ -591,6 +591,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -610,6 +611,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -867,6 +869,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -916,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -929,15 +933,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -979,10 +977,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1021,6 +1020,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1050,21 +1050,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1073,6 +1076,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1180,6 +1184,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1194,12 +1199,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1307,7 +1316,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1320,7 +1328,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1491,6 +1498,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1515,6 +1523,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index ce31325..880ab7a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:32 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:56 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -334,7 +334,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -363,7 +362,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -520,6 +518,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=m
@@ -563,6 +563,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -630,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -817,6 +819,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -829,6 +833,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -947,6 +952,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1004,6 +1010,7 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1017,15 +1024,9 @@ CONFIG_I2C_ALGOBIT=m
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1041,14 +1042,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1081,10 +1086,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1122,6 +1128,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1155,9 +1162,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_TPS65010 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1166,6 +1174,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 CONFIG_AGP=m
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 CONFIG_DRM=m
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_R128 is not set
@@ -1308,6 +1317,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1333,6 +1343,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 0824b46..230aa2f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:33 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:57 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -315,6 +314,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -325,7 +325,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -351,7 +350,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -525,6 +523,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -560,6 +560,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -632,6 +633,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -704,6 +706,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -755,6 +758,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -767,6 +772,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -851,6 +857,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -902,6 +909,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -913,15 +921,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -947,10 +949,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -987,6 +990,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1015,18 +1019,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1035,6 +1042,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1172,6 +1180,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1194,6 +1203,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 2137be4..dbe04b9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:34 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:58 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 5cc89aa..845efa7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:35 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:59 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -67,6 +67,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -98,14 +102,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -324,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -339,7 +339,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -368,7 +367,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -559,6 +557,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -594,6 +594,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -611,6 +612,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -716,6 +718,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -728,6 +732,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -812,6 +817,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -860,6 +866,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -872,15 +879,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -906,10 +907,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -946,6 +948,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -974,18 +977,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -994,6 +1000,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1162,6 +1169,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1184,6 +1192,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index e7b9148..b958136 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:00 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index a998e40..008bc97 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -99,14 +103,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -114,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -318,6 +317,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -328,7 +328,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -354,7 +353,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -528,6 +526,8 @@ CONFIG_MTD_CFI_UTIL=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -564,6 +564,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -636,6 +637,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -708,6 +710,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -760,6 +763,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -772,6 +777,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -858,6 +864,7 @@ CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -912,6 +919,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -923,15 +931,9 @@ CONFIG_I2C_MPC=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -946,14 +948,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -986,10 +992,11 @@ CONFIG_HWMON_DEBUG_CHIP=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1027,6 +1034,7 @@ CONFIG_SENSORS_LM75=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1055,19 +1063,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1076,6 +1089,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1213,6 +1227,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1235,6 +1250,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index fc656af..2cf80db 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:37 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:01 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -69,6 +69,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -104,10 +108,8 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -115,6 +117,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +331,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_FSL_PCI=y
@@ -343,7 +347,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -375,7 +378,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -600,6 +602,8 @@ CONFIG_MTD_NAND_FSL_UPM=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -637,6 +641,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -654,6 +659,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -777,6 +783,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1004,6 +1011,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1053,6 +1061,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1066,15 +1075,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1090,14 +1093,19 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCA953X_IRQ is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1130,10 +1138,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 CONFIG_SENSORS_DS1621=y
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1171,6 +1180,7 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1218,19 +1228,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1239,6 +1254,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1271,6 +1287,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1285,12 +1302,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1386,7 +1407,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1398,7 +1418,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1423,11 +1442,11 @@ CONFIG_LEDS_GPIO_OF=y
 CONFIG_LEDS_PCA955X=y
 # CONFIG_LEDS_BD2802 is not set
 # CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
@@ -1506,6 +1525,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1614,6 +1634,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1641,6 +1662,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1851,6 +1873,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
index 622d84f..183c59c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:43 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:07 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
 # CONFIG_CARDBUS is not set
 
 #
@@ -382,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -819,6 +817,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1059,6 +1058,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1116,6 +1116,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1129,15 +1130,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1152,14 +1147,18 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1192,10 +1191,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1233,6 +1233,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1281,19 +1282,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1302,6 +1308,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1334,6 +1341,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1349,14 +1357,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1463,7 +1476,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1476,7 +1488,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1560,28 +1571,17 @@ CONFIG_RTC_DRV_RX8581=y
 CONFIG_STAGING=y
 # CONFIG_STAGING_EXCLUDE_BUILD is not set
 # CONFIG_ET131X is not set
-# CONFIG_ME4000 is not set
-# CONFIG_MEILHAUS is not set
 # CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
 # CONFIG_ECHO is not set
 # CONFIG_COMEDI is not set
 # CONFIG_ASUS_OLED is not set
-# CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_INPUT_MIMIO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
 # CONFIG_TRANZPORT is not set
 
-#
-# Android
-#
-# CONFIG_ANDROID is not set
-# CONFIG_DST is not set
-# CONFIG_POHMELFS is not set
-# CONFIG_B3DFG is not set
-# CONFIG_IDE_PHISON is not set
-# CONFIG_PLAN9AUTH is not set
-# CONFIG_HECI is not set
-# CONFIG_USB_CPC is not set
-
 #
 # Qualcomm MSM Camera And Video
 #
@@ -1589,14 +1589,17 @@ CONFIG_STAGING=y
 #
 # Camera Sensor Selection
 #
-# CONFIG_HYPERV_STORAGE is not set
-# CONFIG_HYPERV_BLOCK is not set
-# CONFIG_HYPERV_NET is not set
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VT6656 is not set
 CONFIG_VME_BUS=y
 
 #
 # VME Bridge Drivers
 #
+# CONFIG_VME_CA91CX42 is not set
 CONFIG_VME_TSI148=y
 
 #
@@ -1604,6 +1607,24 @@ CONFIG_VME_TSI148=y
 #
 # CONFIG_VME_USER is not set
 
+#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_PCMCIA_WAVELAN is not set
+# CONFIG_PCMCIA_NETWAVE is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
+
 #
 # File systems
 #
@@ -1693,6 +1714,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1719,6 +1741,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1864,6 +1887,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index eb58dec..1524d94 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:05 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -325,6 +321,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -340,13 +337,11 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 # CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_IOCTL is not set
 # CONFIG_CARDBUS is not set
 
 #
@@ -382,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -592,6 +586,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -629,6 +625,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -695,6 +692,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -1001,6 +999,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1058,6 +1057,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1071,15 +1071,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1094,14 +1088,18 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1134,10 +1132,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1175,6 +1174,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1223,19 +1223,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1244,6 +1249,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1276,6 +1282,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1291,14 +1298,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1405,7 +1417,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1418,7 +1429,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1590,6 +1600,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1616,6 +1627,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1761,6 +1773,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index 62c2b81..767c204 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:42 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:06 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -102,11 +102,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -326,6 +322,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -341,7 +338,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -369,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -728,6 +724,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -765,6 +763,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_DS1682=y
 # CONFIG_C2PORT is not set
 
@@ -782,6 +781,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -905,6 +905,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -1155,6 +1156,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1204,6 +1206,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1217,15 +1220,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1241,14 +1238,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1281,10 +1282,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1322,6 +1324,7 @@ CONFIG_SENSORS_LM92=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1370,19 +1373,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1391,6 +1399,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1423,6 +1432,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1438,14 +1448,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1552,7 +1567,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1565,7 +1579,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_ATM is not set
 # CONFIG_USB_GADGET is not set
 
@@ -1650,29 +1663,29 @@ CONFIG_RTC_DRV_RX8581=y
 CONFIG_STAGING=y
 # CONFIG_STAGING_EXCLUDE_BUILD is not set
 # CONFIG_ET131X is not set
-# CONFIG_ME4000 is not set
-# CONFIG_MEILHAUS is not set
 # CONFIG_USB_IP_COMMON is not set
+# CONFIG_PRISM2_USB is not set
 # CONFIG_ECHO is not set
 # CONFIG_COMEDI is not set
 # CONFIG_ASUS_OLED is not set
-# CONFIG_ALTERA_PCIE_CHDMA is not set
-# CONFIG_INPUT_MIMIO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTL8192SU is not set
+# CONFIG_RTL8192U is not set
+# CONFIG_RTL8192E is not set
 # CONFIG_TRANZPORT is not set
 
 #
-# Android
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
 #
-# CONFIG_ANDROID is not set
-# CONFIG_DST is not set
+# CONFIG_INPUT_GPIO is not set
 # CONFIG_POHMELFS is not set
-# CONFIG_B3DFG is not set
 # CONFIG_IDE_PHISON is not set
-# CONFIG_PLAN9AUTH is not set
-# CONFIG_HECI is not set
 # CONFIG_VT6655 is not set
-# CONFIG_USB_CPC is not set
-# CONFIG_RDC_17F3101X is not set
+# CONFIG_VT6656 is not set
 CONFIG_VME_BUS=y
 
 #
@@ -1686,6 +1699,22 @@ CONFIG_VME_TSI148=y
 #
 # CONFIG_VME_USER is not set
 
+#
+# VME Board Drivers
+#
+# CONFIG_VMIVME_7805 is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+# CONFIG_RAMZSWAP is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
+
 #
 # File systems
 #
@@ -1772,6 +1801,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1798,6 +1828,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1870,7 +1901,7 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_DEFLATE=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
@@ -2006,6 +2037,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index aab3bae..55b9e4e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:39 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:03 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,6 +107,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -320,6 +316,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -335,7 +332,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -362,7 +358,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -571,6 +566,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -605,6 +602,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -670,6 +668,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -792,6 +791,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -970,6 +970,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1017,6 +1018,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1029,15 +1031,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1062,18 +1058,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1082,6 +1081,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1434,6 +1434,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1461,6 +1462,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 727a8c8..1be38eb 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:40 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:04 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,15 +97,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -326,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -337,7 +335,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -365,7 +362,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -498,6 +494,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -534,6 +532,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -551,6 +550,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -675,6 +675,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -799,6 +800,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -811,6 +814,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -920,6 +924,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -968,6 +973,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -981,15 +987,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1014,18 +1014,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1034,6 +1037,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1151,6 +1155,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1170,6 +1175,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1185,14 +1191,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1300,7 +1311,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1313,7 +1323,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1475,6 +1484,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1506,6 +1516,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1717,6 +1728,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
index 4fb04dd..a630094 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:38 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:17:02 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -327,6 +323,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -342,7 +339,6 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -369,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -552,6 +547,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -733,6 +729,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -768,6 +766,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -785,6 +784,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -1024,6 +1024,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1074,6 +1075,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1086,15 +1088,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1120,10 +1116,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1160,6 +1157,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1202,18 +1200,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1223,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1376,6 +1378,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1408,6 +1411,7 @@ CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_SMB_FS=m
 CONFIG_SMB_NLS_DEFAULT=y
 CONFIG_SMB_NLS_REMOTE="cp437"
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1540,6 +1544,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1618,6 +1623,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
index 5c1dc76..9f89d5c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:58 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:22 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -91,11 +91,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -307,6 +302,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -336,7 +332,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -505,6 +500,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -516,6 +513,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -664,6 +662,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -802,6 +801,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -826,6 +826,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -924,6 +925,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
index 72137cd..4ab6074 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:23 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -101,11 +101,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -121,6 +116,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -147,7 +143,6 @@ CONFIG_HAVE_PERF_EVENTS=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -158,7 +153,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
@@ -357,6 +351,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PCI=y
@@ -365,7 +360,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -396,7 +390,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -527,6 +520,7 @@ CONFIG_IP_VS_PROTO_UDP=y
 CONFIG_IP_VS_PROTO_AH_ESP=y
 CONFIG_IP_VS_PROTO_ESP=y
 CONFIG_IP_VS_PROTO_AH=y
+# CONFIG_IP_VS_PROTO_SCTP is not set
 
 #
 # IPVS scheduler
@@ -630,6 +624,7 @@ CONFIG_ATM_BR2684=m
 # CONFIG_ATM_BR2684_IPFILTER is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=m
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -690,7 +685,6 @@ CONFIG_NET_SCH_FIFO=y
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -833,6 +827,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=m
 CONFIG_OF_MDIO=y
@@ -867,6 +863,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -1179,6 +1176,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1231,6 +1229,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MV64XXX=m
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1244,15 +1243,9 @@ CONFIG_I2C_MV64XXX=m
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1278,10 +1271,11 @@ CONFIG_SENSORS_ADM1026=m
 # CONFIG_SENSORS_ADM1029 is not set
 CONFIG_SENSORS_ADM1031=m
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 CONFIG_SENSORS_DS1621=m
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1318,6 +1312,7 @@ CONFIG_SENSORS_SMSC47M1=m
 # CONFIG_SENSORS_SMSC47M192 is not set
 CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1369,9 +1364,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1380,6 +1375,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1413,7 +1409,6 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 CONFIG_USB_MON=m
 # CONFIG_USB_WUSB is not set
@@ -1535,6 +1530,7 @@ CONFIG_USB_SERIAL_MCT_U232=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1549,6 +1545,7 @@ CONFIG_USB_SERIAL_XIRCOM=m
 # CONFIG_USB_SERIAL_OPTION is not set
 CONFIG_USB_SERIAL_OMNINET=m
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1561,7 +1558,6 @@ CONFIG_USB_EMI62=m
 CONFIG_USB_RIO500=m
 CONFIG_USB_LEGOTOWER=m
 CONFIG_USB_LCD=m
-# CONFIG_USB_BERRY_CHARGE is not set
 CONFIG_USB_LED=m
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1574,7 +1570,6 @@ CONFIG_USB_LED=m
 # CONFIG_USB_IOWARRIOR is not set
 CONFIG_USB_TEST=m
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_ATM=m
 CONFIG_USB_SPEEDTOUCH=m
 # CONFIG_USB_CXACRU is not set
@@ -1611,6 +1606,7 @@ CONFIG_INFINIBAND_SRP=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1714,6 +1710,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=m
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1742,6 +1739,7 @@ CONFIG_SUNRPC_XPRT_RDMA=m
 CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1817,7 +1815,7 @@ CONFIG_NLS_KOI8_R=m
 CONFIG_NLS_KOI8_U=m
 CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1833,9 +1831,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
@@ -1880,7 +1880,6 @@ CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_HIGHMEM=y
 CONFIG_DEBUG_BUGVERBOSE=y
@@ -1903,16 +1902,12 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
index 7910541..81e904e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:23:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -298,6 +298,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -308,7 +309,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -335,7 +335,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -537,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -566,6 +567,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -671,6 +673,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -683,6 +687,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -737,6 +742,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -765,7 +771,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -804,6 +812,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -812,6 +822,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -869,6 +880,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
index 58f7ca7..c5af46e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:00 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:24 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -90,11 +90,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -306,6 +301,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -335,7 +331,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -504,6 +499,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -515,6 +512,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -616,6 +614,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -753,6 +752,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -777,6 +777,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 9a0c981..588a2ad 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:01 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:25 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,11 +96,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -116,6 +111,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -337,7 +334,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -364,7 +360,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -433,6 +428,7 @@ CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 CONFIG_NETFILTER_XT_TARGET_HL=m
 # CONFIG_NETFILTER_XT_TARGET_MARK is not set
@@ -665,6 +661,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -700,6 +698,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -717,6 +716,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -840,6 +840,7 @@ CONFIG_ATA_SFF=y
 CONFIG_PATA_IT821X=y
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -954,6 +955,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -966,6 +969,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1082,6 +1086,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1131,6 +1136,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1144,15 +1150,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1178,10 +1178,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1218,6 +1219,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1246,18 +1248,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1266,6 +1271,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1417,6 +1423,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_SERIAL_NAVMAN is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1430,6 +1437,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1442,7 +1450,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1455,7 +1462,6 @@ CONFIG_USB_SERIAL_FTDI_SIO=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1620,6 +1626,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1651,6 +1658,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1723,9 +1731,11 @@ CONFIG_CRC32=y
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_HAS_IOMEM=y
index 4c2c877..0cbd56f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:02 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:26 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -105,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -311,6 +312,7 @@ CONFIG_ISA_DMA_API=y
 #
 # CONFIG_ISA is not set
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -321,7 +323,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -348,7 +349,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -536,6 +536,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -570,6 +572,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -704,6 +707,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -769,14 +773,9 @@ CONFIG_I2C_CPM=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -790,14 +789,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -829,19 +832,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -850,6 +858,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -908,6 +917,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1100,6 +1110,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 9e090f2..c1be261 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:03 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:27 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -89,11 +89,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -104,6 +99,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -309,6 +305,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -337,7 +334,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -515,6 +511,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -542,6 +540,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -643,6 +642,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -801,6 +801,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -825,6 +826,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -892,6 +894,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
index 1315b77..27c63ce 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:04 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:28 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,6 +104,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -311,6 +307,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
@@ -319,7 +316,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -345,7 +341,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -440,6 +435,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -484,6 +481,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -605,6 +603,7 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -696,6 +695,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -750,6 +750,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -762,6 +764,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -846,6 +849,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -910,6 +914,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -918,6 +923,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1044,6 +1050,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1066,6 +1073,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 9073778..6875fb8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:05 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:29 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -301,6 +300,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -311,7 +311,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -338,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -540,6 +538,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -569,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -674,6 +675,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -686,6 +689,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -797,6 +801,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -825,7 +830,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -864,6 +871,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -872,6 +881,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -933,6 +943,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
index 05bec48..bbe5ae6 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:30 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,14 +98,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -113,6 +107,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -126,7 +121,7 @@ CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-# CONFIG_EPOLL is not set
+CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
@@ -331,6 +326,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -344,7 +340,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -370,7 +365,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
@@ -560,6 +554,8 @@ CONFIG_MTD_NAND_FSL_ELBC=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -597,6 +593,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -614,6 +611,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -712,7 +710,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_SATA_QSTOR is not set
 # CONFIG_SATA_PROMISE is not set
 # CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_SIL is not set
+CONFIG_SATA_SIL=y
 # CONFIG_SATA_SIS is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
@@ -737,6 +735,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -863,6 +862,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -875,6 +876,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -970,6 +972,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 # CONFIG_SERIAL_QE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -980,8 +983,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_HW_RANDOM=y
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_NVRAM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1022,6 +1023,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1035,15 +1037,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1058,14 +1054,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1098,10 +1098,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1139,6 +1140,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1186,19 +1188,24 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1207,6 +1214,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1232,6 +1240,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1247,14 +1256,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1344,7 +1358,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1357,7 +1370,6 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1372,7 +1384,65 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_DS1374=y
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_GENERIC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -1453,6 +1523,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1479,6 +1550,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 8f35f80..cfebef9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -68,6 +68,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -103,14 +107,8 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -118,6 +116,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -334,6 +333,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -345,7 +345,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -376,7 +375,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -509,6 +507,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -546,6 +546,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -563,6 +564,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -687,6 +689,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -817,8 +820,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -829,6 +835,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -941,6 +948,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -993,6 +1001,7 @@ CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1006,15 +1015,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1030,14 +1033,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1069,20 +1076,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1091,6 +1103,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1208,6 +1221,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1227,6 +1241,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1242,14 +1257,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1358,7 +1378,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1371,7 +1390,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1452,6 +1470,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1554,6 +1573,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1585,6 +1605,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1730,6 +1751,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
index 8755ea3..f5451d8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:07 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:31 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -69,6 +69,10 @@ CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_PPC_ADV_DEBUG_REGS=y
+CONFIG_PPC_ADV_DEBUG_IACS=2
+CONFIG_PPC_ADV_DEBUG_DACS=2
+CONFIG_PPC_ADV_DEBUG_DVCS=0
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -100,18 +104,13 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -119,6 +118,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -338,6 +338,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -349,7 +350,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -380,7 +380,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -513,6 +512,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -550,6 +551,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -567,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -691,6 +694,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -821,8 +825,11 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
+# CONFIG_IXGBEVF is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_VXGE is not set
@@ -833,6 +840,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -945,6 +953,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_SERIAL_QE=m
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -997,6 +1006,7 @@ CONFIG_I2C_CPM=m
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1010,15 +1020,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1034,14 +1038,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1073,20 +1081,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1095,6 +1108,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1212,6 +1226,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1231,6 +1246,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1246,14 +1262,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1362,7 +1383,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1375,7 +1395,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1456,6 +1475,7 @@ CONFIG_RTC_DRV_CMOS=y
 #
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1558,6 +1578,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1589,6 +1610,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1734,6 +1756,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1806,6 +1829,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
index 3f6b11b..d8d3d1d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:08 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:32 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -89,14 +89,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -305,6 +299,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -333,7 +328,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -425,6 +419,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -456,6 +452,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -607,6 +604,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -795,6 +793,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -819,6 +818,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 41884c9..624eae9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:33 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -98,18 +98,13 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -328,6 +324,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -339,7 +336,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -367,7 +363,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -500,6 +495,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_I2C=y
@@ -537,6 +534,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -554,6 +552,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -678,6 +677,7 @@ CONFIG_PATA_ALI=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -802,6 +802,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -814,6 +816,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -923,6 +926,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -972,6 +976,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -985,15 +990,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1009,14 +1008,18 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1048,20 +1051,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1070,6 +1078,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1187,6 +1196,7 @@ CONFIG_SND_INTEL8X0=y
 CONFIG_SND_PPC=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
@@ -1206,6 +1216,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1221,14 +1232,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1336,7 +1352,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1349,7 +1364,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1512,6 +1526,7 @@ CONFIG_BEFS_FS=m
 # CONFIG_BEFS_DEBUG is not set
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 CONFIG_VXFS_FS=m
@@ -1543,6 +1558,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1754,6 +1770,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
index 6b9e6bd..45bd499 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:10 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:34 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -90,14 +90,8 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -313,6 +307,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_FSL_SOC=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
@@ -342,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -515,6 +509,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
@@ -526,6 +522,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -627,6 +624,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -764,6 +762,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -788,6 +787,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
index 5d06f2c..68c175e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:11 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:35 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -105,6 +105,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -304,6 +305,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
 CONFIG_PPC_PCI_CHOICE=y
@@ -315,7 +317,6 @@ CONFIG_PCI_8260=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -342,7 +343,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -544,6 +544,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_MDIO=y
@@ -629,6 +631,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -734,6 +737,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -746,6 +751,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -859,6 +865,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CPM=y
 CONFIG_SERIAL_CPM_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -887,7 +894,9 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 # CONFIG_GPIO_XILINX is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
@@ -926,6 +935,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -934,6 +945,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -996,6 +1008,7 @@ CONFIG_USB_ETH_RNDIS=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1051,6 +1064,7 @@ CONFIG_AUTOFS4_FS=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
index 57ab574..93f4505 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:12 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:36 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -97,11 +97,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -117,6 +112,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -319,6 +315,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_PCI=y
@@ -327,7 +324,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -354,7 +350,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
@@ -533,6 +528,8 @@ CONFIG_MTD_PHYSMAP_OF=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -569,6 +566,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -640,6 +638,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -761,6 +760,7 @@ CONFIG_SATA_MV=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -854,6 +854,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 CONFIG_E100=y
@@ -907,6 +908,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -919,6 +922,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1016,6 +1020,7 @@ CONFIG_SERIAL_MPSC_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -1065,6 +1070,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MV64XXX=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1077,15 +1083,9 @@ CONFIG_I2C_MV64XXX=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1111,10 +1111,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1151,6 +1152,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1179,18 +1181,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1199,6 +1204,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1231,6 +1237,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1247,14 +1254,19 @@ CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 CONFIG_HID_GREENASIA=y
 # CONFIG_GREENASIA_FF is not set
@@ -1350,7 +1362,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1363,7 +1374,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1516,6 +1526,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1538,6 +1549,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1620,9 +1632,11 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
index 32f7058..3808bc2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc7
-# Mon Aug 24 17:38:50 2009
+# Linux kernel version: 2.6.34-rc4
+# Thu Apr 15 11:32:15 2010
 #
 CONFIG_PPC64=y
 
@@ -9,6 +9,7 @@ CONFIG_PPC64=y
 # Processor support
 #
 CONFIG_PPC_BOOK3S_64=y
+# CONFIG_PPC_BOOK3E_64 is not set
 CONFIG_PPC_BOOK3S=y
 # CONFIG_POWER4_ONLY is not set
 CONFIG_POWER3=y
@@ -35,7 +36,9 @@ CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
@@ -60,6 +63,7 @@ CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
 CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
@@ -86,14 +90,15 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -108,6 +113,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -128,21 +134,19 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
-CONFIG_HAVE_PERF_COUNTERS=y
+CONFIG_HAVE_PERF_EVENTS=y
 
 #
-# Performance Counters
+# Kernel Performance Events And Counters
 #
+# CONFIG_PERF_EVENTS is not set
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
-CONFIG_MARKERS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -154,12 +158,14 @@ CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+# CONFIG_SLOW_WORK_DEBUG is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -180,14 +186,41 @@ CONFIG_BLOCK_COMPAT=y
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -226,7 +259,6 @@ CONFIG_PPC_CELL=y
 #
 CONFIG_SPU_FS=m
 CONFIG_SPU_FS_64K_LS=y
-# CONFIG_SPU_TRACE is not set
 CONFIG_SPU_BASE=y
 # CONFIG_PQ2ADS is not set
 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
@@ -267,7 +299,6 @@ CONFIG_COMPAT_BINFMT_ELF=y
 # CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
 CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
-# CONFIG_IOMMU_VMERGE is not set
 CONFIG_IOMMU_HELPER=y
 # CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -276,12 +307,15 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_SPARSE_IRQ=y
 # CONFIG_NUMA is not set
+CONFIG_MAX_ACTIVE_REGIONS=256
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -295,13 +329,12 @@ CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTPLUG_SPARSE=y
 # CONFIG_MEMORY_HOTREMOVE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_SPLIT_PTLOCK_CPUS=999999
 CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=y
@@ -312,11 +345,15 @@ CONFIG_PPC_4K_PAGES=y
 CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
 CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
 # CONFIG_PM_VERBOSE is not set
+# CONFIG_HIBERNATION is not set
+# CONFIG_PM_RUNTIME is not set
 # CONFIG_SECCOMP is not set
 CONFIG_ISA_DMA_API=y
 
@@ -324,6 +361,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
@@ -337,12 +375,12 @@ CONFIG_PAGE_OFFSET=0xc000000000000000
 CONFIG_KERNEL_START=0xc000000000000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_NET=y
+CONFIG_COMPAT_NETLINK_MESSAGES=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -392,6 +430,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
 CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
@@ -400,6 +439,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -422,7 +462,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -445,27 +484,30 @@ CONFIG_BT_HCIBTUSB=m
 # CONFIG_BT_HCIBPA10X is not set
 # CONFIG_BT_HCIBFUSB is not set
 # CONFIG_BT_HCIVHCI is not set
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
 CONFIG_CFG80211=m
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
 # CONFIG_CFG80211_DEBUGFS is not set
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
-CONFIG_WIRELESS_EXT=y
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_LIB80211 is not set
 CONFIG_MAC80211=m
-CONFIG_MAC80211_DEFAULT_PS=y
-CONFIG_MAC80211_DEFAULT_PS_VALUE=1
-
-#
-# Rate control algorithm selection
-#
 CONFIG_MAC80211_RC_PID=y
 # CONFIG_MAC80211_RC_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT_PID=y
 # CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
 # CONFIG_MAC80211_LEDS is not set
 # CONFIG_MAC80211_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
@@ -481,6 +523,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
@@ -491,6 +534,8 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -498,6 +543,10 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
@@ -521,6 +570,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -590,30 +640,27 @@ CONFIG_MII=m
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 # CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
 CONFIG_NETDEV_1000=y
 CONFIG_GELIC_NET=y
 CONFIG_GELIC_WIRELESS=y
 # CONFIG_NETDEV_10000 is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-CONFIG_WLAN_80211=y
-# CONFIG_LIBERTAS is not set
+CONFIG_WLAN=y
 # CONFIG_LIBERTAS_THINFIRM is not set
 # CONFIG_AT76C50X_USB is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_RTL8187 is not set
 # CONFIG_MAC80211_HWSIM is not set
-# CONFIG_P54_COMMON is not set
-# CONFIG_AR9170_USB is not set
-# CONFIG_HOSTAP is not set
+# CONFIG_ATH_COMMON is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
-# CONFIG_ZD1211RW is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_P54_COMMON is not set
 # CONFIG_RT2X00 is not set
+# CONFIG_WL12XX is not set
+# CONFIG_ZD1211RW is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -631,6 +678,7 @@ CONFIG_USB_NET_AX8817X=m
 # CONFIG_USB_NET_CDCETHER is not set
 # CONFIG_USB_NET_CDC_EEM is not set
 # CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC75XX is not set
 # CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
@@ -665,6 +713,7 @@ CONFIG_SLHC=m
 CONFIG_INPUT=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
 
 #
 # Userland interfaces
@@ -712,6 +761,8 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -735,7 +786,6 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -841,13 +891,13 @@ CONFIG_SND_PS3=m
 CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
 CONFIG_SND_USB=y
 CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_USX2Y is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 CONFIG_HIDRAW=y
 
 #
@@ -866,6 +916,7 @@ CONFIG_USB_HIDDEV=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 CONFIG_HID_APPLE=m
 CONFIG_HID_BELKIN=m
@@ -876,17 +927,24 @@ CONFIG_HID_CHERRY=m
 CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
+CONFIG_HID_TWINHAN=m
 # CONFIG_HID_KENSINGTON is not set
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_HID_MAGICMOUSE is not set
 CONFIG_HID_MICROSOFT=m
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=m
 # CONFIG_HID_GREENASIA is not set
 CONFIG_HID_SMARTJOYPLUS=m
@@ -901,7 +959,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
 # Miscellaneous USB options
@@ -909,7 +967,6 @@ CONFIG_USB=m
 CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
-CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -923,12 +980,13 @@ CONFIG_USB_MON=m
 # CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_TT_NEWSCHED=y
 CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
 # CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
@@ -995,7 +1053,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1008,7 +1065,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1048,7 +1104,9 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
 # CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
@@ -1077,10 +1135,10 @@ CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
 CONFIG_EXT4_FS=y
-# CONFIG_EXT4DEV_COMPAT is not set
 CONFIG_EXT4_FS_XATTR=y
 # CONFIG_EXT4_FS_POSIX_ACL is not set
 # CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
 CONFIG_JBD=m
 # CONFIG_JBD_DEBUG is not set
 CONFIG_JBD2=y
@@ -1093,6 +1151,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1154,6 +1213,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1164,7 +1224,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -1181,6 +1240,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 # CONFIG_CIFS_WEAK_PW_HASH is not set
@@ -1237,7 +1297,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -1270,6 +1330,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -1292,6 +1353,7 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_LOCK_ALLOC=y
 CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RCU is not set
 CONFIG_LOCKDEP=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_LOCKDEP=y
@@ -1308,26 +1370,27 @@ CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_DEBUG_PAGEALLOC is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
-CONFIG_TRACING=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1352,13 +1415,16 @@ CONFIG_IRQSTACKS=y
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=m
@@ -1374,6 +1440,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
@@ -1402,11 +1469,13 @@ CONFIG_CRYPTO_PCBC=m
 #
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 # CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_GHASH=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
index f2f8321..b162580 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc3
-# Wed Jan  6 09:24:13 2010
+# Linux kernel version: 2.6.34-rc5
+# Mon Apr 19 23:16:37 2010
 #
 # CONFIG_PPC64 is not set
 
@@ -94,11 +94,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -314,6 +309,7 @@ CONFIG_ISA_DMA_API=y
 # Bus options
 #
 CONFIG_ZONE_DMA=y
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PPC_INDIRECT_PCI=y
 CONFIG_FSL_SOC=y
@@ -323,7 +319,6 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -349,7 +344,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=m
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -524,6 +518,8 @@ CONFIG_MTD_PHYSMAP=y
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
+CONFIG_OF_FLATTREE=y
+CONFIG_OF_DYNAMIC=y
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -555,6 +551,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -626,6 +623,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -846,6 +844,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
 # CONFIG_SERIAL_OF_PLATFORM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
@@ -895,6 +894,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -908,15 +908,9 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -941,18 +935,21 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -961,6 +958,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_AGP is not set
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1071,7 +1069,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1084,7 +1081,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1251,6 +1247,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
index 9f4c9d4..bd100fc 100644 (file)
@@ -130,43 +130,5 @@ static inline int irqs_disabled_flags(unsigned long flags)
  */
 struct irq_chip;
 
-#ifdef CONFIG_PERF_EVENTS
-
-#ifdef CONFIG_PPC64
-static inline unsigned long test_perf_event_pending(void)
-{
-       unsigned long x;
-
-       asm volatile("lbz %0,%1(13)"
-               : "=r" (x)
-               : "i" (offsetof(struct paca_struct, perf_event_pending)));
-       return x;
-}
-
-static inline void set_perf_event_pending(void)
-{
-       asm volatile("stb %0,%1(13)" : :
-               "r" (1),
-               "i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-
-static inline void clear_perf_event_pending(void)
-{
-       asm volatile("stb %0,%1(13)" : :
-               "r" (0),
-               "i" (offsetof(struct paca_struct, perf_event_pending)));
-}
-#endif /* CONFIG_PPC64 */
-
-#else  /* CONFIG_PERF_EVENTS */
-
-static inline unsigned long test_perf_event_pending(void)
-{
-       return 0;
-}
-
-static inline void clear_perf_event_pending(void) {}
-#endif /* CONFIG_PERF_EVENTS */
-
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_HW_IRQ_H */
index e96d52a..53b64be 100644 (file)
@@ -108,8 +108,21 @@ extern phys_addr_t kernstart_addr;
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
-#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET - MEMORY_START))
+/*
+ * On Book-E parts we need __va to parse the device tree and we can't
+ * determine MEMORY_START until then.  However we can determine PHYSICAL_START
+ * from information at hand (program counter, TLB lookup).
+ *
+ * On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use
+ * the other definitions for __va & __pa.
+ */
+#ifdef CONFIG_BOOKE
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) - PHYSICAL_START + KERNELBASE))
+#define __pa(x) ((unsigned long)(x) + PHYSICAL_START - KERNELBASE)
+#else
+#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + PAGE_OFFSET - MEMORY_START))
 #define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + MEMORY_START)
+#endif
 
 /*
  * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
index 957ceb7..c09138d 100644 (file)
@@ -133,7 +133,6 @@ int main(void)
        DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
        DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
        DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
-       DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
        DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
 #ifdef CONFIG_PPC_MM_SLICES
        DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
index 59c9285..4ff4da2 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Contains routines needed to support swiotlb for ppc.
  *
- * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc.
+ * Author: Becky Bruce
  *
  * 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
@@ -70,7 +71,7 @@ static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
        sd->max_direct_dma_addr = 0;
 
        /* May need to bounce if the device can't address all of DRAM */
-       if (dma_get_mask(dev) < lmb_end_of_DRAM())
+       if ((dma_get_mask(dev) + 1) < lmb_end_of_DRAM())
                set_dma_ops(dev, &swiotlb_dma_ops);
 
        return NOTIFY_DONE;
index 07109d8..42e9d90 100644 (file)
@@ -556,15 +556,6 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
 2:
        TRACE_AND_RESTORE_IRQ(r5);
 
-#ifdef CONFIG_PERF_EVENTS
-       /* check paca->perf_event_pending if we're enabling ints */
-       lbz     r3,PACAPERFPEND(r13)
-       and.    r3,r3,r5
-       beq     27f
-       bl      .perf_event_do_pending
-27:
-#endif /* CONFIG_PERF_EVENTS */
-
        /* extract EE bit and use it to restore paca->hard_enabled */
        ld      r3,_MSR(r1)
        rldicl  r4,r3,49,63             /* r0 = (r3 >> 15) & 1 */
index 64f6f20..066bd31 100644 (file)
@@ -53,7 +53,6 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
-#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -145,11 +144,6 @@ notrace void raw_local_irq_restore(unsigned long en)
        }
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
-       if (test_perf_event_pending()) {
-               clear_perf_event_pending();
-               perf_event_do_pending();
-       }
-
        /*
         * if (get_paca()->hard_enabled) return;
         * But again we need to take care that gcc gets hard_enabled directly
index 08460a2..43b83c3 100644 (file)
@@ -35,6 +35,9 @@ struct cpu_hw_events {
        u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
        unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
        unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
+
+       unsigned int group_flag;
+       int n_txn_start;
 };
 DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
 
@@ -718,66 +721,6 @@ static int collect_events(struct perf_event *group, int max_count,
        return n;
 }
 
-static void event_sched_in(struct perf_event *event)
-{
-       event->state = PERF_EVENT_STATE_ACTIVE;
-       event->oncpu = smp_processor_id();
-       event->tstamp_running += event->ctx->time - event->tstamp_stopped;
-       if (is_software_event(event))
-               event->pmu->enable(event);
-}
-
-/*
- * Called to enable a whole group of events.
- * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
- * Assumes the caller has disabled interrupts and has
- * frozen the PMU with hw_perf_save_disable.
- */
-int hw_perf_group_sched_in(struct perf_event *group_leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx)
-{
-       struct cpu_hw_events *cpuhw;
-       long i, n, n0;
-       struct perf_event *sub;
-
-       if (!ppmu)
-               return 0;
-       cpuhw = &__get_cpu_var(cpu_hw_events);
-       n0 = cpuhw->n_events;
-       n = collect_events(group_leader, ppmu->n_counter - n0,
-                          &cpuhw->event[n0], &cpuhw->events[n0],
-                          &cpuhw->flags[n0]);
-       if (n < 0)
-               return -EAGAIN;
-       if (check_excludes(cpuhw->event, cpuhw->flags, n0, n))
-               return -EAGAIN;
-       i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n + n0);
-       if (i < 0)
-               return -EAGAIN;
-       cpuhw->n_events = n0 + n;
-       cpuhw->n_added += n;
-
-       /*
-        * OK, this group can go on; update event states etc.,
-        * and enable any software events
-        */
-       for (i = n0; i < n0 + n; ++i)
-               cpuhw->event[i]->hw.config = cpuhw->events[i];
-       cpuctx->active_oncpu += n;
-       n = 1;
-       event_sched_in(group_leader);
-       list_for_each_entry(sub, &group_leader->sibling_list, group_entry) {
-               if (sub->state != PERF_EVENT_STATE_OFF) {
-                       event_sched_in(sub);
-                       ++n;
-               }
-       }
-       ctx->nr_active += n;
-
-       return 1;
-}
-
 /*
  * Add a event to the PMU.
  * If all events are not already frozen, then we disable and
@@ -805,12 +748,22 @@ static int power_pmu_enable(struct perf_event *event)
        cpuhw->event[n0] = event;
        cpuhw->events[n0] = event->hw.config;
        cpuhw->flags[n0] = event->hw.event_base;
+
+       /*
+        * If group events scheduling transaction was started,
+        * skip the schedulability test here, it will be peformed
+        * at commit time(->commit_txn) as a whole
+        */
+       if (cpuhw->group_flag & PERF_EVENT_TXN_STARTED)
+               goto nocheck;
+
        if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
                goto out;
        if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1))
                goto out;
-
        event->hw.config = cpuhw->events[n0];
+
+nocheck:
        ++cpuhw->n_events;
        ++cpuhw->n_added;
 
@@ -896,11 +849,65 @@ static void power_pmu_unthrottle(struct perf_event *event)
        local_irq_restore(flags);
 }
 
+/*
+ * Start group events scheduling transaction
+ * Set the flag to make pmu::enable() not perform the
+ * schedulability test, it will be performed at commit time
+ */
+void power_pmu_start_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       cpuhw->group_flag |= PERF_EVENT_TXN_STARTED;
+       cpuhw->n_txn_start = cpuhw->n_events;
+}
+
+/*
+ * Stop group events scheduling transaction
+ * Clear the flag and pmu::enable() will perform the
+ * schedulability test.
+ */
+void power_pmu_cancel_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+
+       cpuhw->group_flag &= ~PERF_EVENT_TXN_STARTED;
+}
+
+/*
+ * Commit group events scheduling transaction
+ * Perform the group schedulability test as a whole
+ * Return 0 if success
+ */
+int power_pmu_commit_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuhw;
+       long i, n;
+
+       if (!ppmu)
+               return -EAGAIN;
+       cpuhw = &__get_cpu_var(cpu_hw_events);
+       n = cpuhw->n_events;
+       if (check_excludes(cpuhw->event, cpuhw->flags, 0, n))
+               return -EAGAIN;
+       i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n);
+       if (i < 0)
+               return -EAGAIN;
+
+       for (i = cpuhw->n_txn_start; i < n; ++i)
+               cpuhw->event[i]->hw.config = cpuhw->events[i];
+
+       return 0;
+}
+
 struct pmu power_pmu = {
        .enable         = power_pmu_enable,
        .disable        = power_pmu_disable,
        .read           = power_pmu_read,
        .unthrottle     = power_pmu_unthrottle,
+       .start_txn      = power_pmu_start_txn,
+       .cancel_txn     = power_pmu_cancel_txn,
+       .commit_txn     = power_pmu_commit_txn,
 };
 
 /*
index 5f306c4..97d4bd9 100644 (file)
@@ -653,6 +653,7 @@ static void __init early_cmdline_parse(void)
 #else
 #define OV5_CMO                        0x00
 #endif
+#define OV5_TYPE1_AFFINITY     0x80    /* Type 1 NUMA affinity */
 
 /* Option Vector 6: IBM PAPR hints */
 #define OV6_LINUX              0x02    /* Linux is our OS */
@@ -706,7 +707,7 @@ static unsigned char ibm_architecture_vec[] = {
        OV5_DONATE_DEDICATE_CPU | OV5_MSI,
        0,
        OV5_CMO,
-       0,
+       OV5_TYPE1_AFFINITY,
        0,
        0,
        0,
index 1b16b9a..0441bbd 100644 (file)
@@ -532,25 +532,60 @@ void __init iSeries_time_init_early(void)
 }
 #endif /* CONFIG_PPC_ISERIES */
 
-#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32)
-DEFINE_PER_CPU(u8, perf_event_pending);
+#ifdef CONFIG_PERF_EVENTS
 
-void set_perf_event_pending(void)
+/*
+ * 64-bit uses a byte in the PACA, 32-bit uses a per-cpu variable...
+ */
+#ifdef CONFIG_PPC64
+static inline unsigned long test_perf_event_pending(void)
 {
-       get_cpu_var(perf_event_pending) = 1;
-       set_dec(1);
-       put_cpu_var(perf_event_pending);
+       unsigned long x;
+
+       asm volatile("lbz %0,%1(13)"
+               : "=r" (x)
+               : "i" (offsetof(struct paca_struct, perf_event_pending)));
+       return x;
 }
 
+static inline void set_perf_event_pending_flag(void)
+{
+       asm volatile("stb %0,%1(13)" : :
+               "r" (1),
+               "i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+
+static inline void clear_perf_event_pending(void)
+{
+       asm volatile("stb %0,%1(13)" : :
+               "r" (0),
+               "i" (offsetof(struct paca_struct, perf_event_pending)));
+}
+
+#else /* 32-bit */
+
+DEFINE_PER_CPU(u8, perf_event_pending);
+
+#define set_perf_event_pending_flag()  __get_cpu_var(perf_event_pending) = 1
 #define test_perf_event_pending()      __get_cpu_var(perf_event_pending)
 #define clear_perf_event_pending()     __get_cpu_var(perf_event_pending) = 0
 
-#else  /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
+#endif /* 32 vs 64 bit */
+
+void set_perf_event_pending(void)
+{
+       preempt_disable();
+       set_perf_event_pending_flag();
+       set_dec(1);
+       preempt_enable();
+}
+
+#else  /* CONFIG_PERF_EVENTS */
 
 #define test_perf_event_pending()      0
 #define clear_perf_event_pending()
 
-#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
+#endif /* CONFIG_PERF_EVENTS */
 
 /*
  * For iSeries shared processors, we have to let the hypervisor
@@ -582,10 +617,6 @@ void timer_interrupt(struct pt_regs * regs)
        set_dec(DECREMENTER_MAX);
 
 #ifdef CONFIG_PPC32
-       if (test_perf_event_pending()) {
-               clear_perf_event_pending();
-               perf_event_do_pending();
-       }
        if (atomic_read(&ppc_n_lost_interrupts) != 0)
                do_IRQ(regs);
 #endif
@@ -604,6 +635,11 @@ void timer_interrupt(struct pt_regs * regs)
 
        calculate_steal_time();
 
+       if (test_perf_event_pending()) {
+               clear_perf_event_pending();
+               perf_event_do_pending();
+       }
+
 #ifdef CONFIG_PPC_ISERIES
        if (firmware_has_feature(FW_FEATURE_ISERIES))
                get_lppaca()->int_dword.fields.decr_int = 0;
index 2570fcc..8123125 100644 (file)
@@ -440,7 +440,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
        unsigned int gtlb_index;
 
        gtlb_index = kvmppc_get_gpr(vcpu, ra);
-       if (gtlb_index > KVM44x_GUEST_TLB_SIZE) {
+       if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) {
                printk("%s: index %d\n", __func__, gtlb_index);
                kvmppc_dump_vcpu(vcpu);
                return EMULATE_FAIL;
index 25da07f..604af29 100644 (file)
@@ -1004,7 +1004,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        struct kvm_vcpu *vcpu;
        ulong ga, ga_end;
        int is_dirty = 0;
-       int r, n;
+       int r;
+       unsigned long n;
 
        mutex_lock(&kvm->slots_lock);
 
@@ -1022,7 +1023,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                kvm_for_each_vcpu(n, vcpu, kvm)
                        kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               n = kvm_dirty_bitmap_bytes(memslot);
                memset(memslot->dirty_bitmap, 0, n);
        }
 
index c539472..1ed6b52 100644 (file)
@@ -116,7 +116,7 @@ void loadcam_entry(int idx)
        mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
        mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
 
-       if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+       if (mmu_has_feature(MMU_FTR_BIG_PHYS))
                mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
 
        asm volatile("isync;tlbwe;isync" : : : "memory");
@@ -152,18 +152,13 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
 
        TLBCAM[index].MAS3 = (phys & MAS3_RPN) | MAS3_SX | MAS3_SR;
        TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_SW : 0);
-       if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+       if (mmu_has_feature(MMU_FTR_BIG_PHYS))
                TLBCAM[index].MAS7 = (u64)phys >> 32;
 
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
        if (flags & _PAGE_USER) {
           TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
           TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
        }
-#else
-       TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
-       TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
-#endif
 
        tlbcam_addrs[index].start = virt;
        tlbcam_addrs[index].limit = virt + size - 1;
index 64c0022..eaa7633 100644 (file)
@@ -242,10 +242,11 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
  */
 static int __init find_min_common_depth(void)
 {
-       int depth;
+       int depth, index;
        const unsigned int *ref_points;
        struct device_node *rtas_root;
        unsigned int len;
+       struct device_node *options;
 
        rtas_root = of_find_node_by_path("/rtas");
 
@@ -258,11 +259,23 @@ static int __init find_min_common_depth(void)
         * configuration (should be all 0's) and the second is for a normal
         * NUMA configuration.
         */
+       index = 1;
        ref_points = of_get_property(rtas_root,
                        "ibm,associativity-reference-points", &len);
 
+       /*
+        * For type 1 affinity information we want the first field
+        */
+       options = of_find_node_by_path("/options");
+       if (options) {
+               const char *str;
+               str = of_get_property(options, "ibm,associativity-form", NULL);
+               if (str && !strcmp(str, "1"))
+                        index = 0;
+       }
+
        if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
-               depth = ref_points[1];
+               depth = ref_points[index];
        } else {
                dbg("NUMA: ibm,associativity-reference-points not found.\n");
                depth = -1;
index d951218..3a2ade2 100644 (file)
@@ -51,7 +51,7 @@ config MPC85xx_DS
        bool "Freescale MPC85xx DS"
        select PPC_I8259
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        select SWIOTLB
        help
          This option enables support for the MPC85xx DS (MPC8544 DS) board
@@ -60,7 +60,7 @@ config MPC85xx_RDB
        bool "Freescale MPC85xx RDB"
        select PPC_I8259
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        select SWIOTLB
        help
          This option enables support for the MPC85xx RDB (P2020 RDB) board
index fbe9f36..a0b5638 100644 (file)
@@ -13,7 +13,7 @@ config MPC8641_HPCN
        bool "Freescale MPC8641 HPCN"
        select PPC_I8259
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        select HAS_RAPIDIO
        select SWIOTLB
        help
@@ -28,7 +28,7 @@ config SBC8641D
 config MPC8610_HPCD
        bool "Freescale MPC8610 HPCD"
        select DEFAULT_UIMAGE
-       select FSL_ULI1575
+       select FSL_ULI1575 if PCI
        help
          This option enables support for the MPC8610 HPCD board.
 
index 9b21ee6..01e7b5b 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/of.h>
 #include <linux/lmb.h>
+#include <linux/vmalloc.h>
 #include <asm/firmware.h>
 #include <asm/machdep.h>
 #include <asm/pSeries_reconfig.h>
@@ -54,6 +55,12 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size)
         */
        start = (unsigned long)__va(base);
        ret = remove_section_mapping(start, start + lmb_size);
+
+       /* Ensure all vmalloc mappings are flushed in case they also
+        * hit that section of memory
+        */
+       vm_unmap_aliases();
+
        return ret;
 }
 
index 4dae369..8d103ca 100644 (file)
@@ -486,9 +486,6 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
                return -EINVAL;
        }
 
-       if (reg == &mpc8xx_immr->im_cpm.cp_sicr && mode == CPM_CLK_RX)
-               shift += 3;
-
        for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
                if (clk_map[i][0] == target && clk_map[i][1] == clock) {
                        bits = clk_map[i][2];
@@ -503,6 +500,17 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
 
        bits <<= shift;
        mask <<= shift;
+
+       if (reg == &mpc8xx_immr->im_cpm.cp_sicr) {
+               if (mode == CPM_CLK_RTX) {
+                       bits |= bits << 3;
+                       mask |= mask << 3;
+               } else if (mode == CPM_CLK_RX) {
+                       bits <<= 3;
+                       mask <<= 3;
+               }
+       }
+
        out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
        return 0;
index eb59272..8dc1e24 100644 (file)
@@ -244,9 +244,6 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
                return -EINVAL;
        }
 
-       if (mode == CPM_CLK_RX)
-               shift += 3;
-
        for (i = 0; i < ARRAY_SIZE(clk_map); i++) {
                if (clk_map[i][0] == target && clk_map[i][1] == clock) {
                        bits = clk_map[i][2];
@@ -259,6 +256,14 @@ int cpm2_clk_setup(enum cpm_clk_target target, int clock, int mode)
        bits <<= shift;
        mask <<= shift;
 
+       if (mode == CPM_CLK_RTX) {
+               bits |= bits << 3;
+               mask |= mask << 3;
+       } else if (mode == CPM_CLK_RX) {
+               bits <<= 3;
+               mask <<= 3;
+       }
+
        out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
        cpm2_unmap(im_cpmux);
index 0d8cd9b..79d0ca0 100644 (file)
@@ -444,13 +444,6 @@ config FORCE_MAX_ZONEORDER
        int
        default "9"
 
-config PROCESS_DEBUG
-       bool "Show crashed user process info"
-       help
-         Say Y to print all process fault locations to the console.  This is
-         a debugging option; you probably do not want to set it unless you
-         are an S390 port maintainer.
-
 config PFAULT
        bool "Pseudo page fault support"
        help
index 0da1074..30c5f01 100644 (file)
@@ -116,6 +116,12 @@ image bzImage: vmlinux
 zfcpdump:
        $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
+vdso_install:
+ifeq ($(CONFIG_64BIT),y)
+       $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@
+endif
+       $(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@
+
 archclean:
        $(Q)$(MAKE) $(clean)=$(boot)
 
index aea5720..fa487d4 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/fs.h>
 #include <linux/types.h>
+#include <linux/debugfs.h>
 
 #define REG_FILE_MODE    0440
 #define UPDATE_FILE_MODE 0220
@@ -34,6 +35,9 @@ extern int hypfs_diag_create_files(struct super_block *sb, struct dentry *root);
 
 /* VM Hypervisor */
 extern int hypfs_vm_init(void);
+extern void hypfs_vm_exit(void);
 extern int hypfs_vm_create_files(struct super_block *sb, struct dentry *root);
 
+/* Directory for debugfs files */
+extern struct dentry *hypfs_dbfs_dir;
 #endif /* _HYPFS_H_ */
index 5b1acdb..1211bb1 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <asm/ebcdic.h>
 #include "hypfs.h"
 
@@ -22,6 +23,8 @@
 #define CPU_NAME_LEN 16                /* type name len of cpus in diag224 name table */
 #define TMP_SIZE 64            /* size of temporary buffers */
 
+#define DBFS_D204_HDR_VERSION  0
+
 /* diag 204 subcodes */
 enum diag204_sc {
        SUBC_STIB4 = 4,
@@ -47,6 +50,8 @@ static void *diag204_buf;             /* 4K aligned buffer for diag204 data */
 static void *diag204_buf_vmalloc;      /* vmalloc pointer for diag204 data */
 static int diag204_buf_pages;          /* number of pages for diag204 data */
 
+static struct dentry *dbfs_d204_file;
+
 /*
  * DIAG 204 data structures and member access functions.
  *
@@ -364,18 +369,21 @@ static void diag204_free_buffer(void)
        } else {
                free_pages((unsigned long) diag204_buf, 0);
        }
-       diag204_buf_pages = 0;
        diag204_buf = NULL;
 }
 
+static void *page_align_ptr(void *ptr)
+{
+       return (void *) PAGE_ALIGN((unsigned long) ptr);
+}
+
 static void *diag204_alloc_vbuf(int pages)
 {
        /* The buffer has to be page aligned! */
        diag204_buf_vmalloc = vmalloc(PAGE_SIZE * (pages + 1));
        if (!diag204_buf_vmalloc)
                return ERR_PTR(-ENOMEM);
-       diag204_buf = (void*)((unsigned long)diag204_buf_vmalloc
-                               & ~0xfffUL) + 0x1000;
+       diag204_buf = page_align_ptr(diag204_buf_vmalloc);
        diag204_buf_pages = pages;
        return diag204_buf;
 }
@@ -468,17 +476,26 @@ fail_alloc:
        return rc;
 }
 
+static int diag204_do_store(void *buf, int pages)
+{
+       int rc;
+
+       rc = diag204((unsigned long) diag204_store_sc |
+                    (unsigned long) diag204_info_type, pages, buf);
+       return rc < 0 ? -ENOSYS : 0;
+}
+
 static void *diag204_store(void)
 {
        void *buf;
-       int pages;
+       int pages, rc;
 
        buf = diag204_get_buffer(diag204_info_type, &pages);
        if (IS_ERR(buf))
                goto out;
-       if (diag204((unsigned long)diag204_store_sc |
-                   (unsigned long)diag204_info_type, pages, buf) < 0)
-               return ERR_PTR(-ENOSYS);
+       rc = diag204_do_store(buf, pages);
+       if (rc)
+               return ERR_PTR(rc);
 out:
        return buf;
 }
@@ -526,6 +543,92 @@ static int diag224_idx2name(int index, char *name)
        return 0;
 }
 
+struct dbfs_d204_hdr {
+       u64     len;            /* Length of d204 buffer without header */
+       u16     version;        /* Version of header */
+       u8      sc;             /* Used subcode */
+       char    reserved[53];
+} __attribute__ ((packed));
+
+struct dbfs_d204 {
+       struct dbfs_d204_hdr    hdr;    /* 64 byte header */
+       char                    buf[];  /* d204 buffer */
+} __attribute__ ((packed));
+
+struct dbfs_d204_private {
+       struct dbfs_d204        *d204;  /* Aligned d204 data with header */
+       void                    *base;  /* Base pointer (needed for vfree) */
+};
+
+static int dbfs_d204_open(struct inode *inode, struct file *file)
+{
+       struct dbfs_d204_private *data;
+       struct dbfs_d204 *d204;
+       int rc, buf_size;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+       buf_size = PAGE_SIZE * (diag204_buf_pages + 1) + sizeof(d204->hdr);
+       data->base = vmalloc(buf_size);
+       if (!data->base) {
+               rc = -ENOMEM;
+               goto fail_kfree_data;
+       }
+       memset(data->base, 0, buf_size);
+       d204 = page_align_ptr(data->base + sizeof(d204->hdr))
+               - sizeof(d204->hdr);
+       rc = diag204_do_store(&d204->buf, diag204_buf_pages);
+       if (rc)
+               goto fail_vfree_base;
+       d204->hdr.version = DBFS_D204_HDR_VERSION;
+       d204->hdr.len = PAGE_SIZE * diag204_buf_pages;
+       d204->hdr.sc = diag204_store_sc;
+       data->d204 = d204;
+       file->private_data = data;
+       return nonseekable_open(inode, file);
+
+fail_vfree_base:
+       vfree(data->base);
+fail_kfree_data:
+       kfree(data);
+       return rc;
+}
+
+static int dbfs_d204_release(struct inode *inode, struct file *file)
+{
+       struct dbfs_d204_private *data = file->private_data;
+
+       vfree(data->base);
+       kfree(data);
+       return 0;
+}
+
+static ssize_t dbfs_d204_read(struct file *file, char __user *buf,
+                             size_t size, loff_t *ppos)
+{
+       struct dbfs_d204_private *data = file->private_data;
+
+       return simple_read_from_buffer(buf, size, ppos, data->d204,
+                                      data->d204->hdr.len +
+                                      sizeof(data->d204->hdr));
+}
+
+static const struct file_operations dbfs_d204_ops = {
+       .open           = dbfs_d204_open,
+       .read           = dbfs_d204_read,
+       .release        = dbfs_d204_release,
+};
+
+static int hypfs_dbfs_init(void)
+{
+       dbfs_d204_file = debugfs_create_file("diag_204", 0400, hypfs_dbfs_dir,
+                                            NULL, &dbfs_d204_ops);
+       if (IS_ERR(dbfs_d204_file))
+               return PTR_ERR(dbfs_d204_file);
+       return 0;
+}
+
 __init int hypfs_diag_init(void)
 {
        int rc;
@@ -540,11 +643,17 @@ __init int hypfs_diag_init(void)
                pr_err("The hardware system does not provide all "
                       "functions required by hypfs\n");
        }
+       if (diag204_info_type == INFO_EXT) {
+               rc = hypfs_dbfs_init();
+               if (rc)
+                       diag204_free_buffer();
+       }
        return rc;
 }
 
 void hypfs_diag_exit(void)
 {
+       debugfs_remove(dbfs_d204_file);
        diag224_delete_name_table();
        diag204_free_buffer();
 }
index f0b0d31..ee5ab1a 100644 (file)
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <asm/ebcdic.h>
+#include <asm/timex.h>
 #include "hypfs.h"
 
 #define NAME_LEN 8
+#define DBFS_D2FC_HDR_VERSION 0
 
 static char local_guest[] = "        ";
 static char all_guests[] = "*       ";
 static char *guest_query;
 
+static struct dentry *dbfs_d2fc_file;
+
 struct diag2fc_data {
        __u32 version;
        __u32 flags;
@@ -76,23 +80,26 @@ static int diag2fc(int size, char* query, void *addr)
                return -residual_cnt;
 }
 
-static struct diag2fc_data *diag2fc_store(char *query, int *count)
+/*
+ * Allocate buffer for "query" and store diag 2fc at "offset"
+ */
+static void *diag2fc_store(char *query, unsigned int *count, int offset)
 {
+       void *data;
        int size;
-       struct diag2fc_data *data;
 
        do {
                size = diag2fc(0, query, NULL);
                if (size < 0)
                        return ERR_PTR(-EACCES);
-               data = vmalloc(size);
+               data = vmalloc(size + offset);
                if (!data)
                        return ERR_PTR(-ENOMEM);
-               if (diag2fc(size, query, data) == 0)
+               if (diag2fc(size, query, data + offset) == 0)
                        break;
                vfree(data);
        } while (1);
-       *count = (size / sizeof(*data));
+       *count = (size / sizeof(struct diag2fc_data));
 
        return data;
 }
@@ -168,9 +175,10 @@ int hypfs_vm_create_files(struct super_block *sb, struct dentry *root)
 {
        struct dentry *dir, *file;
        struct diag2fc_data *data;
-       int rc, i, count = 0;
+       unsigned int count = 0;
+       int rc, i;
 
-       data = diag2fc_store(guest_query, &count);
+       data = diag2fc_store(guest_query, &count, 0);
        if (IS_ERR(data))
                return PTR_ERR(data);
 
@@ -218,8 +226,61 @@ failed:
        return rc;
 }
 
+struct dbfs_d2fc_hdr {
+       u64     len;            /* Length of d2fc buffer without header */
+       u16     version;        /* Version of header */
+       char    tod_ext[16];    /* TOD clock for d2fc */
+       u64     count;          /* Number of VM guests in d2fc buffer */
+       char    reserved[30];
+} __attribute__ ((packed));
+
+struct dbfs_d2fc {
+       struct dbfs_d2fc_hdr    hdr;    /* 64 byte header */
+       char                    buf[];  /* d2fc buffer */
+} __attribute__ ((packed));
+
+static int dbfs_d2fc_open(struct inode *inode, struct file *file)
+{
+       struct dbfs_d2fc *data;
+       unsigned int count;
+
+       data = diag2fc_store(guest_query, &count, sizeof(data->hdr));
+       if (IS_ERR(data))
+               return PTR_ERR(data);
+       get_clock_ext(data->hdr.tod_ext);
+       data->hdr.len = count * sizeof(struct diag2fc_data);
+       data->hdr.version = DBFS_D2FC_HDR_VERSION;
+       data->hdr.count = count;
+       memset(&data->hdr.reserved, 0, sizeof(data->hdr.reserved));
+       file->private_data = data;
+       return nonseekable_open(inode, file);
+}
+
+static int dbfs_d2fc_release(struct inode *inode, struct file *file)
+{
+       diag2fc_free(file->private_data);
+       return 0;
+}
+
+static ssize_t dbfs_d2fc_read(struct file *file, char __user *buf,
+                                   size_t size, loff_t *ppos)
+{
+       struct dbfs_d2fc *data = file->private_data;
+
+       return simple_read_from_buffer(buf, size, ppos, data, data->hdr.len +
+                                      sizeof(struct dbfs_d2fc_hdr));
+}
+
+static const struct file_operations dbfs_d2fc_ops = {
+       .open           = dbfs_d2fc_open,
+       .read           = dbfs_d2fc_read,
+       .release        = dbfs_d2fc_release,
+};
+
 int hypfs_vm_init(void)
 {
+       if (!MACHINE_IS_VM)
+               return 0;
        if (diag2fc(0, all_guests, NULL) > 0)
                guest_query = all_guests;
        else if (diag2fc(0, local_guest, NULL) > 0)
@@ -227,5 +288,17 @@ int hypfs_vm_init(void)
        else
                return -EACCES;
 
+       dbfs_d2fc_file = debugfs_create_file("diag_2fc", 0400, hypfs_dbfs_dir,
+                                            NULL, &dbfs_d2fc_ops);
+       if (IS_ERR(dbfs_d2fc_file))
+               return PTR_ERR(dbfs_d2fc_file);
+
        return 0;
 }
+
+void hypfs_vm_exit(void)
+{
+       if (!MACHINE_IS_VM)
+               return;
+       debugfs_remove(dbfs_d2fc_file);
+}
index c53f8ac..6b120f0 100644 (file)
@@ -46,6 +46,8 @@ static const struct super_operations hypfs_s_ops;
 /* start of list of all dentries, which have to be deleted on update */
 static struct dentry *hypfs_last_dentry;
 
+struct dentry *hypfs_dbfs_dir;
+
 static void hypfs_update_update(struct super_block *sb)
 {
        struct hypfs_sb_info *sb_info = sb->s_fs_info;
@@ -145,7 +147,7 @@ static int hypfs_open(struct inode *inode, struct file *filp)
                }
                mutex_unlock(&fs_info->lock);
        }
-       return 0;
+       return nonseekable_open(inode, filp);
 }
 
 static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov,
@@ -468,20 +470,22 @@ static int __init hypfs_init(void)
 {
        int rc;
 
-       if (MACHINE_IS_VM) {
-               if (hypfs_vm_init())
-                       /* no diag 2fc, just exit */
-                       return -ENODATA;
-       } else {
-               if (hypfs_diag_init()) {
-                       rc = -ENODATA;
-                       goto fail_diag;
-               }
+       hypfs_dbfs_dir = debugfs_create_dir("s390_hypfs", NULL);
+       if (IS_ERR(hypfs_dbfs_dir))
+               return PTR_ERR(hypfs_dbfs_dir);
+
+       if (hypfs_diag_init()) {
+               rc = -ENODATA;
+               goto fail_debugfs_remove;
+       }
+       if (hypfs_vm_init()) {
+               rc = -ENODATA;
+               goto fail_hypfs_diag_exit;
        }
        s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
        if (!s390_kobj) {
                rc = -ENOMEM;
-               goto fail_sysfs;
+               goto fail_hypfs_vm_exit;
        }
        rc = register_filesystem(&hypfs_type);
        if (rc)
@@ -490,18 +494,22 @@ static int __init hypfs_init(void)
 
 fail_filesystem:
        kobject_put(s390_kobj);
-fail_sysfs:
-       if (!MACHINE_IS_VM)
-               hypfs_diag_exit();
-fail_diag:
+fail_hypfs_vm_exit:
+       hypfs_vm_exit();
+fail_hypfs_diag_exit:
+       hypfs_diag_exit();
+fail_debugfs_remove:
+       debugfs_remove(hypfs_dbfs_dir);
+
        pr_err("Initialization of hypfs failed with rc=%i\n", rc);
        return rc;
 }
 
 static void __exit hypfs_exit(void)
 {
-       if (!MACHINE_IS_VM)
-               hypfs_diag_exit();
+       hypfs_diag_exit();
+       hypfs_vm_exit();
+       debugfs_remove(hypfs_dbfs_dir);
        unregister_filesystem(&hypfs_type);
        kobject_put(s390_kobj);
 }
index 258ba88..8b1a52a 100644 (file)
@@ -188,15 +188,16 @@ struct s390_idle_data {
 
 DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
 
-void vtime_start_cpu(void);
+void vtime_start_cpu(__u64 int_clock, __u64 enter_timer);
 cputime64_t s390_get_idle_time(int cpu);
 
 #define arch_idle_time(cpu) s390_get_idle_time(cpu)
 
-static inline void s390_idle_check(void)
+static inline void s390_idle_check(struct pt_regs *regs, __u64 int_clock,
+                                  __u64 enter_timer)
 {
-       if ((&__get_cpu_var(s390_idle))->idle_enter != 0ULL)
-               vtime_start_cpu();
+       if (regs->psw.mask & PSW_MASK_WAIT)
+               vtime_start_cpu(int_clock, enter_timer);
 }
 
 static inline int s390_nohz_delay(int cpu)
index 05527c0..0f97ef2 100644 (file)
@@ -104,38 +104,39 @@ struct _lowcore {
        /* CPU time accounting values */
        __u64   sync_enter_timer;               /* 0x0250 */
        __u64   async_enter_timer;              /* 0x0258 */
-       __u64   exit_timer;                     /* 0x0260 */
-       __u64   user_timer;                     /* 0x0268 */
-       __u64   system_timer;                   /* 0x0270 */
-       __u64   steal_timer;                    /* 0x0278 */
-       __u64   last_update_timer;              /* 0x0280 */
-       __u64   last_update_clock;              /* 0x0288 */
+       __u64   mcck_enter_timer;               /* 0x0260 */
+       __u64   exit_timer;                     /* 0x0268 */
+       __u64   user_timer;                     /* 0x0270 */
+       __u64   system_timer;                   /* 0x0278 */
+       __u64   steal_timer;                    /* 0x0280 */
+       __u64   last_update_timer;              /* 0x0288 */
+       __u64   last_update_clock;              /* 0x0290 */
 
        /* Current process. */
-       __u32   current_task;                   /* 0x0290 */
-       __u32   thread_info;                    /* 0x0294 */
-       __u32   kernel_stack;                   /* 0x0298 */
+       __u32   current_task;                   /* 0x0298 */
+       __u32   thread_info;                    /* 0x029c */
+       __u32   kernel_stack;                   /* 0x02a0 */
 
        /* Interrupt and panic stack. */
-       __u32   async_stack;                    /* 0x029c */
-       __u32   panic_stack;                    /* 0x02a0 */
+       __u32   async_stack;                    /* 0x02a4 */
+       __u32   panic_stack;                    /* 0x02a8 */
 
        /* Address space pointer. */
-       __u32   kernel_asce;                    /* 0x02a4 */
-       __u32   user_asce;                      /* 0x02a8 */
-       __u32   user_exec_asce;                 /* 0x02ac */
+       __u32   kernel_asce;                    /* 0x02ac */
+       __u32   user_asce;                      /* 0x02b0 */
+       __u32   user_exec_asce;                 /* 0x02b4 */
 
        /* SMP info area */
-       struct cpuid cpu_id;                    /* 0x02b0 */
        __u32   cpu_nr;                         /* 0x02b8 */
        __u32   softirq_pending;                /* 0x02bc */
        __u32   percpu_offset;                  /* 0x02c0 */
        __u32   ext_call_fast;                  /* 0x02c4 */
        __u64   int_clock;                      /* 0x02c8 */
-       __u64   clock_comparator;               /* 0x02d0 */
-       __u32   machine_flags;                  /* 0x02d8 */
-       __u32   ftrace_func;                    /* 0x02dc */
-       __u8    pad_0x02e0[0x0300-0x02e0];      /* 0x02e0 */
+       __u64   mcck_clock;                     /* 0x02d0 */
+       __u64   clock_comparator;               /* 0x02d8 */
+       __u32   machine_flags;                  /* 0x02e0 */
+       __u32   ftrace_func;                    /* 0x02e4 */
+       __u8    pad_0x02e8[0x0300-0x02e8];      /* 0x02e8 */
 
        /* Interrupt response block */
        __u8    irb[64];                        /* 0x0300 */
@@ -189,14 +190,14 @@ struct _lowcore {
        __u32   data_exc_code;                  /* 0x0090 */
        __u16   mon_class_num;                  /* 0x0094 */
        __u16   per_perc_atmid;                 /* 0x0096 */
-       addr_t  per_address;                    /* 0x0098 */
+       __u64   per_address;                    /* 0x0098 */
        __u8    exc_access_id;                  /* 0x00a0 */
        __u8    per_access_id;                  /* 0x00a1 */
        __u8    op_access_id;                   /* 0x00a2 */
        __u8    ar_access_id;                   /* 0x00a3 */
        __u8    pad_0x00a4[0x00a8-0x00a4];      /* 0x00a4 */
-       addr_t  trans_exc_code;                 /* 0x00a8 */
-       addr_t  monitor_code;                   /* 0x00b0 */
+       __u64   trans_exc_code;                 /* 0x00a8 */
+       __u64   monitor_code;                   /* 0x00b0 */
        __u16   subchannel_id;                  /* 0x00b8 */
        __u16   subchannel_nr;                  /* 0x00ba */
        __u32   io_int_parm;                    /* 0x00bc */
@@ -207,7 +208,7 @@ struct _lowcore {
        __u32   mcck_interruption_code[2];      /* 0x00e8 */
        __u8    pad_0x00f0[0x00f4-0x00f0];      /* 0x00f0 */
        __u32   external_damage_code;           /* 0x00f4 */
-       addr_t  failing_storage_address;        /* 0x00f8 */
+       __u64   failing_storage_address;        /* 0x00f8 */
        __u8    pad_0x0100[0x0110-0x0100];      /* 0x0100 */
        __u64   breaking_event_addr;            /* 0x0110 */
        __u8    pad_0x0118[0x0120-0x0118];      /* 0x0118 */
@@ -233,39 +234,41 @@ struct _lowcore {
        /* CPU accounting and timing values. */
        __u64   sync_enter_timer;               /* 0x02a0 */
        __u64   async_enter_timer;              /* 0x02a8 */
-       __u64   exit_timer;                     /* 0x02b0 */
-       __u64   user_timer;                     /* 0x02b8 */
-       __u64   system_timer;                   /* 0x02c0 */
-       __u64   steal_timer;                    /* 0x02c8 */
-       __u64   last_update_timer;              /* 0x02d0 */
-       __u64   last_update_clock;              /* 0x02d8 */
+       __u64   mcck_enter_timer;               /* 0x02b0 */
+       __u64   exit_timer;                     /* 0x02b8 */
+       __u64   user_timer;                     /* 0x02c0 */
+       __u64   system_timer;                   /* 0x02c8 */
+       __u64   steal_timer;                    /* 0x02d0 */
+       __u64   last_update_timer;              /* 0x02d8 */
+       __u64   last_update_clock;              /* 0x02e0 */
 
        /* Current process. */
-       __u64   current_task;                   /* 0x02e0 */
-       __u64   thread_info;                    /* 0x02e8 */
-       __u64   kernel_stack;                   /* 0x02f0 */
+       __u64   current_task;                   /* 0x02e8 */
+       __u64   thread_info;                    /* 0x02f0 */
+       __u64   kernel_stack;                   /* 0x02f8 */
 
        /* Interrupt and panic stack. */
-       __u64   async_stack;                    /* 0x02f8 */
-       __u64   panic_stack;                    /* 0x0300 */
+       __u64   async_stack;                    /* 0x0300 */
+       __u64   panic_stack;                    /* 0x0308 */
 
        /* Address space pointer. */
-       __u64   kernel_asce;                    /* 0x0308 */
-       __u64   user_asce;                      /* 0x0310 */
-       __u64   user_exec_asce;                 /* 0x0318 */
+       __u64   kernel_asce;                    /* 0x0310 */
+       __u64   user_asce;                      /* 0x0318 */
+       __u64   user_exec_asce;                 /* 0x0320 */
 
        /* SMP info area */
-       struct cpuid cpu_id;                    /* 0x0320 */
        __u32   cpu_nr;                         /* 0x0328 */
        __u32   softirq_pending;                /* 0x032c */
        __u64   percpu_offset;                  /* 0x0330 */
        __u64   ext_call_fast;                  /* 0x0338 */
        __u64   int_clock;                      /* 0x0340 */
-       __u64   clock_comparator;               /* 0x0348 */
-       __u64   vdso_per_cpu_data;              /* 0x0350 */
-       __u64   machine_flags;                  /* 0x0358 */
-       __u64   ftrace_func;                    /* 0x0360 */
-       __u8    pad_0x0368[0x0380-0x0368];      /* 0x0368 */
+       __u64   mcck_clock;                     /* 0x0348 */
+       __u64   clock_comparator;               /* 0x0350 */
+       __u64   vdso_per_cpu_data;              /* 0x0358 */
+       __u64   machine_flags;                  /* 0x0360 */
+       __u64   ftrace_func;                    /* 0x0368 */
+       __u64   sie_hook;                       /* 0x0370 */
+       __u64   cmf_hpp;                        /* 0x0378 */
 
        /* Interrupt response block. */
        __u8    irb[64];                        /* 0x0380 */
index fef9b33..e2c218d 100644 (file)
@@ -328,8 +328,8 @@ struct pt_regs
        psw_t psw;
        unsigned long gprs[NUM_GPRS];
        unsigned long orig_gpr2;
-       unsigned short svcnr;
        unsigned short ilc;
+       unsigned short svcnr;
 };
 #endif
 
@@ -436,6 +436,7 @@ typedef struct
 #define PTRACE_PEEKDATA_AREA         0x5003
 #define PTRACE_POKETEXT_AREA         0x5004
 #define PTRACE_POKEDATA_AREA         0x5005
+#define PTRACE_GET_LAST_BREAK        0x5006
 
 /*
  * PT_PROT definition is loosely based on hppa bsd definition in
index 9b04b11..0eaae62 100644 (file)
@@ -368,14 +368,12 @@ struct qdio_initialize {
 #define QDIO_FLAG_SYNC_OUTPUT          0x02
 #define QDIO_FLAG_PCI_OUT              0x10
 
-extern int qdio_initialize(struct qdio_initialize *);
 extern int qdio_allocate(struct qdio_initialize *);
 extern int qdio_establish(struct qdio_initialize *);
 extern int qdio_activate(struct ccw_device *);
 
 extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
                   int q_nr, unsigned int bufnr, unsigned int count);
-extern int qdio_cleanup(struct ccw_device*, int);
 extern int qdio_shutdown(struct ccw_device*, int);
 extern int qdio_free(struct ccw_device *);
 extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*);
index 9ab6bd3..25e831d 100644 (file)
@@ -2,7 +2,7 @@
  *  include/asm-s390/setup.h
  *
  *  S390 version
- *    Copyright IBM Corp. 1999,2006
+ *    Copyright IBM Corp. 1999,2010
  */
 
 #ifndef _ASM_S390_SETUP_H
@@ -72,6 +72,7 @@ extern unsigned int user_mode;
 #define MACHINE_FLAG_HPAGE     (1UL << 10)
 #define MACHINE_FLAG_PFMF      (1UL << 11)
 #define MACHINE_FLAG_LPAR      (1UL << 12)
+#define MACHINE_FLAG_SPP       (1UL << 13)
 
 #define MACHINE_IS_VM          (S390_lowcore.machine_flags & MACHINE_FLAG_VM)
 #define MACHINE_IS_KVM         (S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
@@ -88,6 +89,7 @@ extern unsigned int user_mode;
 #define MACHINE_HAS_MVCOS      (0)
 #define MACHINE_HAS_HPAGE      (0)
 #define MACHINE_HAS_PFMF       (0)
+#define MACHINE_HAS_SPP                (0)
 #else /* __s390x__ */
 #define MACHINE_HAS_IEEE       (1)
 #define MACHINE_HAS_CSP                (1)
@@ -97,6 +99,7 @@ extern unsigned int user_mode;
 #define MACHINE_HAS_MVCOS      (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
 #define MACHINE_HAS_HPAGE      (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
 #define MACHINE_HAS_PFMF       (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
+#define MACHINE_HAS_SPP                (S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE      (32UL<<20)
index 1741c15..cef6621 100644 (file)
@@ -459,11 +459,6 @@ extern void (*_machine_power_off)(void);
 
 #define arch_align_stack(x) (x)
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-extern psw_t sysc_restore_trace_psw;
-extern psw_t io_restore_trace_psw;
-#endif
-
 static inline int tprot(unsigned long addr)
 {
        int rc = -EFAULT;
index 34f0873..be3d3f9 100644 (file)
@@ -50,6 +50,7 @@ struct thread_info {
        struct restart_block    restart_block;
        __u64                   user_timer;
        __u64                   system_timer;
+       unsigned long           last_break;     /* last breaking-event-address. */
 };
 
 /*
index f174bda..09d345a 100644 (file)
@@ -61,11 +61,15 @@ static inline unsigned long long get_clock (void)
        return clk;
 }
 
+static inline void get_clock_ext(char *clk)
+{
+       asm volatile("stcke %0" : "=Q" (*clk) : : "cc");
+}
+
 static inline unsigned long long get_clock_xt(void)
 {
        unsigned char clk[16];
-
-       asm volatile("stcke %0" : "=Q" (clk) : : "cc");
+       get_clock_ext(clk);
        return *((unsigned long long *)&clk[1]);
 }
 
index 6e7211a..dc8a672 100644 (file)
@@ -7,8 +7,10 @@
 
 const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
 
+extern unsigned char cpu_core_id[NR_CPUS];
 extern cpumask_t cpu_core_map[NR_CPUS];
 
+#define topology_core_id(cpu)          (cpu_core_id[cpu])
 #define topology_core_cpumask(cpu)     (&cpu_core_map[cpu])
 
 int topology_set_cpu_management(int fc);
index 4a76d94..533f357 100644 (file)
@@ -29,6 +29,7 @@ struct vdso_data {
        __u32 tz_minuteswest;           /* Minutes west of Greenwich    0x30 */
        __u32 tz_dsttime;               /* Type of dst correction       0x34 */
        __u32 ectg_available;
+       __u32 ntp_mult;                 /* NTP adjusted multiplier      0x3C */
 };
 
 struct vdso_per_cpu_data {
index 08db736..d9b490a 100644 (file)
@@ -39,6 +39,7 @@ int main(void)
        DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count));
        DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer));
        DEFINE(__TI_system_timer, offsetof(struct thread_info, system_timer));
+       DEFINE(__TI_last_break, offsetof(struct thread_info, last_break));
        BLANK();
        DEFINE(__PT_ARGS, offsetof(struct pt_regs, args));
        DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
@@ -61,6 +62,7 @@ int main(void)
        DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
        DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
        DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
+       DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
        DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
        DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
        /* constants used by the vdso */
@@ -111,6 +113,7 @@ int main(void)
        DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
        DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
        DEFINE(__LC_ASYNC_ENTER_TIMER, offsetof(struct _lowcore, async_enter_timer));
+       DEFINE(__LC_MCCK_ENTER_TIMER, offsetof(struct _lowcore, mcck_enter_timer));
        DEFINE(__LC_EXIT_TIMER, offsetof(struct _lowcore, exit_timer));
        DEFINE(__LC_USER_TIMER, offsetof(struct _lowcore, user_timer));
        DEFINE(__LC_SYSTEM_TIMER, offsetof(struct _lowcore, system_timer));
@@ -125,10 +128,12 @@ int main(void)
        DEFINE(__LC_KERNEL_ASCE, offsetof(struct _lowcore, kernel_asce));
        DEFINE(__LC_USER_ASCE, offsetof(struct _lowcore, user_asce));
        DEFINE(__LC_USER_EXEC_ASCE, offsetof(struct _lowcore, user_exec_asce));
-       DEFINE(__LC_CPUID, offsetof(struct _lowcore, cpu_id));
        DEFINE(__LC_INT_CLOCK, offsetof(struct _lowcore, int_clock));
+       DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
        DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
        DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func));
+       DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook));
+       DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp));
        DEFINE(__LC_IRB, offsetof(struct _lowcore, irb));
        DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area));
        DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area));
index 0168472..9819226 100644 (file)
@@ -655,6 +655,7 @@ found:
        p_info->act_entry_offset = 0;
        file->private_data = p_info;
        debug_info_get(debug_info);
+       nonseekable_open(inode, file);
 out:
        mutex_unlock(&debug_mutex);
        return rc;
index 2d92c2c..c00856a 100644 (file)
@@ -356,6 +356,7 @@ static __init void detect_machine_facilities(void)
 {
 #ifdef CONFIG_64BIT
        unsigned int facilities;
+       unsigned long long facility_bits;
 
        facilities = stfl();
        if (facilities & (1 << 28))
@@ -364,6 +365,9 @@ static __init void detect_machine_facilities(void)
                S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
        if (facilities & (1 << 4))
                S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
+       if ((stfle(&facility_bits, 1) > 0) &&
+           (facility_bits & (1ULL << (63 - 40))))
+               S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
 #endif
 }
 
index 6af7045..d5e3e60 100644 (file)
@@ -73,21 +73,24 @@ STACK_SIZE  = 1 << STACK_SHIFT
        basr    %r14,%r1
        .endm
 
-       .macro  TRACE_IRQS_CHECK
-       basr    %r2,%r0
+       .macro  TRACE_IRQS_CHECK_ON
        tm      SP_PSW(%r15),0x03       # irqs enabled?
-       jz      0f
-       l       %r1,BASED(.Ltrace_irq_on_caller)
-       basr    %r14,%r1
-       j       1f
-0:     l       %r1,BASED(.Ltrace_irq_off_caller)
-       basr    %r14,%r1
-1:
+       bz      BASED(0f)
+       TRACE_IRQS_ON
+0:
+       .endm
+
+       .macro  TRACE_IRQS_CHECK_OFF
+       tm      SP_PSW(%r15),0x03       # irqs enabled?
+       bz      BASED(0f)
+       TRACE_IRQS_OFF
+0:
        .endm
 #else
 #define TRACE_IRQS_ON
 #define TRACE_IRQS_OFF
-#define TRACE_IRQS_CHECK
+#define TRACE_IRQS_CHECK_ON
+#define TRACE_IRQS_CHECK_OFF
 #endif
 
 #ifdef CONFIG_LOCKDEP
@@ -177,9 +180,9 @@ STACK_SIZE  = 1 << STACK_SHIFT
        s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
        mvc     SP_PSW(8,%r15),0(%r12)  # move user PSW to stack
        st      %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
-       icm     %r12,3,__LC_SVC_ILC
+       icm     %r12,12,__LC_SVC_ILC
        stm     %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
-       st      %r12,SP_SVCNR(%r15)
+       st      %r12,SP_ILC(%r15)
        mvc     SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
        la      %r12,0
        st      %r12,__SF_BACKCHAIN(%r15)       # clear back chain
@@ -273,66 +276,45 @@ sysc_do_restart:
        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
 
 sysc_return:
+       LOCKDEP_SYS_EXIT
+sysc_tif:
        tm      __TI_flags+3(%r9),_TIF_WORK_SVC
        bnz     BASED(sysc_work)  # there is work to do (signals etc.)
 sysc_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       la      %r1,BASED(sysc_restore_trace_psw_addr)
-       l       %r1,0(%r1)
-       lpsw    0(%r1)
-sysc_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-sysc_leave:
        RESTORE_ALL __LC_RETURN_PSW,1
 sysc_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-sysc_restore_trace_psw_addr:
-       .long sysc_restore_trace_psw
-
-       .section .data,"aw",@progbits
-       .align  8
-       .globl  sysc_restore_trace_psw
-sysc_restore_trace_psw:
-       .long   0, sysc_restore_trace + 0x80000000
-       .previous
-#endif
-
-#
-# recheck if there is more work to do
 #
-sysc_work_loop:
-       tm      __TI_flags+3(%r9),_TIF_WORK_SVC
-       bz      BASED(sysc_restore)     # there is no work to do
-#
-# One of the work bits is on. Find out which one.
+# There is work to do, but first we need to check if we return to userspace.
 #
 sysc_work:
        tm      SP_PSW+1(%r15),0x01     # returning to user ?
        bno     BASED(sysc_restore)
+
+#
+# One of the work bits is on. Find out which one.
+#
+sysc_work_tif:
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bo      BASED(sysc_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
        bo      BASED(sysc_reschedule)
        tm      __TI_flags+3(%r9),_TIF_SIGPENDING
-       bnz     BASED(sysc_sigpending)
+       b     BASED(sysc_sigpending)
        tm      __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
-       bnz     BASED(sysc_notify_resume)
+       b     BASED(sysc_notify_resume)
        tm      __TI_flags+3(%r9),_TIF_RESTART_SVC
        bo      BASED(sysc_restart)
        tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
        bo      BASED(sysc_singlestep)
-       b       BASED(sysc_restore)
-sysc_work_done:
+       b       BASED(sysc_return)      # beware of critical section cleanup
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #
 sysc_reschedule:
        l       %r1,BASED(.Lschedule)
-       la      %r14,BASED(sysc_work_loop)
+       la      %r14,BASED(sysc_return)
        br      %r1                     # call scheduler
 
 #
@@ -340,7 +322,7 @@ sysc_reschedule:
 #
 sysc_mcck_pending:
        l       %r1,BASED(.Ls390_handle_mcck)
-       la      %r14,BASED(sysc_work_loop)
+       la      %r14,BASED(sysc_return)
        br      %r1                     # TIF bit will be cleared by handler
 
 #
@@ -355,7 +337,7 @@ sysc_sigpending:
        bo      BASED(sysc_restart)
        tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
        bo      BASED(sysc_singlestep)
-       b       BASED(sysc_work_loop)
+       b       BASED(sysc_return)
 
 #
 # _TIF_NOTIFY_RESUME is set, call do_notify_resume
@@ -363,7 +345,7 @@ sysc_sigpending:
 sysc_notify_resume:
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ldo_notify_resume)
-       la      %r14,BASED(sysc_work_loop)
+       la      %r14,BASED(sysc_return)
        br      %r1                     # call do_notify_resume
 
 
@@ -458,11 +440,13 @@ kernel_execve:
        br      %r14
        # execve succeeded.
 0:     stnsm   __SF_EMPTY(%r15),0xfc   # disable interrupts
+       TRACE_IRQS_OFF
        l       %r15,__LC_KERNEL_STACK  # load ksp
        s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
        l       %r9,__LC_THREAD_INFO
        mvc     SP_PTREGS(__PT_SIZE,%r15),0(%r12)       # copy pt_regs
        xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+       TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        l       %r1,BASED(.Lexecve_tail)
        basr    %r14,%r1
@@ -499,8 +483,8 @@ pgm_check_handler:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime:
+       TRACE_IRQS_CHECK_OFF
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       TRACE_IRQS_OFF
        l       %r3,__LC_PGM_ILC        # load program interruption code
        la      %r8,0x7f
        nr      %r8,%r3
@@ -509,8 +493,10 @@ pgm_do_call:
        sll     %r8,2
        l       %r7,0(%r8,%r7)          # load address of handler routine
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       la      %r14,BASED(sysc_return)
-       br      %r7                     # branch to interrupt-handler
+       basr    %r14,%r7                # branch to interrupt-handler
+pgm_exit:
+       TRACE_IRQS_CHECK_ON
+       b       BASED(sysc_return)
 
 #
 # handle per exception
@@ -537,19 +523,19 @@ pgm_per_std:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
 pgm_no_vtime2:
+       TRACE_IRQS_CHECK_OFF
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       TRACE_IRQS_OFF
        l       %r1,__TI_task(%r9)
+       tm      SP_PSW+1(%r15),0x01     # kernel per event ?
+       bz      BASED(kernel_per)
        mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
-       tm      SP_PSW+1(%r15),0x01     # kernel per event ?
-       bz      BASED(kernel_per)
        l       %r3,__LC_PGM_ILC        # load program interruption code
        la      %r8,0x7f
        nr      %r8,%r3                 # clear per-event-bit and ilc
-       be      BASED(sysc_return)      # only per or per+check ?
+       be      BASED(pgm_exit)         # only per or per+check ?
        b       BASED(pgm_do_call)
 
 #
@@ -570,8 +556,8 @@ pgm_svcper:
        mvc     __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        TRACE_IRQS_ON
-       lm      %r2,%r6,SP_R2(%r15)     # load svc arguments
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       lm      %r2,%r6,SP_R2(%r15)     # load svc arguments
        b       BASED(sysc_do_svc)
 
 #
@@ -582,8 +568,8 @@ kernel_per:
        mvi     SP_SVCNR+1(%r15),0xff
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        l       %r1,BASED(.Lhandle_per) # load adr. of per handler
-       la      %r14,BASED(sysc_restore)# load adr. of system return
-       br      %r1                     # branch to do_single_step
+       basr    %r14,%r1                # branch to do_single_step
+       b       BASED(pgm_exit)
 
 /*
  * IO interrupt handler routine
@@ -602,134 +588,126 @@ io_int_handler:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
 io_no_vtime:
-       l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
+       l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        l       %r1,BASED(.Ldo_IRQ)     # load address of do_IRQ
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        basr    %r14,%r1                # branch to standard irq handler
 io_return:
+       LOCKDEP_SYS_EXIT
+       TRACE_IRQS_ON
+io_tif:
        tm      __TI_flags+3(%r9),_TIF_WORK_INT
        bnz     BASED(io_work)          # there is work to do (signals etc.)
 io_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       la      %r1,BASED(io_restore_trace_psw_addr)
-       l       %r1,0(%r1)
-       lpsw    0(%r1)
-io_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-io_leave:
        RESTORE_ALL __LC_RETURN_PSW,0
 io_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-io_restore_trace_psw_addr:
-       .long io_restore_trace_psw
-
-       .section .data,"aw",@progbits
-       .align  8
-       .globl  io_restore_trace_psw
-io_restore_trace_psw:
-       .long   0, io_restore_trace + 0x80000000
-       .previous
-#endif
-
 #
-# switch to kernel stack, then check the TIF bits
+# There is work todo, find out in which context we have been interrupted:
+# 1) if we return to user space we can do all _TIF_WORK_INT work
+# 2) if we return to kernel code and preemptive scheduling is enabled check
+#    the preemption counter and if it is zero call preempt_schedule_irq
+# Before any work can be done, a switch to the kernel stack is required.
 #
 io_work:
        tm      SP_PSW+1(%r15),0x01     # returning to user ?
-#ifndef CONFIG_PREEMPT
-       bno     BASED(io_restore)       # no-> skip resched & signal
-#else
-       bnz     BASED(io_work_user)     # no -> check for preemptive scheduling
+       bo      BASED(io_work_user)     # yes -> do resched & signal
+#ifdef CONFIG_PREEMPT
        # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
        bnz     BASED(io_restore)       # preemption disabled
+       tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
+       bno     BASED(io_restore)
+       # switch to kernel stack
        l       %r1,SP_R15(%r15)
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
-io_resume_loop:
-       tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
-       bno     BASED(io_restore)
+       # TRACE_IRQS_ON already done at io_return, call
+       # TRACE_IRQS_OFF to keep things symmetrical
+       TRACE_IRQS_OFF
        l       %r1,BASED(.Lpreempt_schedule_irq)
-       la      %r14,BASED(io_resume_loop)
-       br      %r1                     # call schedule
+       basr    %r14,%r1                # call preempt_schedule_irq
+       b       BASED(io_return)
+#else
+       b       BASED(io_restore)
 #endif
 
+#
+# Need to do work before returning to userspace, switch to kernel stack
+#
 io_work_user:
        l       %r1,__LC_KERNEL_STACK
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lr      %r15,%r1
+
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED
+# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
 #              and _TIF_MCCK_PENDING
 #
-io_work_loop:
+io_work_tif:
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bo      BASED(io_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
        bo      BASED(io_reschedule)
        tm      __TI_flags+3(%r9),_TIF_SIGPENDING
-       bnz     BASED(io_sigpending)
+       b     BASED(io_sigpending)
        tm      __TI_flags+3(%r9),_TIF_NOTIFY_RESUME
-       bnz     BASED(io_notify_resume)
-       b       BASED(io_restore)
-io_work_done:
+       bo      BASED(io_notify_resume)
+       b       BASED(io_return)        # beware of critical section cleanup
 
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
 io_mcck_pending:
+       # TRACE_IRQS_ON already done at io_return
        l       %r1,BASED(.Ls390_handle_mcck)
        basr    %r14,%r1                # TIF bit will be cleared by handler
-       b       BASED(io_work_loop)
+       TRACE_IRQS_OFF
+       b       BASED(io_return)
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #
 io_reschedule:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        l       %r1,BASED(.Lschedule)
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        basr    %r14,%r1                # call scheduler
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       tm      __TI_flags+3(%r9),_TIF_WORK_INT
-       bz      BASED(io_restore)       # there is no work to do
-       b       BASED(io_work_loop)
+       b       BASED(io_return)
 
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
 io_sigpending:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ldo_signal)
        basr    %r14,%r1                # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       b       BASED(io_work_loop)
+       b       BASED(io_return)
 
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
 io_notify_resume:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ldo_notify_resume)
        basr    %r14,%r1                # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       b       BASED(io_work_loop)
+       b       BASED(io_return)
 
 /*
  * External interrupt handler routine
@@ -764,15 +742,14 @@ __critical_end:
 
        .globl mcck_int_handler
 mcck_int_handler:
-       stck    __LC_INT_CLOCK
+       stck    __LC_MCCK_CLOCK
        spt     __LC_CPU_TIMER_SAVE_AREA        # revalidate cpu timer
        lm      %r0,%r15,__LC_GPREGS_SAVE_AREA  # revalidate gprs
        SAVE_ALL_BASE __LC_SAVE_AREA+32
        la      %r12,__LC_MCK_OLD_PSW
        tm      __LC_MCCK_CODE,0x80     # system damage?
        bo      BASED(mcck_int_main)    # yes -> rest of mcck code invalid
-       mvc     __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER
-       mvc     __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
+       mvc     __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
        tm      __LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
        bo      BASED(1f)
        la      %r14,__LC_SYNC_ENTER_TIMER
@@ -786,7 +763,7 @@ mcck_int_handler:
        bl      BASED(0f)
        la      %r14,__LC_LAST_UPDATE_TIMER
 0:     spt     0(%r14)
-       mvc     __LC_ASYNC_ENTER_TIMER(8),0(%r14)
+       mvc     __LC_MCCK_ENTER_TIMER(8),0(%r14)
 1:     tm      __LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
        bno     BASED(mcck_int_main)    # no -> skip cleanup critical
        tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
@@ -808,9 +785,9 @@ mcck_int_main:
        bno     BASED(mcck_no_vtime)    # no -> skip cleanup critical
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(mcck_no_vtime)
-       UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+       UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
-       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
 mcck_no_vtime:
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
@@ -833,7 +810,6 @@ mcck_no_vtime:
 mcck_return:
        mvc     __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
        ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
-       mvc     __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52
        tm      __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
        bno     BASED(0f)
        lm      %r0,%r15,SP_R0(%r15)    # load gprs 0-15
@@ -917,18 +893,14 @@ stack_overflow:
 
 cleanup_table_system_call:
        .long   system_call + 0x80000000, sysc_do_svc + 0x80000000
-cleanup_table_sysc_return:
-       .long   sysc_return + 0x80000000, sysc_leave + 0x80000000
-cleanup_table_sysc_leave:
-       .long   sysc_leave + 0x80000000, sysc_done + 0x80000000
-cleanup_table_sysc_work_loop:
-       .long   sysc_work_loop + 0x80000000, sysc_work_done + 0x80000000
-cleanup_table_io_return:
-       .long   io_return + 0x80000000, io_leave + 0x80000000
-cleanup_table_io_leave:
-       .long   io_leave + 0x80000000, io_done + 0x80000000
-cleanup_table_io_work_loop:
-       .long   io_work_loop + 0x80000000, io_work_done + 0x80000000
+cleanup_table_sysc_tif:
+       .long   sysc_tif + 0x80000000, sysc_restore + 0x80000000
+cleanup_table_sysc_restore:
+       .long   sysc_restore + 0x80000000, sysc_done + 0x80000000
+cleanup_table_io_tif:
+       .long   io_tif + 0x80000000, io_restore + 0x80000000
+cleanup_table_io_restore:
+       .long   io_restore + 0x80000000, io_done + 0x80000000
 
 cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_system_call)
@@ -936,49 +908,40 @@ cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_system_call+4)
        bl      BASED(cleanup_system_call)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_sysc_return)
-       bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_sysc_return+4)
-       bl      BASED(cleanup_sysc_return)
-0:
-       clc     4(4,%r12),BASED(cleanup_table_sysc_leave)
-       bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_sysc_leave+4)
-       bl      BASED(cleanup_sysc_leave)
-0:
-       clc     4(4,%r12),BASED(cleanup_table_sysc_work_loop)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_tif)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
-       bl      BASED(cleanup_sysc_return)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_tif+4)
+       bl      BASED(cleanup_sysc_tif)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_io_return)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_restore)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_io_return+4)
-       bl      BASED(cleanup_io_return)
+       clc     4(4,%r12),BASED(cleanup_table_sysc_restore+4)
+       bl      BASED(cleanup_sysc_restore)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_io_leave)
+       clc     4(4,%r12),BASED(cleanup_table_io_tif)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_io_leave+4)
-       bl      BASED(cleanup_io_leave)
+       clc     4(4,%r12),BASED(cleanup_table_io_tif+4)
+       bl      BASED(cleanup_io_tif)
 0:
-       clc     4(4,%r12),BASED(cleanup_table_io_work_loop)
+       clc     4(4,%r12),BASED(cleanup_table_io_restore)
        bl      BASED(0f)
-       clc     4(4,%r12),BASED(cleanup_table_io_work_loop+4)
-       bl      BASED(cleanup_io_work_loop)
+       clc     4(4,%r12),BASED(cleanup_table_io_restore+4)
+       bl      BASED(cleanup_io_restore)
 0:
        br      %r14
 
 cleanup_system_call:
        mvc     __LC_RETURN_PSW(8),0(%r12)
-       c       %r12,BASED(.Lmck_old_psw)
-       be      BASED(0f)
-       la      %r12,__LC_SAVE_AREA+16
-       b       BASED(1f)
-0:     la      %r12,__LC_SAVE_AREA+32
-1:
        clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4)
        bh      BASED(0f)
+       mvc     __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
+       c       %r12,BASED(.Lmck_old_psw)
+       be      BASED(0f)
        mvc     __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
+0:     c       %r12,BASED(.Lmck_old_psw)
+       la      %r12,__LC_SAVE_AREA+32
+       be      BASED(0f)
+       la      %r12,__LC_SAVE_AREA+16
 0:     clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8)
        bhe     BASED(cleanup_vtime)
        clc     __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn)
@@ -1011,61 +974,54 @@ cleanup_system_call_insn:
        .long   sysc_stime + 0x80000000
        .long   sysc_update + 0x80000000
 
-cleanup_sysc_return:
+cleanup_sysc_tif:
        mvc     __LC_RETURN_PSW(4),0(%r12)
-       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_return)
+       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_sysc_leave:
-       clc     4(4,%r12),BASED(cleanup_sysc_leave_insn)
+cleanup_sysc_restore:
+       clc     4(4,%r12),BASED(cleanup_sysc_restore_insn)
        be      BASED(2f)
+       mvc     __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
+       c       %r12,BASED(.Lmck_old_psw)
+       be      BASED(0f)
        mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
-       clc     4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
+0:     clc     4(4,%r12),BASED(cleanup_sysc_restore_insn+4)
        be      BASED(2f)
        mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)
        c       %r12,BASED(.Lmck_old_psw)
-       bne     BASED(0f)
-       mvc     __LC_SAVE_AREA+32(16),SP_R12(%r15)
-       b       BASED(1f)
-0:     mvc     __LC_SAVE_AREA+16(16),SP_R12(%r15)
-1:     lm      %r0,%r11,SP_R0(%r15)
+       la      %r12,__LC_SAVE_AREA+32
+       be      BASED(1f)
+       la      %r12,__LC_SAVE_AREA+16
+1:     mvc     0(16,%r12),SP_R12(%r15)
+       lm      %r0,%r11,SP_R0(%r15)
        l       %r15,SP_R15(%r15)
 2:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_sysc_leave_insn:
+cleanup_sysc_restore_insn:
        .long   sysc_done - 4 + 0x80000000
        .long   sysc_done - 8 + 0x80000000
 
-cleanup_io_return:
+cleanup_io_tif:
        mvc     __LC_RETURN_PSW(4),0(%r12)
-       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_io_work_loop:
-       mvc     __LC_RETURN_PSW(4),0(%r12)
-       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
-       la      %r12,__LC_RETURN_PSW
-       br      %r14
-
-cleanup_io_leave:
-       clc     4(4,%r12),BASED(cleanup_io_leave_insn)
-       be      BASED(2f)
-       mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
-       clc     4(4,%r12),BASED(cleanup_io_leave_insn+4)
-       be      BASED(2f)
+cleanup_io_restore:
+       clc     4(4,%r12),BASED(cleanup_io_restore_insn)
+       be      BASED(1f)
+       mvc     __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
+       clc     4(4,%r12),BASED(cleanup_io_restore_insn+4)
+       be      BASED(1f)
        mvc     __LC_RETURN_PSW(8),SP_PSW(%r15)
-       c       %r12,BASED(.Lmck_old_psw)
-       bne     BASED(0f)
        mvc     __LC_SAVE_AREA+32(16),SP_R12(%r15)
-       b       BASED(1f)
-0:     mvc     __LC_SAVE_AREA+16(16),SP_R12(%r15)
-1:     lm      %r0,%r11,SP_R0(%r15)
+       lm      %r0,%r11,SP_R0(%r15)
        l       %r15,SP_R15(%r15)
-2:     la      %r12,__LC_RETURN_PSW
+1:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_io_leave_insn:
+cleanup_io_restore_insn:
        .long   io_done - 4 + 0x80000000
        .long   io_done - 8 + 0x80000000
 
index 52106d5..178d925 100644 (file)
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/entry64.S
  *    S390 low-level entry points.
  *
- *    Copyright (C) IBM Corp. 1999,2006
+ *    Copyright (C) IBM Corp. 1999,2010
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *              Hartmut Penner (hp@de.ibm.com),
  *              Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
@@ -59,30 +59,45 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
 
 #define BASED(name) name-system_call(%r13)
 
+       .macro  HANDLE_SIE_INTERCEPT
+#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+       lg      %r3,__LC_SIE_HOOK
+       ltgr    %r3,%r3
+       jz      0f
+       basr    %r14,%r3
+       0:
+#endif
+       .endm
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        .macro  TRACE_IRQS_ON
-        basr   %r2,%r0
-        brasl  %r14,trace_hardirqs_on_caller
+       basr    %r2,%r0
+       brasl   %r14,trace_hardirqs_on_caller
        .endm
 
        .macro  TRACE_IRQS_OFF
-        basr   %r2,%r0
-        brasl  %r14,trace_hardirqs_off_caller
+       basr    %r2,%r0
+       brasl   %r14,trace_hardirqs_off_caller
        .endm
 
-       .macro TRACE_IRQS_CHECK
-       basr    %r2,%r0
+       .macro TRACE_IRQS_CHECK_ON
        tm      SP_PSW(%r15),0x03       # irqs enabled?
        jz      0f
-       brasl   %r14,trace_hardirqs_on_caller
-       j       1f
-0:     brasl   %r14,trace_hardirqs_off_caller
-1:
+       TRACE_IRQS_ON
+0:
+       .endm
+
+       .macro TRACE_IRQS_CHECK_OFF
+       tm      SP_PSW(%r15),0x03       # irqs enabled?
+       jz      0f
+       TRACE_IRQS_OFF
+0:
        .endm
 #else
 #define TRACE_IRQS_ON
 #define TRACE_IRQS_OFF
-#define TRACE_IRQS_CHECK
+#define TRACE_IRQS_CHECK_ON
+#define TRACE_IRQS_CHECK_OFF
 #endif
 
 #ifdef CONFIG_LOCKDEP
@@ -111,31 +126,35 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
  *    R15 - kernel stack pointer
  */
 
-       .macro  SAVE_ALL_BASE savearea
-       stmg    %r12,%r15,\savearea
-       larl    %r13,system_call
-       .endm
-
        .macro  SAVE_ALL_SVC psworg,savearea
-       la      %r12,\psworg
+       stmg    %r11,%r15,\savearea
        lg      %r15,__LC_KERNEL_STACK  # problem state -> load ksp
+       aghi    %r15,-SP_SIZE           # make room for registers & psw
+       lg      %r11,__LC_LAST_BREAK
        .endm
 
-       .macro  SAVE_ALL_SYNC psworg,savearea
-       la      %r12,\psworg
+       .macro  SAVE_ALL_PGM psworg,savearea
+       stmg    %r11,%r15,\savearea
        tm      \psworg+1,0x01          # test problem state bit
-       jz      2f                      # skip stack setup save
-       lg      %r15,__LC_KERNEL_STACK  # problem state -> load ksp
 #ifdef CONFIG_CHECK_STACK
-       j       3f
-2:     tml     %r15,STACK_SIZE - CONFIG_STACK_GUARD
-       jz      stack_overflow
-3:
+       jnz     1f
+       tml     %r15,STACK_SIZE - CONFIG_STACK_GUARD
+       jnz     2f
+       la      %r12,\psworg
+       j       stack_overflow
+#else
+       jz      2f
 #endif
-2:
+1:     lg      %r15,__LC_KERNEL_STACK  # problem state -> load ksp
+2:     aghi    %r15,-SP_SIZE           # make room for registers & psw
+       larl    %r13,system_call
+       lg      %r11,__LC_LAST_BREAK
        .endm
 
        .macro  SAVE_ALL_ASYNC psworg,savearea
+       stmg    %r11,%r15,\savearea
+       larl    %r13,system_call
+       lg      %r11,__LC_LAST_BREAK
        la      %r12,\psworg
        tm      \psworg+1,0x01          # test problem state bit
        jnz     1f                      # from user -> load kernel stack
@@ -149,27 +168,23 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
 0:     lg      %r14,__LC_ASYNC_STACK   # are we already on the async. stack ?
        slgr    %r14,%r15
        srag    %r14,%r14,STACK_SHIFT
-       jz      2f
-1:     lg      %r15,__LC_ASYNC_STACK   # load async stack
 #ifdef CONFIG_CHECK_STACK
-       j       3f
-2:     tml     %r15,STACK_SIZE - CONFIG_STACK_GUARD
-       jz      stack_overflow
-3:
+       jnz     1f
+       tml     %r15,STACK_SIZE - CONFIG_STACK_GUARD
+       jnz     2f
+       j       stack_overflow
+#else
+       jz      2f
 #endif
-2:
+1:     lg      %r15,__LC_ASYNC_STACK   # load async stack
+2:     aghi    %r15,-SP_SIZE           # make room for registers & psw
        .endm
 
-       .macro  CREATE_STACK_FRAME psworg,savearea
-       aghi    %r15,-SP_SIZE           # make room for registers & psw
-       mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
+       .macro  CREATE_STACK_FRAME savearea
+       xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
        stg     %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
-       icm     %r12,3,__LC_SVC_ILC
-       stmg    %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
-       st      %r12,SP_SVCNR(%r15)
-       mvc     SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
-       la      %r12,0
-       stg     %r12,__SF_BACKCHAIN(%r15)
+       mvc     SP_R11(40,%r15),\savearea # move %r11-%r15 to stack
+       stmg    %r0,%r10,SP_R0(%r15)    # store gprs %r0-%r10 to kernel stack
        .endm
 
        .macro  RESTORE_ALL psworg,sync
@@ -185,6 +200,13 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
        lpswe   \psworg                 # back to caller
        .endm
 
+       .macro  LAST_BREAK
+       srag    %r10,%r11,23
+       jz      0f
+       stg     %r11,__TI_last_break(%r12)
+0:
+       .endm
+
 /*
  * Scheduler resume function, called by switch_to
  *  gpr2 = (task_struct *) prev
@@ -230,143 +252,129 @@ __critical_start:
 system_call:
        stpt    __LC_SYNC_ENTER_TIMER
 sysc_saveall:
-       SAVE_ALL_BASE __LC_SAVE_AREA
        SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-       llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
+       CREATE_STACK_FRAME __LC_SAVE_AREA
+       mvc     SP_PSW(16,%r15),__LC_SVC_OLD_PSW
+       mvc     SP_ILC(4,%r15),__LC_SVC_ILC
+       stg     %r7,SP_ARGS(%r15)
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
 sysc_vtime:
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
 sysc_stime:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
 sysc_update:
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+       LAST_BREAK
 sysc_do_svc:
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       ltgr    %r7,%r7         # test for svc 0
+       llgh    %r7,SP_SVCNR(%r15)
+       slag    %r7,%r7,2       # shift and test for svc 0
        jnz     sysc_nr_ok
        # svc 0: system call number in %r1
-       cl      %r1,BASED(.Lnr_syscalls)
+       llgfr   %r1,%r1         # clear high word in r1
+       cghi    %r1,NR_syscalls
        jnl     sysc_nr_ok
-       lgfr    %r7,%r1         # clear high word in r1
+       sth     %r1,SP_SVCNR(%r15)
+       slag    %r7,%r1,2       # shift and test for svc 0
 sysc_nr_ok:
-       mvc     SP_ARGS(8,%r15),SP_R7(%r15)
-sysc_do_restart:
-       sth     %r7,SP_SVCNR(%r15)
-       sllg    %r7,%r7,2       # svc number * 4
        larl    %r10,sys_call_table
 #ifdef CONFIG_COMPAT
-       tm      __TI_flags+5(%r9),(_TIF_31BIT>>16)  # running in 31 bit mode ?
+       tm      __TI_flags+5(%r12),(_TIF_31BIT>>16)  # running in 31 bit mode ?
        jno     sysc_noemu
        larl    %r10,sys_call_table_emu  # use 31 bit emulation system calls
 sysc_noemu:
 #endif
-       tm      __TI_flags+6(%r9),_TIF_SYSCALL
+       tm      __TI_flags+6(%r12),_TIF_SYSCALL
        lgf     %r8,0(%r7,%r10) # load address of system call routine
        jnz     sysc_tracesys
        basr    %r14,%r8        # call sys_xxxx
        stg     %r2,SP_R2(%r15) # store return value (change R2 on stack)
 
 sysc_return:
-       tm      __TI_flags+7(%r9),_TIF_WORK_SVC
+       LOCKDEP_SYS_EXIT
+sysc_tif:
+       tm      __TI_flags+7(%r12),_TIF_WORK_SVC
        jnz     sysc_work       # there is work to do (signals etc.)
 sysc_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       larl    %r1,sysc_restore_trace_psw
-       lpswe   0(%r1)
-sysc_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-sysc_leave:
        RESTORE_ALL __LC_RETURN_PSW,1
 sysc_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-       .section .data,"aw",@progbits
-       .align  8
-       .globl sysc_restore_trace_psw
-sysc_restore_trace_psw:
-       .quad   0, sysc_restore_trace
-       .previous
-#endif
-
-#
-# recheck if there is more work to do
 #
-sysc_work_loop:
-       tm      __TI_flags+7(%r9),_TIF_WORK_SVC
-       jz      sysc_restore      # there is no work to do
-#
-# One of the work bits is on. Find out which one.
+# There is work to do, but first we need to check if we return to userspace.
 #
 sysc_work:
        tm      SP_PSW+1(%r15),0x01     # returning to user ?
        jno     sysc_restore
-       tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
+
+#
+# One of the work bits is on. Find out which one.
+#
+sysc_work_tif:
+       tm      __TI_flags+7(%r12),_TIF_MCCK_PENDING
        jo      sysc_mcck_pending
-       tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
+       tm      __TI_flags+7(%r12),_TIF_NEED_RESCHED
        jo      sysc_reschedule
-       tm      __TI_flags+7(%r9),_TIF_SIGPENDING
-       jnz     sysc_sigpending
-       tm      __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
-       jnz     sysc_notify_resume
-       tm      __TI_flags+7(%r9),_TIF_RESTART_SVC
+       tm      __TI_flags+7(%r12),_TIF_SIGPENDING
+       j     sysc_sigpending
+       tm      __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
+       j     sysc_notify_resume
+       tm      __TI_flags+7(%r12),_TIF_RESTART_SVC
        jo      sysc_restart
-       tm      __TI_flags+7(%r9),_TIF_SINGLE_STEP
+       tm      __TI_flags+7(%r12),_TIF_SINGLE_STEP
        jo      sysc_singlestep
-       j       sysc_restore
-sysc_work_done:
+       j       sysc_return             # beware of critical section cleanup
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #
 sysc_reschedule:
-       larl    %r14,sysc_work_loop
-       jg      schedule        # return point is sysc_return
+       larl    %r14,sysc_return
+       jg      schedule                # return point is sysc_return
 
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
 sysc_mcck_pending:
-       larl    %r14,sysc_work_loop
+       larl    %r14,sysc_return
        jg      s390_handle_mcck        # TIF bit will be cleared by handler
 
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
 sysc_sigpending:
-       ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
+       ni      __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,do_signal          # call do_signal
-       tm      __TI_flags+7(%r9),_TIF_RESTART_SVC
+       tm      __TI_flags+7(%r12),_TIF_RESTART_SVC
        jo      sysc_restart
-       tm      __TI_flags+7(%r9),_TIF_SINGLE_STEP
+       tm      __TI_flags+7(%r12),_TIF_SINGLE_STEP
        jo      sysc_singlestep
-       j       sysc_work_loop
+       j       sysc_return
 
 #
 # _TIF_NOTIFY_RESUME is set, call do_notify_resume
 #
 sysc_notify_resume:
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
-       larl    %r14,sysc_work_loop
+       larl    %r14,sysc_return
        jg      do_notify_resume        # call do_notify_resume
 
 #
 # _TIF_RESTART_SVC is set, set up registers and restart svc
 #
 sysc_restart:
-       ni      __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
+       ni      __TI_flags+7(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
        lg      %r7,SP_R2(%r15)         # load new svc number
        mvc     SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
        lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
-       j       sysc_do_restart         # restart svc
+       sth     %r7,SP_SVCNR(%r15)
+       slag    %r7,%r7,2
+       j       sysc_nr_ok              # restart svc
 
 #
 # _TIF_SINGLE_STEP is set, call do_single_step
 #
 sysc_singlestep:
-       ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP  # clear TIF_SINGLE_STEP
+       ni      __TI_flags+7(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
        xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15)         # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        larl    %r14,sysc_return        # load adr. of system return
@@ -379,8 +387,8 @@ sysc_singlestep:
 sysc_tracesys:
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        la      %r3,0
-       srl     %r7,2
-       stg     %r7,SP_R2(%r15)
+       llgh    %r0,SP_SVCNR(%r15)
+       stg     %r0,SP_R2(%r15)
        brasl   %r14,do_syscall_trace_enter
        lghi    %r0,NR_syscalls
        clgr    %r0,%r2
@@ -393,7 +401,7 @@ sysc_tracego:
        basr    %r14,%r8                # call sys_xxx
        stg     %r2,SP_R2(%r15)         # store return value
 sysc_tracenogo:
-       tm      __TI_flags+6(%r9),_TIF_SYSCALL
+       tm      __TI_flags+6(%r12),_TIF_SYSCALL
        jz      sysc_return
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        larl    %r14,sysc_return        # return point is sysc_return
@@ -405,7 +413,7 @@ sysc_tracenogo:
        .globl  ret_from_fork
 ret_from_fork:
        lg      %r13,__LC_SVC_NEW_PSW+8
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # forking a kernel thread ?
        jo      0f
        stg     %r15,SP_R15(%r15)       # store stack pointer for new kthread
@@ -435,12 +443,14 @@ kernel_execve:
        br      %r14
        # execve succeeded.
 0:     stnsm   __SF_EMPTY(%r15),0xfc   # disable interrupts
+#      TRACE_IRQS_OFF
        lg      %r15,__LC_KERNEL_STACK  # load ksp
        aghi    %r15,-SP_SIZE           # make room for registers & psw
        lg      %r13,__LC_SVC_NEW_PSW+8
-       lg      %r9,__LC_THREAD_INFO
        mvc     SP_PTREGS(__PT_SIZE,%r15),0(%r12)       # copy pt_regs
+       lg      %r12,__LC_THREAD_INFO
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+#      TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        brasl   %r14,execve_tail
        j       sysc_return
@@ -465,20 +475,23 @@ pgm_check_handler:
  * for LPSW?).
  */
        stpt    __LC_SYNC_ENTER_TIMER
-       SAVE_ALL_BASE __LC_SAVE_AREA
        tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
        jnz     pgm_per                  # got per exception -> special case
-       SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
-       CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+       SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+       CREATE_STACK_FRAME __LC_SAVE_AREA
+       xc      SP_ILC(4,%r15),SP_ILC(%r15)
+       mvc     SP_PSW(16,%r15),__LC_PGM_OLD_PSW
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      pgm_no_vtime
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+       LAST_BREAK
 pgm_no_vtime:
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       mvc     SP_ARGS(8,%r15),__LC_LAST_BREAK
-       TRACE_IRQS_OFF
+       HANDLE_SIE_INTERCEPT
+       TRACE_IRQS_CHECK_OFF
+       stg     %r11,SP_ARGS(%r15)
        lgf     %r3,__LC_PGM_ILC        # load program interruption code
        lghi    %r8,0x7f
        ngr     %r8,%r3
@@ -487,8 +500,10 @@ pgm_do_call:
        larl    %r1,pgm_check_table
        lg      %r1,0(%r8,%r1)          # load address of handler routine
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       larl    %r14,sysc_return
-       br      %r1                     # branch to interrupt-handler
+       basr    %r14,%r1                # branch to interrupt-handler
+pgm_exit:
+       TRACE_IRQS_CHECK_ON
+       j       sysc_return
 
 #
 # handle per exception
@@ -500,55 +515,60 @@ pgm_per:
        clc     __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
        je      pgm_svcper
 # no interesting special case, ignore PER event
-       lmg     %r12,%r15,__LC_SAVE_AREA
        lpswe   __LC_PGM_OLD_PSW
 
 #
 # Normal per exception
 #
 pgm_per_std:
-       SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
-       CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+       SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
+       CREATE_STACK_FRAME __LC_SAVE_AREA
+       mvc     SP_PSW(16,%r15),__LC_PGM_OLD_PSW
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      pgm_no_vtime2
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+       LAST_BREAK
 pgm_no_vtime2:
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       TRACE_IRQS_OFF
-       lg      %r1,__TI_task(%r9)
+       HANDLE_SIE_INTERCEPT
+       TRACE_IRQS_CHECK_OFF
+       lg      %r1,__TI_task(%r12)
        tm      SP_PSW+1(%r15),0x01     # kernel per event ?
        jz      kernel_per
        mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
-       oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       oi      __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        lgf     %r3,__LC_PGM_ILC        # load program interruption code
        lghi    %r8,0x7f
        ngr     %r8,%r3                 # clear per-event-bit and ilc
-       je      sysc_return
+       je      pgm_exit
        j       pgm_do_call
 
 #
 # it was a single stepped SVC that is causing all the trouble
 #
 pgm_svcper:
-       SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+       SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA
+       CREATE_STACK_FRAME __LC_SAVE_AREA
+       mvc     SP_PSW(16,%r15),__LC_SVC_OLD_PSW
+       mvc     SP_ILC(4,%r15),__LC_SVC_ILC
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-       llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       lg      %r8,__TI_task(%r9)
+       LAST_BREAK
+       TRACE_IRQS_OFF
+       lg      %r8,__TI_task(%r12)
        mvc     __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
        mvc     __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
        mvc     __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
-       oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
+       oi      __TI_flags+7(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        TRACE_IRQS_ON
-       lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
+       lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
        j       sysc_do_svc
 
 #
@@ -557,8 +577,8 @@ pgm_svcper:
 kernel_per:
        xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
-       larl    %r14,sysc_restore       # load adr. of system ret, no work
-       jg      do_single_step          # branch to do_single_step
+       brasl   %r14,do_single_step
+       j       pgm_exit
 
 /*
  * IO interrupt handler routine
@@ -567,162 +587,133 @@ kernel_per:
 io_int_handler:
        stck    __LC_INT_CLOCK
        stpt    __LC_ASYNC_ENTER_TIMER
-       SAVE_ALL_BASE __LC_SAVE_AREA+32
-       SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
-       CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
+       SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40
+       CREATE_STACK_FRAME __LC_SAVE_AREA+40
+       mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      io_no_vtime
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       LAST_BREAK
 io_no_vtime:
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       HANDLE_SIE_INTERCEPT
        TRACE_IRQS_OFF
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        brasl   %r14,do_IRQ             # call standard irq handler
 io_return:
-       tm      __TI_flags+7(%r9),_TIF_WORK_INT
+       LOCKDEP_SYS_EXIT
+       TRACE_IRQS_ON
+io_tif:
+       tm      __TI_flags+7(%r12),_TIF_WORK_INT
        jnz     io_work                 # there is work to do (signals etc.)
 io_restore:
-#ifdef CONFIG_TRACE_IRQFLAGS
-       larl    %r1,io_restore_trace_psw
-       lpswe   0(%r1)
-io_restore_trace:
-       TRACE_IRQS_CHECK
-       LOCKDEP_SYS_EXIT
-#endif
-io_leave:
        RESTORE_ALL __LC_RETURN_PSW,0
 io_done:
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-       .section .data,"aw",@progbits
-       .align  8
-       .globl io_restore_trace_psw
-io_restore_trace_psw:
-       .quad   0, io_restore_trace
-       .previous
-#endif
-
 #
-# There is work todo, we need to check if we return to userspace, then
-# check, if we are in SIE, if yes leave it
+# There is work todo, find out in which context we have been interrupted:
+# 1) if we return to user space we can do all _TIF_WORK_INT work
+# 2) if we return to kernel code and kvm is enabled check if we need to
+#    modify the psw to leave SIE
+# 3) if we return to kernel code and preemptive scheduling is enabled check
+#    the preemption counter and if it is zero call preempt_schedule_irq
+# Before any work can be done, a switch to the kernel stack is required.
 #
 io_work:
        tm      SP_PSW+1(%r15),0x01     # returning to user ?
-#ifndef CONFIG_PREEMPT
-#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
-       jnz     io_work_user            # yes -> no need to check for SIE
-       la      %r1, BASED(sie_opcode)  # we return to kernel here
-       lg      %r2, SP_PSW+8(%r15)
-       clc     0(2,%r1), 0(%r2)        # is current instruction = SIE?
-       jne     io_restore              # no-> return to kernel
-       lg      %r1, SP_PSW+8(%r15)     # yes-> add 4 bytes to leave SIE
-       aghi    %r1, 4
-       stg     %r1, SP_PSW+8(%r15)
-       j       io_restore              # return to kernel
-#else
-       jno     io_restore              # no-> skip resched & signal
-#endif
-#else
-       jnz     io_work_user            # yes -> do resched & signal
-#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
-       la      %r1, BASED(sie_opcode)
-       lg      %r2, SP_PSW+8(%r15)
-       clc     0(2,%r1), 0(%r2)        # is current instruction = SIE?
-       jne     0f                      # no -> leave PSW alone
-       lg      %r1, SP_PSW+8(%r15)     # yes-> add 4 bytes to leave SIE
-       aghi    %r1, 4
-       stg     %r1, SP_PSW+8(%r15)
-0:
-#endif
+       jo      io_work_user            # yes -> do resched & signal
+#ifdef CONFIG_PREEMPT
        # check for preemptive scheduling
-       icm     %r0,15,__TI_precount(%r9)
+       icm     %r0,15,__TI_precount(%r12)
        jnz     io_restore              # preemption is disabled
+       tm      __TI_flags+7(%r12),_TIF_NEED_RESCHED
+       jno     io_restore
        # switch to kernel stack
        lg      %r1,SP_R15(%r15)
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lgr     %r15,%r1
-io_resume_loop:
-       tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
-       jno     io_restore
-       larl    %r14,io_resume_loop
-       jg      preempt_schedule_irq
+       # TRACE_IRQS_ON already done at io_return, call
+       # TRACE_IRQS_OFF to keep things symmetrical
+       TRACE_IRQS_OFF
+       brasl   %r14,preempt_schedule_irq
+       j       io_return
+#else
+       j       io_restore
 #endif
 
+#
+# Need to do work before returning to userspace, switch to kernel stack
+#
 io_work_user:
        lg      %r1,__LC_KERNEL_STACK
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lgr     %r15,%r1
+
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGPENDING, _TIF_NEED_RESCHED
+# Checked are: _TIF_SIGPENDING, _TIF_NOTIFY_RESUME, _TIF_NEED_RESCHED
 #             and _TIF_MCCK_PENDING
 #
-io_work_loop:
-       tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
+io_work_tif:
+       tm      __TI_flags+7(%r12),_TIF_MCCK_PENDING
        jo      io_mcck_pending
-       tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
+       tm      __TI_flags+7(%r12),_TIF_NEED_RESCHED
        jo      io_reschedule
-       tm      __TI_flags+7(%r9),_TIF_SIGPENDING
-       jnz     io_sigpending
-       tm      __TI_flags+7(%r9),_TIF_NOTIFY_RESUME
-       jnz     io_notify_resume
-       j       io_restore
-io_work_done:
-
-#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
-sie_opcode:
-       .long 0xb2140000
-#endif
+       tm      __TI_flags+7(%r12),_TIF_SIGPENDING
+       jo      io_sigpending
+       tm      __TI_flags+7(%r12),_TIF_NOTIFY_RESUME
+       jo      io_notify_resume
+       j       io_return               # beware of critical section cleanup
 
 #
 # _TIF_MCCK_PENDING is set, call handler
 #
 io_mcck_pending:
+       # TRACE_IRQS_ON already done at io_return
        brasl   %r14,s390_handle_mcck   # TIF bit will be cleared by handler
-       j       io_work_loop
+       TRACE_IRQS_OFF
+       j       io_return
 
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #
 io_reschedule:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        brasl   %r14,schedule           # call scheduler
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       tm      __TI_flags+7(%r9),_TIF_WORK_INT
-       jz      io_restore              # there is no work to do
-       j       io_work_loop
+       j       io_return
 
 #
 # _TIF_SIGPENDING or is set, call do_signal
 #
 io_sigpending:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,do_signal          # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       j       io_work_loop
+       j       io_return
 
 #
 # _TIF_NOTIFY_RESUME or is set, call do_notify_resume
 #
 io_notify_resume:
-       TRACE_IRQS_ON
+       # TRACE_IRQS_ON already done at io_return
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,do_notify_resume   # call do_notify_resume
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
        TRACE_IRQS_OFF
-       j       io_work_loop
+       j       io_return
 
 /*
  * External interrupt handler routine
@@ -731,16 +722,18 @@ io_notify_resume:
 ext_int_handler:
        stck    __LC_INT_CLOCK
        stpt    __LC_ASYNC_ENTER_TIMER
-       SAVE_ALL_BASE __LC_SAVE_AREA+32
-       SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
-       CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
+       SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40
+       CREATE_STACK_FRAME __LC_SAVE_AREA+40
+       mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      ext_no_vtime
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       LAST_BREAK
 ext_no_vtime:
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       HANDLE_SIE_INTERCEPT
        TRACE_IRQS_OFF
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        llgh    %r3,__LC_EXT_INT_CODE   # get interruption code
@@ -754,17 +747,18 @@ __critical_end:
  */
        .globl mcck_int_handler
 mcck_int_handler:
-       stck    __LC_INT_CLOCK
+       stck    __LC_MCCK_CLOCK
        la      %r1,4095                # revalidate r1
        spt     __LC_CPU_TIMER_SAVE_AREA-4095(%r1)      # revalidate cpu timer
        lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
-       SAVE_ALL_BASE __LC_SAVE_AREA+64
+       stmg    %r11,%r15,__LC_SAVE_AREA+80
+       larl    %r13,system_call
+       lg      %r11,__LC_LAST_BREAK
        la      %r12,__LC_MCK_OLD_PSW
        tm      __LC_MCCK_CODE,0x80     # system damage?
        jo      mcck_int_main           # yes -> rest of mcck code invalid
        la      %r14,4095
-       mvc     __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER
-       mvc     __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14)
+       mvc     __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14)
        tm      __LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
        jo      1f
        la      %r14,__LC_SYNC_ENTER_TIMER
@@ -778,7 +772,7 @@ mcck_int_handler:
        jl      0f
        la      %r14,__LC_LAST_UPDATE_TIMER
 0:     spt     0(%r14)
-       mvc     __LC_ASYNC_ENTER_TIMER(8),0(%r14)
+       mvc     __LC_MCCK_ENTER_TIMER(8),0(%r14)
 1:     tm      __LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
        jno     mcck_int_main           # no -> skip cleanup critical
        tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
@@ -794,16 +788,19 @@ mcck_int_main:
        srag    %r14,%r14,PAGE_SHIFT
        jz      0f
        lg      %r15,__LC_PANIC_STACK   # load panic stack
-0:     CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64
+0:     aghi    %r15,-SP_SIZE           # make room for registers & psw
+       CREATE_STACK_FRAME __LC_SAVE_AREA+80
+       mvc     SP_PSW(16,%r15),0(%r12)
+       lg      %r12,__LC_THREAD_INFO   # load pointer to thread_info struct
        tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
        jno     mcck_no_vtime           # no -> no timer update
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      mcck_no_vtime
-       UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+       UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
-       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
+       LAST_BREAK
 mcck_no_vtime:
-       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
        brasl   %r14,s390_do_machine_check
        tm      SP_PSW+1(%r15),0x01     # returning to user ?
@@ -814,8 +811,9 @@ mcck_no_vtime:
        xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
        lgr     %r15,%r1
        stosm   __SF_EMPTY(%r15),0x04   # turn dat on
-       tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
+       tm      __TI_flags+7(%r12),_TIF_MCCK_PENDING
        jno     mcck_return
+       HANDLE_SIE_INTERCEPT
        TRACE_IRQS_OFF
        brasl   %r14,s390_handle_mcck
        TRACE_IRQS_ON
@@ -823,11 +821,11 @@ mcck_return:
        mvc     __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
        ni      __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
        lmg     %r0,%r15,SP_R0(%r15)    # load gprs 0-15
-       mvc     __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104
        tm      __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
        jno     0f
        stpt    __LC_EXIT_TIMER
 0:     lpswe   __LC_RETURN_MCCK_PSW    # back to caller
+mcck_done:
 
 /*
  * Restart interruption handler, kick starter for additional CPUs
@@ -883,14 +881,14 @@ stack_overflow:
        lg      %r15,__LC_PANIC_STACK   # change to panic stack
        aghi    %r15,-SP_SIZE
        mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
-       stmg    %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
+       stmg    %r0,%r10,SP_R0(%r15)    # store gprs %r0-%r10 to kernel stack
        la      %r1,__LC_SAVE_AREA
        chi     %r12,__LC_SVC_OLD_PSW
        je      0f
        chi     %r12,__LC_PGM_OLD_PSW
        je      0f
-       la      %r1,__LC_SAVE_AREA+32
-0:     mvc     SP_R12(32,%r15),0(%r1)  # move %r12-%r15 to stack
+       la      %r1,__LC_SAVE_AREA+40
+0:     mvc     SP_R11(40,%r15),0(%r1)  # move %r11-%r15 to stack
        mvc     SP_ARGS(8,%r15),__LC_LAST_BREAK
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
        la      %r2,SP_PTREGS(%r15)     # load pt_regs
@@ -899,18 +897,14 @@ stack_overflow:
 
 cleanup_table_system_call:
        .quad   system_call, sysc_do_svc
-cleanup_table_sysc_return:
-       .quad   sysc_return, sysc_leave
-cleanup_table_sysc_leave:
-       .quad   sysc_leave, sysc_done
-cleanup_table_sysc_work_loop:
-       .quad   sysc_work_loop, sysc_work_done
-cleanup_table_io_return:
-       .quad   io_return, io_leave
-cleanup_table_io_leave:
-       .quad   io_leave, io_done
-cleanup_table_io_work_loop:
-       .quad   io_work_loop, io_work_done
+cleanup_table_sysc_tif:
+       .quad   sysc_tif, sysc_restore
+cleanup_table_sysc_restore:
+       .quad   sysc_restore, sysc_done
+cleanup_table_io_tif:
+       .quad   io_tif, io_restore
+cleanup_table_io_restore:
+       .quad   io_restore, io_done
 
 cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_system_call)
@@ -918,61 +912,54 @@ cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_system_call+8)
        jl      cleanup_system_call
 0:
-       clc     8(8,%r12),BASED(cleanup_table_sysc_return)
-       jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_sysc_return+8)
-       jl      cleanup_sysc_return
-0:
-       clc     8(8,%r12),BASED(cleanup_table_sysc_leave)
+       clc     8(8,%r12),BASED(cleanup_table_sysc_tif)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_sysc_leave+8)
-       jl      cleanup_sysc_leave
+       clc     8(8,%r12),BASED(cleanup_table_sysc_tif+8)
+       jl      cleanup_sysc_tif
 0:
-       clc     8(8,%r12),BASED(cleanup_table_sysc_work_loop)
+       clc     8(8,%r12),BASED(cleanup_table_sysc_restore)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
-       jl      cleanup_sysc_return
+       clc     8(8,%r12),BASED(cleanup_table_sysc_restore+8)
+       jl      cleanup_sysc_restore
 0:
-       clc     8(8,%r12),BASED(cleanup_table_io_return)
+       clc     8(8,%r12),BASED(cleanup_table_io_tif)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_io_return+8)
-       jl      cleanup_io_return
+       clc     8(8,%r12),BASED(cleanup_table_io_tif+8)
+       jl      cleanup_io_tif
 0:
-       clc     8(8,%r12),BASED(cleanup_table_io_leave)
+       clc     8(8,%r12),BASED(cleanup_table_io_restore)
        jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_io_leave+8)
-       jl      cleanup_io_leave
-0:
-       clc     8(8,%r12),BASED(cleanup_table_io_work_loop)
-       jl      0f
-       clc     8(8,%r12),BASED(cleanup_table_io_work_loop+8)
-       jl      cleanup_io_work_loop
+       clc     8(8,%r12),BASED(cleanup_table_io_restore+8)
+       jl      cleanup_io_restore
 0:
        br      %r14
 
 cleanup_system_call:
        mvc     __LC_RETURN_PSW(16),0(%r12)
-       cghi    %r12,__LC_MCK_OLD_PSW
-       je      0f
-       la      %r12,__LC_SAVE_AREA+32
-       j       1f
-0:     la      %r12,__LC_SAVE_AREA+64
-1:
        clc     __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8)
        jh      0f
+       mvc     __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
+       cghi    %r12,__LC_MCK_OLD_PSW
+       je      0f
        mvc     __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
+0:     cghi    %r12,__LC_MCK_OLD_PSW
+       la      %r12,__LC_SAVE_AREA+80
+       je      0f
+       la      %r12,__LC_SAVE_AREA+40
 0:     clc     __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16)
        jhe     cleanup_vtime
        clc     __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
        jh      0f
-       mvc     __LC_SAVE_AREA(32),0(%r12)
-0:     stg     %r13,8(%r12)
-       stg     %r12,__LC_SAVE_AREA+96  # argh
-       SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
-       lg      %r12,__LC_SAVE_AREA+96  # argh
-       stg     %r15,24(%r12)
-       llgh    %r7,__LC_SVC_INT_CODE
+       mvc     __LC_SAVE_AREA(40),0(%r12)
+0:     lg      %r15,__LC_KERNEL_STACK  # problem state -> load ksp
+       aghi    %r15,-SP_SIZE           # make room for registers & psw
+       stg     %r15,32(%r12)
+       stg     %r11,0(%r12)
+       CREATE_STACK_FRAME __LC_SAVE_AREA
+       mvc     SP_PSW(16,%r15),__LC_SVC_OLD_PSW
+       mvc     SP_ILC(4,%r15),__LC_SVC_ILC
+       stg     %r7,SP_ARGS(%r15)
+       mvc     8(8,%r12),__LC_THREAD_INFO
 cleanup_vtime:
        clc     __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
        jhe     cleanup_stime
@@ -983,7 +970,11 @@ cleanup_stime:
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
 cleanup_update:
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
-       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
+       srag    %r12,%r11,23
+       lg      %r12,__LC_THREAD_INFO
+       jz      0f
+       stg     %r11,__TI_last_break(%r12)
+0:     mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 cleanup_system_call_insn:
@@ -993,61 +984,54 @@ cleanup_system_call_insn:
        .quad   sysc_stime
        .quad   sysc_update
 
-cleanup_sysc_return:
+cleanup_sysc_tif:
        mvc     __LC_RETURN_PSW(8),0(%r12)
-       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_return)
+       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_sysc_leave:
-       clc     8(8,%r12),BASED(cleanup_sysc_leave_insn)
-       je      3f
-       clc     8(8,%r12),BASED(cleanup_sysc_leave_insn+8)
+cleanup_sysc_restore:
+       clc     8(8,%r12),BASED(cleanup_sysc_restore_insn)
+       je      2f
+       clc     8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
        jhe     0f
+       mvc     __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
+       cghi    %r12,__LC_MCK_OLD_PSW
+       je      0f
        mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
 0:     mvc     __LC_RETURN_PSW(16),SP_PSW(%r15)
        cghi    %r12,__LC_MCK_OLD_PSW
-       jne     1f
-       mvc     __LC_SAVE_AREA+64(32),SP_R12(%r15)
-       j       2f
-1:     mvc     __LC_SAVE_AREA+32(32),SP_R12(%r15)
-2:     lmg     %r0,%r11,SP_R0(%r15)
+       la      %r12,__LC_SAVE_AREA+80
+       je      1f
+       la      %r12,__LC_SAVE_AREA+40
+1:     mvc     0(40,%r12),SP_R11(%r15)
+       lmg     %r0,%r10,SP_R0(%r15)
        lg      %r15,SP_R15(%r15)
-3:     la      %r12,__LC_RETURN_PSW
+2:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_sysc_leave_insn:
+cleanup_sysc_restore_insn:
        .quad   sysc_done - 4
        .quad   sysc_done - 16
 
-cleanup_io_return:
-       mvc     __LC_RETURN_PSW(8),0(%r12)
-       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
-       la      %r12,__LC_RETURN_PSW
-       br      %r14
-
-cleanup_io_work_loop:
+cleanup_io_tif:
        mvc     __LC_RETURN_PSW(8),0(%r12)
-       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
+       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
        la      %r12,__LC_RETURN_PSW
        br      %r14
 
-cleanup_io_leave:
-       clc     8(8,%r12),BASED(cleanup_io_leave_insn)
-       je      3f
-       clc     8(8,%r12),BASED(cleanup_io_leave_insn+8)
+cleanup_io_restore:
+       clc     8(8,%r12),BASED(cleanup_io_restore_insn)
+       je      1f
+       clc     8(8,%r12),BASED(cleanup_io_restore_insn+8)
        jhe     0f
-       mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       mvc     __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
 0:     mvc     __LC_RETURN_PSW(16),SP_PSW(%r15)
-       cghi    %r12,__LC_MCK_OLD_PSW
-       jne     1f
-       mvc     __LC_SAVE_AREA+64(32),SP_R12(%r15)
-       j       2f
-1:     mvc     __LC_SAVE_AREA+32(32),SP_R12(%r15)
-2:     lmg     %r0,%r11,SP_R0(%r15)
+       mvc     __LC_SAVE_AREA+80(40),SP_R11(%r15)
+       lmg     %r0,%r10,SP_R0(%r15)
        lg      %r15,SP_R15(%r15)
-3:     la      %r12,__LC_RETURN_PSW
+1:     la      %r12,__LC_RETURN_PSW
        br      %r14
-cleanup_io_leave_insn:
+cleanup_io_restore_insn:
        .quad   io_done - 4
        .quad   io_done - 16
 
@@ -1055,13 +1039,6 @@ cleanup_io_leave_insn:
  * Integer constants
  */
                .align  4
-.Lconst:
-.Lnr_syscalls: .long   NR_syscalls
-.L0x0130:      .short  0x130
-.L0x0140:      .short  0x140
-.L0x0150:      .short  0x150
-.L0x0160:      .short  0x160
-.L0x0170:      .short  0x170
 .Lcritical_start:
                .quad   __critical_start
 .Lcritical_end:
index 9d1f767..51838ad 100644 (file)
@@ -328,8 +328,8 @@ iplstart:
 #
 # reset files in VM reader
 #
-       stidp   __LC_CPUID              # store cpuid
-       tm      __LC_CPUID,0xff         # running VM ?
+       stidp   __LC_SAVE_AREA          # store cpuid
+       tm      __LC_SAVE_AREA,0xff     # running VM ?
        bno     .Lnoreset
        la      %r2,.Lreset
        lhi     %r3,26
index 1bbcc49..b8f8dc1 100644 (file)
@@ -82,7 +82,7 @@ startup_continue:
 _ehead:
 
 #ifdef CONFIG_SHARED_KERNEL
-       .org    0x100000
+       .org    0x100000 - 0x11000      # head.o ends at 0x11000
 #endif
 
 #
index 1f70970..cdef687 100644 (file)
@@ -80,7 +80,7 @@ startup_continue:
 _ehead:
 
 #ifdef CONFIG_SHARED_KERNEL
-       .org    0x100000
+       .org    0x100000 - 0x11000      # head.o ends at 0x11000
 #endif
 
 #
index 015e27d..ac15139 100644 (file)
@@ -255,7 +255,8 @@ void notrace s390_do_machine_check(struct pt_regs *regs)
        int umode;
 
        nmi_enter();
-       s390_idle_check();
+       s390_idle_check(regs, S390_lowcore.mcck_clock,
+                       S390_lowcore.mcck_enter_timer);
 
        mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
        mcck = &__get_cpu_var(cpu_mcck);
index 0729f36..ecb2d02 100644 (file)
 #include <asm/lowcore.h>
 #include <asm/param.h>
 
+static DEFINE_PER_CPU(struct cpuid, cpu_id);
+
+/*
+ * cpu_init - initializes state that is per-CPU.
+ */
+void __cpuinit cpu_init(void)
+{
+       struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
+
+       get_cpu_id(id);
+       atomic_inc(&init_mm.mm_count);
+       current->active_mm = &init_mm;
+       BUG_ON(current->mm);
+       enter_lazy_tlb(&init_mm, current);
+}
+
+/*
+ * print_cpu_info - print basic information about a cpu
+ */
 void __cpuinit print_cpu_info(void)
 {
+       struct cpuid *id = &per_cpu(cpu_id, smp_processor_id());
+
        pr_info("Processor %d started, address %d, identification %06X\n",
-               S390_lowcore.cpu_nr, S390_lowcore.cpu_addr,
-               S390_lowcore.cpu_id.ident);
+               S390_lowcore.cpu_nr, S390_lowcore.cpu_addr, id->ident);
 }
 
 /*
  * show_cpuinfo - Get information on one CPU for use by procfs.
  */
-
 static int show_cpuinfo(struct seq_file *m, void *v)
 {
        static const char *hwcap_str[10] = {
                "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
                "edat", "etf3eh", "highgprs"
        };
-       struct _lowcore *lc;
        unsigned long n = (unsigned long) v - 1;
        int i;
 
@@ -55,19 +73,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
        }
 
        if (cpu_online(n)) {
-#ifdef CONFIG_SMP
-               lc = (smp_processor_id() == n) ?
-                       &S390_lowcore : lowcore_ptr[n];
-#else
-               lc = &S390_lowcore;
-#endif
+               struct cpuid *id = &per_cpu(cpu_id, n);
                seq_printf(m, "processor %li: "
                           "version = %02X,  "
                           "identification = %06X,  "
                           "machine = %04X\n",
-                          n, lc->cpu_id.version,
-                          lc->cpu_id.ident,
-                          lc->cpu_id.machine);
+                          n, id->version, id->ident, id->machine);
        }
        preempt_enable();
        return 0;
index 33fdc5a..83339d3 100644 (file)
@@ -57,6 +57,7 @@
 enum s390_regset {
        REGSET_GENERAL,
        REGSET_FP,
+       REGSET_LAST_BREAK,
        REGSET_GENERAL_EXTENDED,
 };
 
@@ -381,6 +382,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        copied += sizeof(unsigned long);
                }
                return 0;
+       case PTRACE_GET_LAST_BREAK:
+               put_user(task_thread_info(child)->last_break,
+                        (unsigned long __user *) data);
+               return 0;
        default:
                /* Removing high order bit from addr (only for 31 bit). */
                addr &= PSW_ADDR_INSN;
@@ -633,6 +638,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        copied += sizeof(unsigned int);
                }
                return 0;
+       case PTRACE_GET_LAST_BREAK:
+               put_user(task_thread_info(child)->last_break,
+                        (unsigned int __user *) data);
+               return 0;
        }
        return compat_ptrace_request(child, request, addr, data);
 }
@@ -640,7 +649,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
-       long ret;
+       long ret = 0;
 
        /* Do the secure computing check first. */
        secure_computing(regs->gprs[2]);
@@ -649,7 +658,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
         * The sysc_tracesys code in entry.S stored the system
         * call number to gprs[2].
         */
-       ret = regs->gprs[2];
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
            (tracehook_report_syscall_entry(regs) ||
             regs->gprs[2] >= NR_syscalls)) {
@@ -671,7 +679,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                                    regs->gprs[2], regs->orig_gpr2,
                                    regs->gprs[3], regs->gprs[4],
                                    regs->gprs[5]);
-       return ret;
+       return ret ?: regs->gprs[2];
 }
 
 asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
@@ -798,6 +806,28 @@ static int s390_fpregs_set(struct task_struct *target,
        return rc;
 }
 
+#ifdef CONFIG_64BIT
+
+static int s390_last_break_get(struct task_struct *target,
+                              const struct user_regset *regset,
+                              unsigned int pos, unsigned int count,
+                              void *kbuf, void __user *ubuf)
+{
+       if (count > 0) {
+               if (kbuf) {
+                       unsigned long *k = kbuf;
+                       *k = task_thread_info(target)->last_break;
+               } else {
+                       unsigned long  __user *u = ubuf;
+                       if (__put_user(task_thread_info(target)->last_break, u))
+                               return -EFAULT;
+               }
+       }
+       return 0;
+}
+
+#endif
+
 static const struct user_regset s390_regsets[] = {
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
@@ -815,6 +845,15 @@ static const struct user_regset s390_regsets[] = {
                .get = s390_fpregs_get,
                .set = s390_fpregs_set,
        },
+#ifdef CONFIG_64BIT
+       [REGSET_LAST_BREAK] = {
+               .core_note_type = NT_S390_LAST_BREAK,
+               .n = 1,
+               .size = sizeof(long),
+               .align = sizeof(long),
+               .get = s390_last_break_get,
+       },
+#endif
 };
 
 static const struct user_regset_view user_s390_view = {
@@ -949,6 +988,27 @@ static int s390_compat_regs_high_set(struct task_struct *target,
        return rc;
 }
 
+static int s390_compat_last_break_get(struct task_struct *target,
+                                     const struct user_regset *regset,
+                                     unsigned int pos, unsigned int count,
+                                     void *kbuf, void __user *ubuf)
+{
+       compat_ulong_t last_break;
+
+       if (count > 0) {
+               last_break = task_thread_info(target)->last_break;
+               if (kbuf) {
+                       unsigned long *k = kbuf;
+                       *k = last_break;
+               } else {
+                       unsigned long  __user *u = ubuf;
+                       if (__put_user(last_break, u))
+                               return -EFAULT;
+               }
+       }
+       return 0;
+}
+
 static const struct user_regset s390_compat_regsets[] = {
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
@@ -966,6 +1026,13 @@ static const struct user_regset s390_compat_regsets[] = {
                .get = s390_fpregs_get,
                .set = s390_fpregs_set,
        },
+       [REGSET_LAST_BREAK] = {
+               .core_note_type = NT_S390_LAST_BREAK,
+               .n = 1,
+               .size = sizeof(long),
+               .align = sizeof(long),
+               .get = s390_compat_last_break_get,
+       },
        [REGSET_GENERAL_EXTENDED] = {
                .core_note_type = NT_S390_HIGH_GPRS,
                .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
index 59618bc..9ce641b 100644 (file)
@@ -120,7 +120,8 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
        struct pt_regs *old_regs;
 
        old_regs = set_irq_regs(regs);
-       s390_idle_check();
+       s390_idle_check(regs, S390_lowcore.int_clock,
+                       S390_lowcore.async_enter_timer);
        irq_enter();
        if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
                /* Serve timer interrupts first. */
index 91625f7..7d89324 100644 (file)
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/setup.c
  *
  *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) IBM Corp. 1999,2010
  *    Author(s): Hartmut Penner (hp@de.ibm.com),
  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  *
@@ -112,22 +112,6 @@ static struct resource data_resource = {
        .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
 };
 
-/*
- * cpu_init() initializes state that is per-CPU.
- */
-void __cpuinit cpu_init(void)
-{
-        /*
-         * Store processor id in lowcore (used e.g. in timer_interrupt)
-         */
-       get_cpu_id(&S390_lowcore.cpu_id);
-
-       atomic_inc(&init_mm.mm_count);
-       current->active_mm = &init_mm;
-       BUG_ON(current->mm);
-        enter_lazy_tlb(&init_mm, current);
-}
-
 /*
  * condev= and conmode= setup parameter.
  */
@@ -385,10 +369,6 @@ static void setup_addressing_mode(void)
                        pr_info("Address spaces switched, "
                                "mvcos not available\n");
        }
-#ifdef CONFIG_TRACE_IRQFLAGS
-       sysc_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
-       io_restore_trace_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
-#endif
 }
 
 static void __init
@@ -421,6 +401,7 @@ setup_lowcore(void)
        lc->io_new_psw.mask = psw_kernel_bits;
        lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
        lc->clock_comparator = -1ULL;
+       lc->cmf_hpp = -1ULL;
        lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
        lc->async_stack = (unsigned long)
                __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
@@ -695,6 +676,7 @@ static void __init setup_hwcaps(void)
        static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
        unsigned long long facility_list_extended;
        unsigned int facility_list;
+       struct cpuid cpu_id;
        int i;
 
        facility_list = stfl();
@@ -756,7 +738,8 @@ static void __init setup_hwcaps(void)
         */
        elf_hwcap |= HWCAP_S390_HIGH_GPRS;
 
-       switch (S390_lowcore.cpu_id.machine) {
+       get_cpu_id(&cpu_id);
+       switch (cpu_id.machine) {
        case 0x9672:
 #if !defined(CONFIG_64BIT)
        default:        /* Use "g5" as default for 31 bit kernels. */
index 6289945..ee7ac8b 100644 (file)
@@ -313,6 +313,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
           To avoid breaking binary compatibility, they are passed as args. */
        regs->gprs[4] = current->thread.trap_no;
        regs->gprs[5] = current->thread.prot_addr;
+       regs->gprs[6] = task_thread_info(current)->last_break;
 
        /* Place signal number on stack to allow backtrace from handler.  */
        if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
@@ -376,6 +377,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->gprs[2] = map_signal(sig);
        regs->gprs[3] = (unsigned long) &frame->info;
        regs->gprs[4] = (unsigned long) &frame->uc;
+       regs->gprs[5] = task_thread_info(current)->last_break;
        return 0;
 
 give_sigsegv:
index b354427..c56d3f5 100644 (file)
@@ -256,6 +256,9 @@ restore_registers:
        lghi    %r2,0
        brasl   %r14,arch_set_page_states
 
+       /* Reinitialize the channel subsystem */
+       brasl   %r14,channel_subsystem_reinit
+
        /* Return 0 */
        lmg     %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
        lghi    %r2,0
index fba6dec..a2163c9 100644 (file)
@@ -221,6 +221,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
        vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
        vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
        vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+       vdso_data->ntp_mult = mult;
        smp_wmb();
        ++vdso_data->tb_update_count;
 }
@@ -390,7 +391,6 @@ static void __init time_init_wq(void)
        if (time_sync_wq)
                return;
        time_sync_wq = create_singlethread_workqueue("timesync");
-       stop_machine_create();
 }
 
 /*
index 247b4c2..bcef007 100644 (file)
@@ -37,7 +37,8 @@ struct tl_cpu {
 };
 
 struct tl_container {
-       unsigned char reserved[8];
+       unsigned char reserved[7];
+       unsigned char id;
 };
 
 union tl_entry {
@@ -58,6 +59,7 @@ struct tl_info {
 
 struct core_info {
        struct core_info *next;
+       unsigned char id;
        cpumask_t mask;
 };
 
@@ -73,6 +75,7 @@ static DECLARE_WORK(topology_work, topology_work_fn);
 static DEFINE_SPINLOCK(topology_lock);
 
 cpumask_t cpu_core_map[NR_CPUS];
+unsigned char cpu_core_id[NR_CPUS];
 
 static cpumask_t cpu_coregroup_map(unsigned int cpu)
 {
@@ -116,6 +119,7 @@ static void add_cpus_to_core(struct tl_cpu *tl_cpu, struct core_info *core)
                for_each_present_cpu(lcpu) {
                        if (cpu_logical_map(lcpu) == rcpu) {
                                cpu_set(lcpu, core->mask);
+                               cpu_core_id[lcpu] = core->id;
                                smp_cpu_polarization[lcpu] = tl_cpu->pp;
                        }
                }
@@ -158,6 +162,7 @@ static void tl_to_cores(struct tl_info *info)
                        break;
                case 1:
                        core = core->next;
+                       core->id = tle->container.id;
                        break;
                case 0:
                        add_cpus_to_core(&tle->cpu, core);
index 6e7ad63..5d8f0f3 100644 (file)
 
 pgm_check_handler_t *pgm_check_table[128];
 
-#ifdef CONFIG_SYSCTL
-#ifdef CONFIG_PROCESS_DEBUG
-int sysctl_userprocess_debug = 1;
-#else
-int sysctl_userprocess_debug = 0;
-#endif
-#endif
+int show_unhandled_signals;
 
 extern pgm_check_handler_t do_protection_exception;
 extern pgm_check_handler_t do_dat_exception;
@@ -315,18 +309,19 @@ void die(const char * str, struct pt_regs * regs, long err)
        do_exit(SIGSEGV);
 }
 
-static void inline
-report_user_fault(long interruption_code, struct pt_regs *regs)
+static void inline report_user_fault(struct pt_regs *regs, long int_code,
+                                    int signr)
 {
-#if defined(CONFIG_SYSCTL)
-       if (!sysctl_userprocess_debug)
+       if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
                return;
-#endif
-#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
-       printk("User process fault: interruption code 0x%lX\n",
-              interruption_code);
+       if (!unhandled_signal(current, signr))
+               return;
+       if (!printk_ratelimit())
+               return;
+       printk("User process fault: interruption code 0x%lX ", int_code);
+       print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
+       printk("\n");
        show_regs(regs);
-#endif
 }
 
 int is_valid_bugaddr(unsigned long addr)
@@ -354,7 +349,7 @@ static void __kprobes inline do_trap(long interruption_code, int signr,
 
                 tsk->thread.trap_no = interruption_code & 0xffff;
                force_sig_info(signr, info, tsk);
-               report_user_fault(interruption_code, regs);
+               report_user_fault(regs, interruption_code, signr);
         } else {
                 const struct exception_table_entry *fixup;
                 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -390,8 +385,8 @@ static void default_trap_handler(struct pt_regs * regs, long interruption_code)
 {
         if (regs->psw.mask & PSW_MASK_PSTATE) {
                local_irq_enable();
+               report_user_fault(regs, interruption_code, SIGSEGV);
                do_exit(SIGSEGV);
-               report_user_fault(interruption_code, regs);
        } else
                die("Unknown program exception", regs, interruption_code);
 }
index 6bc9c19..6b83870 100644 (file)
@@ -102,11 +102,7 @@ static void vdso_init_per_cpu_data(int cpu, struct vdso_per_cpu_data *vpcd)
 /*
  * Allocate/free per cpu vdso data.
  */
-#ifdef CONFIG_64BIT
 #define SEGMENT_ORDER  2
-#else
-#define SEGMENT_ORDER  1
-#endif
 
 int vdso_alloc_per_cpu(int cpu, struct _lowcore *lowcore)
 {
index 4a98909..9696439 100644 (file)
@@ -38,13 +38,13 @@ __kernel_clock_gettime:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,2f
        ahi     %r0,-1
-2:     mhi     %r0,1000                        /* cyc2ns(clock,cycle_delta) */
+2:     ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
        lr      %r2,%r0
-       lhi     %r0,1000
+       l       %r0,__VDSO_NTP_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     3f
-       ahi     %r0,1000
+       a       %r0,__VDSO_NTP_MULT(%r5)
 3:     alr     %r0,%r2
        srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
@@ -86,13 +86,13 @@ __kernel_clock_gettime:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,12f
        ahi     %r0,-1
-12:    mhi     %r0,1000                        /* cyc2ns(clock,cycle_delta) */
+12:    ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
        lr      %r2,%r0
-       lhi     %r0,1000
+       l       %r0,__VDSO_NTP_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     13f
-       ahi     %r0,1000
+       a       %r0,__VDSO_NTP_MULT(%r5)
 13:    alr     %r0,%r2
        srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
index ad8acfc..2d36331 100644 (file)
@@ -35,13 +35,13 @@ __kernel_gettimeofday:
        sl      %r1,__VDSO_XTIME_STAMP+4(%r5)
        brc     3,3f
        ahi     %r0,-1
-3:     mhi     %r0,1000                        /* cyc2ns(clock,cycle_delta) */
+3:     ms      %r0,__VDSO_NTP_MULT(%r5)        /* cyc2ns(clock,cycle_delta) */
        st      %r0,24(%r15)
-       lhi     %r0,1000
+       l       %r0,__VDSO_NTP_MULT(%r5)
        ltr     %r1,%r1
        mr      %r0,%r0
        jnm     4f
-       ahi     %r0,1000
+       a       %r0,__VDSO_NTP_MULT(%r5)
 4:     al      %r0,24(%r15)
        srdl    %r0,12
        al      %r0,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
index 49106c6..f404678 100644 (file)
@@ -36,7 +36,7 @@ __kernel_clock_gettime:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       mghi    %r1,1000
+       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
        srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
        lg      %r0,__VDSO_XTIME_SEC(%r5)
@@ -64,7 +64,7 @@ __kernel_clock_gettime:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       mghi    %r1,1000
+       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
        srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime */
        lg      %r0,__VDSO_XTIME_SEC(%r5)
index f873e75..36ee674 100644 (file)
@@ -31,7 +31,7 @@ __kernel_gettimeofday:
        stck    48(%r15)                        /* Store TOD clock */
        lg      %r1,48(%r15)
        sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
-       mghi    %r1,1000
+       msgf    %r1,__VDSO_NTP_MULT(%r5)        /*  * NTP adjustment */
        srlg    %r1,%r1,12                      /* cyc2ns(clock,cycle_delta) */
        alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + xtime.tv_nsec */
        lg      %r0,__VDSO_XTIME_SEC(%r5)       /* xtime.tv_sec */
index b59a812..3479f1b 100644 (file)
@@ -121,32 +121,35 @@ void account_system_vtime(struct task_struct *tsk)
 }
 EXPORT_SYMBOL_GPL(account_system_vtime);
 
-void vtime_start_cpu(void)
+void vtime_start_cpu(__u64 int_clock, __u64 enter_timer)
 {
        struct s390_idle_data *idle = &__get_cpu_var(s390_idle);
        struct vtimer_queue *vq = &__get_cpu_var(virt_cpu_timer);
        __u64 idle_time, expires;
 
+       if (idle->idle_enter == 0ULL)
+               return;
+
        /* Account time spent with enabled wait psw loaded as idle time. */
-       idle_time = S390_lowcore.int_clock - idle->idle_enter;
+       idle_time = int_clock - idle->idle_enter;
        account_idle_time(idle_time);
        S390_lowcore.steal_timer +=
                idle->idle_enter - S390_lowcore.last_update_clock;
-       S390_lowcore.last_update_clock = S390_lowcore.int_clock;
+       S390_lowcore.last_update_clock = int_clock;
 
        /* Account system time spent going idle. */
        S390_lowcore.system_timer += S390_lowcore.last_update_timer - vq->idle;
-       S390_lowcore.last_update_timer = S390_lowcore.async_enter_timer;
+       S390_lowcore.last_update_timer = enter_timer;
 
        /* Restart vtime CPU timer */
        if (vq->do_spt) {
                /* Program old expire value but first save progress. */
-               expires = vq->idle - S390_lowcore.async_enter_timer;
+               expires = vq->idle - enter_timer;
                expires += get_vtimer();
                set_vtimer(expires);
        } else {
                /* Don't account the CPU timer delta while the cpu was idle. */
-               vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer;
+               vq->elapsed -= vq->idle - enter_timer;
        }
 
        idle->sequence++;
index a725158..2f4b687 100644 (file)
@@ -33,6 +33,17 @@ config KVM
 
          If unsure, say N.
 
+config KVM_AWARE_CMF
+       depends on KVM
+       bool "KVM aware sampling"
+       ---help---
+         This option enhances the sampling data from the CPU Measurement
+         Facility with additional information, that allows to distinguish
+         guest(s) and host when using the kernel based virtual machine
+         functionality.
+
+         If unsure, say N.
+
 # OK, it's a little counter-intuitive to do this, but it puts it neatly under
 # the virtualization menu.
 source drivers/vhost/Kconfig
index 934fd6a..31646bd 100644 (file)
@@ -1,20 +1,60 @@
 /*
  * sie64a.S - low level sie call
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2010
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
  * as published by the Free Software Foundation.
  *
  *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ *              Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
  */
 
 #include <linux/errno.h>
 #include <asm/asm-offsets.h>
+#include <asm/setup.h>
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+
+_TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
+
+/*
+ * offsets into stackframe
+ * SP_ = offsets into stack sie64 is called with
+ * SPI_ = offsets into irq stack
+ */
+SP_GREGS = __SF_EMPTY
+SP_HOOK  = __SF_EMPTY+8
+SP_GPP  = __SF_EMPTY+16
+SPI_PSW  = STACK_FRAME_OVERHEAD + __PT_PSW
+
 
-SP_R5 =        5 * 8   # offset into stackframe
-SP_R6 =        6 * 8
+       .macro SPP newpp
+#ifdef CONFIG_KVM_AWARE_CMF
+       tm      __LC_MACHINE_FLAGS+6,0x20       # MACHINE_FLAG_SPP
+       jz      0f
+       .insn   s,0xb2800000,\newpp
+       0:
+#endif
+       .endm
+
+sie_irq_handler:
+       SPP     __LC_CMF_HPP                    # set host id
+       larl    %r2,sie_inst
+       clg     %r2,SPI_PSW+8(0,%r15)           # intercepted sie
+       jne     1f
+       xc      __LC_SIE_HOOK(8),__LC_SIE_HOOK
+       lg      %r2,__LC_THREAD_INFO            # pointer thread_info struct
+       tm      __TI_flags+7(%r2),_TIF_EXIT_SIE
+       jz      0f
+       larl    %r2,sie_exit                    # work pending, leave sie
+       stg     %r2,__LC_RETURN_PSW+8
+       br      %r14
+0:     larl    %r2,sie_reenter                 # re-enter with guest id
+       stg     %r2,__LC_RETURN_PSW+8
+1:     br      %r14
 
 /*
  * sie64a calling convention:
@@ -23,23 +63,34 @@ SP_R6 =     6 * 8
  */
        .globl  sie64a
 sie64a:
-       lgr     %r5,%r3
-       stmg    %r5,%r14,SP_R5(%r15)    # save register on entry
-       lgr     %r14,%r2                # pointer to sie control block
-       lmg     %r0,%r13,0(%r3)         # load guest gprs 0-13
+       stg     %r3,SP_GREGS(%r15)              # save guest register save area
+       stmg    %r6,%r14,__SF_GPRS(%r15)        # save registers on entry
+       lgr     %r14,%r2                        # pointer to sie control block
+       larl    %r5,sie_irq_handler
+       stg     %r2,SP_GPP(%r15)
+       stg     %r5,SP_HOOK(%r15)               # save hook target
+       lmg     %r0,%r13,0(%r3)                 # load guest gprs 0-13
+sie_reenter:
+       mvc     __LC_SIE_HOOK(8),SP_HOOK(%r15)
+       SPP     SP_GPP(%r15)                    # set guest id
 sie_inst:
        sie     0(%r14)
-       lg      %r14,SP_R5(%r15)
-       stmg    %r0,%r13,0(%r14)        # save guest gprs 0-13
+       xc      __LC_SIE_HOOK(8),__LC_SIE_HOOK
+       SPP     __LC_CMF_HPP                    # set host id
+sie_exit:
+       lg      %r14,SP_GREGS(%r15)
+       stmg    %r0,%r13,0(%r14)                # save guest gprs 0-13
        lghi    %r2,0
-       lmg     %r6,%r14,SP_R6(%r15)
+       lmg     %r6,%r14,__SF_GPRS(%r15)
        br      %r14
 
 sie_err:
-       lg      %r14,SP_R5(%r15)
-       stmg    %r0,%r13,0(%r14)        # save guest gprs 0-13
+       xc      __LC_SIE_HOOK(8),__LC_SIE_HOOK
+       SPP     __LC_CMF_HPP                    # set host id
+       lg      %r14,SP_GREGS(%r15)
+       stmg    %r0,%r13,0(%r14)                # save guest gprs 0-13
        lghi    %r2,-EFAULT
-       lmg     %r6,%r14,SP_R6(%r15)
+       lmg     %r6,%r14,__SF_GPRS(%r15)
        br      %r14
 
        .section __ex_table,"a"
index 3040d7c..2505b2e 100644 (file)
 #define __PF_RES_FIELD 0x8000000000000000ULL
 #endif /* CONFIG_64BIT */
 
-#ifdef CONFIG_SYSCTL
-extern int sysctl_userprocess_debug;
-#endif
-
 #define VM_FAULT_BADCONTEXT    0x010000
 #define VM_FAULT_BADMAP                0x020000
 #define VM_FAULT_BADACCESS     0x040000
@@ -120,6 +116,22 @@ static inline int user_space_fault(unsigned long trans_exc_code)
        return trans_exc_code != 3;
 }
 
+static inline void report_user_fault(struct pt_regs *regs, long int_code,
+                                    int signr, unsigned long address)
+{
+       if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
+               return;
+       if (!unhandled_signal(current, signr))
+               return;
+       if (!printk_ratelimit())
+               return;
+       printk("User process fault: interruption code 0x%lX ", int_code);
+       print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
+       printk("\n");
+       printk("failing address: %lX\n", address);
+       show_regs(regs);
+}
+
 /*
  * Send SIGSEGV to task.  This is an external routine
  * to keep the stack usage of do_page_fault small.
@@ -133,17 +145,7 @@ static noinline void do_sigsegv(struct pt_regs *regs, long int_code,
        address = trans_exc_code & __FAIL_ADDR_MASK;
        current->thread.prot_addr = address;
        current->thread.trap_no = int_code;
-#if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG)
-#if defined(CONFIG_SYSCTL)
-       if (sysctl_userprocess_debug)
-#endif
-       {
-               printk("User process fault: interruption code 0x%lX\n",
-                      int_code);
-               printk("failing address: %lX\n", address);
-               show_regs(regs);
-       }
-#endif
+       report_user_fault(regs, int_code, SIGSEGV, address);
        si.si_signo = SIGSEGV;
        si.si_code = si_code;
        si.si_addr = (void __user *) address;
index 8d90564..0e318c9 100644 (file)
@@ -44,6 +44,7 @@ config SUPERH32
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_ARCH_KGDB
        select HAVE_HW_BREAKPOINT
+       select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS if HAVE_HW_BREAKPOINT
        select ARCH_HIBERNATION_POSSIBLE if MMU
 
@@ -157,7 +158,6 @@ config LOCKDEP_SUPPORT
 
 config HAVE_LATENCYTOP_SUPPORT
        def_bool y
-       depends on !SMP
 
 config ARCH_HAS_ILOG2_U32
        def_bool n
@@ -237,6 +237,8 @@ config CPU_SHX2
 config CPU_SHX3
        bool
        select DMA_COHERENT
+       select SYS_SUPPORTS_SMP
+       select SYS_SUPPORTS_NUMA
 
 config ARCH_SHMOBILE
        bool
@@ -453,18 +455,12 @@ config CPU_SUBTYPE_SH7786
        select CPU_SH4A
        select CPU_SHX3
        select CPU_HAS_PTEAEX
-       select ARCH_SPARSEMEM_ENABLE
-       select SYS_SUPPORTS_NUMA
-       select SYS_SUPPORTS_SMP
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 
 config CPU_SUBTYPE_SHX3
        bool "Support SH-X3 processor"
        select CPU_SH4A
        select CPU_SHX3
-       select ARCH_SPARSEMEM_ENABLE
-       select SYS_SUPPORTS_NUMA
-       select SYS_SUPPORTS_SMP
        select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 
 # SH4AL-DSP Processor Support
@@ -634,7 +630,7 @@ config KEXEC
 
 config CRASH_DUMP
        bool "kernel crash dumps (EXPERIMENTAL)"
-       depends on SUPERH32 && EXPERIMENTAL
+       depends on SUPERH32 && EXPERIMENTAL && BROKEN_ON_SMP
        help
          Generate crash dump after being started by kexec.
          This should be normally only set in special crash dump kernels
@@ -706,6 +702,13 @@ config NR_CPUS
          This is purely to save memory - each supported CPU adds
          approximately eight kilobytes to the kernel image.
 
+config HOTPLUG_CPU
+       bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+       depends on SMP && HOTPLUG && EXPERIMENTAL
+       help
+         Say Y here to experiment with turning CPUs off and on.  CPUs
+         can be controlled through /sys/devices/system/cpu.
+
 source "kernel/Kconfig.preempt"
 
 config GUSA
@@ -732,6 +735,8 @@ config GUSA_RB
          LLSC, this should be more efficient than the other alternative of
          disabling interrupts around the atomic sequence.
 
+source "drivers/sh/Kconfig"
+
 endmenu
 
 menu "Boot options"
@@ -863,4 +868,20 @@ source "security/Kconfig"
 
 source "crypto/Kconfig"
 
+menuconfig VIRTUALIZATION
+       bool "Virtualization"
+       default n
+       ---help---
+         Say Y here to get to see options for using your Linux host to run other
+         operating systems inside virtual machines (guests).
+         This option alone does not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and disabled.
+
+if VIRTUALIZATION
+
+source drivers/virtio/Kconfig
+
+endif # VIRTUALIZATION
+
 source "lib/Kconfig"
index 588579a..307b3a4 100644 (file)
@@ -83,7 +83,6 @@ defaultimage-$(CONFIG_SH_AP325RXA)            := uImage
 defaultimage-$(CONFIG_SH_7724_SOLUTION_ENGINE) := uImage
 defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux
 defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux
-defaultimage-$(CONFIG_SH_SDK7786)              := vmlinux.bin
 
 # Set some sensible Kbuild defaults
 KBUILD_IMAGE           := $(defaultimage-y)
index a9bd6e3..d81c609 100644 (file)
@@ -24,6 +24,7 @@
 #include <cpu/sh7786.h>
 #include <asm/heartbeat.h>
 #include <asm/sizes.h>
+#include <asm/smp-ops.h>
 
 /*
  * bit  1234 5678
@@ -203,6 +204,8 @@ static void __init urquell_setup(char **cmdline_p)
        printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n");
 
        pm_power_off = urquell_power_off;
+
+       register_smp_ops(&shx3_smp_ops);
 }
 
 /*
index 6c13b92..6212388 100644 (file)
@@ -710,8 +710,6 @@ static struct clk_ops fsimck_clk_ops = {
 };
 
 static struct clk fsimckb_clk = {
-       .name           = "fsimckb_clk",
-       .id             = -1,
        .ops            = &fsimck_clk_ops,
        .enable_reg     = (void __iomem *)FCLKBCR,
        .rate           = 0, /* unknown */
@@ -1138,16 +1136,20 @@ static int __init arch_setup(void)
 
        /* set SPU2 clock to 83.4 MHz */
        clk = clk_get(NULL, "spu_clk");
-       clk_set_rate(clk, clk_round_rate(clk, 83333333));
-       clk_put(clk);
+       if (clk) {
+               clk_set_rate(clk, clk_round_rate(clk, 83333333));
+               clk_put(clk);
+       }
 
        /* change parent of FSI B */
        clk = clk_get(NULL, "fsib_clk");
-       clk_register(&fsimckb_clk);
-       clk_set_parent(clk, &fsimckb_clk);
-       clk_set_rate(clk, 11000);
-       clk_set_rate(&fsimckb_clk, 11000);
-       clk_put(clk);
+       if (clk) {
+               clk_register(&fsimckb_clk);
+               clk_set_parent(clk, &fsimckb_clk);
+               clk_set_rate(clk, 11000);
+               clk_set_rate(&fsimckb_clk, 11000);
+               clk_put(clk);
+       }
 
        gpio_request(GPIO_PTU0, NULL);
        gpio_direction_output(GPIO_PTU0, 0);
@@ -1159,8 +1161,10 @@ static int __init arch_setup(void)
 
        /* set VPU clock to 166 MHz */
        clk = clk_get(NULL, "vpu_clk");
-       clk_set_rate(clk, clk_round_rate(clk, 166000000));
-       clk_put(clk);
+       if (clk) {
+               clk_set_rate(clk, clk_round_rate(clk, 166000000));
+               clk_put(clk);
+       }
 
        /* enable IrDA */
        gpio_request(GPIO_FN_IRDA_OUT, NULL);
index affd667..a5ecfba 100644 (file)
@@ -14,6 +14,7 @@
  * for more details.
  */
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/types.h>
@@ -26,6 +27,7 @@
 #include <net/ax88796.h>
 #include <asm/machvec.h>
 #include <mach/highlander.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/heartbeat.h>
 #include <asm/io.h>
@@ -326,7 +328,6 @@ static struct clk_ops ivdr_clk_ops = {
 };
 
 static struct clk ivdr_clk = {
-       .name           = "ivdr_clk",
        .ops            = &ivdr_clk_ops,
 };
 
@@ -334,6 +335,13 @@ static struct clk *r7780rp_clocks[] = {
        &ivdr_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("ivdr_clk", &ivdr_clk),
+};
+
 static void r7780rp_power_off(void)
 {
        if (mach_is_r7780mp() || mach_is_r7785rp())
@@ -370,6 +378,8 @@ static void __init highlander_setup(char **cmdline_p)
                clk_enable(clk);
        }
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        __raw_writew(0x0000, PA_OBLED); /* Clear LED. */
 
        if (mach_is_r7780rp())
index f094ea2..2ec1ea5 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/heartbeat.h>
 #include <asm/sizes.h>
 #include <asm/reboot.h>
+#include <asm/smp-ops.h>
 
 static struct resource heartbeat_resource = {
        .start          = 0x07fff8b0,
@@ -165,6 +166,19 @@ static void sdk7786_restart(char *cmd)
        fpga_write_reg(0xa5a5, SRSTR);
 }
 
+static void sdk7786_power_off(void)
+{
+       fpga_write_reg(fpga_read_reg(PWRCR) | PWRCR_PDWNREQ, PWRCR);
+
+       /*
+        * It can take up to 20us for the R8C to do its job, back off and
+        * wait a bit until we've been shut off. Even though newer FPGA
+        * versions don't set the ACK bit, the latency issue remains.
+        */
+       while ((fpga_read_reg(PWRCR) & PWRCR_PDWNACK) == 0)
+               cpu_sleep();
+}
+
 /* Initialize the board */
 static void __init sdk7786_setup(char **cmdline_p)
 {
@@ -175,6 +189,9 @@ static void __init sdk7786_setup(char **cmdline_p)
        pr_info("\tPCB revision:\t%d\n", fpga_read_reg(PCBRR) & 0xf);
 
        machine_ops.restart = sdk7786_restart;
+       pm_power_off = sdk7786_power_off;
+
+       register_smp_ops(&shx3_smp_ops);
 }
 
 /*
index ccaa290..e74ae7b 100644 (file)
@@ -276,8 +276,6 @@ static struct clk_ops fsimck_clk_ops = {
 };
 
 static struct clk fsimcka_clk = {
-       .name           = "fsimcka_clk",
-       .id             = -1,
        .ops            = &fsimck_clk_ops,
        .enable_reg     = (void __iomem *)FCLKACR,
        .rate           = 0, /* unknown */
@@ -771,16 +769,20 @@ static int __init devices_setup(void)
 
        /* set SPU2 clock to 83.4 MHz */
        clk = clk_get(NULL, "spu_clk");
-       clk_set_rate(clk, clk_round_rate(clk, 83333333));
-       clk_put(clk);
+       if (clk) {
+               clk_set_rate(clk, clk_round_rate(clk, 83333333));
+               clk_put(clk);
+       }
 
        /* change parent of FSI A */
        clk = clk_get(NULL, "fsia_clk");
-       clk_register(&fsimcka_clk);
-       clk_set_parent(clk, &fsimcka_clk);
-       clk_set_rate(clk, 11000);
-       clk_set_rate(&fsimcka_clk, 11000);
-       clk_put(clk);
+       if (clk) {
+               clk_register(&fsimcka_clk);
+               clk_set_parent(clk, &fsimcka_clk);
+               clk_set_rate(clk, 11000);
+               clk_set_rate(&fsimcka_clk, 11000);
+               clk_put(clk);
+       }
 
        /* SDHI0 connected to cn7 */
        gpio_request(GPIO_FN_SDHI0CD, NULL);
index e284592..102bf56 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/usb/r8a66597.h>
 #include <linux/usb/m66592.h>
 #include <asm/ilsel.h>
+#include <asm/smp-ops.h>
 
 static struct resource heartbeat_resources[] = {
        [0] = {
@@ -152,7 +153,13 @@ static void __init x3proto_init_irq(void)
        __raw_writel(__raw_readl(0xfe410000) | (1 << 21), 0xfe410000);
 }
 
+static void __init x3proto_setup(char **cmdline_p)
+{
+       register_smp_ops(&shx3_smp_ops);
+}
+
 static struct sh_machine_vector mv_x3proto __initmv = {
        .mv_name                = "x3proto",
+       .mv_setup               = x3proto_setup,
        .mv_init_irq            = x3proto_init_irq,
 };
index 5d660b9..cfa5a08 100644 (file)
@@ -14,10 +14,16 @@ OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
 #
 # IMAGE_OFFSET is the load offset of the compression loader
 #
+ifeq ($(CONFIG_32BIT),y)
+IMAGE_OFFSET   := $(shell /bin/bash -c 'printf "0x%08x" \
+                    $$[$(CONFIG_MEMORY_START)  + \
+                       $(CONFIG_BOOT_LINK_OFFSET)]')
+else
 IMAGE_OFFSET   := $(shell /bin/bash -c 'printf "0x%08x" \
                     $$[$(CONFIG_PAGE_OFFSET)  + \
                        $(KERNEL_MEMORY) + \
                        $(CONFIG_BOOT_LINK_OFFSET)]')
+endif
 
 LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
index 02a3093..200c1d4 100644 (file)
@@ -97,7 +97,11 @@ init_stack_addr:
 decompress_kernel_addr:
        .long   decompress_kernel
 kernel_start_addr:
+#ifdef CONFIG_32BIT
+       .long   ___pa(_text+PAGE_SIZE)
+#else
        .long   _text+PAGE_SIZE
+#endif
 
        .align  9
 fake_headers_as_bzImage:
index 8931a60..7fefa2b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:10:59 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:04:35 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -107,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -116,13 +114,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -237,8 +235,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -246,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -261,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -335,7 +335,7 @@ CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -371,6 +371,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -378,7 +379,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -594,6 +594,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -613,6 +614,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -774,6 +776,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -802,6 +805,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -814,15 +818,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -853,13 +851,16 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -891,22 +892,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
@@ -1041,10 +1045,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
-# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1120,8 +1121,6 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1206,6 +1205,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1234,6 +1234,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1426,6 +1427,7 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 92589a9..edae0a6 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:14:50 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:01:02 2010
 #
 CONFIG_SUPERH=y
 # CONFIG_SUPERH32 is not set
@@ -13,7 +13,6 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
@@ -32,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 CONFIG_POSIX_MQUEUE=y
@@ -70,7 +72,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -114,7 +115,6 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
@@ -204,6 +204,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -225,7 +226,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -294,7 +295,6 @@ CONFIG_HZ=250
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -309,9 +309,9 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -337,7 +337,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -463,6 +462,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -480,6 +480,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -569,7 +570,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -638,6 +639,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -650,6 +653,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -732,6 +736,7 @@ CONFIG_DEVKMEM=y
 #
 # CONFIG_SERIAL_SH_SCI is not set
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -779,6 +784,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -791,15 +797,9 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -823,10 +823,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -863,6 +864,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -909,9 +911,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
-# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -919,6 +921,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=y
@@ -1125,6 +1128,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1153,6 +1157,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1208,6 +1213,7 @@ CONFIG_SCHEDSTATS=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1234,6 +1240,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1361,6 +1368,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 55f652b..b96bf3d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:17:35 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:11:55 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -72,7 +75,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -124,6 +126,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -242,6 +245,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -263,7 +267,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -360,7 +364,6 @@ CONFIG_SECCOMP=y
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -377,9 +380,9 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3"
 #
 CONFIG_MAPLE=y
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -404,7 +407,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -532,6 +534,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -549,7 +552,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -589,6 +592,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -717,6 +721,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -771,6 +776,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -778,6 +784,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -918,7 +925,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -976,6 +982,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -990,6 +997,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1135,6 +1143,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 662c1ad..58aec9d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:18:17 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:14:56 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -86,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -111,7 +110,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -120,13 +119,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -237,8 +236,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x10000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -246,6 +245,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -261,7 +262,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -336,7 +337,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -370,6 +371,7 @@ CONFIG_PM=y
 # CONFIG_SUSPEND is not set
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -377,7 +379,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -485,6 +486,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -585,6 +587,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -650,6 +653,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -678,6 +682,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -690,15 +695,9 @@ CONFIG_I2C_SH_MOBILE=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -712,13 +711,16 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -747,20 +749,23 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -868,7 +873,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -880,7 +884,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -911,7 +914,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1027,6 +1029,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1056,6 +1059,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 6041c66..67c6656 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc2
-# Mon Mar 29 02:21:58 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:17:28 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -336,6 +336,7 @@ CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -762,6 +763,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -1755,6 +1757,7 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 72f8718..0883d87 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:24:26 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:21:52 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -29,6 +29,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -43,9 +44,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 
@@ -61,11 +64,11 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_KALLSYMS is not set
@@ -87,7 +90,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_COMPAT_BRK is not set
@@ -103,6 +106,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -202,6 +206,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -217,7 +222,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -330,6 +335,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_PHONE is not set
@@ -361,6 +367,7 @@ CONFIG_HAVE_IDE=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -440,6 +447,7 @@ CONFIG_INOTIFY_USER=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # Pseudo filesystems
@@ -491,6 +499,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 0932e6d..8257f57 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:24:44 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:23:10 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -72,7 +75,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -83,6 +85,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -110,8 +113,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 CONFIG_COMPAT_BRK=y
@@ -128,6 +132,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -246,6 +251,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -261,7 +267,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -342,7 +348,6 @@ CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -379,7 +384,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -579,6 +583,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -685,6 +690,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -713,6 +719,7 @@ CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_SH7760=y
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -725,15 +732,9 @@ CONFIG_I2C_SH7760=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
 # CONFIG_SPI is not set
 
 #
@@ -756,6 +757,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -763,12 +765,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -947,6 +950,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -969,6 +973,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1048,6 +1053,7 @@ CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1096,6 +1102,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1214,6 +1221,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index f899e56..8acdc37 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:26:55 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:27:14 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -69,11 +72,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -120,7 +117,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -131,6 +127,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -243,7 +240,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
+# CONFIG_PMB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -253,6 +250,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -269,7 +267,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -344,7 +342,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -381,7 +379,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -444,7 +441,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -584,6 +580,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -688,6 +685,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -753,6 +751,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -944,7 +943,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -956,7 +954,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1052,6 +1049,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1078,6 +1076,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1144,13 +1143,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1158,10 +1156,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -1269,7 +1264,8 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 0664490..f894bdc 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:30:31 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:30:50 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 CONFIG_BSD_PROCESS_ACCT=y
@@ -66,7 +69,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -99,7 +101,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -115,6 +117,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -228,6 +231,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -243,7 +247,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -326,7 +330,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -344,7 +347,6 @@ CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 
 #
 # PC-card bridges
@@ -369,6 +371,7 @@ CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_APM_EMULATION=y
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 # CONFIG_NET is not set
 
@@ -412,6 +415,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -544,6 +548,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -722,7 +727,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -780,6 +784,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -977,6 +982,7 @@ CONFIG_CRYPTO_MD5=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 3d834e5..8c54e16 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:31:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:33:23 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
@@ -70,11 +73,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -85,6 +83,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -110,7 +109,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -119,13 +118,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -222,8 +221,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -231,6 +230,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -246,7 +247,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -321,7 +322,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -354,6 +355,7 @@ CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
 # CONFIG_SUSPEND is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -361,7 +363,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -449,6 +450,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_SCSI_DMA is not set
 # CONFIG_SCSI_NETLINK is not set
 # CONFIG_NETDEVICES is not set
@@ -511,6 +513,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -538,6 +541,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -549,15 +553,9 @@ CONFIG_I2C_SH_MOBILE=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -571,13 +569,16 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -606,20 +607,23 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -690,6 +694,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 CONFIG_USB_CDC_COMPOSITE=y
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -794,6 +799,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index f22be49..2e74b08 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:32:55 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:35:20 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -72,11 +75,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -87,6 +85,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -112,7 +111,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -121,13 +120,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -243,8 +242,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -252,6 +251,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -267,7 +268,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -343,7 +344,7 @@ CONFIG_KEXEC=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -377,6 +378,7 @@ CONFIG_PM=y
 # CONFIG_SUSPEND is not set
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_IDLE_GOV_MENU=y
@@ -386,7 +388,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -580,6 +581,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -659,6 +661,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -687,6 +690,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -699,15 +703,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -721,13 +719,16 @@ CONFIG_GPIO_SYSFS=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -756,20 +757,23 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -889,6 +893,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 CONFIG_USB_CDC_COMPOSITE=m
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -912,9 +917,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
-# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -982,8 +984,6 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -996,7 +996,6 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1074,6 +1073,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1103,6 +1103,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 2a42d49..8778934 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:35:31 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:38:08 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -102,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -120,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -238,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -253,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -333,7 +337,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -348,15 +351,14 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=y
 
 #
@@ -392,7 +394,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -612,6 +613,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -711,7 +713,7 @@ CONFIG_MD_RAID1=m
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -751,6 +753,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -798,6 +801,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -810,6 +815,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -835,6 +841,7 @@ CONFIG_WLAN=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_NET_PCMCIA is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
@@ -910,6 +917,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -977,6 +985,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -984,6 +993,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1025,6 +1035,7 @@ CONFIG_USB_HID=m
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=m
 CONFIG_HID_APPLE=m
 CONFIG_HID_BELKIN=m
@@ -1040,14 +1051,19 @@ CONFIG_HID_GYRATION=m
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=m
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=m
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=m
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=m
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=m
 CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=m
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1169,6 +1185,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1182,6 +1199,7 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1194,7 +1212,6 @@ CONFIG_USB_EMI26=m
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1208,7 +1225,6 @@ CONFIG_USB_SISUSBVGA_CON=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1313,6 +1329,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1347,6 +1364,7 @@ CONFIG_SUNRPC=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1531,6 +1549,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index f2f1f8c..6088a76 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:37:01 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:42:57 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -102,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -120,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -238,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -253,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -333,7 +337,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -349,15 +352,14 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=y
 
 #
@@ -392,7 +394,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -552,6 +553,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -670,6 +672,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -707,7 +710,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -747,6 +750,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -798,6 +802,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -810,6 +816,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -908,6 +915,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -975,6 +983,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -982,6 +991,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1155,6 +1165,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1173,6 +1184,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1357,6 +1369,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index a7a16ce..28c104d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:37:42 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:44:00 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,7 +74,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -82,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -109,8 +112,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -126,6 +130,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -244,6 +249,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -259,7 +265,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -344,7 +350,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -380,7 +385,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -586,6 +590,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -741,6 +746,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -765,6 +771,7 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
@@ -953,6 +960,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -977,6 +985,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1051,6 +1060,7 @@ CONFIG_DEBUG_KERNEL=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1097,6 +1107,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1125,6 +1136,7 @@ CONFIG_DUMP_CODE=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 7d43fab..41cefa4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:40:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:48:22 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -80,6 +82,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -106,7 +109,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -122,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -235,6 +239,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -256,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -334,7 +339,6 @@ CONFIG_HZ=250
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -515,6 +519,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -596,6 +601,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -774,6 +780,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -800,6 +807,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -992,6 +1000,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index d2b1831..1c889b7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:41:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:01:29 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,7 +74,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -82,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -109,7 +112,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -117,17 +119,16 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -243,7 +244,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_X2TLB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_NUMA=y
 CONFIG_NODES_SHIFT=1
@@ -254,6 +255,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -271,7 +274,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_MIGRATION is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -348,7 +351,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -384,6 +387,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -391,7 +395,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -454,7 +457,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -564,6 +566,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_NANDSIM is not set
 CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_NAND_SH_FLCTL is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -596,6 +599,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -612,6 +616,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -764,6 +769,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -792,6 +798,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -804,15 +811,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -826,13 +827,16 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -861,20 +865,23 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -1054,6 +1061,7 @@ CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1129,8 +1137,6 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1143,7 +1149,6 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1202,6 +1207,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1224,6 +1230,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1251,13 +1258,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1265,10 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -1383,7 +1386,8 @@ CONFIG_CRYPTO_WORKQUEUE=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index d50c031..826b119 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 11:45:25 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:53:51 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -109,8 +107,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -126,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -244,6 +244,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -259,7 +260,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=999999
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -340,7 +341,6 @@ CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -377,7 +377,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -583,6 +582,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -712,6 +712,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -829,7 +830,6 @@ CONFIG_RTC_DRV_SH=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -896,6 +896,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -919,6 +920,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -958,6 +960,7 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_DEBUG_PI_LIST=y
@@ -1010,6 +1013,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1038,6 +1042,7 @@ CONFIG_DUMP_CODE=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index efda63d..4b751bd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:16:13 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 15:58:09 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,11 +76,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -122,7 +119,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -133,6 +129,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -245,11 +242,8 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-# CONFIG_29BIT is not set
-CONFIG_32BIT=y
-CONFIG_PMB_ENABLE=y
+CONFIG_29BIT=y
 # CONFIG_PMB is not set
-CONFIG_PMB_FIXED=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -257,6 +251,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -278,7 +273,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -358,7 +353,7 @@ CONFIG_KEXEC=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -374,9 +369,9 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -402,7 +397,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -452,6 +446,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
@@ -472,7 +467,6 @@ CONFIG_LLC=m
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -621,6 +615,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -638,6 +633,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -755,6 +751,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -791,7 +788,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -832,6 +829,7 @@ CONFIG_NET_PCI=y
 CONFIG_PCNET32=m
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -884,6 +882,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -896,6 +896,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -995,6 +996,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1043,6 +1045,7 @@ CONFIG_I2C_HIGHLANDER=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1055,15 +1058,9 @@ CONFIG_I2C_HIGHLANDER=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1087,10 +1084,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1127,6 +1125,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1156,6 +1155,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -1163,12 +1163,14 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1176,6 +1178,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1372,6 +1375,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1402,6 +1406,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1480,6 +1485,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1490,7 +1496,6 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
@@ -1507,11 +1512,11 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1519,10 +1524,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -1535,6 +1537,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1662,7 +1665,8 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index f4b0045..f5e3819 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:19:35 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:03:27 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -34,6 +34,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -49,9 +50,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -77,7 +80,6 @@ CONFIG_TREE_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,7 +114,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -122,18 +123,17 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_KRETPROBES=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -247,12 +247,9 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-# CONFIG_29BIT is not set
-CONFIG_32BIT=y
-CONFIG_PMB_ENABLE=y
+CONFIG_29BIT=y
 # CONFIG_PMB is not set
-CONFIG_PMB_FIXED=y
-# CONFIG_X2TLB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -263,6 +260,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -285,7 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=999999
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -303,6 +302,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
 CONFIG_SH_STORE_QUEUES=y
+# CONFIG_SPECULATIVE_EXECUTION is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_FPU=y
@@ -377,7 +377,7 @@ CONFIG_KEXEC=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -393,9 +393,9 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -421,7 +421,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -471,6 +470,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ATM is not set
 CONFIG_STP=m
 CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
@@ -492,7 +492,6 @@ CONFIG_LLC=m
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -557,6 +556,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_C2PORT is not set
 
@@ -574,6 +574,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -691,6 +692,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -727,7 +729,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -797,6 +799,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -809,6 +813,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -910,6 +915,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -959,6 +965,7 @@ CONFIG_I2C_HIGHLANDER=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -971,15 +978,9 @@ CONFIG_I2C_HIGHLANDER=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -994,13 +995,17 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1033,10 +1038,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1074,6 +1080,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1102,20 +1109,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1123,6 +1135,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1371,6 +1384,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1401,6 +1415,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1475,6 +1490,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1510,7 +1526,6 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1518,10 +1533,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -1534,6 +1546,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1661,7 +1674,8 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 2fc635a..80e7b41 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:23:12 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:09:18 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -44,9 +45,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
@@ -65,7 +68,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -79,6 +81,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -105,7 +108,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -114,7 +116,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLOB=y
 # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -124,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -240,6 +242,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -255,7 +258,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -326,7 +329,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -485,6 +487,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -545,6 +548,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=8
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -657,7 +661,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -720,6 +723,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -756,13 +760,12 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -770,10 +773,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -795,7 +795,8 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 0169e60..66eb7d7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:23:54 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:11:37 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
@@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -85,6 +87,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -112,7 +115,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -122,7 +124,6 @@ CONFIG_COMPAT_BRK=y
 CONFIG_SLOB=y
 # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -132,6 +133,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -248,6 +250,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -263,7 +266,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -350,7 +353,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -448,7 +450,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -592,6 +593,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -662,6 +664,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -723,6 +726,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=4
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -745,6 +749,7 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
@@ -783,6 +788,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
 # CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
@@ -816,6 +822,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -831,14 +838,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -859,7 +871,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -916,7 +927,6 @@ CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -928,7 +938,6 @@ CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -948,11 +957,11 @@ CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_GPIO_PLATFORM=y
 # CONFIG_LEDS_REGULATOR is not set
 # CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_BACKLIGHT=y
@@ -1018,7 +1027,6 @@ CONFIG_RTC_DRV_SH=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1072,6 +1080,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1098,6 +1107,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1180,6 +1190,7 @@ CONFIG_DEBUG_OBJECTS=y
 # CONFIG_DEBUG_OBJECTS_TIMERS is not set
 # CONFIG_DEBUG_OBJECTS_WORK is not set
 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1189,7 +1200,6 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
@@ -1207,11 +1217,11 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_PAGE_POISONING is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1219,10 +1229,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -1234,6 +1241,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1263,7 +1271,8 @@ CONFIG_DUMP_CODE=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index fba1f62..6bd3d95 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:25:36 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:15:07 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -104,7 +106,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -113,7 +114,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -124,6 +124,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -242,6 +243,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -257,7 +259,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -343,7 +345,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -359,9 +360,9 @@ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -389,7 +390,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -449,7 +449,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -525,6 +524,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -642,6 +642,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -678,7 +679,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -719,6 +720,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -771,6 +773,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -783,6 +787,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -805,6 +810,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -877,11 +883,12 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -964,6 +971,7 @@ CONFIG_MFD_SM501=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_EZX_PCAP is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -971,6 +979,7 @@ CONFIG_MFD_SM501=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1152,6 +1161,7 @@ CONFIG_SND_SPI=y
 CONFIG_SND_SUPERH=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 CONFIG_SOUND_PRIME=m
@@ -1170,6 +1180,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1185,14 +1196,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1291,7 +1307,6 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1303,7 +1318,6 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1381,7 +1395,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1442,6 +1455,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1456,6 +1470,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1522,13 +1537,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1536,10 +1550,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -1648,7 +1659,8 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index a8d538f..487abcc 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:26:39 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:20:00 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -104,7 +106,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -113,7 +114,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -124,6 +124,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -242,6 +243,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -257,7 +259,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -343,7 +345,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -359,9 +360,9 @@ CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 root=/dev/sda1"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -389,7 +390,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -449,7 +449,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -611,6 +610,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -728,6 +728,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -764,7 +765,7 @@ CONFIG_PATA_PLATFORM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -805,6 +806,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -857,6 +859,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -869,6 +873,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -891,6 +896,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -963,11 +969,12 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1050,6 +1057,7 @@ CONFIG_MFD_SM501=y
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_EZX_PCAP is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1057,6 +1065,7 @@ CONFIG_MFD_SM501=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1238,6 +1247,7 @@ CONFIG_SND_SPI=y
 CONFIG_SND_SUPERH=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 CONFIG_SOUND_PRIME=m
@@ -1256,6 +1266,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1271,14 +1282,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1377,7 +1393,6 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1389,7 +1404,6 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1467,7 +1481,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1529,6 +1542,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1543,6 +1557,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1609,13 +1624,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1623,10 +1637,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -1735,7 +1746,8 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 1859ba0..fe92314 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:27:20 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:21:00 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -107,8 +109,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -126,6 +129,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -237,11 +241,8 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-# CONFIG_29BIT is not set
-CONFIG_32BIT=y
-CONFIG_PMB_ENABLE=y
+CONFIG_29BIT=y
 # CONFIG_PMB is not set
-CONFIG_PMB_FIXED=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -249,6 +250,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -270,7 +272,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -353,7 +355,7 @@ CONFIG_SCHED_HRTICK=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -369,16 +371,15 @@ CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/n
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA=y
 CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
 CONFIG_CARDBUS=y
 
 #
@@ -417,7 +418,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -659,6 +659,7 @@ CONFIG_BLK_DEV_GENERIC=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -777,6 +778,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -824,7 +826,7 @@ CONFIG_BLK_DEV_DM=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -890,6 +892,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_NET_PCMCIA is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
@@ -995,6 +998,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1057,6 +1061,7 @@ CONFIG_SSB_DRIVER_PCICORE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1064,6 +1069,7 @@ CONFIG_SSB_DRIVER_PCICORE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1167,6 +1173,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1182,14 +1189,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1288,7 +1300,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1301,7 +1312,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1317,10 +1327,6 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
-
-#
-# LED Triggers
-#
 # CONFIG_LEDS_TRIGGERS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
@@ -1416,6 +1422,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1444,6 +1451,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1523,6 +1531,7 @@ CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1571,6 +1580,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1690,6 +1700,7 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 9b331ea..2698245 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc7
-# Tue Feb  9 15:27:06 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:03:37 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,6 +18,8 @@ CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_GENERIC_LOCKBREAK=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_HUGETLBFS=y
@@ -35,6 +37,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_COHERENT=y
 # CONFIG_DMA_NONCOHERENT is not set
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -42,7 +45,6 @@ CONFIG_CONSTRUCTORS=y
 # General setup
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
@@ -51,25 +53,27 @@ CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
 CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_GZIP is not set
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
-# CONFIG_KERNEL_LZO is not set
+CONFIG_KERNEL_LZO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_BSD_PROCESS_ACCT_V3=y
 # CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_TREE=y
 
 #
 # RCU Subsystem
 #
-CONFIG_TREE_RCU=y
-# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_TREE_PREEMPT_RCU=y
 # CONFIG_TINY_RCU is not set
 CONFIG_RCU_TRACE=y
 CONFIG_RCU_FANOUT=32
@@ -77,32 +81,36 @@ CONFIG_RCU_FANOUT=32
 CONFIG_TREE_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
+CONFIG_LOG_BUF_SHIFT=17
 CONFIG_CGROUPS=y
-# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_DEBUG=y
 CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
-# CONFIG_CPUSETS is not set
+CONFIG_CPUSETS=y
+# CONFIG_PROC_PID_CPUSET is not set
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
-# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
 CONFIG_MM_OWNER=y
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
 CONFIG_NET_NS=y
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -131,7 +139,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -142,13 +149,15 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
 CONFIG_TRACEPOINTS=y
-# CONFIG_OPROFILE is not set
+CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
 CONFIG_HAVE_HW_BREAKPOINT=y
@@ -157,7 +166,8 @@ CONFIG_HAVE_HW_BREAKPOINT=y
 # GCOV-based kernel profiling
 #
 # CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
+CONFIG_SLOW_WORK=y
+CONFIG_SLOW_WORK_DEBUG=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -168,9 +178,10 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLK_CGROUP=y
 # CONFIG_DEBUG_BLK_CGROUP is not set
@@ -215,7 +226,7 @@ CONFIG_DEFAULT_IOSCHED="cfq"
 # CONFIG_INLINE_WRITE_UNLOCK_BH is not set
 # CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
 # CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
 CONFIG_FREEZER=y
 
 #
@@ -267,16 +278,15 @@ CONFIG_QUICKLIST=y
 CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
-CONFIG_MEMORY_START=0x60000000
+CONFIG_MEMORY_START=0x40000000
 CONFIG_MEMORY_SIZE=0x20000000
 # CONFIG_29BIT is not set
 CONFIG_32BIT=y
 CONFIG_PMB=y
-# CONFIG_PMB_LEGACY is not set
 CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
-# CONFIG_NUMA is not set
-CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=1
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
@@ -286,21 +296,23 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_64K is not set
 # CONFIG_HUGETLB_PAGE_SIZE_256K is not set
-CONFIG_HUGETLB_PAGE_SIZE_1MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
 # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
-# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_64MB=y
 # CONFIG_HUGETLB_PAGE_SIZE_512MB is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
+CONFIG_NEED_MULTIPLE_NODES=y
 CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_STATIC=y
 CONFIG_MEMORY_HOTPLUG=y
@@ -313,6 +325,7 @@ CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=1
 CONFIG_KSM=y
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_SCHED_MC=y
 
 #
 # Cache configuration
@@ -328,6 +341,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
 CONFIG_SH_STORE_QUEUES=y
+CONFIG_SPECULATIVE_EXECUTION=y
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_PTEAEX=y
@@ -372,7 +386,10 @@ CONFIG_SH_CPU_FREQ=y
 #
 # DMA support
 #
-# CONFIG_SH_DMA is not set
+CONFIG_SH_DMA=y
+# CONFIG_SH_DMA_API is not set
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
+# CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
 #
 # Companion Chips
@@ -388,19 +405,21 @@ CONFIG_HEARTBEAT=y
 # Kernel features
 #
 # CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
+# CONFIG_HZ_250 is not set
 # CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
 CONFIG_SCHED_HRTICK=y
 CONFIG_KEXEC=y
-# CONFIG_CRASH_DUMP is not set
 CONFIG_SECCOMP=y
-# CONFIG_SMP is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-CONFIG_GUSA=y
+CONFIG_INTC_USERIMASK=y
+CONFIG_INTC_BALANCING=y
 
 #
 # Boot options
@@ -410,7 +429,7 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
 CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_CMDLINE_OVERWRITE=y
 # CONFIG_CMDLINE_EXTEND is not set
-CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=10"
+CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200 root=/dev/sda1 nmi_debug=state,debounce rootdelay=5 pmb=iomap ignore_loglevel"
 
 #
 # Bus options
@@ -424,8 +443,7 @@ CONFIG_PCIEAER_INJECT=y
 CONFIG_PCIEASPM=y
 CONFIG_PCIEASPM_DEBUG=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
-CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -435,7 +453,7 @@ CONFIG_PCI_DEBUG=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
 # CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=y
 
@@ -444,9 +462,11 @@ CONFIG_BINFMT_MISC=y
 #
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
 CONFIG_PM_VERBOSE=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_IDLE_GOV_MENU=y
@@ -456,7 +476,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -520,19 +539,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
 # CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-# CONFIG_LIB80211 is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
+# CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -553,14 +567,118 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=y
+CONFIG_NFTL=y
+# CONFIG_NFTL_RW is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+CONFIG_MTD_OOPS=m
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+CONFIG_MTD_ABSENT=m
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+CONFIG_MTD_PHRAM=y
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_SH_FLCTL=m
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+CONFIG_MTD_UBI_GLUEBI=m
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
 
 #
 # DRBD disabled because PROC_FS, INET or CONNECTOR not selected
@@ -575,34 +693,63 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_AD525X_DPOT is not set
-# CONFIG_PHANTOM is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
-# CONFIG_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_DS1682 is not set
-# CONFIG_TI_DAC7512 is not set
-# CONFIG_C2PORT is not set
-
-#
-# EEPROM support
-#
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_AT25 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_MAX6875 is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_CB710_CORE is not set
+# CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_BLK_DEV_PLATFORM=y
+
+#
+# PCI IDE chipsets support
+#
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
 
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -616,11 +763,12 @@ CONFIG_SCSI_PROC_FS=y
 CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
 # CONFIG_CHR_DEV_SG is not set
 # CONFIG_CHR_DEV_SCH is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 # CONFIG_SCSI_SCAN_ASYNC is not set
 CONFIG_SCSI_WAIT_SCAN=m
@@ -631,52 +779,10 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SPI_ATTRS is not set
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
 # CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_BNX2_ISCSI is not set
-# CONFIG_BE2ISCSI is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_HPSA is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_3W_SAS is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_MPT2SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_FCOE is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_PMCRAID is not set
-# CONFIG_SCSI_PM8001 is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
@@ -719,6 +825,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -743,7 +850,17 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
 # CONFIG_PATA_SCH is not set
-# CONFIG_MD is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_DEBUG=y
+# CONFIG_DM_CRYPT is not set
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
+CONFIG_DM_UEVENT=y
 # CONFIG_FUSION is not set
 
 #
@@ -820,11 +937,7 @@ CONFIG_SMSC911X=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-CONFIG_WLAN=y
-# CONFIG_ATMEL is not set
-# CONFIG_PRISM54 is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_HOSTAP is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -838,6 +951,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -923,7 +1037,7 @@ CONFIG_VT=y
 CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_NOZOMI is not set
@@ -940,9 +1054,11 @@ CONFIG_DEVKMEM=y
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_SH_SCI_DMA=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -988,6 +1104,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1001,15 +1118,9 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -1045,7 +1156,8 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_ALIM7101_WDT is not set
-# CONFIG_SH_WDT is not set
+CONFIG_SH_WDT=y
+# CONFIG_SH_WDT_MMAP is not set
 
 #
 # PCI-based Watchdog Cards
@@ -1068,6 +1180,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -1075,15 +1188,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1091,6 +1206,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
@@ -1121,6 +1237,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1135,12 +1252,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1241,7 +1362,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1253,7 +1373,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -1291,6 +1410,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1370,43 +1490,102 @@ CONFIG_RTC_DRV_MAX6900=y
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_RTC_DRV_GENERIC is not set
-# CONFIG_DMADEVICES is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_SH_DMAE=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
 # CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=m
 # CONFIG_UIO_CIF is not set
-# CONFIG_UIO_PDRV is not set
-# CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
+CONFIG_UIO_PDRV=m
+CONFIG_UIO_PDRV_GENIRQ=m
 # CONFIG_UIO_AEC is not set
 # CONFIG_UIO_SERCOS3 is not set
-# CONFIG_UIO_PCI_GENERIC is not set
+CONFIG_UIO_PCI_GENERIC=m
+# CONFIG_UIO_NETX is not set
 
 #
 # TI VLYNQ
 #
-# CONFIG_STAGING is not set
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+# CONFIG_USB_IP_COMMON is not set
+# CONFIG_ECHO is not set
+# CONFIG_POCH is not set
+# CONFIG_COMEDI is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Qualcomm MSM Camera And Video
+#
+
+#
+# Camera Sensor Selection
+#
+# CONFIG_INPUT_GPIO is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_IDE_PHISON is not set
+# CONFIG_VME_BUS is not set
+
+#
+# RAR Register Driver
+#
+# CONFIG_RAR_REGISTER is not set
+# CONFIG_IIO is not set
+CONFIG_RAMZSWAP=m
+CONFIG_RAMZSWAP_STATS=y
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_STRIP is not set
+# CONFIG_DT3155 is not set
+# CONFIG_CRYSTALHD is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=y
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
+CONFIG_BTRFS_FS=y
+# CONFIG_BTRFS_FS_POSIX_ACL is not set
 # CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
@@ -1415,19 +1594,30 @@ CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
 
 #
 # Caches
 #
-# CONFIG_FSCACHE is not set
+CONFIG_FSCACHE=m
+# CONFIG_FSCACHE_STATS is not set
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+CONFIG_CACHEFILES=m
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
 
 #
 # CD-ROM/DVD Filesystems
 #
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
@@ -1448,7 +1638,7 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
@@ -1457,30 +1647,60 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=m
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+CONFIG_LOGFS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_ROMFS_FS=m
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1493,7 +1713,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
+CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
 # CONFIG_NLS_CODEPAGE_850 is not set
@@ -1508,16 +1728,16 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_865 is not set
 # CONFIG_NLS_CODEPAGE_866 is not set
 # CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=m
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
 # CONFIG_NLS_ISO8859_4 is not set
@@ -1527,10 +1747,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_ISO8859_9 is not set
 # CONFIG_NLS_ISO8859_13 is not set
 # CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_ISO8859_15=m
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
 
 #
@@ -1538,7 +1758,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_PRINTK_TIME=y
-CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
@@ -1547,7 +1767,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
@@ -1555,8 +1775,8 @@ CONFIG_DETECT_HUNG_TASK=y
 # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
 CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_DEBUG_PREEMPT=y
@@ -1573,24 +1793,28 @@ CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_DEBUG_CREDENTIALS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
+# CONFIG_RCU_CPU_STALL_VERBOSE is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FTRACE_NMI_ENTER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1598,16 +1822,19 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
+CONFIG_FTRACE_NMI_ENTER=y
 CONFIG_EVENT_TRACING=y
 CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
 CONFIG_TRACING=y
+CONFIG_GENERIC_TRACER=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
-# CONFIG_FUNCTION_TRACER is not set
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_FUNCTION_GRAPH_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_PREEMPT_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_FTRACE_SYSCALLS is not set
 # CONFIG_BOOT_TRACER is not set
 CONFIG_BRANCH_PROFILE_NONE=y
@@ -1619,9 +1846,13 @@ CONFIG_KSYM_TRACER=y
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_DYNAMIC_FTRACE=y
+# CONFIG_FUNCTION_PROFILER is not set
+CONFIG_FTRACE_MCOUNT_RECORD=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
 # CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_DMA_API_DEBUG is not set
+CONFIG_DMA_API_DEBUG=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1632,6 +1863,7 @@ CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DUMP_CODE=y
 CONFIG_DWARF_UNWINDER=y
 # CONFIG_SH_NO_BSS_INIT is not set
+CONFIG_MCOUNT=y
 
 #
 # Security options
@@ -1649,10 +1881,21 @@ CONFIG_CRYPTO=y
 #
 # Crypto core or helper
 #
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1667,7 +1910,7 @@ CONFIG_CRYPTO=y
 #
 # Block modes
 #
-# CONFIG_CRYPTO_CBC is not set
+CONFIG_CRYPTO_CBC=y
 # CONFIG_CRYPTO_CTR is not set
 # CONFIG_CRYPTO_CTS is not set
 # CONFIG_CRYPTO_ECB is not set
@@ -1685,10 +1928,10 @@ CONFIG_CRYPTO=y
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=y
 # CONFIG_CRYPTO_GHASH is not set
 # CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_RMD128 is not set
 # CONFIG_CRYPTO_RMD160 is not set
@@ -1710,7 +1953,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
+CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_SALSA20 is not set
@@ -1722,9 +1965,9 @@ CONFIG_CRYPTO=y
 #
 # Compression
 #
-# CONFIG_CRYPTO_DEFLATE is not set
+CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_LZO=m
 
 #
 # Random Number Generation
@@ -1732,6 +1975,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 CONFIG_BINARY_PRINTF=y
 
 #
@@ -1740,12 +1984,22 @@ CONFIG_BINARY_PRINTF=y
 CONFIG_BITREVERSE=y
 CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 # CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_BTREE=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
index 43e6780..910eaec 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:30:00 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:34:06 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
@@ -72,7 +75,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_TREE_RCU_TRACE=y
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
 CONFIG_CGROUP_NS=y
@@ -82,6 +84,7 @@ CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_MM_OWNER=y
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
@@ -96,6 +99,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -123,7 +127,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -133,7 +136,6 @@ CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLOB=y
 # CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -143,6 +145,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -162,7 +165,6 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
@@ -261,6 +263,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -276,7 +279,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -361,7 +364,6 @@ CONFIG_HZ=1000
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -400,7 +402,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -463,7 +464,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -607,6 +607,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -688,6 +689,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=4
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -799,7 +801,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -853,6 +854,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -881,6 +883,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -919,6 +922,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -929,7 +933,6 @@ CONFIG_DEBUG_PREEMPT=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -947,11 +950,11 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -959,10 +962,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -975,6 +975,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1094,7 +1095,8 @@ CONFIG_CRYPTO_LZO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index ec494e3..586cb1e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:30:41 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:37:31 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -70,11 +73,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -107,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -124,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -245,6 +244,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -260,7 +260,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -335,7 +335,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -370,6 +370,7 @@ CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -377,7 +378,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -569,6 +569,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -635,6 +636,7 @@ CONFIG_USB_USBNET=y
 CONFIG_USB_NET_CDCETHER=y
 # CONFIG_USB_NET_CDC_EEM is not set
 CONFIG_USB_NET_DM9601=y
+# CONFIG_USB_NET_SMSC75XX is not set
 # CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
@@ -644,6 +646,7 @@ CONFIG_USB_NET_DM9601=y
 # CONFIG_USB_NET_CDC_SUBSET is not set
 # CONFIG_USB_NET_ZAURUS is not set
 # CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -713,6 +716,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=4
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -739,6 +743,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -752,15 +757,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -783,6 +782,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -790,12 +790,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -878,6 +879,7 @@ CONFIG_SND_DRIVERS=y
 CONFIG_SND_SUPERH=y
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
@@ -895,6 +897,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -910,14 +913,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -997,7 +1005,6 @@ CONFIG_USB_ISP116X_HCD=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1009,7 +1016,6 @@ CONFIG_USB_ISP116X_HCD=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1027,8 +1033,6 @@ CONFIG_RTC_LIB=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1115,6 +1119,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1141,6 +1146,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1324,6 +1330,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index ee87e2b..acb3e02 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:34:15 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:41:13 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -44,9 +45,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 
@@ -62,7 +65,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -91,7 +93,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
 CONFIG_COMPAT_BRK=y
@@ -107,6 +109,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -217,6 +220,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -232,7 +236,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
 
 #
@@ -301,7 +305,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -453,6 +456,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -513,6 +517,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -612,7 +617,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -664,6 +668,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -729,6 +734,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 03f4219..084fec9 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:34:37 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:42:43 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -67,7 +70,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -76,6 +78,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -101,7 +104,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -117,6 +120,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -234,6 +238,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -249,7 +254,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -327,7 +332,6 @@ CONFIG_HZ=250
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -362,7 +366,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -562,6 +565,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -679,6 +683,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -798,7 +803,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -863,6 +867,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -885,6 +890,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1026,6 +1032,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index cfa5819..4487a23 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:44:56 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:05:15 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -29,6 +29,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -43,9 +44,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -68,7 +71,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -102,8 +104,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -119,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -236,6 +240,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -251,7 +256,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -329,7 +334,6 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -366,7 +370,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -614,6 +617,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -754,6 +758,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -834,11 +839,11 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_TIMER is not set
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
@@ -940,6 +945,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -962,6 +968,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -997,6 +1004,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1042,6 +1050,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1167,6 +1176,7 @@ CONFIG_CRYPTO_DEFLATE=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 201283c..7c06b5c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:46:58 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:06:03 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -44,9 +45,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -69,11 +72,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -107,8 +105,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
@@ -124,6 +123,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -241,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -256,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -334,7 +335,6 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -371,7 +371,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -620,6 +619,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -687,6 +687,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -764,6 +765,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -829,6 +831,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -844,14 +847,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -946,7 +954,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -958,7 +965,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -973,11 +979,11 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+CONFIG_LEDS_TRIGGERS=y
 
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
 # CONFIG_LEDS_TRIGGER_TIMER is not set
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
@@ -1082,6 +1088,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1163,6 +1170,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1208,6 +1216,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1333,6 +1342,7 @@ CONFIG_CRYPTO_DEFLATE=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 4a4efd2..42782e7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 13:49:15 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:07:07 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -84,6 +86,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -122,13 +125,13 @@ CONFIG_PROFILING=y
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -245,7 +248,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_X2TLB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_NUMA=y
 CONFIG_NODES_SHIFT=1
@@ -256,6 +259,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -279,7 +284,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -356,7 +361,7 @@ CONFIG_KEXEC=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -391,6 +396,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -398,7 +404,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -519,6 +524,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -676,6 +682,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -898,6 +905,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -912,6 +920,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -944,6 +953,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1059,6 +1069,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index ab371af..ebb4ac4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 14:36:56 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 16:55:41 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -47,9 +48,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,11 +74,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -107,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -116,13 +114,13 @@ CONFIG_SLAB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -237,8 +235,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -246,6 +244,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -261,7 +261,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -340,7 +340,7 @@ CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -376,6 +376,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -383,7 +384,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -559,6 +559,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_NANDSIM is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_SH_FLCTL is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -600,6 +601,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -619,6 +621,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -726,6 +729,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -805,6 +809,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -833,6 +838,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -846,15 +852,9 @@ CONFIG_I2C_SH_MOBILE=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 
@@ -885,13 +885,16 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -923,22 +926,25 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
@@ -1001,7 +1007,9 @@ CONFIG_USB_GSPCA=m
 # CONFIG_USB_M5602 is not set
 # CONFIG_USB_STV06XX is not set
 # CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
 # CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
 # CONFIG_USB_GSPCA_ETOMS is not set
 # CONFIG_USB_GSPCA_FINEPIX is not set
 # CONFIG_USB_GSPCA_JEILINJ is not set
@@ -1009,9 +1017,11 @@ CONFIG_USB_GSPCA=m
 # CONFIG_USB_GSPCA_MR97310A is not set
 # CONFIG_USB_GSPCA_OV519 is not set
 # CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
 # CONFIG_USB_GSPCA_PAC207 is not set
 # CONFIG_USB_GSPCA_PAC7302 is not set
 # CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
 # CONFIG_USB_GSPCA_SN9C20X is not set
 # CONFIG_USB_GSPCA_SONIXB is not set
 # CONFIG_USB_GSPCA_SONIXJ is not set
@@ -1033,6 +1043,7 @@ CONFIG_USB_GSPCA=m
 # CONFIG_VIDEO_PVRUSB2 is not set
 # CONFIG_VIDEO_HDPVR is not set
 # CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_TLG2300 is not set
 # CONFIG_VIDEO_CX231XX is not set
 # CONFIG_VIDEO_USBVISION is not set
 # CONFIG_USB_ET61X251 is not set
@@ -1147,6 +1158,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_SUPERH is not set
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_CAIAQ is not set
 CONFIG_SND_SOC=m
 
@@ -1155,6 +1167,7 @@ CONFIG_SND_SOC=m
 #
 CONFIG_SND_SOC_SH4_FSI=m
 CONFIG_SND_FSI_AK4642=y
+# CONFIG_SND_FSI_DA7210 is not set
 CONFIG_SND_SOC_I2C_AND_SPI=m
 CONFIG_SND_SOC_ALL_CODECS=m
 CONFIG_SND_SOC_WM_HUBS=m
@@ -1167,6 +1180,7 @@ CONFIG_SND_SOC_AK4535=m
 CONFIG_SND_SOC_AK4642=m
 CONFIG_SND_SOC_AK4671=m
 CONFIG_SND_SOC_CS4270=m
+CONFIG_SND_SOC_DA7210=m
 CONFIG_SND_SOC_L3=m
 CONFIG_SND_SOC_PCM3008=m
 CONFIG_SND_SOC_SPDIF=m
@@ -1189,17 +1203,21 @@ CONFIG_SND_SOC_WM8753=m
 CONFIG_SND_SOC_WM8776=m
 CONFIG_SND_SOC_WM8900=m
 CONFIG_SND_SOC_WM8903=m
+CONFIG_SND_SOC_WM8904=m
 CONFIG_SND_SOC_WM8940=m
+CONFIG_SND_SOC_WM8955=m
 CONFIG_SND_SOC_WM8960=m
 CONFIG_SND_SOC_WM8961=m
 CONFIG_SND_SOC_WM8971=m
 CONFIG_SND_SOC_WM8974=m
+CONFIG_SND_SOC_WM8978=m
 CONFIG_SND_SOC_WM8988=m
 CONFIG_SND_SOC_WM8990=m
 CONFIG_SND_SOC_WM8993=m
 CONFIG_SND_SOC_WM9081=m
 CONFIG_SND_SOC_MAX9877=m
 CONFIG_SND_SOC_TPA6130A2=m
+CONFIG_SND_SOC_WM2000=m
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
@@ -1215,6 +1233,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 # CONFIG_HID_A4TECH is not set
 # CONFIG_HID_APPLE is not set
 # CONFIG_HID_BELKIN is not set
@@ -1229,12 +1248,16 @@ CONFIG_USB_HID=y
 # CONFIG_HID_KENSINGTON is not set
 # CONFIG_HID_LOGITECH is not set
 # CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_QUANTA is not set
 # CONFIG_HID_SAMSUNG is not set
 # CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
 # CONFIG_HID_SUNPLUS is not set
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1327,7 +1350,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1339,7 +1361,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
 CONFIG_USB_GADGET_VBUS_DRAW=2
@@ -1378,6 +1399,7 @@ CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1401,10 +1423,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 CONFIG_MMC_SPI=y
-# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1480,8 +1499,6 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1566,6 +1583,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_UBIFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1594,6 +1612,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1786,6 +1805,7 @@ CONFIG_CRYPTO_CBC=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index b15a44e..e096c3e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 14:39:10 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:00:16 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -70,7 +73,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -103,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -120,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -237,6 +240,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -252,7 +256,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -329,7 +333,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -364,7 +367,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -580,6 +582,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -698,6 +701,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -816,7 +820,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -885,6 +888,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -907,6 +911,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1063,6 +1068,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index d1effde..84d3fac 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 14:39:56 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:03:26 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -69,7 +72,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -80,6 +82,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -106,7 +109,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -123,6 +126,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -240,6 +244,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -255,7 +260,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -333,7 +338,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -369,7 +373,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -589,6 +592,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -666,6 +670,7 @@ CONFIG_DEVKMEM=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -785,7 +790,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -854,6 +858,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -868,6 +873,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1012,6 +1018,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 58533d5..f0d7e67 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 14:40:32 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:06:12 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -100,7 +103,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -117,6 +120,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -238,6 +242,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -253,7 +258,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -328,6 +333,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -343,9 +349,9 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 
@@ -362,7 +368,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -571,6 +576,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -714,7 +720,7 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -772,6 +778,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -807,6 +814,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_PPP is not set
@@ -878,6 +886,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 # CONFIG_LEGACY_PTYS is not set
@@ -928,6 +937,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -935,6 +945,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1032,6 +1043,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1047,14 +1059,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1148,7 +1165,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1161,7 +1177,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1192,7 +1207,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -1211,6 +1225,7 @@ CONFIG_INOTIFY_USER=y
 #
 # Caches
 #
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1332,6 +1347,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1442,6 +1458,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 666fde1..562147d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 14:41:25 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:10:00 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -84,6 +86,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -111,7 +114,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -120,7 +122,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -131,6 +132,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -250,6 +252,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -265,7 +268,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -342,7 +345,6 @@ CONFIG_HZ=250
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -358,9 +360,9 @@ CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -388,7 +390,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -453,7 +454,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -574,6 +574,7 @@ CONFIG_IDE_PROC_FS=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=m
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=m
 CONFIG_SCSI_DMA=y
@@ -664,7 +665,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -704,6 +705,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -751,6 +753,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -763,6 +767,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -853,6 +858,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -927,6 +933,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -934,6 +941,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1075,6 +1083,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1105,6 +1114,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1187,13 +1197,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1201,10 +1210,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -1323,7 +1329,8 @@ CONFIG_CRYPTO_DEFLATE=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 35a3bee..98485ca 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 14:43:04 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:14:59 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -30,6 +30,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -44,9 +45,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -68,11 +71,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -105,7 +103,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -122,6 +120,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -240,6 +239,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -255,7 +255,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -331,7 +331,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -367,7 +366,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -620,6 +618,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -723,6 +722,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -824,7 +824,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -890,6 +889,7 @@ CONFIG_JFFS2_ZLIB=y
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -904,6 +904,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -934,6 +935,7 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
@@ -1049,6 +1051,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index a3056b6..a6a9e68 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:03:45 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:17:36 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -65,11 +68,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 # CONFIG_CGROUP_NS is not set
@@ -78,6 +76,7 @@ CONFIG_CGROUPS=y
 # CONFIG_CPUSETS is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -106,7 +105,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_COMPAT_BRK is not set
@@ -114,21 +112,19 @@ CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
 #
-# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_RT_MUTEXES=y
@@ -138,7 +134,6 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
@@ -235,8 +230,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -246,6 +241,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -262,7 +259,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -353,7 +350,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -390,6 +387,7 @@ CONFIG_HIBERNATION_NVS=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION=""
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_IDLE_GOV_MENU=y
@@ -428,6 +426,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -467,6 +466,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -491,6 +491,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -502,15 +503,9 @@ CONFIG_I2C_SH_MOBILE=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -533,6 +528,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -540,12 +536,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -629,8 +626,6 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -643,7 +638,6 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -707,15 +701,12 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -723,13 +714,9 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -747,7 +734,8 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 04b841b..6f308b7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:05:29 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:19:21 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -69,11 +72,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -120,7 +117,6 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
@@ -131,6 +127,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -243,7 +240,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
+# CONFIG_PMB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -253,6 +250,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -269,7 +267,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -344,7 +342,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -381,7 +379,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -444,7 +441,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -585,6 +581,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -689,6 +686,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -754,6 +752,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -945,7 +944,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -957,7 +955,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -980,9 +977,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
-# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1074,6 +1068,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1096,6 +1091,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1162,13 +1158,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1176,10 +1171,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
@@ -1287,7 +1279,8 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 7b24705..4327f89 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:06:28 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:20:25 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -45,9 +46,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -64,11 +67,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 # CONFIG_CGROUP_NS is not set
@@ -77,6 +75,7 @@ CONFIG_CGROUPS=y
 # CONFIG_CPUSETS is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
@@ -105,7 +104,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 # CONFIG_COMPAT_BRK is not set
@@ -113,7 +111,6 @@ CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_IOREMAP_PROT=y
@@ -123,11 +120,11 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
 #
-# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_RT_MUTEXES=y
@@ -137,7 +134,6 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
@@ -232,7 +228,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
+# CONFIG_PMB is not set
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -242,6 +238,7 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -258,7 +255,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -347,7 +344,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -382,6 +379,7 @@ CONFIG_HIBERNATION_NVS=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION=""
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_IDLE_GOV_MENU=y
@@ -420,6 +418,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -459,6 +458,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=6
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -483,6 +483,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -494,15 +495,9 @@ CONFIG_I2C_SH_MOBILE=y
 # Other I2C/SMBus bus drivers
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -525,6 +520,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -532,12 +528,13 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -621,8 +618,6 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -635,7 +630,6 @@ CONFIG_UIO_PDRV_GENIRQ=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -699,15 +693,12 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -715,13 +706,9 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
@@ -739,7 +726,8 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 8330813..e9af616 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:07:40 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:22:09 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -74,11 +77,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -112,7 +110,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 CONFIG_PERF_COUNTERS=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -126,13 +123,13 @@ CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_KRETPROBES=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -246,12 +243,9 @@ CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x40000000
 CONFIG_MEMORY_SIZE=0x20000000
-# CONFIG_29BIT is not set
-CONFIG_32BIT=y
-CONFIG_PMB_ENABLE=y
+CONFIG_29BIT=y
 # CONFIG_PMB is not set
-CONFIG_PMB_FIXED=y
-# CONFIG_X2TLB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -262,6 +256,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -284,7 +280,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -302,6 +298,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
 CONFIG_SH_STORE_QUEUES=y
+# CONFIG_SPECULATIVE_EXECUTION is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_FPU=y
@@ -311,7 +308,7 @@ CONFIG_CPU_HAS_FPU=y
 #
 # CONFIG_SH_HIGHLANDER is not set
 CONFIG_SH_SH7785LCR=y
-# CONFIG_SH_SH7785LCR_PT is not set
+CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y
 
 #
 # Timer and clock configuration
@@ -374,7 +371,7 @@ CONFIG_SECCOMP=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-CONFIG_SPARSE_IRQ=y
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -389,9 +386,9 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
@@ -421,7 +418,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -633,6 +629,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -706,6 +703,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -742,7 +740,7 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -797,6 +795,7 @@ CONFIG_R8169=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -901,6 +900,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
 # CONFIG_LEGACY_PTYS is not set
@@ -947,6 +947,7 @@ CONFIG_I2C_ALGOPCA=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -960,15 +961,9 @@ CONFIG_I2C_ALGOPCA=y
 #
 CONFIG_I2C_PCA_PLATFORM=y
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1011,6 +1006,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 CONFIG_MFD_SM501=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -1018,12 +1014,14 @@ CONFIG_MFD_SM501=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1209,6 +1207,7 @@ CONFIG_SND_CMIPCI=y
 # CONFIG_SND_SUPERH is not set
 CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
 # CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
@@ -1226,6 +1225,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=m
 CONFIG_HID_APPLE=m
 CONFIG_HID_BELKIN=m
@@ -1242,14 +1242,19 @@ CONFIG_HID_KENSINGTON=m
 CONFIG_HID_LOGITECH=m
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=m
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=m
 CONFIG_HID_NTRIG=m
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=m
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=m
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=m
 CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=m
 CONFIG_HID_GREENASIA=m
 # CONFIG_GREENASIA_FF is not set
@@ -1273,7 +1278,6 @@ CONFIG_USB=y
 # CONFIG_USB_DEVICEFS is not set
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -1351,7 +1355,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1364,7 +1367,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1390,10 +1392,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 CONFIG_MMC_SDHCI=m
 # CONFIG_MMC_SDHCI_PCI is not set
 CONFIG_MMC_SDHCI_PLTFM=m
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
 # CONFIG_MMC_TIFM_SD is not set
-# CONFIG_MMC_TMIO is not set
 # CONFIG_MMC_CB710 is not set
 # CONFIG_MMC_VIA_SDMMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1460,6 +1459,7 @@ CONFIG_RTC_DRV_RS5C372=y
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_RTC_DRV_GENERIC is not set
 CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
 
 #
 # DMA Devices
@@ -1469,10 +1469,10 @@ CONFIG_UIO=m
 # CONFIG_UIO_CIF is not set
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
 # CONFIG_UIO_AEC is not set
 # CONFIG_UIO_SERCOS3 is not set
 # CONFIG_UIO_PCI_GENERIC is not set
+# CONFIG_UIO_NETX is not set
 
 #
 # TI VLYNQ
@@ -1556,6 +1556,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1586,6 +1587,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1660,6 +1662,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LKDTM is not set
 CONFIG_LATENCYTOP=y
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_NOP_TRACER=y
@@ -1690,6 +1693,7 @@ CONFIG_SCHED_TRACER=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 CONFIG_STACK_TRACER=y
 CONFIG_KMEMTRACE=y
 CONFIG_WORKQUEUE_TRACER=y
@@ -1815,6 +1819,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_VIRTUALIZATION is not set
 CONFIG_BINARY_PRINTF=y
 
 #
index f196e87..30f38c2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:09:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:27:53 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,11 +76,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -124,13 +122,13 @@ CONFIG_PROFILING=y
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -244,8 +242,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -254,6 +252,8 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -269,7 +269,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -287,6 +287,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
 CONFIG_SH_STORE_QUEUES=y
+# CONFIG_SPECULATIVE_EXECUTION is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_FPU=y
@@ -344,7 +345,7 @@ CONFIG_KEXEC=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -359,9 +360,9 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -387,7 +388,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -598,6 +598,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -671,6 +672,7 @@ CONFIG_SATA_SIL=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -707,7 +709,7 @@ CONFIG_SATA_SIL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -766,6 +768,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -851,6 +854,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -899,6 +903,7 @@ CONFIG_I2C_ALGOPCA=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -912,15 +917,9 @@ CONFIG_I2C_ALGOPCA=y
 #
 CONFIG_I2C_PCA_PLATFORM=y
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -943,6 +942,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 CONFIG_MFD_SM501=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
@@ -950,12 +950,14 @@ CONFIG_MFD_SM501=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -963,6 +965,7 @@ CONFIG_MFD_SM501=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1059,6 +1062,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1074,14 +1078,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1182,7 +1191,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1195,7 +1203,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 CONFIG_USB_TEST=m
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1353,6 +1360,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1383,6 +1391,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1461,6 +1470,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1509,6 +1519,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1633,6 +1644,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 45441c0..4ba2705 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:10:09 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:32:23 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -12,8 +12,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -29,6 +29,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -43,9 +44,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -65,7 +68,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
@@ -95,7 +97,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -111,6 +113,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -222,6 +225,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -237,7 +241,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -312,7 +316,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -544,6 +547,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -625,6 +629,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -719,7 +724,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -773,6 +777,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -797,6 +802,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -936,6 +942,7 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index ecf50cd..42f6bd3 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:10:45 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:08:45 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -28,6 +28,7 @@ CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_TMU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -35,6 +36,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_COHERENT=y
 # CONFIG_DMA_NONCOHERENT is not set
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -49,9 +51,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,15 +77,11 @@ CONFIG_TREE_RCU=y
 CONFIG_RCU_TRACE=y
 CONFIG_RCU_FANOUT=32
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 CONFIG_TREE_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
@@ -92,6 +92,7 @@ CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
 # CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_MM_OWNER=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -131,7 +132,6 @@ CONFIG_PERF_USE_VMALLOC=y
 # Kernel Performance Events And Counters
 #
 CONFIG_PERF_EVENTS=y
-CONFIG_EVENT_PROFILE=y
 # CONFIG_PERF_COUNTERS is not set
 # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
@@ -140,12 +140,10 @@ CONFIG_COMPAT_BRK=y
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
 CONFIG_PROFILING=y
-CONFIG_TRACEPOINTS=y
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_KRETPROBES=y
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
@@ -153,6 +151,7 @@ CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -173,7 +172,6 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
@@ -269,8 +267,8 @@ CONFIG_FORCE_MAX_ZONEORDER=7
 CONFIG_MEMORY_START=0x0c000000
 CONFIG_MEMORY_SIZE=0x04000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_NUMA=y
 CONFIG_NODES_SHIFT=3
@@ -282,6 +280,8 @@ CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_ARCH_MEMORY_PROBE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 # CONFIG_PAGE_SIZE_4KB is not set
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -307,7 +307,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SCHED_MC=y
@@ -392,14 +392,14 @@ CONFIG_HZ_250=y
 CONFIG_HZ=250
 CONFIG_SCHED_HRTICK=y
 CONFIG_KEXEC=y
-# CONFIG_CRASH_DUMP is not set
 CONFIG_SECCOMP=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=4
+# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -518,7 +518,6 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
-# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 CONFIG_CAN=m
 CONFIG_CAN_RAW=m
@@ -583,6 +582,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
 # CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
@@ -601,6 +601,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -693,6 +694,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -734,6 +736,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=2
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -760,6 +763,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -773,15 +777,9 @@ CONFIG_I2C_HELPER_AUTO=y
 #
 # CONFIG_I2C_PCA_PLATFORM is not set
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
 # CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
@@ -838,10 +836,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_MFD_MC13783 is not set
-# CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
 # CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
@@ -933,7 +930,6 @@ CONFIG_USB_R8A66597_HCD=m
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -945,7 +941,6 @@ CONFIG_USB_R8A66597_HCD=m
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -983,6 +978,7 @@ CONFIG_USB_GADGET_DUALSPEED=y
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_NOKIA is not set
 # CONFIG_USB_G_MULTI is not set
 
 #
@@ -1065,8 +1061,6 @@ CONFIG_RTC_DRV_SH=y
 CONFIG_UIO=m
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
-# CONFIG_UIO_SMX is not set
-# CONFIG_UIO_SERCOS3 is not set
 
 #
 # TI VLYNQ
@@ -1145,6 +1139,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1159,6 +1154,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1246,7 +1242,6 @@ CONFIG_DEBUG_PREEMPT=y
 # CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -1266,9 +1261,9 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
-CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
@@ -1276,10 +1271,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_RING_BUFFER=y
-CONFIG_EVENT_TRACING=y
-CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_RING_BUFFER_ALLOW_SWAP=y
-CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -1292,6 +1284,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1329,6 +1322,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1407,7 +1401,8 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
-CONFIG_BINARY_PRINTF=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
index 98352d7..513834d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:14:18 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:36:53 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -68,7 +71,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -79,6 +81,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -105,7 +108,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
@@ -122,6 +125,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -235,6 +239,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -250,7 +255,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -335,7 +340,6 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -350,9 +354,9 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 
@@ -569,6 +573,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -586,7 +591,7 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -626,6 +631,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -726,6 +732,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -764,6 +771,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -771,6 +779,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -848,7 +857,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -907,6 +915,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -925,6 +934,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -983,6 +993,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 72982e3..14e69a2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:14:50 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:39:19 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -31,6 +31,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -65,7 +68,6 @@ CONFIG_RCU_FANOUT=32
 # CONFIG_TREE_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -76,6 +78,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -102,7 +105,7 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_COMPAT_BRK=y
@@ -119,6 +122,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -237,6 +241,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -252,7 +257,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -332,7 +337,6 @@ CONFIG_HZ=250
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -402,6 +406,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 # CONFIG_SCSI_DMA is not set
@@ -442,6 +447,7 @@ CONFIG_DEVKMEM=y
 # Non-8250 serial port support
 #
 # CONFIG_SERIAL_SH_SCI is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -552,7 +558,6 @@ CONFIG_RTC_LIB=y
 # CONFIG_EXT2_FS is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_EXT4_FS is not set
-CONFIG_EXT4_USE_FOR_EXT23=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -609,6 +614,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -676,6 +682,7 @@ CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_DEFAULT_SECURITY=""
 # CONFIG_CRYPTO is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 78c2570..79196b4 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:17:20 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 17:41:12 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -32,6 +32,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -46,9 +47,11 @@ CONFIG_LOCALVERSION=""
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -71,7 +74,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -82,6 +84,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -109,8 +112,9 @@ CONFIG_PERF_USE_VMALLOC=y
 #
 # Kernel Performance Events And Counters
 #
-# CONFIG_PERF_EVENTS is not set
+CONFIG_PERF_EVENTS=y
 # CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_COMPAT_BRK=y
@@ -127,6 +131,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -245,6 +250,7 @@ CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_MAX_ACTIVE_REGIONS=1
 CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -260,7 +266,7 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -345,7 +351,6 @@ CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
 # CONFIG_GUSA_RB is not set
-# CONFIG_SPARSE_IRQ is not set
 
 #
 # Boot options
@@ -361,9 +366,9 @@ CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw"
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -392,7 +397,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -561,6 +565,7 @@ CONFIG_IP6_NF_RAW=m
 # CONFIG_ATM is not set
 CONFIG_STP=y
 CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
 # CONFIG_NET_DSA is not set
 CONFIG_VLAN_8021Q=y
 # CONFIG_VLAN_8021Q_GVRP is not set
@@ -749,6 +754,7 @@ CONFIG_MTD_NAND_IDS=m
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_SH_FLCTL is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -768,10 +774,6 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-
-#
-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
-#
 # CONFIG_BLK_DEV_DRBD is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
@@ -802,6 +804,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -892,7 +895,7 @@ CONFIG_SCSI_LOWLEVEL=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -951,6 +954,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -1002,6 +1006,8 @@ CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
@@ -1014,6 +1020,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
@@ -1040,6 +1047,7 @@ CONFIG_USB_NET_AX8817X=m
 CONFIG_USB_NET_CDCETHER=m
 # CONFIG_USB_NET_CDC_EEM is not set
 # CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC75XX is not set
 # CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 CONFIG_USB_NET_NET1080=m
@@ -1049,6 +1057,7 @@ CONFIG_USB_NET_PLUSB=m
 # CONFIG_USB_NET_CDC_SUBSET is not set
 CONFIG_USB_NET_ZAURUS=m
 # CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -1136,6 +1145,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1215,6 +1225,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -1222,6 +1233,7 @@ CONFIG_SSB_POSSIBLE=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1372,6 +1384,7 @@ CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
 # CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
@@ -1385,6 +1398,7 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 # CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1397,7 +1411,6 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1410,7 +1423,6 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1552,6 +1564,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1585,6 +1598,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
 CONFIG_CIFS=m
 # CONFIG_CIFS_STATS is not set
 CONFIG_CIFS_WEAK_PW_HASH=y
@@ -1680,6 +1694,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1726,6 +1741,7 @@ CONFIG_FTRACE=y
 CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 # CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -1853,6 +1869,7 @@ CONFIG_CRYPTO_DEFLATE=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 4fa03bf..17b7258 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:18:53 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:10:50 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -33,6 +33,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -48,9 +49,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -73,7 +76,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_GROUP_SCHED is not set
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -84,6 +86,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -122,13 +125,13 @@ CONFIG_PROFILING=y
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -244,7 +247,7 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x01f00000
 CONFIG_29BIT=y
-# CONFIG_X2TLB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 CONFIG_NUMA=y
 CONFIG_NODES_SHIFT=1
@@ -255,6 +258,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -278,7 +283,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_MIGRATION is not set
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -352,7 +357,7 @@ CONFIG_KEXEC=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 CONFIG_GUSA=y
-# CONFIG_SPARSE_IRQ is not set
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -388,6 +393,7 @@ CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
 # CONFIG_HIBERNATION is not set
 CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
 # CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
@@ -395,7 +401,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -473,7 +478,7 @@ CONFIG_CFG80211=y
 # CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
 # CONFIG_CFG80211_REG_DEBUG is not set
 CONFIG_CFG80211_DEFAULT_PS=y
-# CONFIG_WIRELESS_OLD_REGULATORY is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
 CONFIG_CFG80211_WEXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 CONFIG_LIB80211=m
@@ -619,6 +624,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -709,6 +715,7 @@ CONFIG_LIBERTAS=m
 # CONFIG_LIBERTAS_USB is not set
 CONFIG_LIBERTAS_SDIO=m
 CONFIG_LIBERTAS_DEBUG=y
+# CONFIG_LIBERTAS_MESH is not set
 # CONFIG_P54_COMMON is not set
 # CONFIG_RT2X00 is not set
 # CONFIG_WL12XX is not set
@@ -730,6 +737,7 @@ CONFIG_USB_NET_AX8817X=y
 CONFIG_USB_NET_CDCETHER=y
 # CONFIG_USB_NET_CDC_EEM is not set
 # CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_SMSC75XX is not set
 # CONFIG_USB_NET_SMSC95XX is not set
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
@@ -739,6 +747,7 @@ CONFIG_USB_NET_CDCETHER=y
 # CONFIG_USB_NET_CDC_SUBSET is not set
 # CONFIG_USB_NET_ZAURUS is not set
 # CONFIG_USB_NET_INT51X1 is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -800,6 +809,7 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=1
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
 # CONFIG_UNIX98_PTYS is not set
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
@@ -952,7 +962,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -964,7 +973,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -987,9 +995,6 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_AT91 is not set
-# CONFIG_MMC_ATMELMCI is not set
-# CONFIG_MMC_TMIO is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
@@ -1079,6 +1084,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 CONFIG_CRAMFS=y
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1104,6 +1110,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1299,6 +1306,7 @@ CONFIG_CRYPTO_ARC4=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 23bda19..28bb19d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 15:27:53 2010
+# Linux kernel version: 2.6.34-rc5
+# Tue May 18 18:13:10 2010
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -13,8 +13,8 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -35,6 +35,7 @@ CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DMA_COHERENT=y
 # CONFIG_DMA_NONCOHERENT is not set
+# CONFIG_NEED_DMA_MAP_STATE is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
 
@@ -49,9 +50,11 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_BZIP2=y
 CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
 CONFIG_KERNEL_GZIP=y
 # CONFIG_KERNEL_BZIP2 is not set
 # CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
@@ -77,11 +80,6 @@ CONFIG_RCU_FANOUT=32
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-# CONFIG_USER_SCHED is not set
-CONFIG_CGROUP_SCHED=y
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
 CONFIG_CGROUP_NS=y
@@ -93,6 +91,9 @@ CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
 CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
 CONFIG_MM_OWNER=y
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
@@ -102,6 +103,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 # CONFIG_RD_BZIP2 is not set
 # CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -142,13 +144,13 @@ CONFIG_PROFILING=y
 # CONFIG_OPROFILE is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
 
 #
 # GCOV-based kernel profiling
@@ -169,7 +171,6 @@ CONFIG_BLOCK=y
 CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_CGROUP is not set
 
 #
 # IO Schedulers
@@ -265,8 +266,8 @@ CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
 CONFIG_29BIT=y
-# CONFIG_PMB_ENABLE is not set
-# CONFIG_X2TLB is not set
+# CONFIG_PMB is not set
+CONFIG_X2TLB=y
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -277,6 +278,8 @@ CONFIG_ARCH_POPULATES_NODE_MAP=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
@@ -299,7 +302,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
-CONFIG_NR_QUICK=2
+CONFIG_NR_QUICK=1
 # CONFIG_KSM is not set
 CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 
@@ -317,6 +320,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y
 # CONFIG_CPU_BIG_ENDIAN is not set
 CONFIG_SH_FPU=y
 CONFIG_SH_STORE_QUEUES=y
+# CONFIG_SPECULATIVE_EXECUTION is not set
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
 CONFIG_CPU_HAS_PTEAEX=y
@@ -325,15 +329,14 @@ CONFIG_CPU_HAS_FPU=y
 #
 # Board support
 #
+# CONFIG_SH_SDK7786 is not set
 CONFIG_SH_URQUELL=y
 
 #
 # Timer and clock configuration
 #
 CONFIG_SH_TIMER_TMU=y
-CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_SH_CLK_CPG=y
-CONFIG_SH_CLK_CPG_LEGACY=y
 CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
 CONFIG_HIGH_RES_TIMERS=y
@@ -376,7 +379,7 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_GUSA=y
-CONFIG_SPARSE_IRQ=y
+# CONFIG_INTC_USERIMASK is not set
 
 #
 # Boot options
@@ -391,6 +394,7 @@ CONFIG_ENTRY_OFFSET=0x00001000
 # Bus options
 #
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCIEAER=y
 # CONFIG_PCIE_ECRC is not set
@@ -398,7 +402,6 @@ CONFIG_PCIEAER=y
 CONFIG_PCIEASPM=y
 CONFIG_PCIEASPM_DEBUG=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
@@ -428,7 +431,6 @@ CONFIG_NET=y
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -639,6 +641,7 @@ CONFIG_HAVE_IDE=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -712,6 +715,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -748,7 +752,7 @@ CONFIG_ATA_SFF=y
 #
 
 #
-# See the help texts for more information.
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -807,6 +811,7 @@ CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_KSZ884X_PCI is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
 # CONFIG_E100 is not set
@@ -871,6 +876,7 @@ CONFIG_WLAN=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -958,6 +964,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
@@ -1007,6 +1014,7 @@ CONFIG_I2C_ALGOPCA=y
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SH_MOBILE is not set
 # CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
 
 #
 # External I2C/SMBus adapter drivers
@@ -1020,15 +1028,9 @@ CONFIG_I2C_ALGOPCA=y
 #
 CONFIG_I2C_PCA_PLATFORM=y
 # CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
 
 #
@@ -1043,13 +1045,17 @@ CONFIG_GPIOLIB=y
 #
 # Memory mapped GPIO expanders:
 #
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_SCH is not set
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX7300 is not set
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
 
 #
 # PCI GPIO expanders:
@@ -1082,10 +1088,11 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1123,6 +1130,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_TMP421 is not set
@@ -1151,21 +1159,26 @@ CONFIG_SSB_POSSIBLE=y
 # Multifunction device drivers
 #
 # CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 CONFIG_MFD_SM501=y
 # CONFIG_MFD_SM501_GPIO is not set
 # CONFIG_MFD_SH_MOBILE_SDHI is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
 # CONFIG_TPS65010 is not set
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
 # CONFIG_AB3100_CORE is not set
-# CONFIG_MFD_88PM8607 is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
 # CONFIG_REGULATOR is not set
 CONFIG_MEDIA_SUPPORT=y
 
@@ -1187,6 +1200,7 @@ CONFIG_VIDEO_IR=y
 # Graphics support
 #
 CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1283,6 +1297,7 @@ CONFIG_USB_HID=y
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
@@ -1298,14 +1313,19 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
 # CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
 CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
 CONFIG_HID_MONTEREY=y
 # CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
 CONFIG_HID_PANTHERLORD=y
 # CONFIG_PANTHERLORD_FF is not set
 CONFIG_HID_PETALYNX=y
+# CONFIG_HID_QUANTA is not set
 CONFIG_HID_SAMSUNG=y
 CONFIG_HID_SONY=y
+# CONFIG_HID_STANTUM is not set
 CONFIG_HID_SUNPLUS=y
 # CONFIG_HID_GREENASIA is not set
 # CONFIG_HID_SMARTJOYPLUS is not set
@@ -1326,7 +1346,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
@@ -1405,7 +1424,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
@@ -1417,7 +1435,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 
 #
@@ -1584,6 +1601,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1610,6 +1628,7 @@ CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1688,6 +1707,7 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1713,6 +1733,7 @@ CONFIG_FRAME_POINTER=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
@@ -1846,6 +1867,7 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 # CONFIG_CRYPTO_HW is not set
+# CONFIG_VIRTUALIZATION is not set
 # CONFIG_BINARY_PRINTF is not set
 
 #
index 17811e5..f98141b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include "pci-sh4.h"
 #include <asm/addrspace.h>
+#include <asm/sizes.h>
 
 static int __init __area_sdram_check(struct pci_channel *chan,
                                     unsigned int area)
@@ -47,8 +48,8 @@ static int __init __area_sdram_check(struct pci_channel *chan,
 static struct resource sh7751_pci_resources[] = {
        {
                .name   = "SH7751_IO",
-               .start  = SH7751_PCI_IO_BASE,
-               .end    = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
+               .start  = 0x1000,
+               .end    = SZ_4M - 1,
                .flags  = IORESOURCE_IO
        }, {
                .name   = "SH7751_mem",
index 275a448..c798312 100644 (file)
@@ -13,7 +13,7 @@
 
 #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
 
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 #define atomic_set(v,i)                ((v)->counter = (i))
 
 #if defined(CONFIG_GUSA_RB)
index 02df18e..e461d67 100644 (file)
@@ -38,14 +38,10 @@ struct cache_info {
         * 2. those in the physical page number.
         */
        unsigned int alias_mask;
-
        unsigned int n_aliases;         /* Number of aliases */
 
        unsigned long flags;
 };
-
-int __init detect_cpu_and_cache_system(void);
-
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHE_H */
diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h
new file mode 100644 (file)
index 0000000..5645f35
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  arch/sh/include/asm/clkdev.h
+ *
+ * Cloned from arch/arm/include/asm/clkdev.h:
+ *
+ *  Copyright (C) 2008 Russell King.
+ *
+ * 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __ASM_CLKDEV_H
+#define __ASM_CLKDEV_H
+
+struct clk;
+
+struct clk_lookup {
+       struct list_head        node;
+       const char              *dev_id;
+       const char              *con_id;
+       struct clk              *clk;
+};
+
+struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+       const char *dev_fmt, ...);
+
+void clkdev_add(struct clk_lookup *cl);
+void clkdev_drop(struct clk_lookup *cl);
+
+void clkdev_add_table(struct clk_lookup *, size_t);
+int clk_add_alias(const char *, const char *, char *, struct device *);
+
+#endif
index 11da4c5..803d4c7 100644 (file)
 #ifndef __ASM_SH_CLOCK_H
 #define __ASM_SH_CLOCK_H
 
-#include <linux/list.h>
-#include <linux/seq_file.h>
-#include <linux/cpufreq.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-struct clk;
-
-struct clk_ops {
-       void (*init)(struct clk *clk);
-       int (*enable)(struct clk *clk);
-       void (*disable)(struct clk *clk);
-       unsigned long (*recalc)(struct clk *clk);
-       int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
-       int (*set_parent)(struct clk *clk, struct clk *parent);
-       long (*round_rate)(struct clk *clk, unsigned long rate);
-};
-
-struct clk {
-       struct list_head        node;
-       const char              *name;
-       int                     id;
-       struct module           *owner;
-
-       struct clk              *parent;
-       struct clk_ops          *ops;
-
-       struct list_head        children;
-       struct list_head        sibling;        /* node for children */
-
-       int                     usecount;
-
-       unsigned long           rate;
-       unsigned long           flags;
-
-       void __iomem            *enable_reg;
-       unsigned int            enable_bit;
-
-       unsigned long           arch_flags;
-       void                    *priv;
-       struct dentry           *dentry;
-       struct cpufreq_frequency_table *freq_table;
-};
-
-struct clk_lookup {
-       struct list_head        node;
-       const char              *dev_id;
-       const char              *con_id;
-       struct clk              *clk;
-};
-
-#define CLK_ENABLE_ON_INIT     (1 << 0)
+#include <linux/sh_clk.h>
 
 /* Should be defined by processor-specific code */
 void __deprecated arch_init_clk_ops(struct clk_ops **, int type);
 int __init arch_clk_init(void);
 
-/* arch/sh/kernel/cpu/clock.c */
-int clk_init(void);
-unsigned long followparent_recalc(struct clk *);
-void recalculate_root_clocks(void);
-void propagate_rate(struct clk *);
-int clk_reparent(struct clk *child, struct clk *parent);
-int clk_register(struct clk *);
-void clk_unregister(struct clk *);
-
 /* arch/sh/kernel/cpu/clock-cpg.c */
 int __init __deprecated cpg_clk_init(void);
 
-/* the exported API, in addition to clk_set_rate */
-/**
- * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
- * @clk: clock source
- * @rate: desired clock rate in Hz
- * @algo_id: algorithm id to be passed down to ops->set_rate
- *
- * Returns success (0) or negative errno.
- */
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
-
-enum clk_sh_algo_id {
-       NO_CHANGE = 0,
-
-       IUS_N1_N1,
-       IUS_322,
-       IUS_522,
-       IUS_N11,
-
-       SB_N1,
-
-       SB3_N1,
-       SB3_32,
-       SB3_43,
-       SB3_54,
-
-       BP_N1,
-
-       IP_N1,
-};
-
-struct clk_div_mult_table {
-       unsigned int *divisors;
-       unsigned int nr_divisors;
-       unsigned int *multipliers;
-       unsigned int nr_multipliers;
-};
-
-struct cpufreq_frequency_table;
-void clk_rate_table_build(struct clk *clk,
-                         struct cpufreq_frequency_table *freq_table,
-                         int nr_freqs,
-                         struct clk_div_mult_table *src_table,
-                         unsigned long *bitmap);
-
-long clk_rate_table_round(struct clk *clk,
-                         struct cpufreq_frequency_table *freq_table,
-                         unsigned long rate);
-
-int clk_rate_table_find(struct clk *clk,
-                       struct cpufreq_frequency_table *freq_table,
-                       unsigned long rate);
-
-#define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg,        \
-           _enable_bit, _flags)                        \
-{                                                      \
-       .name           = _name,                        \
-       .id             = _id,                          \
-       .parent         = _parent,                      \
-       .enable_reg     = (void __iomem *)_enable_reg,  \
-       .enable_bit     = _enable_bit,                  \
-       .flags          = _flags,                       \
-}
-
-int sh_clk_mstp32_register(struct clk *clks, int nr);
-
-#define SH_CLK_DIV4(_name, _parent, _reg, _shift, _div_bitmap, _flags) \
-{                                                                      \
-       .name = _name,                                                  \
-       .parent = _parent,                                              \
-       .enable_reg = (void __iomem *)_reg,                             \
-       .enable_bit = _shift,                                           \
-       .arch_flags = _div_bitmap,                                      \
-       .flags = _flags,                                                \
-}
-
-struct clk_div4_table {
-       struct clk_div_mult_table *div_mult_table;
-       void (*kick)(struct clk *clk);
-};
-
-int sh_clk_div4_register(struct clk *clks, int nr,
-                        struct clk_div4_table *table);
-int sh_clk_div4_enable_register(struct clk *clks, int nr,
-                        struct clk_div4_table *table);
-int sh_clk_div4_reparent_register(struct clk *clks, int nr,
-                        struct clk_div4_table *table);
-
-#define SH_CLK_DIV6(_name, _parent, _reg, _flags)      \
-{                                                      \
-       .name = _name,                                  \
-       .parent = _parent,                              \
-       .enable_reg = (void __iomem *)_reg,             \
-       .flags = _flags,                                \
-}
-
-int sh_clk_div6_register(struct clk *clks, int nr);
+/* arch/sh/kernel/cpu/clock.c */
+int clk_init(void);
 
 #endif /* __ASM_SH_CLOCK_H */
index bf2f30c..2a02b61 100644 (file)
 #ifndef ASM_DMAENGINE_H
 #define ASM_DMAENGINE_H
 
-#include <linux/dmaengine.h>
-#include <linux/list.h>
+#include <linux/sh_dma.h>
 
-#include <asm/dma-register.h>
-
-#define SH_DMAC_MAX_CHANNELS   6
-
-enum sh_dmae_slave_chan_id {
+enum {
        SHDMA_SLAVE_SCIF0_TX,
        SHDMA_SLAVE_SCIF0_RX,
        SHDMA_SLAVE_SCIF1_TX,
@@ -34,60 +29,6 @@ enum sh_dmae_slave_chan_id {
        SHDMA_SLAVE_SIUA_RX,
        SHDMA_SLAVE_SIUB_TX,
        SHDMA_SLAVE_SIUB_RX,
-       SHDMA_SLAVE_NUMBER,     /* Must stay last */
-};
-
-struct sh_dmae_slave_config {
-       enum sh_dmae_slave_chan_id      slave_id;
-       dma_addr_t                      addr;
-       u32                             chcr;
-       char                            mid_rid;
-};
-
-struct sh_dmae_channel {
-       unsigned int    offset;
-       unsigned int    dmars;
-       unsigned int    dmars_bit;
-};
-
-struct sh_dmae_pdata {
-       struct sh_dmae_slave_config *slave;
-       int slave_num;
-       struct sh_dmae_channel *channel;
-       int channel_num;
-       unsigned int ts_low_shift;
-       unsigned int ts_low_mask;
-       unsigned int ts_high_shift;
-       unsigned int ts_high_mask;
-       unsigned int *ts_shift;
-       int ts_shift_num;
-       u16 dmaor_init;
-};
-
-struct device;
-
-/* Used by slave DMA clients to request DMA to/from a specific peripheral */
-struct sh_dmae_slave {
-       enum sh_dmae_slave_chan_id      slave_id; /* Set by the platform */
-       struct device                   *dma_dev; /* Set by the platform */
-       struct sh_dmae_slave_config     *config;  /* Set by the driver */
-};
-
-struct sh_dmae_regs {
-       u32 sar; /* SAR / source address */
-       u32 dar; /* DAR / destination address */
-       u32 tcr; /* TCR / transfer count */
-};
-
-struct sh_desc {
-       struct sh_dmae_regs hw;
-       struct list_head node;
-       struct dma_async_tx_descriptor async_tx;
-       enum dma_data_direction direction;
-       dma_cookie_t cookie;
-       size_t partial;
-       int chunks;
-       int mark;
 };
 
 #endif
index 965dd78..89890f6 100644 (file)
@@ -46,17 +46,20 @@ struct pmu;
 /* Maximum number of UBC channels */
 #define HBP_NUM                2
 
+static inline int hw_breakpoint_slots(int type)
+{
+       return HBP_NUM;
+}
+
 /* arch/sh/kernel/hw_breakpoint.c */
-extern int arch_check_va_in_userspace(unsigned long va, u16 hbp_len);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                        struct task_struct *tsk);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
 int arch_install_hw_breakpoint(struct perf_event *bp);
 void arch_uninstall_hw_breakpoint(struct perf_event *bp);
 void hw_breakpoint_pmu_read(struct perf_event *bp);
-void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);
 
 extern void arch_fill_perf_breakpoint(struct perf_event *bp);
 extern int register_sh_ubc(struct sh_ubc *);
index 5d3ccae..855e945 100644 (file)
@@ -58,13 +58,11 @@ void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
 void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
 
 /* allow clocks to enable and disable hardware blocks */
-#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags)      \
-{                                                      \
-       .name           = _name,                        \
-       .id             = _id,                          \
-       .parent         = _parent,                      \
-       .arch_flags     = _hwblk,                       \
-       .flags          = _flags,                       \
+#define SH_HWBLK_CLK(_hwblk, _parent, _flags)  \
+[_hwblk] = {                                   \
+       .parent         = _parent,              \
+       .arch_flags     = _hwblk,               \
+       .flags          = _flags,               \
 }
 
 int sh_hwblk_clk_register(struct clk *clks, int nr);
index 1e5d375..491df93 100644 (file)
@@ -38,5 +38,6 @@ void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
 
 void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size);
 void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr);
+void IO_CONCAT(__IO_PREFIX,mem_init)(void);
 
 #undef __IO_PREFIX
index df8e150..02c2f01 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __ASM_SH_IRQ_H
 #define __ASM_SH_IRQ_H
 
+#include <linux/cpumask.h>
 #include <asm/machvec.h>
 
 /*
 #define NR_IRQS                        256
 #define NR_IRQS_LEGACY         8       /* Legacy external IRQ0-7 */
 
+/*
+ * This is a special IRQ number for indicating that no IRQ has been
+ * triggered and to simply ignore the IRQ dispatch. This is a special
+ * case that can happen with IRQ auto-distribution when multiple CPUs
+ * are woken up and signalled in parallel.
+ */
+#define NO_IRQ_IGNORE          ((unsigned int)-1)
+
 /*
  * Convert back and forth between INTEVT and IRQ values.
  */
@@ -42,6 +51,8 @@ static inline int generic_irq_demux(int irq)
 #define irq_demux(irq)         sh_mv.mv_irq_demux(irq)
 
 void init_IRQ(void);
+void migrate_irqs(void);
+
 asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs);
 
 #ifdef CONFIG_IRQSTACKS
@@ -53,6 +64,14 @@ extern void irq_ctx_exit(int cpu);
 # define irq_ctx_exit(cpu) do { } while (0)
 #endif
 
+#ifdef CONFIG_INTC_BALANCING
+extern unsigned int irq_lookup(unsigned int irq);
+extern void irq_finish(unsigned int irq);
+#else
+#define irq_lookup(irq)                (irq)
+#define irq_finish(irq)                do { } while (0)
+#endif
+
 #include <asm-generic/irq.h>
 #ifdef CONFIG_CPU_SH5
 #include <cpu/irq.h>
index 765a5e1..ad6ef8a 100644 (file)
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_SH
 
+#ifdef CONFIG_KEXEC
+/* arch/sh/kernel/machine_kexec.c */
+void reserve_crashkernel(void);
+
 static inline void crash_setup_regs(struct pt_regs *newregs,
                                    struct pt_regs *oldregs)
 {
@@ -59,4 +63,8 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
                newregs->pc = (unsigned long)current_text_addr();
        }
 }
+#else
+static inline void reserve_crashkernel(void) { }
+#endif /* CONFIG_KEXEC */
+
 #endif /* __ASM_SH_KEXEC_H */
index 9c30955..bc0218c 100644 (file)
@@ -49,6 +49,8 @@ struct sh_machine_vector {
 
        int (*mv_clk_init)(void);
        int (*mv_mode_pins)(void);
+
+       void (*mv_mem_init)(void);
 };
 
 extern struct sh_machine_vector sh_mv;
index 7f5363b..8887baf 100644 (file)
@@ -42,9 +42,10 @@ setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 void __init plat_mem_setup(void);
 
 /* arch/sh/kernel/setup.c */
-void __init setup_bootmem_allocator(unsigned long start_pfn);
 void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
                               unsigned long end_pfn);
+/* arch/sh/mm/init.c */
+void __init allocate_pgdat(unsigned int nid);
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_MMZONE_H */
index d71feb3..fb703d1 100644 (file)
@@ -49,7 +49,7 @@
 
 extern unsigned long shm_align_mask;
 extern unsigned long max_low_pfn, min_low_pfn;
-extern unsigned long memory_start, memory_end;
+extern unsigned long memory_start, memory_end, memory_limit;
 
 static inline unsigned long
 pages_do_alias(unsigned long addr1, unsigned long addr2)
@@ -128,13 +128,18 @@ typedef struct page *pgtable_t;
  * added or subtracted as required.
  */
 #ifdef CONFIG_PMB
-#define __pa(x)        ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START)
-#define __va(x)        ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START))
+#define ___pa(x)       ((x)-PAGE_OFFSET+__MEMORY_START)
+#define ___va(x)       ((x)+PAGE_OFFSET-__MEMORY_START)
 #else
-#define __pa(x)        ((unsigned long)(x)-PAGE_OFFSET)
-#define __va(x)        ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#define ___pa(x)       ((x)-PAGE_OFFSET)
+#define ___va(x)       ((x)+PAGE_OFFSET)
 #endif
 
+#ifndef __ASSEMBLY__
+#define __pa(x)                ___pa((unsigned long)x)
+#define __va(x)                (void *)___va((unsigned long)x)
+#endif /* !__ASSEMBLY__ */
+
 #ifdef CONFIG_UNCACHED_MAPPING
 #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + uncached_start)
 #define CAC_ADDR(addr)         ((addr) - uncached_start + PAGE_OFFSET)
index 9605e06..0a58cb2 100644 (file)
@@ -85,6 +85,10 @@ struct sh_cpuinfo {
        struct tlb_info itlb;
        struct tlb_info dtlb;
 
+#ifdef CONFIG_SMP
+       struct task_struct *idle;
+#endif
+
        unsigned long flags;
 } __attribute__ ((aligned(L1_CACHE_BYTES)));
 
@@ -102,6 +106,9 @@ struct task_struct;
 
 extern struct pt_regs fake_swapper_regs;
 
+extern void cpu_init(void);
+extern void cpu_probe(void);
+
 /* arch/sh/kernel/process.c */
 extern unsigned int xstate_size;
 extern void free_thread_xstate(struct task_struct *);
index 572b4eb..61a445d 100644 (file)
@@ -27,8 +27,6 @@
 #define CCN_CVR                0xff000040
 #define CCN_PRR                0xff000044
 
-asmlinkage void __init sh_cpu_init(void);
-
 /*
  * User space process size: 2GB.
  *
index 4758325..01fa17a 100644 (file)
@@ -19,6 +19,7 @@
 #define COMMAND_LINE ((char *) (PARAM+0x100))
 
 void sh_mv_setup(void);
+void check_for_initrd(void);
 
 #endif /* __KERNEL__ */
 
index f1b1e69..e8d4142 100644 (file)
@@ -17,10 +17,10 @@ struct device;
 
 struct siu_platform {
        struct device *dma_dev;
-       enum sh_dmae_slave_chan_id dma_slave_tx_a;
-       enum sh_dmae_slave_chan_id dma_slave_rx_a;
-       enum sh_dmae_slave_chan_id dma_slave_tx_b;
-       enum sh_dmae_slave_chan_id dma_slave_rx_b;
+       unsigned int dma_slave_tx_a;
+       unsigned int dma_slave_rx_a;
+       unsigned int dma_slave_tx_b;
+       unsigned int dma_slave_rx_b;
 };
 
 #endif /* ASM_SIU_H */
diff --git a/arch/sh/include/asm/smp-ops.h b/arch/sh/include/asm/smp-ops.h
new file mode 100644 (file)
index 0000000..c590f76
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __ASM_SH_SMP_OPS_H
+#define __ASM_SH_SMP_OPS_H
+
+struct plat_smp_ops {
+       void (*smp_setup)(void);
+       unsigned int (*smp_processor_id)(void);
+       void (*prepare_cpus)(unsigned int max_cpus);
+       void (*start_cpu)(unsigned int cpu, unsigned long entry_point);
+       void (*send_ipi)(unsigned int cpu, unsigned int message);
+       int (*cpu_disable)(unsigned int cpu);
+       void (*cpu_die)(unsigned int cpu);
+       void (*play_dead)(void);
+};
+
+extern struct plat_smp_ops *mp_ops;
+extern struct plat_smp_ops shx3_smp_ops;
+
+#ifdef CONFIG_SMP
+
+static inline void plat_smp_setup(void)
+{
+       BUG_ON(!mp_ops);
+       mp_ops->smp_setup();
+}
+
+static inline void play_dead(void)
+{
+       mp_ops->play_dead();
+}
+
+extern void register_smp_ops(struct plat_smp_ops *ops);
+
+#else
+
+static inline void plat_smp_setup(void)
+{
+       /* UP, nothing to do ... */
+}
+
+static inline void register_smp_ops(struct plat_smp_ops *ops)
+{
+}
+
+static inline void play_dead(void)
+{
+       BUG();
+}
+
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_SH_SMP_OPS_H */
index 53ef26c..9070d94 100644 (file)
@@ -3,15 +3,16 @@
 
 #include <linux/bitops.h>
 #include <linux/cpumask.h>
+#include <asm/smp-ops.h>
 
 #ifdef CONFIG_SMP
 
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
 #include <asm/current.h>
+#include <asm/percpu.h>
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
-#define hard_smp_processor_id()        plat_smp_processor_id()
 
 /* Map from cpu id to sequential logical cpu number. */
 extern int __cpu_number_map[NR_CPUS];
@@ -30,20 +31,43 @@ enum {
        SMP_MSG_NR,     /* must be last */
 };
 
+DECLARE_PER_CPU(int, cpu_state);
+
 void smp_message_recv(unsigned int msg);
 void smp_timer_broadcast(const struct cpumask *mask);
 
 void local_timer_interrupt(void);
 void local_timer_setup(unsigned int cpu);
-
-void plat_smp_setup(void);
-void plat_prepare_cpus(unsigned int max_cpus);
-int plat_smp_processor_id(void);
-void plat_start_cpu(unsigned int cpu, unsigned long entry_point);
-void plat_send_ipi(unsigned int cpu, unsigned int message);
+void local_timer_stop(unsigned int cpu);
 
 void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+
+void native_play_dead(void);
+void native_cpu_die(unsigned int cpu);
+int native_cpu_disable(unsigned int cpu);
+
+#ifdef CONFIG_HOTPLUG_CPU
+void play_dead_common(void);
+extern int __cpu_disable(void);
+
+static inline void __cpu_die(unsigned int cpu)
+{
+       extern struct plat_smp_ops *mp_ops;     /* private */
+
+       mp_ops->cpu_die(cpu);
+}
+#endif
+
+static inline int hard_smp_processor_id(void)
+{
+       extern struct plat_smp_ops *mp_ops;     /* private */
+
+       if (!mp_ops)
+               return 0;       /* boot CPU */
+
+       return mp_ops->smp_processor_id();
+}
 
 #else
 
index 55f9fec..9a6125e 100644 (file)
@@ -23,7 +23,8 @@
 #define CHCR_TS_HIGH_MASK      0
 #define CHCR_TS_HIGH_SHIFT     0
 #elif defined(CONFIG_CPU_SUBTYPE_SH7722) || \
-       defined(CONFIG_CPU_SUBTYPE_SH7724)
+       defined(CONFIG_CPU_SUBTYPE_SH7724) || \
+       defined(CONFIG_CPU_SUBTYPE_SH7786)
 #define CHCR_TS_LOW_MASK       0x00000018
 #define CHCR_TS_LOW_SHIFT      3
 #define CHCR_TS_HIGH_MASK      0x00300000
@@ -76,7 +77,7 @@ enum {
 }
 
 #define TS_INDEX2VAL(i)        ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
-                        ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
+                        (((i) & 0xc) << CHCR_TS_HIGH_SHIFT))
 
 #else /* CONFIG_CPU_SH4A */
 
index 5963124..e46ec70 100644 (file)
 
 #define MMUCR          0xFF000010      /* MMU Control Register */
 
+#define MMU_TLB_ENTRY_SHIFT    8
+
 #define MMU_ITLB_ADDRESS_ARRAY  0xF2000000
 #define MMU_ITLB_ADDRESS_ARRAY2        0xF2800000
+#define MMU_ITLB_DATA_ARRAY    0xF3000000
+#define MMU_ITLB_DATA_ARRAY2   0xF3800000
+
 #define MMU_UTLB_ADDRESS_ARRAY 0xF6000000
 #define MMU_UTLB_ADDRESS_ARRAY2        0xF6800000
+#define MMU_UTLB_DATA_ARRAY    0xF7000000
+#define MMU_UTLB_DATA_ARRAY2   0xF7800000
 #define MMU_PAGE_ASSOC_BIT     0x80
 
-#define MMUCR_TI               (1<<2)
+#ifdef CONFIG_MMU
+#define MMUCR_AT               (1 << 0)
+#else
+#define MMUCR_AT               (0)
+#endif
+
+#define MMUCR_TI               (1 << 2)
 
 #define MMUCR_URB              0x00FC0000
 #define MMUCR_URB_SHIFT                18
@@ -58,7 +71,8 @@
 #endif
 
 #define MMU_NTLB_ENTRIES       64
-#define MMU_CONTROL_INIT       (0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE|MMUCR_AEX)
+#define MMU_CONTROL_INIT       (MMUCR_AT | MMUCR_TI | MMUCR_SQMD | \
+                                MMUCR_ME | MMUCR_SE | MMUCR_AEX)
 
 #define TRA    0xff000020
 #define EXPEVT 0xff000024
index 2120d67..416b621 100644 (file)
 #define  SCBR_I2CCEN   BIT(1)  /* CPU I2C master enable */
 
 #define PWRCR          0x1a0
+#define  PWRCR_SCISEL0 BIT(0)
+#define  PWRCR_SCISEL1 BIT(1)
+#define  PWRCR_SCIEN   BIT(2)  /* Serial port enable */
+#define  PWRCR_PDWNACK BIT(5)  /* Power down acknowledge */
+#define  PWRCR_PDWNREQ BIT(7)  /* Power down request */
+#define  PWRCR_INT2    BIT(11) /* INT2 connection to power manager */
+#define  PWRCR_BUPINIT BIT(13) /* DDR backup initialize */
+#define  PWRCR_BKPRST  BIT(15) /* Backup power reset */
+
 #define SPCBR          0x1b0
 #define SPICR          0x1c0
 #define SPIDR          0x1d0
index 02fd3ae..650b92f 100644 (file)
@@ -11,7 +11,7 @@ endif
 
 CFLAGS_REMOVE_return_address.o = -pg
 
-obj-y  := debugtraps.o dma-nommu.o dumpstack.o                         \
+obj-y  := clkdev.o debugtraps.o dma-nommu.o dumpstack.o                \
           idle.o io.o io_generic.o irq.o                               \
           irq_$(BITS).o machvec.o nmi_debug.o process.o                \
           process_$(BITS).o ptrace_$(BITS).o                           \
diff --git a/arch/sh/kernel/clkdev.c b/arch/sh/kernel/clkdev.c
new file mode 100644 (file)
index 0000000..defdd6e
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * arch/sh/kernel/clkdev.c
+ *
+ * Cloned from arch/arm/common/clkdev.c:
+ *
+ *  Copyright (C) 2008 Russell King.
+ *
+ * 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <asm/clock.h>
+#include <asm/clkdev.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*
+ * Find the correct struct clk for the device and connection ID.
+ * We do slightly fuzzy matching here:
+ *  An entry with a NULL ID is assumed to be a wildcard.
+ *  If an entry has a device ID, it must match
+ *  If an entry has a connection ID, it must match
+ * Then we take the most specific entry - with the following
+ * order of precidence: dev+con > dev only > con only.
+ */
+static struct clk *clk_find(const char *dev_id, const char *con_id)
+{
+       struct clk_lookup *p;
+       struct clk *clk = NULL;
+       int match, best = 0;
+
+       list_for_each_entry(p, &clocks, node) {
+               match = 0;
+               if (p->dev_id) {
+                       if (!dev_id || strcmp(p->dev_id, dev_id))
+                               continue;
+                       match += 2;
+               }
+               if (p->con_id) {
+                       if (!con_id || strcmp(p->con_id, con_id))
+                               continue;
+                       match += 1;
+               }
+               if (match == 0)
+                       continue;
+
+               if (match > best) {
+                       clk = p->clk;
+                       best = match;
+               }
+       }
+       return clk;
+}
+
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+{
+       struct clk *clk;
+
+       mutex_lock(&clocks_mutex);
+       clk = clk_find(dev_id, con_id);
+       mutex_unlock(&clocks_mutex);
+
+       return clk ? clk : ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get_sys);
+
+void clkdev_add(struct clk_lookup *cl)
+{
+       mutex_lock(&clocks_mutex);
+       list_add_tail(&cl->node, &clocks);
+       mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clkdev_add);
+
+void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
+{
+       mutex_lock(&clocks_mutex);
+       while (num--) {
+               list_add_tail(&cl->node, &clocks);
+               cl++;
+       }
+       mutex_unlock(&clocks_mutex);
+}
+
+#define MAX_DEV_ID     20
+#define MAX_CON_ID     16
+
+struct clk_lookup_alloc {
+       struct clk_lookup cl;
+       char    dev_id[MAX_DEV_ID];
+       char    con_id[MAX_CON_ID];
+};
+
+struct clk_lookup * __init_refok
+clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
+{
+       struct clk_lookup_alloc *cla;
+
+       if (!slab_is_available())
+               cla = alloc_bootmem_low_pages(sizeof(*cla));
+       else
+               cla = kzalloc(sizeof(*cla), GFP_KERNEL);
+
+       if (!cla)
+               return NULL;
+
+       cla->cl.clk = clk;
+       if (con_id) {
+               strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
+               cla->cl.con_id = cla->con_id;
+       }
+
+       if (dev_fmt) {
+               va_list ap;
+
+               va_start(ap, dev_fmt);
+               vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
+               cla->cl.dev_id = cla->dev_id;
+               va_end(ap);
+       }
+
+       return &cla->cl;
+}
+EXPORT_SYMBOL(clkdev_alloc);
+
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
+       struct device *dev)
+{
+       struct clk *r = clk_get(dev, id);
+       struct clk_lookup *l;
+
+       if (IS_ERR(r))
+               return PTR_ERR(r);
+
+       l = clkdev_alloc(r, alias, alias_dev_name);
+       clk_put(r);
+       if (!l)
+               return -ENODEV;
+       clkdev_add(l);
+       return 0;
+}
+EXPORT_SYMBOL(clk_add_alias);
+
+/*
+ * clkdev_drop - remove a clock dynamically allocated
+ */
+void clkdev_drop(struct clk_lookup *cl)
+{
+       mutex_lock(&clocks_mutex);
+       list_del(&cl->node);
+       mutex_unlock(&clocks_mutex);
+       kfree(cl);
+}
+EXPORT_SYMBOL(clkdev_drop);
index 0e48bc6..4edcb60 100644 (file)
@@ -16,7 +16,7 @@ obj-$(CONFIG_ARCH_SHMOBILE)   += shmobile/
 # Common interfaces.
 
 obj-$(CONFIG_SH_ADC)           += adc.o
-obj-$(CONFIG_SH_CLK_CPG)       += clock-cpg.o
+obj-$(CONFIG_SH_CLK_CPG_LEGACY)        += clock-cpg.o
 obj-$(CONFIG_SH_FPU)           += fpu.o
 obj-$(CONFIG_SH_FPU_EMU)       += fpu.o
 
index eed5eaf..e2f63d6 100644 (file)
 #include <linux/compiler.h>
 #include <linux/slab.h>
 #include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 
-static int sh_clk_mstp32_enable(struct clk *clk)
-{
-       __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
-                    clk->enable_reg);
-       return 0;
-}
-
-static void sh_clk_mstp32_disable(struct clk *clk)
-{
-       __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
-                    clk->enable_reg);
-}
-
-static struct clk_ops sh_clk_mstp32_clk_ops = {
-       .enable         = sh_clk_mstp32_enable,
-       .disable        = sh_clk_mstp32_disable,
-       .recalc         = followparent_recalc,
-};
-
-int __init sh_clk_mstp32_register(struct clk *clks, int nr)
-{
-       struct clk *clkp;
-       int ret = 0;
-       int k;
-
-       for (k = 0; !ret && (k < nr); k++) {
-               clkp = clks + k;
-               clkp->ops = &sh_clk_mstp32_clk_ops;
-               ret |= clk_register(clkp);
-       }
-
-       return ret;
-}
-
-static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
-{
-       return clk_rate_table_round(clk, clk->freq_table, rate);
-}
-
-static int sh_clk_div6_divisors[64] = {
-       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
-       33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
-       49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
-};
-
-static struct clk_div_mult_table sh_clk_div6_table = {
-       .divisors = sh_clk_div6_divisors,
-       .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
-};
-
-static unsigned long sh_clk_div6_recalc(struct clk *clk)
-{
-       struct clk_div_mult_table *table = &sh_clk_div6_table;
-       unsigned int idx;
-
-       clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
-                            table, NULL);
-
-       idx = __raw_readl(clk->enable_reg) & 0x003f;
-
-       return clk->freq_table[idx].frequency;
-}
-
-static int sh_clk_div6_set_rate(struct clk *clk,
-                               unsigned long rate, int algo_id)
-{
-       unsigned long value;
-       int idx;
-
-       idx = clk_rate_table_find(clk, clk->freq_table, rate);
-       if (idx < 0)
-               return idx;
-
-       value = __raw_readl(clk->enable_reg);
-       value &= ~0x3f;
-       value |= idx;
-       __raw_writel(value, clk->enable_reg);
-       return 0;
-}
-
-static int sh_clk_div6_enable(struct clk *clk)
-{
-       unsigned long value;
-       int ret;
-
-       ret = sh_clk_div6_set_rate(clk, clk->rate, 0);
-       if (ret == 0) {
-               value = __raw_readl(clk->enable_reg);
-               value &= ~0x100; /* clear stop bit to enable clock */
-               __raw_writel(value, clk->enable_reg);
-       }
-       return ret;
-}
-
-static void sh_clk_div6_disable(struct clk *clk)
-{
-       unsigned long value;
-
-       value = __raw_readl(clk->enable_reg);
-       value |= 0x100; /* stop clock */
-       value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
-       __raw_writel(value, clk->enable_reg);
-}
-
-static struct clk_ops sh_clk_div6_clk_ops = {
-       .recalc         = sh_clk_div6_recalc,
-       .round_rate     = sh_clk_div_round_rate,
-       .set_rate       = sh_clk_div6_set_rate,
-       .enable         = sh_clk_div6_enable,
-       .disable        = sh_clk_div6_disable,
-};
-
-int __init sh_clk_div6_register(struct clk *clks, int nr)
-{
-       struct clk *clkp;
-       void *freq_table;
-       int nr_divs = sh_clk_div6_table.nr_divisors;
-       int freq_table_size = sizeof(struct cpufreq_frequency_table);
-       int ret = 0;
-       int k;
-
-       freq_table_size *= (nr_divs + 1);
-       freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
-       if (!freq_table) {
-               pr_err("sh_clk_div6_register: unable to alloc memory\n");
-               return -ENOMEM;
-       }
-
-       for (k = 0; !ret && (k < nr); k++) {
-               clkp = clks + k;
-
-               clkp->ops = &sh_clk_div6_clk_ops;
-               clkp->id = -1;
-               clkp->freq_table = freq_table + (k * freq_table_size);
-               clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
-
-               ret = clk_register(clkp);
-       }
-
-       return ret;
-}
-
-static unsigned long sh_clk_div4_recalc(struct clk *clk)
-{
-       struct clk_div4_table *d4t = clk->priv;
-       struct clk_div_mult_table *table = d4t->div_mult_table;
-       unsigned int idx;
-
-       clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
-                            table, &clk->arch_flags);
-
-       idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
-
-       return clk->freq_table[idx].frequency;
-}
-
-static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
-{
-       struct clk_div4_table *d4t = clk->priv;
-       struct clk_div_mult_table *table = d4t->div_mult_table;
-       u32 value;
-       int ret;
-
-       if (!strcmp("pll_clk", parent->name))
-               value = __raw_readl(clk->enable_reg) & ~(1 << 7);
-       else
-               value = __raw_readl(clk->enable_reg) | (1 << 7);
-
-       ret = clk_reparent(clk, parent);
-       if (ret < 0)
-               return ret;
-
-       __raw_writel(value, clk->enable_reg);
-
-       /* Rebiuld the frequency table */
-       clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
-                            table, &clk->arch_flags);
-
-       return 0;
-}
-
-static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
-{
-       struct clk_div4_table *d4t = clk->priv;
-       unsigned long value;
-       int idx = clk_rate_table_find(clk, clk->freq_table, rate);
-       if (idx < 0)
-               return idx;
-
-       value = __raw_readl(clk->enable_reg);
-       value &= ~(0xf << clk->enable_bit);
-       value |= (idx << clk->enable_bit);
-       __raw_writel(value, clk->enable_reg);
-
-       if (d4t->kick)
-               d4t->kick(clk);
-
-       return 0;
-}
-
-static int sh_clk_div4_enable(struct clk *clk)
-{
-       __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
-       return 0;
-}
-
-static void sh_clk_div4_disable(struct clk *clk)
-{
-       __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
-}
-
-static struct clk_ops sh_clk_div4_clk_ops = {
-       .recalc         = sh_clk_div4_recalc,
-       .set_rate       = sh_clk_div4_set_rate,
-       .round_rate     = sh_clk_div_round_rate,
-};
-
-static struct clk_ops sh_clk_div4_enable_clk_ops = {
-       .recalc         = sh_clk_div4_recalc,
-       .set_rate       = sh_clk_div4_set_rate,
-       .round_rate     = sh_clk_div_round_rate,
-       .enable         = sh_clk_div4_enable,
-       .disable        = sh_clk_div4_disable,
-};
-
-static struct clk_ops sh_clk_div4_reparent_clk_ops = {
-       .recalc         = sh_clk_div4_recalc,
-       .set_rate       = sh_clk_div4_set_rate,
-       .round_rate     = sh_clk_div_round_rate,
-       .enable         = sh_clk_div4_enable,
-       .disable        = sh_clk_div4_disable,
-       .set_parent     = sh_clk_div4_set_parent,
-};
-
-static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
-                       struct clk_div4_table *table, struct clk_ops *ops)
-{
-       struct clk *clkp;
-       void *freq_table;
-       int nr_divs = table->div_mult_table->nr_divisors;
-       int freq_table_size = sizeof(struct cpufreq_frequency_table);
-       int ret = 0;
-       int k;
-
-       freq_table_size *= (nr_divs + 1);
-       freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
-       if (!freq_table) {
-               pr_err("sh_clk_div4_register: unable to alloc memory\n");
-               return -ENOMEM;
-       }
-
-       for (k = 0; !ret && (k < nr); k++) {
-               clkp = clks + k;
-
-               clkp->ops = ops;
-               clkp->id = -1;
-               clkp->priv = table;
-
-               clkp->freq_table = freq_table + (k * freq_table_size);
-               clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
-
-               ret = clk_register(clkp);
-       }
-
-       return ret;
-}
-
-int __init sh_clk_div4_register(struct clk *clks, int nr,
-                               struct clk_div4_table *table)
-{
-       return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
-}
-
-int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
-                               struct clk_div4_table *table)
-{
-       return sh_clk_div4_register_ops(clks, nr, table,
-                                       &sh_clk_div4_enable_clk_ops);
-}
-
-int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
-                               struct clk_div4_table *table)
-{
-       return sh_clk_div4_register_ops(clks, nr, table,
-                                       &sh_clk_div4_reparent_clk_ops);
-}
-
-#ifdef CONFIG_SH_CLK_CPG_LEGACY
 static struct clk master_clk = {
-       .name           = "master_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .rate           = CONFIG_SH_PCLK_FREQ,
 };
 
 static struct clk peripheral_clk = {
-       .name           = "peripheral_clk",
        .parent         = &master_clk,
        .flags          = CLK_ENABLE_ON_INIT,
 };
 
 static struct clk bus_clk = {
-       .name           = "bus_clk",
        .parent         = &master_clk,
        .flags          = CLK_ENABLE_ON_INIT,
 };
 
 static struct clk cpu_clk = {
-       .name           = "cpu_clk",
        .parent         = &master_clk,
        .flags          = CLK_ENABLE_ON_INIT,
 };
@@ -327,6 +35,16 @@ static struct clk *onchip_clocks[] = {
        &cpu_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("master_clk", &master_clk),
+       CLKDEV_CON_ID("peripheral_clk", &peripheral_clk),
+       CLKDEV_CON_ID("bus_clk", &bus_clk),
+       CLKDEV_CON_ID("cpu_clk", &cpu_clk),
+};
+
 int __init __deprecated cpg_clk_init(void)
 {
        int i, ret = 0;
@@ -338,6 +56,13 @@ int __init __deprecated cpg_clk_init(void)
                        ret |= clk_register(clk);
        }
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+       clk_add_alias("tmu_fck", NULL, "peripheral_clk", NULL);
+       clk_add_alias("mtu2_fck", NULL, "peripheral_clk", NULL);
+       clk_add_alias("cmt_fck", NULL, "peripheral_clk", NULL);
+       clk_add_alias("sci_ick", NULL, "peripheral_clk", NULL);
+
        return ret;
 }
 
@@ -349,4 +74,3 @@ int __init __weak arch_clk_init(void)
 {
        return cpg_clk_init();
 }
-#endif /* CONFIG_SH_CPG_CLK_LEGACY */
index e9fa1bf..50f887d 100644 (file)
  *
  *  Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
  *
- *  With clkdev bits:
- *
- *     Copyright (C) 2008 Russell King.
- *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/kobject.h>
-#include <linux/sysdev.h>
-#include <linux/seq_file.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <linux/cpufreq.h>
+#include <linux/clk.h>
 #include <asm/clock.h>
 #include <asm/machvec.h>
 
-static LIST_HEAD(clock_list);
-static DEFINE_SPINLOCK(clock_lock);
-static DEFINE_MUTEX(clock_list_sem);
-
-void clk_rate_table_build(struct clk *clk,
-                         struct cpufreq_frequency_table *freq_table,
-                         int nr_freqs,
-                         struct clk_div_mult_table *src_table,
-                         unsigned long *bitmap)
-{
-       unsigned long mult, div;
-       unsigned long freq;
-       int i;
-
-       for (i = 0; i < nr_freqs; i++) {
-               div = 1;
-               mult = 1;
-
-               if (src_table->divisors && i < src_table->nr_divisors)
-                       div = src_table->divisors[i];
-
-               if (src_table->multipliers && i < src_table->nr_multipliers)
-                       mult = src_table->multipliers[i];
-
-               if (!div || !mult || (bitmap && !test_bit(i, bitmap)))
-                       freq = CPUFREQ_ENTRY_INVALID;
-               else
-                       freq = clk->parent->rate * mult / div;
-
-               freq_table[i].index = i;
-               freq_table[i].frequency = freq;
-       }
-
-       /* Termination entry */
-       freq_table[i].index = i;
-       freq_table[i].frequency = CPUFREQ_TABLE_END;
-}
-
-long clk_rate_table_round(struct clk *clk,
-                         struct cpufreq_frequency_table *freq_table,
-                         unsigned long rate)
-{
-       unsigned long rate_error, rate_error_prev = ~0UL;
-       unsigned long rate_best_fit = rate;
-       unsigned long highest, lowest;
-       int i;
-
-       highest = lowest = 0;
-
-       for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-               unsigned long freq = freq_table[i].frequency;
-
-               if (freq == CPUFREQ_ENTRY_INVALID)
-                       continue;
-
-               if (freq > highest)
-                       highest = freq;
-               if (freq < lowest)
-                       lowest = freq;
-
-               rate_error = abs(freq - rate);
-               if (rate_error < rate_error_prev) {
-                       rate_best_fit = freq;
-                       rate_error_prev = rate_error;
-               }
-
-               if (rate_error == 0)
-                       break;
-       }
-
-       if (rate >= highest)
-               rate_best_fit = highest;
-       if (rate <= lowest)
-               rate_best_fit = lowest;
-
-       return rate_best_fit;
-}
-
-int clk_rate_table_find(struct clk *clk,
-                       struct cpufreq_frequency_table *freq_table,
-                       unsigned long rate)
-{
-       int i;
-
-       for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-               unsigned long freq = freq_table[i].frequency;
-
-               if (freq == CPUFREQ_ENTRY_INVALID)
-                       continue;
-
-               if (freq == rate)
-                       return i;
-       }
-
-       return -ENOENT;
-}
-
-/* Used for clocks that always have same value as the parent clock */
-unsigned long followparent_recalc(struct clk *clk)
-{
-       return clk->parent ? clk->parent->rate : 0;
-}
-
-int clk_reparent(struct clk *child, struct clk *parent)
-{
-       list_del_init(&child->sibling);
-       if (parent)
-               list_add(&child->sibling, &parent->children);
-       child->parent = parent;
-
-       /* now do the debugfs renaming to reattach the child
-          to the proper parent */
-
-       return 0;
-}
-
-/* Propagate rate to children */
-void propagate_rate(struct clk *tclk)
-{
-       struct clk *clkp;
-
-       list_for_each_entry(clkp, &tclk->children, sibling) {
-               if (clkp->ops && clkp->ops->recalc)
-                       clkp->rate = clkp->ops->recalc(clkp);
-
-               propagate_rate(clkp);
-       }
-}
-
-static void __clk_disable(struct clk *clk)
-{
-       if (clk->usecount == 0) {
-               printk(KERN_ERR "Trying disable clock %s with 0 usecount\n",
-                      clk->name);
-               WARN_ON(1);
-               return;
-       }
-
-       if (!(--clk->usecount)) {
-               if (likely(clk->ops && clk->ops->disable))
-                       clk->ops->disable(clk);
-               if (likely(clk->parent))
-                       __clk_disable(clk->parent);
-       }
-}
-
-void clk_disable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return;
-
-       spin_lock_irqsave(&clock_lock, flags);
-       __clk_disable(clk);
-       spin_unlock_irqrestore(&clock_lock, flags);
-}
-EXPORT_SYMBOL_GPL(clk_disable);
-
-static int __clk_enable(struct clk *clk)
-{
-       int ret = 0;
-
-       if (clk->usecount++ == 0) {
-               if (clk->parent) {
-                       ret = __clk_enable(clk->parent);
-                       if (unlikely(ret))
-                               goto err;
-               }
-
-               if (clk->ops && clk->ops->enable) {
-                       ret = clk->ops->enable(clk);
-                       if (ret) {
-                               if (clk->parent)
-                                       __clk_disable(clk->parent);
-                               goto err;
-                       }
-               }
-       }
-
-       return ret;
-err:
-       clk->usecount--;
-       return ret;
-}
-
-int clk_enable(struct clk *clk)
-{
-       unsigned long flags;
-       int ret;
-
-       if (!clk)
-               return -EINVAL;
-
-       spin_lock_irqsave(&clock_lock, flags);
-       ret = __clk_enable(clk);
-       spin_unlock_irqrestore(&clock_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(clk_enable);
-
-static LIST_HEAD(root_clks);
-
-/**
- * recalculate_root_clocks - recalculate and propagate all root clocks
- *
- * Recalculates all root clocks (clocks with no parent), which if the
- * clock's .recalc is set correctly, should also propagate their rates.
- * Called at init.
- */
-void recalculate_root_clocks(void)
-{
-       struct clk *clkp;
-
-       list_for_each_entry(clkp, &root_clks, sibling) {
-               if (clkp->ops && clkp->ops->recalc)
-                       clkp->rate = clkp->ops->recalc(clkp);
-               propagate_rate(clkp);
-       }
-}
-
-int clk_register(struct clk *clk)
-{
-       if (clk == NULL || IS_ERR(clk))
-               return -EINVAL;
-
-       /*
-        * trap out already registered clocks
-        */
-       if (clk->node.next || clk->node.prev)
-               return 0;
-
-       mutex_lock(&clock_list_sem);
-
-       INIT_LIST_HEAD(&clk->children);
-       clk->usecount = 0;
-
-       if (clk->parent)
-               list_add(&clk->sibling, &clk->parent->children);
-       else
-               list_add(&clk->sibling, &root_clks);
-
-       list_add(&clk->node, &clock_list);
-       if (clk->ops && clk->ops->init)
-               clk->ops->init(clk);
-       mutex_unlock(&clock_list_sem);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
-       mutex_lock(&clock_list_sem);
-       list_del(&clk->sibling);
-       list_del(&clk->node);
-       mutex_unlock(&clock_list_sem);
-}
-EXPORT_SYMBOL_GPL(clk_unregister);
-
-static void clk_enable_init_clocks(void)
-{
-       struct clk *clkp;
-
-       list_for_each_entry(clkp, &clock_list, node)
-               if (clkp->flags & CLK_ENABLE_ON_INIT)
-                       clk_enable(clkp);
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-EXPORT_SYMBOL_GPL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       return clk_set_rate_ex(clk, rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
-{
-       int ret = -EOPNOTSUPP;
-       unsigned long flags;
-
-       spin_lock_irqsave(&clock_lock, flags);
-
-       if (likely(clk->ops && clk->ops->set_rate)) {
-               ret = clk->ops->set_rate(clk, rate, algo_id);
-               if (ret != 0)
-                       goto out_unlock;
-       } else {
-               clk->rate = rate;
-               ret = 0;
-       }
-
-       if (clk->ops && clk->ops->recalc)
-               clk->rate = clk->ops->recalc(clk);
-
-       propagate_rate(clk);
-
-out_unlock:
-       spin_unlock_irqrestore(&clock_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_rate_ex);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       unsigned long flags;
-       int ret = -EINVAL;
-
-       if (!parent || !clk)
-               return ret;
-       if (clk->parent == parent)
-               return 0;
-
-       spin_lock_irqsave(&clock_lock, flags);
-       if (clk->usecount == 0) {
-               if (clk->ops->set_parent)
-                       ret = clk->ops->set_parent(clk, parent);
-               else
-                       ret = clk_reparent(clk, parent);
-
-               if (ret == 0) {
-                       pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
-                                clk->name, clk->parent->name, clk->rate);
-                       if (clk->ops->recalc)
-                               clk->rate = clk->ops->recalc(clk);
-                       propagate_rate(clk);
-               }
-       } else
-               ret = -EBUSY;
-       spin_unlock_irqrestore(&clock_lock, flags);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-       return clk->parent;
-}
-EXPORT_SYMBOL_GPL(clk_get_parent);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       if (likely(clk->ops && clk->ops->round_rate)) {
-               unsigned long flags, rounded;
-
-               spin_lock_irqsave(&clock_lock, flags);
-               rounded = clk->ops->round_rate(clk, rate);
-               spin_unlock_irqrestore(&clock_lock, flags);
-
-               return rounded;
-       }
-
-       return clk_get_rate(clk);
-}
-EXPORT_SYMBOL_GPL(clk_round_rate);
-
-/*
- * Find the correct struct clk for the device and connection ID.
- * We do slightly fuzzy matching here:
- *  An entry with a NULL ID is assumed to be a wildcard.
- *  If an entry has a device ID, it must match
- *  If an entry has a connection ID, it must match
- * Then we take the most specific entry - with the following
- * order of precedence: dev+con > dev only > con only.
- */
-static struct clk *clk_find(const char *dev_id, const char *con_id)
-{
-       struct clk_lookup *p;
-       struct clk *clk = NULL;
-       int match, best = 0;
-
-       list_for_each_entry(p, &clock_list, node) {
-               match = 0;
-               if (p->dev_id) {
-                       if (!dev_id || strcmp(p->dev_id, dev_id))
-                               continue;
-                       match += 2;
-               }
-               if (p->con_id) {
-                       if (!con_id || strcmp(p->con_id, con_id))
-                               continue;
-                       match += 1;
-               }
-               if (match == 0)
-                       continue;
-
-               if (match > best) {
-                       clk = p->clk;
-                       best = match;
-               }
-       }
-       return clk;
-}
-
-struct clk *clk_get_sys(const char *dev_id, const char *con_id)
-{
-       struct clk *clk;
-
-       mutex_lock(&clock_list_sem);
-       clk = clk_find(dev_id, con_id);
-       mutex_unlock(&clock_list_sem);
-
-       return clk ? clk : ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL_GPL(clk_get_sys);
-
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk *clk_get(struct device *dev, const char *id)
-{
-       const char *dev_id = dev ? dev_name(dev) : NULL;
-       struct clk *p, *clk = ERR_PTR(-ENOENT);
-       int idno;
-
-       clk = clk_get_sys(dev_id, id);
-       if (clk && !IS_ERR(clk))
-               return clk;
-
-       if (dev == NULL || dev->bus != &platform_bus_type)
-               idno = -1;
-       else
-               idno = to_platform_device(dev)->id;
-
-       mutex_lock(&clock_list_sem);
-       list_for_each_entry(p, &clock_list, node) {
-               if (p->id == idno &&
-                   strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-                       clk = p;
-                       goto found;
-               }
-       }
-
-       list_for_each_entry(p, &clock_list, node) {
-               if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-                       clk = p;
-                       break;
-               }
-       }
-
-found:
-       mutex_unlock(&clock_list_sem);
-
-       return clk;
-}
-EXPORT_SYMBOL_GPL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-       if (clk && !IS_ERR(clk))
-               module_put(clk->owner);
-}
-EXPORT_SYMBOL_GPL(clk_put);
-
-#ifdef CONFIG_PM
-static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
-{
-       static pm_message_t prev_state;
-       struct clk *clkp;
-
-       switch (state.event) {
-       case PM_EVENT_ON:
-               /* Resumeing from hibernation */
-               if (prev_state.event != PM_EVENT_FREEZE)
-                       break;
-
-               list_for_each_entry(clkp, &clock_list, node) {
-                       if (likely(clkp->ops)) {
-                               unsigned long rate = clkp->rate;
-
-                               if (likely(clkp->ops->set_parent))
-                                       clkp->ops->set_parent(clkp,
-                                               clkp->parent);
-                               if (likely(clkp->ops->set_rate))
-                                       clkp->ops->set_rate(clkp,
-                                               rate, NO_CHANGE);
-                               else if (likely(clkp->ops->recalc))
-                                       clkp->rate = clkp->ops->recalc(clkp);
-                       }
-               }
-               break;
-       case PM_EVENT_FREEZE:
-               break;
-       case PM_EVENT_SUSPEND:
-               break;
-       }
-
-       prev_state = state;
-       return 0;
-}
-
-static int clks_sysdev_resume(struct sys_device *dev)
-{
-       return clks_sysdev_suspend(dev, PMSG_ON);
-}
-
-static struct sysdev_class clks_sysdev_class = {
-       .name = "clks",
-};
-
-static struct sysdev_driver clks_sysdev_driver = {
-       .suspend = clks_sysdev_suspend,
-       .resume = clks_sysdev_resume,
-};
-
-static struct sys_device clks_sysdev_dev = {
-       .cls = &clks_sysdev_class,
-};
-
-static int __init clk_sysdev_init(void)
-{
-       sysdev_class_register(&clks_sysdev_class);
-       sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
-       sysdev_register(&clks_sysdev_dev);
-
-       return 0;
-}
-subsys_initcall(clk_sysdev_init);
-#endif
-
 int __init clk_init(void)
 {
        int ret;
@@ -591,89 +49,19 @@ int __init clk_init(void)
 }
 
 /*
- *     debugfs support to trace clock tree hierarchy and attributes
+ * Returns a clock. Note that we first try to use device id on the bus
+ * and clock name. If this fails, we try to use clock name only.
  */
-static struct dentry *clk_debugfs_root;
-
-static int clk_debugfs_register_one(struct clk *c)
+struct clk *clk_get(struct device *dev, const char *con_id)
 {
-       int err;
-       struct dentry *d, *child, *child_tmp;
-       struct clk *pa = c->parent;
-       char s[255];
-       char *p = s;
-
-       p += sprintf(p, "%s", c->name);
-       if (c->id >= 0)
-               sprintf(p, ":%d", c->id);
-       d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root);
-       if (!d)
-               return -ENOMEM;
-       c->dentry = d;
-
-       d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount);
-       if (!d) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate);
-       if (!d) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags);
-       if (!d) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       return 0;
+       const char *dev_id = dev ? dev_name(dev) : NULL;
 
-err_out:
-       d = c->dentry;
-       list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
-               debugfs_remove(child);
-       debugfs_remove(c->dentry);
-       return err;
+       return clk_get_sys(dev_id, con_id);
 }
+EXPORT_SYMBOL_GPL(clk_get);
 
-static int clk_debugfs_register(struct clk *c)
+void clk_put(struct clk *clk)
 {
-       int err;
-       struct clk *pa = c->parent;
-
-       if (pa && !pa->dentry) {
-               err = clk_debugfs_register(pa);
-               if (err)
-                       return err;
-       }
-
-       if (!c->dentry) {
-               err = clk_debugfs_register_one(c);
-               if (err)
-                       return err;
-       }
-       return 0;
 }
+EXPORT_SYMBOL_GPL(clk_put);
 
-static int __init clk_debugfs_init(void)
-{
-       struct clk *c;
-       struct dentry *d;
-       int err;
-
-       d = debugfs_create_dir("clock", NULL);
-       if (!d)
-               return -ENOMEM;
-       clk_debugfs_root = d;
-
-       list_for_each_entry(c, &clock_list, node) {
-               err = clk_debugfs_register(c);
-               if (err)
-                       goto err_out;
-       }
-       return 0;
-err_out:
-       debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */
-       return err;
-}
-late_initcall(clk_debugfs_init);
index 67a1e81..3e985aa 100644 (file)
@@ -146,6 +146,11 @@ int __init sh_hwblk_clk_register(struct clk *clks, int nr)
 
        for (k = 0; !ret && (k < nr); k++) {
                clkp = clks + k;
+
+               /* skip over clocks using hwblk 0 (HWBLK_UNKNOWN) */
+               if (!clkp->arch_flags)
+                       continue;
+
                clkp->ops = &sh_hwblk_clk_ops;
                ret |= clk_register(clkp);
        }
index c736422..9766106 100644 (file)
@@ -43,9 +43,9 @@
  * peripherals (nofpu, nodsp, and so forth).
  */
 #define onchip_setup(x)                                        \
-static int x##_disabled __initdata = !cpu_has_##x;     \
+static int x##_disabled __cpuinitdata = !cpu_has_##x;  \
                                                        \
-static int __init x##_setup(char *opts)                        \
+static int __cpuinit x##_setup(char *opts)                     \
 {                                                      \
        x##_disabled = 1;                               \
        return 1;                                       \
@@ -59,7 +59,7 @@ onchip_setup(dsp);
 #define CPUOPM         0xff2f0000
 #define CPUOPM_RABD    (1 << 5)
 
-static void __init speculative_execution_init(void)
+static void __cpuinit speculative_execution_init(void)
 {
        /* Clear RABD */
        __raw_writel(__raw_readl(CPUOPM) & ~CPUOPM_RABD, CPUOPM);
@@ -78,7 +78,7 @@ static void __init speculative_execution_init(void)
 #define EXPMASK_BRDSSLP                (1 << 1)
 #define EXPMASK_MMCAW          (1 << 4)
 
-static void __init expmask_init(void)
+static void __cpuinit expmask_init(void)
 {
        unsigned long expmask = __raw_readl(EXPMASK);
 
@@ -217,7 +217,7 @@ static void detect_cache_shape(void)
                l2_cache_shape = -1; /* No S-cache */
 }
 
-static void __init fpu_init(void)
+static void __cpuinit fpu_init(void)
 {
        /* Disable the FPU */
        if (fpu_disabled && (current_cpu_data.flags & CPU_HAS_FPU)) {
@@ -230,7 +230,7 @@ static void __init fpu_init(void)
 }
 
 #ifdef CONFIG_SH_DSP
-static void __init release_dsp(void)
+static void __cpuinit release_dsp(void)
 {
        unsigned long sr;
 
@@ -244,7 +244,7 @@ static void __init release_dsp(void)
        );
 }
 
-static void __init dsp_init(void)
+static void __cpuinit dsp_init(void)
 {
        unsigned long sr;
 
@@ -276,11 +276,11 @@ static void __init dsp_init(void)
        release_dsp();
 }
 #else
-static inline void __init dsp_init(void) { }
+static inline void __cpuinit dsp_init(void) { }
 #endif /* CONFIG_SH_DSP */
 
 /**
- * sh_cpu_init
+ * cpu_init
  *
  * This is our initial entry point for each CPU, and is invoked on the
  * boot CPU prior to calling start_kernel(). For SMP, a combination of
@@ -293,14 +293,14 @@ static inline void __init dsp_init(void) { }
  * subtype and initial configuration will all be done.
  *
  * Each processor family is still responsible for doing its own probing
- * and cache configuration in detect_cpu_and_cache_system().
+ * and cache configuration in cpu_probe().
  */
-asmlinkage void __init sh_cpu_init(void)
+asmlinkage void __cpuinit cpu_init(void)
 {
        current_thread_info()->cpu = hard_smp_processor_id();
 
        /* First, probe the CPU */
-       detect_cpu_and_cache_system();
+       cpu_probe();
 
        if (current_cpu_data.type == CPU_SH_NONE)
                panic("Unknown CPU");
index 1db6d88..bab8e75 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 
-int __init detect_cpu_and_cache_system(void)
+void __cpuinit cpu_probe(void)
 {
 #if defined(CONFIG_CPU_SUBTYPE_SH7619)
        boot_cpu_data.type                      = CPU_SH7619;
@@ -30,7 +30,4 @@ int __init detect_cpu_and_cache_system(void)
        boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
        boot_cpu_data.icache = boot_cpu_data.dcache;
        boot_cpu_data.family = CPU_FAMILY_SH2;
-
-       return 0;
 }
-
index 114c7ce..c363851 100644 (file)
@@ -128,17 +128,14 @@ static struct platform_device eth_device = {
 };
 
 static struct sh_timer_config cmt0_platform_data = {
-       .name = "CMT0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 0, /* disabled due to code generation issues */
 };
 
 static struct resource cmt0_resources[] = {
        [0] = {
-               .name   = "CMT0",
                .start  = 0xf84a0072,
                .end    = 0xf84a0077,
                .flags  = IORESOURCE_MEM,
@@ -160,17 +157,14 @@ static struct platform_device cmt0_device = {
 };
 
 static struct sh_timer_config cmt1_platform_data = {
-       .name = "CMT1",
        .channel_offset = 0x08,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 0, /* disabled due to code generation issues */
 };
 
 static struct resource cmt1_resources[] = {
        [0] = {
-               .name   = "CMT1",
                .start  = 0xf84a0078,
                .end    = 0xf84a007d,
                .flags  = IORESOURCE_MEM,
index 6825d65..48e97a2 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 
-int __init detect_cpu_and_cache_system(void)
+void __cpuinit cpu_probe(void)
 {
        boot_cpu_data.family                    = CPU_FAMILY_SH2A;
 
@@ -51,6 +51,4 @@ int __init detect_cpu_and_cache_system(void)
         * on the cache info.
         */
        boot_cpu_data.icache            = boot_cpu_data.dcache;
-
-       return 0;
 }
index 8f669dc..6c96ea0 100644 (file)
@@ -115,16 +115,13 @@ static DECLARE_INTC_DESC(intc_desc, "mxg", vectors, groups,
                         mask_registers, prio_registers, NULL);
 
 static struct sh_timer_config mtu2_0_platform_data = {
-       .name = "MTU2_0",
        .channel_offset = -0x80,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_0_resources[] = {
        [0] = {
-               .name   = "MTU2_0",
                .start  = 0xff801300,
                .end    = 0xff801326,
                .flags  = IORESOURCE_MEM,
@@ -146,16 +143,13 @@ static struct platform_device mtu2_0_device = {
 };
 
 static struct sh_timer_config mtu2_1_platform_data = {
-       .name = "MTU2_1",
        .channel_offset = -0x100,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_1_resources[] = {
        [0] = {
-               .name   = "MTU2_1",
                .start  = 0xff801380,
                .end    = 0xff801390,
                .flags  = IORESOURCE_MEM,
@@ -177,16 +171,13 @@ static struct platform_device mtu2_1_device = {
 };
 
 static struct sh_timer_config mtu2_2_platform_data = {
-       .name = "MTU2_2",
        .channel_offset = 0x80,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_2_resources[] = {
        [0] = {
-               .name   = "MTU2_2",
                .start  = 0xff801000,
                .end    = 0xff80100a,
                .flags  = IORESOURCE_MEM,
index 4ccfeb5..d08bf4c 100644 (file)
@@ -318,16 +318,13 @@ static struct platform_device rtc_device = {
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
-       .name = "MTU2_0",
        .channel_offset = -0x80,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_0_resources[] = {
        [0] = {
-               .name   = "MTU2_0",
                .start  = 0xfffe4300,
                .end    = 0xfffe4326,
                .flags  = IORESOURCE_MEM,
@@ -349,16 +346,13 @@ static struct platform_device mtu2_0_device = {
 };
 
 static struct sh_timer_config mtu2_1_platform_data = {
-       .name = "MTU2_1",
        .channel_offset = -0x100,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_1_resources[] = {
        [0] = {
-               .name   = "MTU2_1",
                .start  = 0xfffe4380,
                .end    = 0xfffe4390,
                .flags  = IORESOURCE_MEM,
@@ -380,16 +374,13 @@ static struct platform_device mtu2_1_device = {
 };
 
 static struct sh_timer_config mtu2_2_platform_data = {
-       .name = "MTU2_2",
        .channel_offset = 0x80,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_2_resources[] = {
        [0] = {
-               .name   = "MTU2_2",
                .start  = 0xfffe4000,
                .end    = 0xfffe400a,
                .flags  = IORESOURCE_MEM,
index 3136966..832f401 100644 (file)
@@ -234,17 +234,14 @@ static struct platform_device scif3_device = {
 };
 
 static struct sh_timer_config cmt0_platform_data = {
-       .name = "CMT0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 0, /* disabled due to code generation issues */
 };
 
 static struct resource cmt0_resources[] = {
        [0] = {
-               .name   = "CMT0",
                .start  = 0xfffec002,
                .end    = 0xfffec007,
                .flags  = IORESOURCE_MEM,
@@ -266,17 +263,14 @@ static struct platform_device cmt0_device = {
 };
 
 static struct sh_timer_config cmt1_platform_data = {
-       .name = "CMT1",
        .channel_offset = 0x08,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 0, /* disabled due to code generation issues */
 };
 
 static struct resource cmt1_resources[] = {
        [0] = {
-               .name   = "CMT1",
                .start  = 0xfffec008,
                .end    = 0xfffec00d,
                .flags  = IORESOURCE_MEM,
@@ -298,16 +292,13 @@ static struct platform_device cmt1_device = {
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
-       .name = "MTU2_0",
        .channel_offset = -0x80,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_0_resources[] = {
        [0] = {
-               .name   = "MTU2_0",
                .start  = 0xfffe4300,
                .end    = 0xfffe4326,
                .flags  = IORESOURCE_MEM,
@@ -329,16 +320,13 @@ static struct platform_device mtu2_0_device = {
 };
 
 static struct sh_timer_config mtu2_1_platform_data = {
-       .name = "MTU2_1",
        .channel_offset = -0x100,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_1_resources[] = {
        [0] = {
-               .name   = "MTU2_1",
                .start  = 0xfffe4380,
                .end    = 0xfffe4390,
                .flags  = IORESOURCE_MEM,
index 0648735..dc47b04 100644 (file)
@@ -194,17 +194,14 @@ static struct platform_device scif3_device = {
 };
 
 static struct sh_timer_config cmt0_platform_data = {
-       .name = "CMT0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 0, /* disabled due to code generation issues */
 };
 
 static struct resource cmt0_resources[] = {
        [0] = {
-               .name   = "CMT0",
                .start  = 0xfffec002,
                .end    = 0xfffec007,
                .flags  = IORESOURCE_MEM,
@@ -226,17 +223,14 @@ static struct platform_device cmt0_device = {
 };
 
 static struct sh_timer_config cmt1_platform_data = {
-       .name = "CMT1",
        .channel_offset = 0x08,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 0, /* disabled due to code generation issues */
 };
 
 static struct resource cmt1_resources[] = {
        [0] = {
-               .name   = "CMT1",
                .start  = 0xfffec008,
                .end    = 0xfffec00d,
                .flags  = IORESOURCE_MEM,
@@ -258,16 +252,13 @@ static struct platform_device cmt1_device = {
 };
 
 static struct sh_timer_config mtu2_0_platform_data = {
-       .name = "MTU2_0",
        .channel_offset = -0x80,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_0_resources[] = {
        [0] = {
-               .name   = "MTU2_0",
                .start  = 0xfffe4300,
                .end    = 0xfffe4326,
                .flags  = IORESOURCE_MEM,
@@ -289,16 +280,13 @@ static struct platform_device mtu2_0_device = {
 };
 
 static struct sh_timer_config mtu2_1_platform_data = {
-       .name = "MTU2_1",
        .channel_offset = -0x100,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_1_resources[] = {
        [0] = {
-               .name   = "MTU2_1",
                .start  = 0xfffe4380,
                .end    = 0xfffe4390,
                .flags  = IORESOURCE_MEM,
@@ -320,16 +308,13 @@ static struct platform_device mtu2_1_device = {
 };
 
 static struct sh_timer_config mtu2_2_platform_data = {
-       .name = "MTU2_2",
        .channel_offset = 0x80,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource mtu2_2_resources[] = {
        [0] = {
-               .name   = "MTU2_2",
                .start  = 0xfffe4000,
                .end    = 0xfffe400a,
                .flags  = IORESOURCE_MEM,
index 295ec4c..bf23c32 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/cache.h>
 #include <asm/io.h>
 
-int detect_cpu_and_cache_system(void)
+void __cpuinit cpu_probe(void)
 {
        unsigned long addr0, addr1, data0, data1, data2, data3;
 
@@ -108,6 +108,4 @@ int detect_cpu_and_cache_system(void)
        boot_cpu_data.icache = boot_cpu_data.dcache;
 
        boot_cpu_data.family = CPU_FAMILY_SH3;
-
-       return 0;
 }
index 7b892d6..baadd7f 100644 (file)
@@ -124,16 +124,13 @@ static struct platform_device rtc_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xfffffe94,
                .end    = 0xfffffe9f,
                .flags  = IORESOURCE_MEM,
@@ -155,16 +152,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0xe,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xfffffea0,
                .end    = 0xfffffeab,
                .flags  = IORESOURCE_MEM,
@@ -186,15 +180,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1a,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xfffffeac,
                .end    = 0xfffffebb,
                .flags  = IORESOURCE_MEM,
index bc0c4f6..3cf8c8e 100644 (file)
@@ -157,16 +157,13 @@ static struct platform_device scif2_device = {
 #endif
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xfffffe94,
                .end    = 0xfffffe9f,
                .flags  = IORESOURCE_MEM,
@@ -188,16 +185,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0xe,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xfffffea0,
                .end    = 0xfffffeab,
                .flags  = IORESOURCE_MEM,
@@ -219,15 +213,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1a,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xfffffeac,
                .end    = 0xfffffebb,
                .flags  = IORESOURCE_MEM,
index 0845a3a..b0c2fb4 100644 (file)
@@ -127,16 +127,13 @@ static struct platform_device scif1_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xa412fe94,
                .end    = 0xa412fe9f,
                .flags  = IORESOURCE_MEM,
@@ -158,16 +155,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0xe,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xa412fea0,
                .end    = 0xa412feab,
                .flags  = IORESOURCE_MEM,
@@ -189,15 +183,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1a,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xa412feac,
                .end    = 0xa412feb5,
                .flags  = IORESOURCE_MEM,
index a718a62..24b1713 100644 (file)
@@ -130,17 +130,14 @@ static struct platform_device usbf_device = {
 };
 
 static struct sh_timer_config cmt0_platform_data = {
-       .name = "CMT0",
        .channel_offset = 0x10,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
 
 static struct resource cmt0_resources[] = {
        [0] = {
-               .name   = "CMT0",
                .start  = 0x044a0010,
                .end    = 0x044a001b,
                .flags  = IORESOURCE_MEM,
@@ -162,15 +159,12 @@ static struct platform_device cmt0_device = {
 };
 
 static struct sh_timer_config cmt1_platform_data = {
-       .name = "CMT1",
        .channel_offset = 0x20,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource cmt1_resources[] = {
        [0] = {
-               .name   = "CMT1",
                .start  = 0x044a0020,
                .end    = 0x044a002b,
                .flags  = IORESOURCE_MEM,
@@ -192,15 +186,12 @@ static struct platform_device cmt1_device = {
 };
 
 static struct sh_timer_config cmt2_platform_data = {
-       .name = "CMT2",
        .channel_offset = 0x30,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource cmt2_resources[] = {
        [0] = {
-               .name   = "CMT2",
                .start  = 0x044a0030,
                .end    = 0x044a003b,
                .flags  = IORESOURCE_MEM,
@@ -222,15 +213,12 @@ static struct platform_device cmt2_device = {
 };
 
 static struct sh_timer_config cmt3_platform_data = {
-       .name = "CMT3",
        .channel_offset = 0x40,
        .timer_bit = 3,
-       .clk = "peripheral_clk",
 };
 
 static struct resource cmt3_resources[] = {
        [0] = {
-               .name   = "CMT3",
                .start  = 0x044a0040,
                .end    = 0x044a004b,
                .flags  = IORESOURCE_MEM,
@@ -252,15 +240,12 @@ static struct platform_device cmt3_device = {
 };
 
 static struct sh_timer_config cmt4_platform_data = {
-       .name = "CMT4",
        .channel_offset = 0x50,
        .timer_bit = 4,
-       .clk = "peripheral_clk",
 };
 
 static struct resource cmt4_resources[] = {
        [0] = {
-               .name   = "CMT4",
                .start  = 0x044a0050,
                .end    = 0x044a005b,
                .flags  = IORESOURCE_MEM,
@@ -282,16 +267,13 @@ static struct platform_device cmt4_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x02,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xa412fe94,
                .end    = 0xa412fe9f,
                .flags  = IORESOURCE_MEM,
@@ -313,16 +295,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0xe,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xa412fea0,
                .end    = 0xa412feab,
                .flags  = IORESOURCE_MEM,
@@ -344,15 +323,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1a,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xa412feac,
                .end    = 0xa412feb5,
                .flags  = IORESOURCE_MEM,
index 6b80850..4eabc68 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
-#include <asm/io.h>
 
 #define CPG2_FRQCR3    0xfe0a0018
 
@@ -45,7 +46,6 @@ static struct clk_ops sh4202_emi_clk_ops = {
 };
 
 static struct clk sh4202_emi_clk = {
-       .name           = "emi_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &sh4202_emi_clk_ops,
 };
@@ -61,7 +61,6 @@ static struct clk_ops sh4202_femi_clk_ops = {
 };
 
 static struct clk sh4202_femi_clk = {
-       .name           = "femi_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &sh4202_femi_clk_ops,
 };
@@ -139,7 +138,6 @@ static struct clk_ops sh4202_shoc_clk_ops = {
 };
 
 static struct clk sh4202_shoc_clk = {
-       .name           = "shoc_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &sh4202_shoc_clk_ops,
 };
@@ -150,6 +148,15 @@ static struct clk *sh4202_onchip_clocks[] = {
        &sh4202_shoc_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("emi_clk", &sh4202_emi_clk),
+       CLKDEV_CON_ID("femi_clk", &sh4202_femi_clk),
+       CLKDEV_CON_ID("shoc_clk", &sh4202_shoc_clk),
+};
+
 int __init arch_clk_init(void)
 {
        struct clk *clk;
@@ -167,5 +174,7 @@ int __init arch_clk_init(void)
 
        clk_put(clk);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        return ret;
 }
index 822977a..d180f16 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/processor.h>
 #include <asm/cache.h>
 
-int __init detect_cpu_and_cache_system(void)
+void __cpuinit cpu_probe(void)
 {
        unsigned long pvr, prr, cvr;
        unsigned long size;
@@ -251,6 +251,4 @@ int __init detect_cpu_and_cache_system(void)
                                 boot_cpu_data.scache.linesz);
                }
        }
-
-       return 0;
 }
index b9b7e10..e916b18 100644 (file)
@@ -31,16 +31,13 @@ static struct platform_device scif0_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -62,16 +59,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -93,15 +87,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
index ffd79e5..911d196 100644 (file)
@@ -66,16 +66,13 @@ static struct platform_device scif1_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -97,16 +94,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -128,15 +122,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
@@ -163,15 +154,12 @@ static struct platform_device tmu2_device = {
        defined(CONFIG_CPU_SUBTYPE_SH7751R)
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xfe100008,
                .end    = 0xfe100013,
                .flags  = IORESOURCE_MEM,
@@ -193,15 +181,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xfe100014,
                .end    = 0xfe10001f,
                .flags  = IORESOURCE_MEM,
index a16eb36..48ea8fe 100644 (file)
@@ -187,16 +187,13 @@ static struct platform_device scif3_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -218,16 +215,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -249,15 +243,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
index 2c16df3..71291ae 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 
 /* SH7343 registers */
@@ -36,8 +37,6 @@
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
 static struct clk r_clk = {
-       .name           = "rclk",
-       .id             = -1,
        .rate           = 32768,
 };
 
@@ -46,8 +45,6 @@ static struct clk r_clk = {
  * from the platform code.
  */
 struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -69,8 +66,6 @@ static struct clk_ops dll_clk_ops = {
 };
 
 static struct clk dll_clk = {
-       .name           = "dll_clk",
-       .id             = -1,
        .ops            = &dll_clk_ops,
        .parent         = &r_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -91,8 +86,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .flags          = CLK_ENABLE_ON_INIT,
 };
@@ -121,72 +114,168 @@ static struct clk_div4_table div4_table = {
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
        DIV4_SIUA, DIV4_SIUB, DIV4_NR };
 
-#define DIV4(_str, _reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
+#define DIV4(_reg, _bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0),
-       [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0),
-       [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0),
+       [DIV4_I] = DIV4(FRQCR, 20, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
+       [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
+       [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
 };
 
-struct clk div6_clks[] = {
-       SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
+enum { DIV6_V, DIV6_NR };
+
+struct clk div6_clks[DIV6_NR] = {
+       [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
+};
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026,
+       MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016,
+       MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010,
+       MSTP007, MSTP006, MSTP005, MSTP004, MSTP003, MSTP002, MSTP001,
+       MSTP109, MSTP108, MSTP100,
+       MSTP225, MSTP224, MSTP218, MSTP217, MSTP216,
+       MSTP214, MSTP213, MSTP212, MSTP211, MSTP208,
+       MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+       MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+       [MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
+       [MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
+       [MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
+       [MSTP028] = MSTP(&div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
+       [MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
+       [MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
+       [MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
+       [MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
+       [MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
+       [MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
+       [MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
+       [MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
+       [MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0),
+       [MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0),
+       [MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
+       [MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
+       [MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
+       [MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
+       [MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
+       [MSTP004] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
+       [MSTP003] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
+       [MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
+       [MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
+
+       [MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
+       [MSTP108] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 8, 0),
+
+       [MSTP225] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 25, 0),
+       [MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
+       [MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
+       [MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0),
+       [MSTP216] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 16, 0),
+       [MSTP214] = MSTP(&r_clk, MSTPCR2, 14, 0),
+       [MSTP213] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 13, 0),
+       [MSTP212] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 12, 0),
+       [MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
+       [MSTP208] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 8, 0),
+       [MSTP206] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
+       [MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
+       [MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
+       [MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
+       [MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
+       [MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
+       [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
-
-static struct clk mstp_clks[] = {
-       MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
-       MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
-       MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
-       MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
-       MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
-       MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0),
-       MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0),
-       MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0),
-       MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0),
-       MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0),
-       MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0),
-       MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0),
-       MSTP("cmt0", &r_clk, MSTPCR0, 14, 0),
-       MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0),
-       MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0),
-       MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0),
-       MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0),
-       MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0),
-       MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0),
-       MSTP("scif3", &div4_clks[DIV4_P], MSTPCR0, 4, 0),
-       MSTP("sio0", &div4_clks[DIV4_P], MSTPCR0, 3, 0),
-       MSTP("siof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0),
-       MSTP("siof1", &div4_clks[DIV4_P], MSTPCR0, 1, 0),
-
-       MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0),
-       MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0),
-
-       MSTP("tpu0", &div4_clks[DIV4_P], MSTPCR2, 25, 0),
-       MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0),
-       MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0),
-       MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0),
-       MSTP("sim0", &div4_clks[DIV4_P], MSTPCR2, 16, 0),
-       MSTP("keysc0", &r_clk, MSTPCR2, 14, 0),
-       MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 13, 0),
-       MSTP("s3d40", &div4_clks[DIV4_P], MSTPCR2, 12, 0),
-       MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0),
-       MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0),
-       MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
-       MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0),
-       MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0),
-       MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0),
-       MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
-       MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
-       MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0),
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("rclk", &r_clk),
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("dll_clk", &dll_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+       CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]),
+       CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]),
+
+       /* DIV6 clocks */
+       CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
+
+       /* MSTP32 clocks */
+       CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]),
+       CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]),
+       CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]),
+       CLKDEV_CON_ID("uram0", &mstp_clks[MSTP028]),
+       CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]),
+       CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]),
+       CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]),
+       CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]),
+       CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]),
+       CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
+       CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
+       CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
+       CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+       CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
+       CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
+       CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
+       {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP007],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP006],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP005],
+       }, {
+               /* SCIF3 */
+               .dev_id         = "sh-sci.3",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP004],
+       },
+       CLKDEV_CON_ID("sio0", &mstp_clks[MSTP003]),
+       CLKDEV_CON_ID("siof0", &mstp_clks[MSTP002]),
+       CLKDEV_CON_ID("siof1", &mstp_clks[MSTP001]),
+       CLKDEV_CON_ID("i2c0", &mstp_clks[MSTP109]),
+       CLKDEV_CON_ID("i2c1", &mstp_clks[MSTP108]),
+       CLKDEV_CON_ID("tpu0", &mstp_clks[MSTP225]),
+       CLKDEV_CON_ID("irda0", &mstp_clks[MSTP224]),
+       CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]),
+       CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]),
+       CLKDEV_CON_ID("sim0", &mstp_clks[MSTP216]),
+       CLKDEV_CON_ID("keysc0", &mstp_clks[MSTP214]),
+       CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP213]),
+       CLKDEV_CON_ID("s3d40", &mstp_clks[MSTP212]),
+       CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]),
+       CLKDEV_CON_ID("siu0", &mstp_clks[MSTP208]),
+       CLKDEV_CON_ID("jpu0", &mstp_clks[MSTP206]),
+       CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]),
+       CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]),
+       CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]),
+       CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]),
+       CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]),
+       CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]),
 };
 
 int __init arch_clk_init(void)
@@ -202,14 +291,16 @@ int __init arch_clk_init(void)
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
                ret = clk_register(main_clks[k]);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
+               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
        return ret;
 }
index 91588d2..7ce5bbc 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 
 /* SH7366 registers */
@@ -36,8 +37,6 @@
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
 static struct clk r_clk = {
-       .name           = "rclk",
-       .id             = -1,
        .rate           = 32768,
 };
 
@@ -46,8 +45,6 @@ static struct clk r_clk = {
  * from the platform code.
  */
 struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -69,8 +66,6 @@ static struct clk_ops dll_clk_ops = {
 };
 
 static struct clk dll_clk = {
-       .name           = "dll_clk",
-       .id             = -1,
        .ops            = &dll_clk_ops,
        .parent         = &r_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -94,8 +89,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .flags          = CLK_ENABLE_ON_INIT,
 };
@@ -124,69 +117,154 @@ static struct clk_div4_table div4_table = {
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P,
        DIV4_SIUA, DIV4_SIUB, DIV4_NR };
 
-#define DIV4(_str, _reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
+#define DIV4(_reg, _bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
-       [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0),
-       [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0),
-       [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0),
+       [DIV4_I] = DIV4(FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
+       [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
+       [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
+       [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
 };
 
-struct clk div6_clks[] = {
-       SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
+enum { DIV6_V, DIV6_NR };
+
+struct clk div6_clks[DIV6_NR] = {
+       [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
+#define MSTP(_parent, _reg, _bit, _flags) \
+  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+enum { MSTP031, MSTP030, MSTP029, MSTP028, MSTP026,
+       MSTP023, MSTP022, MSTP021, MSTP020, MSTP019, MSTP018, MSTP017, MSTP016,
+       MSTP015, MSTP014, MSTP013, MSTP012, MSTP011, MSTP010,
+       MSTP007, MSTP006, MSTP005, MSTP002, MSTP001,
+       MSTP109, MSTP100,
+       MSTP227, MSTP226, MSTP224, MSTP223, MSTP222, MSTP218, MSTP217,
+       MSTP211, MSTP207, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+       MSTP_NR };
 
-static struct clk mstp_clks[] = {
+static struct clk mstp_clks[MSTP_NR] = {
        /* See page 52 of Datasheet V0.40: Overview -> Block Diagram */
-       MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
-       MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
-       MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
-       MSTP("rsmem0", &div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
-       MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
-       MSTP("intc3", &div4_clks[DIV4_P], MSTPCR0, 23, 0),
-       MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 0),
-       MSTP("dmac0", &div4_clks[DIV4_P], MSTPCR0, 21, 0),
-       MSTP("sh0", &div4_clks[DIV4_P], MSTPCR0, 20, 0),
-       MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0),
-       MSTP("ubc0", &div4_clks[DIV4_P], MSTPCR0, 17, 0),
-       MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0),
-       MSTP("cmt0", &r_clk, MSTPCR0, 14, 0),
-       MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0),
-       MSTP("mfi0", &div4_clks[DIV4_P], MSTPCR0, 11, 0),
-       MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0),
-       MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0),
-       MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0),
-       MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0),
-       MSTP("msiof0", &div4_clks[DIV4_P], MSTPCR0, 2, 0),
-       MSTP("sbr0", &div4_clks[DIV4_P], MSTPCR0, 1, 0),
-
-       MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0),
-
-       MSTP("icb0", &div4_clks[DIV4_P], MSTPCR2, 27, 0),
-       MSTP("meram0", &div4_clks[DIV4_P], MSTPCR2, 26, 0),
-       MSTP("dacy1", &div4_clks[DIV4_P], MSTPCR2, 24, 0),
-       MSTP("dacy0", &div4_clks[DIV4_P], MSTPCR2, 23, 0),
-       MSTP("tsif0", &div4_clks[DIV4_P], MSTPCR2, 22, 0),
-       MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0),
-       MSTP("mmcif0", &div4_clks[DIV4_P], MSTPCR2, 17, 0),
-       MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0),
-       MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 9, 0),
-       MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT),
-       MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0),
-       MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0),
-       MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0),
-       MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
-       MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
-       MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0),
+       [MSTP031] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 31, CLK_ENABLE_ON_INIT),
+       [MSTP030] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 30, CLK_ENABLE_ON_INIT),
+       [MSTP029] = MSTP(&div4_clks[DIV4_I], MSTPCR0, 29, CLK_ENABLE_ON_INIT),
+       [MSTP028] = MSTP(&div4_clks[DIV4_SH], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
+       [MSTP026] = MSTP(&div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
+       [MSTP023] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
+       [MSTP022] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
+       [MSTP021] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
+       [MSTP020] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
+       [MSTP019] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 19, 0),
+       [MSTP017] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
+       [MSTP015] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
+       [MSTP014] = MSTP(&r_clk, MSTPCR0, 14, 0),
+       [MSTP013] = MSTP(&r_clk, MSTPCR0, 13, 0),
+       [MSTP011] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
+       [MSTP010] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
+       [MSTP007] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 7, 0),
+       [MSTP006] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 6, 0),
+       [MSTP005] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
+       [MSTP002] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
+       [MSTP001] = MSTP(&div4_clks[DIV4_P], MSTPCR0, 1, 0),
+
+       [MSTP109] = MSTP(&div4_clks[DIV4_P], MSTPCR1, 9, 0),
+
+       [MSTP227] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 27, 0),
+       [MSTP226] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 26, 0),
+       [MSTP224] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 24, 0),
+       [MSTP223] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 23, 0),
+       [MSTP222] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 22, 0),
+       [MSTP218] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 18, 0),
+       [MSTP217] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 17, 0),
+       [MSTP211] = MSTP(&div4_clks[DIV4_P], MSTPCR2, 11, 0),
+       [MSTP207] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 7, CLK_ENABLE_ON_INIT),
+       [MSTP205] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 5, 0),
+       [MSTP204] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 4, 0),
+       [MSTP203] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 3, 0),
+       [MSTP202] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
+       [MSTP201] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
+       [MSTP200] = MSTP(&div4_clks[DIV4_B], MSTPCR2, 0, 0),
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("rclk", &r_clk),
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("dll_clk", &dll_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+       CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("siua_clk", &div4_clks[DIV4_SIUA]),
+       CLKDEV_CON_ID("siub_clk", &div4_clks[DIV4_SIUB]),
+
+       /* DIV6 clocks */
+       CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
+
+       /* MSTP32 clocks */
+       CLKDEV_CON_ID("tlb0", &mstp_clks[MSTP031]),
+       CLKDEV_CON_ID("ic0", &mstp_clks[MSTP030]),
+       CLKDEV_CON_ID("oc0", &mstp_clks[MSTP029]),
+       CLKDEV_CON_ID("rsmem0", &mstp_clks[MSTP028]),
+       CLKDEV_CON_ID("xymem0", &mstp_clks[MSTP026]),
+       CLKDEV_CON_ID("intc3", &mstp_clks[MSTP023]),
+       CLKDEV_CON_ID("intc0", &mstp_clks[MSTP022]),
+       CLKDEV_CON_ID("dmac0", &mstp_clks[MSTP021]),
+       CLKDEV_CON_ID("sh0", &mstp_clks[MSTP020]),
+       CLKDEV_CON_ID("hudi0", &mstp_clks[MSTP019]),
+       CLKDEV_CON_ID("ubc0", &mstp_clks[MSTP017]),
+       CLKDEV_CON_ID("tmu_fck", &mstp_clks[MSTP015]),
+       CLKDEV_CON_ID("cmt_fck", &mstp_clks[MSTP014]),
+       CLKDEV_CON_ID("rwdt0", &mstp_clks[MSTP013]),
+       CLKDEV_CON_ID("mfi0", &mstp_clks[MSTP011]),
+       CLKDEV_CON_ID("flctl0", &mstp_clks[MSTP010]),
+       {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP007],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP006],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP005],
+       },
+       CLKDEV_CON_ID("msiof0", &mstp_clks[MSTP002]),
+       CLKDEV_CON_ID("sbr0", &mstp_clks[MSTP001]),
+       CLKDEV_CON_ID("i2c0", &mstp_clks[MSTP109]),
+       CLKDEV_CON_ID("icb0", &mstp_clks[MSTP227]),
+       CLKDEV_CON_ID("meram0", &mstp_clks[MSTP226]),
+       CLKDEV_CON_ID("dacy1", &mstp_clks[MSTP224]),
+       CLKDEV_CON_ID("dacy0", &mstp_clks[MSTP223]),
+       CLKDEV_CON_ID("tsif0", &mstp_clks[MSTP222]),
+       CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP218]),
+       CLKDEV_CON_ID("mmcif0", &mstp_clks[MSTP217]),
+       CLKDEV_CON_ID("usbf0", &mstp_clks[MSTP211]),
+       CLKDEV_CON_ID("veu1", &mstp_clks[MSTP207]),
+       CLKDEV_CON_ID("vou0", &mstp_clks[MSTP205]),
+       CLKDEV_CON_ID("beu0", &mstp_clks[MSTP204]),
+       CLKDEV_CON_ID("ceu0", &mstp_clks[MSTP203]),
+       CLKDEV_CON_ID("veu0", &mstp_clks[MSTP202]),
+       CLKDEV_CON_ID("vpu0", &mstp_clks[MSTP201]),
+       CLKDEV_CON_ID("lcdc0", &mstp_clks[MSTP200]),
 };
 
 int __init arch_clk_init(void)
@@ -202,14 +280,16 @@ int __init arch_clk_init(void)
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
                ret = clk_register(main_clks[k]);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
+               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
        return ret;
 }
index 15db6d5..2030f3d 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/hwblk.h>
 #include <cpu/sh7722.h>
@@ -36,8 +37,6 @@
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
 static struct clk r_clk = {
-       .name           = "rclk",
-       .id             = -1,
        .rate           = 32768,
 };
 
@@ -46,8 +45,6 @@ static struct clk r_clk = {
  * from the platform code.
  */
 struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -69,8 +66,6 @@ static struct clk_ops dll_clk_ops = {
 };
 
 static struct clk dll_clk = {
-       .name           = "dll_clk",
-       .id             = -1,
        .ops            = &dll_clk_ops,
        .parent         = &r_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -94,8 +89,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .flags          = CLK_ENABLE_ON_INIT,
 };
@@ -121,68 +114,142 @@ static struct clk_div4_table div4_table = {
        .div_mult_table = &div4_div_mult_table,
 };
 
-#define DIV4(_str, _reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
+#define DIV4(_reg, _bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
 
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
-       [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
-       [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x1fff, 0),
+       [DIV4_I] = DIV4(FRQCR, 20, 0x1fef, CLK_ENABLE_ON_INIT),
+       [DIV4_U] = DIV4(FRQCR, 16, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(FRQCR, 12, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(FRQCR, 8, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_B3] = DIV4(FRQCR, 4, 0x1fff, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(FRQCR, 0, 0x1fff, 0),
 };
 
 enum { DIV4_IRDA, DIV4_ENABLE_NR };
 
 struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
-       [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x1fff, 0),
+       [DIV4_IRDA] = DIV4(IRDACLKCR, 0, 0x1fff, 0),
 };
 
 enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
 
 struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
-       [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x1fff, 0),
-       [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x1fff, 0),
+       [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x1fff, 0),
+       [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x1fff, 0),
 };
 
-struct clk div6_clks[] = {
-       SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
+enum { DIV6_V, DIV6_NR };
+
+struct clk div6_clks[DIV6_NR] = {
+       [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
+};
+
+static struct clk mstp_clks[HWBLK_NR] = {
+       SH_HWBLK_CLK(HWBLK_URAM, &div4_clks[DIV4_U], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_XYMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_TMU, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0),
+
+       SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0),
+
+       SH_HWBLK_CLK(HWBLK_SDHI, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_USBF, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VEU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_P], 0),
 };
 
-#define R_CLK &r_clk
-#define P_CLK &div4_clks[DIV4_P]
-#define B_CLK &div4_clks[DIV4_B]
-#define U_CLK &div4_clks[DIV4_U]
-
-static struct clk mstp_clks[] = {
-       SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU, 0),
-       SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
-       SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
-       SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
-       SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
-       SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
-       SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
-
-       SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
-       SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
-
-       SH_HWBLK_CLK("sdhi0", -1, P_CLK, HWBLK_SDHI, 0),
-       SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
-       SH_HWBLK_CLK("usbf0", -1, P_CLK, HWBLK_USBF, 0),
-       SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
-       SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
-       SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
-       SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0),
-       SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
-       SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
-       SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, 0),
-       SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
-       SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0),
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("rclk", &r_clk),
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("dll_clk", &dll_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+       CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("irda_clk", &div4_enable_clks[DIV4_IRDA]),
+       CLKDEV_CON_ID("siua_clk", &div4_reparent_clks[DIV4_SIUA]),
+       CLKDEV_CON_ID("siub_clk", &div4_reparent_clks[DIV4_SIUB]),
+
+       /* DIV6 clocks */
+       CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
+
+       /* MSTP clocks */
+       CLKDEV_CON_ID("uram0", &mstp_clks[HWBLK_URAM]),
+       CLKDEV_CON_ID("xymem0", &mstp_clks[HWBLK_XYMEM]),
+       {
+               /* TMU0 */
+               .dev_id         = "sh_tmu.0",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU],
+       }, {
+               /* TMU1 */
+               .dev_id         = "sh_tmu.1",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU],
+       }, {
+               /* TMU2 */
+               .dev_id         = "sh_tmu.2",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU],
+       },
+       CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+       CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
+       CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
+       {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF0],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF1],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF2],
+       },
+       CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC]),
+       CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
+       CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI]),
+       CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]),
+       CLKDEV_CON_ID("usbf0", &mstp_clks[HWBLK_USBF]),
+       CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
+       CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]),
+       CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]),
+       CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
+       CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
+       CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]),
+       CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]),
+       CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
+       CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
 };
 
 int __init arch_clk_init(void)
@@ -198,6 +265,8 @@ int __init arch_clk_init(void)
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
                ret = clk_register(main_clks[k]);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
@@ -210,10 +279,10 @@ int __init arch_clk_init(void)
                                        DIV4_REPARENT_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
+               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
        if (!ret)
-               ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
 
        return ret;
 }
index 50babe0..d3938f0 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/clk.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/hwblk.h>
 #include <cpu/sh7723.h>
@@ -36,8 +38,6 @@
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
 static struct clk r_clk = {
-       .name           = "rclk",
-       .id             = -1,
        .rate           = 32768,
 };
 
@@ -46,8 +46,6 @@ static struct clk r_clk = {
  * from the platform code.
  */
 struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -69,8 +67,6 @@ static struct clk_ops dll_clk_ops = {
 };
 
 static struct clk dll_clk = {
-       .name           = "dll_clk",
-       .id             = -1,
        .ops            = &dll_clk_ops,
        .parent         = &r_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -94,8 +90,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .flags          = CLK_ENABLE_ON_INIT,
 };
@@ -123,92 +117,215 @@ static struct clk_div4_table div4_table = {
 
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_B3, DIV4_P, DIV4_NR };
 
-#define DIV4(_str, _reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
+#define DIV4(_reg, _bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_I] = DIV4("cpu_clk", FRQCR, 20, 0x0dbf, CLK_ENABLE_ON_INIT),
-       [DIV4_U] = DIV4("umem_clk", FRQCR, 16, 0x0dbf, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", FRQCR, 12, 0x0dbf, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT),
-       [DIV4_B3] = DIV4("b3_clk", FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT),
-       [DIV4_P] = DIV4("peripheral_clk", FRQCR, 0, 0x0dbf, 0),
+       [DIV4_I] = DIV4(FRQCR, 20, 0x0dbf, CLK_ENABLE_ON_INIT),
+       [DIV4_U] = DIV4(FRQCR, 16, 0x0dbf, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(FRQCR, 12, 0x0dbf, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(FRQCR, 8, 0x0dbf, CLK_ENABLE_ON_INIT),
+       [DIV4_B3] = DIV4(FRQCR, 4, 0x0db4, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(FRQCR, 0, 0x0dbf, 0),
 };
 
 enum { DIV4_IRDA, DIV4_ENABLE_NR };
 
 struct clk div4_enable_clks[DIV4_ENABLE_NR] = {
-       [DIV4_IRDA] = DIV4("irda_clk", IRDACLKCR, 0, 0x0dbf, 0),
+       [DIV4_IRDA] = DIV4(IRDACLKCR, 0, 0x0dbf, 0),
 };
 
 enum { DIV4_SIUA, DIV4_SIUB, DIV4_REPARENT_NR };
 
 struct clk div4_reparent_clks[DIV4_REPARENT_NR] = {
-       [DIV4_SIUA] = DIV4("siua_clk", SCLKACR, 0, 0x0dbf, 0),
-       [DIV4_SIUB] = DIV4("siub_clk", SCLKBCR, 0, 0x0dbf, 0),
-};
-struct clk div6_clks[] = {
-       SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
+       [DIV4_SIUA] = DIV4(SCLKACR, 0, 0x0dbf, 0),
+       [DIV4_SIUB] = DIV4(SCLKBCR, 0, 0x0dbf, 0),
 };
+enum { DIV6_V, DIV6_NR };
 
-#define R_CLK (&r_clk)
-#define P_CLK (&div4_clks[DIV4_P])
-#define B_CLK (&div4_clks[DIV4_B])
-#define U_CLK (&div4_clks[DIV4_U])
-#define I_CLK (&div4_clks[DIV4_I])
-#define SH_CLK (&div4_clks[DIV4_SH])
+struct clk div6_clks[DIV6_NR] = {
+       [DIV6_V] = SH_CLK_DIV6(&pll_clk, VCLKCR, 0),
+};
 
 static struct clk mstp_clks[] = {
        /* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
-       SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("intc0", -1, I_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
-       SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
-       SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
-       SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
-       SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
-       SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
-       SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
-       SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
-       SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
-       SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
-       SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
-       SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
-       SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
-       SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
-       SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
-       SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
-       SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
-       SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0),
-
-       SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
-       SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
-
-       SH_HWBLK_CLK("atapi0", -1, SH_CLK, HWBLK_ATAPI, 0),
-       SH_HWBLK_CLK("adc0", -1, P_CLK, HWBLK_ADC, 0),
-       SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
-       SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
-       SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
-       SH_HWBLK_CLK("icb0", -1, B_CLK, HWBLK_ICB, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
-       SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
-       SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
-       SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0),
-       SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
-       SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
-       SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, 0),
-       SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
-       SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
-       SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
-       SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, 0),
-       SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
-       SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
+       SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_OC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_L2C, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_ILMEM, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_FPU, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_INTC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_DMAC0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SHYWAY, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_HUDI, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_UBC, &div4_clks[DIV4_I], 0),
+       SH_HWBLK_CLK(HWBLK_TMU0, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_DMAC1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_TMU1, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_FLCTL, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF3, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF4, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF5, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_MSIOF0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_MSIOF1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_MERAM, &div4_clks[DIV4_SH], 0),
+
+       SH_HWBLK_CLK(HWBLK_IIC, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0),
+
+       SH_HWBLK_CLK(HWBLK_ATAPI, &div4_clks[DIV4_SH], 0),
+       SH_HWBLK_CLK(HWBLK_ADC, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_TPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_IRDA, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_TSIF, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_ICB, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_SDHI0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SDHI1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_USB, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SIU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VEU2H1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_BEU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_CEU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VEU2H0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0),
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("rclk", &r_clk),
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("dll_clk", &dll_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+       CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("b3_clk", &div4_clks[DIV4_B3]),
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("irda_clk", &div4_enable_clks[DIV4_IRDA]),
+       CLKDEV_CON_ID("siua_clk", &div4_reparent_clks[DIV4_SIUA]),
+       CLKDEV_CON_ID("siub_clk", &div4_reparent_clks[DIV4_SIUB]),
+
+       /* DIV6 clocks */
+       CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
+
+       /* MSTP clocks */
+       CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]),
+       CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]),
+       CLKDEV_CON_ID("oc0", &mstp_clks[HWBLK_OC]),
+       CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]),
+       CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]),
+       CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]),
+       CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]),
+       CLKDEV_CON_ID("dmac0", &mstp_clks[HWBLK_DMAC0]),
+       CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
+       CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
+       CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
+       {
+               /* TMU0 */
+               .dev_id         = "sh_tmu.0",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU0],
+       }, {
+               /* TMU1 */
+               .dev_id         = "sh_tmu.1",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU0],
+       }, {
+               /* TMU2 */
+               .dev_id         = "sh_tmu.2",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU0],
+       },
+       CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+       CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
+       CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
+       {
+               /* TMU3 */
+               .dev_id         = "sh_tmu.3",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU1],
+       }, {
+               /* TMU4 */
+               .dev_id         = "sh_tmu.4",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU1],
+       }, {
+               /* TMU5 */
+               .dev_id         = "sh_tmu.5",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU1],
+       },
+       CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
+       {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF0],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF1],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF2],
+       }, {
+               /* SCIF3 */
+               .dev_id         = "sh-sci.3",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF3],
+       }, {
+               /* SCIF4 */
+               .dev_id         = "sh-sci.4",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF4],
+       }, {
+               /* SCIF5 */
+               .dev_id         = "sh-sci.5",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF5],
+       },
+       CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
+       CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
+       CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]),
+       CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC]),
+       CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
+       CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
+       CLKDEV_CON_ID("adc0", &mstp_clks[HWBLK_ADC]),
+       CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]),
+       CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
+       CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]),
+       CLKDEV_CON_ID("icb0", &mstp_clks[HWBLK_ICB]),
+       CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI0]),
+       CLKDEV_CON_ID("sdhi1", &mstp_clks[HWBLK_SDHI1]),
+       CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]),
+       CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB]),
+       CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
+       CLKDEV_CON_ID("siu0", &mstp_clks[HWBLK_SIU]),
+       CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU2H1]),
+       CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]),
+       CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
+       CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU]),
+       CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]),
+       CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
+       CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
 };
 
 int __init arch_clk_init(void)
@@ -222,7 +339,9 @@ int __init arch_clk_init(void)
                pll_clk.parent = &extal_clk;
 
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
-               ret = clk_register(main_clks[k]);
+               ret |= clk_register(main_clks[k]);
+
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
@@ -236,10 +355,10 @@ int __init arch_clk_init(void)
                                        DIV4_REPARENT_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
+               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
        if (!ret)
-               ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
 
        return ret;
 }
index 6707061..2d9700c 100644 (file)
@@ -21,6 +21,8 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/clk.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/hwblk.h>
 #include <cpu/sh7724.h>
@@ -39,8 +41,6 @@
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
 static struct clk r_clk = {
-       .name           = "rclk",
-       .id             = -1,
        .rate           = 32768,
 };
 
@@ -49,8 +49,6 @@ static struct clk r_clk = {
  * from the platform code.
  */
 struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -74,8 +72,6 @@ static struct clk_ops fll_clk_ops = {
 };
 
 static struct clk fll_clk = {
-       .name           = "fll_clk",
-       .id             = -1,
        .ops            = &fll_clk_ops,
        .parent         = &r_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -96,8 +92,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .flags          = CLK_ENABLE_ON_INIT,
 };
@@ -113,8 +107,6 @@ static struct clk_ops div3_clk_ops = {
 };
 
 static struct clk div3_clk = {
-       .name           = "div3_clk",
-       .id             = -1,
        .ops            = &div3_clk_ops,
        .parent         = &pll_clk,
 };
@@ -151,86 +143,215 @@ static struct clk_div4_table div4_table = {
 
 enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_P, DIV4_M1, DIV4_NR };
 
-#define DIV4(_str, _reg, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, _reg, _bit, _mask, _flags)
+#define DIV4(_reg, _bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_I] = DIV4("cpu_clk", FRQCRA, 20, 0x2f7d, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT),
-       [DIV4_P] = DIV4("peripheral_clk", FRQCRA, 0, 0x2f7c, 0),
-       [DIV4_M1] = DIV4("vpu_clk", FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
+       [DIV4_I] = DIV4(FRQCRA, 20, 0x2f7d, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(FRQCRA, 12, 0x2f7c, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(FRQCRA, 8, 0x2f7c, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(FRQCRA, 0, 0x2f7c, 0),
+       [DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
 };
 
-struct clk div6_clks[] = {
-       SH_CLK_DIV6("video_clk", &div3_clk, VCLKCR, 0),
-       SH_CLK_DIV6("fsia_clk", &div3_clk, FCLKACR, 0),
-       SH_CLK_DIV6("fsib_clk", &div3_clk, FCLKBCR, 0),
-       SH_CLK_DIV6("irda_clk", &div3_clk, IRDACLKCR, 0),
-       SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
+enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR };
+
+struct clk div6_clks[DIV6_NR] = {
+       [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
+       [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0),
+       [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0),
+       [DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
+       [DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
+};
+
+static struct clk mstp_clks[HWBLK_NR] = {
+       SH_HWBLK_CLK(HWBLK_TLB, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_IC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_OC, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_RSMEM, &div4_clks[DIV4_B], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_ILMEM, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_L2C, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_FPU, &div4_clks[DIV4_I], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_INTC, &div4_clks[DIV4_P], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_DMAC0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SHYWAY, &div4_clks[DIV4_SH], CLK_ENABLE_ON_INIT),
+       SH_HWBLK_CLK(HWBLK_HUDI, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_UBC, &div4_clks[DIV4_I], 0),
+       SH_HWBLK_CLK(HWBLK_TMU0, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_CMT, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_RWDT, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_DMAC1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_TMU1, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF0, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF1, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF2, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF3, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF4, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SCIF5, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_MSIOF0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_MSIOF1, &div4_clks[DIV4_B], 0),
+
+       SH_HWBLK_CLK(HWBLK_KEYSC, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_RTC, &r_clk, 0),
+       SH_HWBLK_CLK(HWBLK_IIC0, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_IIC1, &div4_clks[DIV4_P], 0),
+
+       SH_HWBLK_CLK(HWBLK_MMC, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_ETHER, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_ATAPI, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_TPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_IRDA, &div4_clks[DIV4_P], 0),
+       SH_HWBLK_CLK(HWBLK_TSIF, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_USB1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_USB0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_2DG, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SDHI0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_SDHI1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VEU1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_CEU1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_BEU1, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_2DDMAC, &div4_clks[DIV4_SH], 0),
+       SH_HWBLK_CLK(HWBLK_SPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_JPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VOU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_BEU0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_CEU0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VEU0, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_VPU, &div4_clks[DIV4_B], 0),
+       SH_HWBLK_CLK(HWBLK_LCDC, &div4_clks[DIV4_B], 0),
 };
 
-#define R_CLK (&r_clk)
-#define P_CLK (&div4_clks[DIV4_P])
-#define B_CLK (&div4_clks[DIV4_B])
-#define I_CLK (&div4_clks[DIV4_I])
-#define SH_CLK (&div4_clks[DIV4_SH])
-
-static struct clk mstp_clks[] = {
-       SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("rs0", -1, B_CLK, HWBLK_RSMEM, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("intc0", -1, P_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
-       SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
-       SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
-       SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
-       SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
-       SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
-       SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
-       SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
-       SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
-       SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
-       SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
-       SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
-       SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
-       SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
-       SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
-       SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
-       SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
-
-       SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
-       SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
-       SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC0, 0),
-       SH_HWBLK_CLK("i2c1", -1, P_CLK, HWBLK_IIC1, 0),
-
-       SH_HWBLK_CLK("mmc0", -1, B_CLK, HWBLK_MMC, 0),
-       SH_HWBLK_CLK("eth0", -1, B_CLK, HWBLK_ETHER, 0),
-       SH_HWBLK_CLK("atapi0", -1, B_CLK, HWBLK_ATAPI, 0),
-       SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
-       SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
-       SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
-       SH_HWBLK_CLK("usb1", -1, B_CLK, HWBLK_USB1, 0),
-       SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB0, 0),
-       SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
-       SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
-       SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
-       SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, 0),
-       SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0),
-       SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0),
-       SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0),
-       SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0),
-       SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0),
-       SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
-       SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0),
-       SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0),
-       SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, 0),
-       SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
-       SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("rclk", &r_clk),
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("fll_clk", &fll_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+       CLKDEV_CON_ID("div3_clk", &div3_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("vpu_clk", &div4_clks[DIV4_M1]),
+
+       /* DIV6 clocks */
+       CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
+       CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
+       CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
+       CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
+       CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
+
+       /* MSTP clocks */
+       CLKDEV_CON_ID("tlb0", &mstp_clks[HWBLK_TLB]),
+       CLKDEV_CON_ID("ic0", &mstp_clks[HWBLK_IC]),
+       CLKDEV_CON_ID("oc0", &mstp_clks[HWBLK_OC]),
+       CLKDEV_CON_ID("rs0", &mstp_clks[HWBLK_RSMEM]),
+       CLKDEV_CON_ID("ilmem0", &mstp_clks[HWBLK_ILMEM]),
+       CLKDEV_CON_ID("l2c0", &mstp_clks[HWBLK_L2C]),
+       CLKDEV_CON_ID("fpu0", &mstp_clks[HWBLK_FPU]),
+       CLKDEV_CON_ID("intc0", &mstp_clks[HWBLK_INTC]),
+       CLKDEV_CON_ID("dmac0", &mstp_clks[HWBLK_DMAC0]),
+       CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
+       CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
+       CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
+       {
+               /* TMU0 */
+               .dev_id         = "sh_tmu.0",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU0],
+       }, {
+               /* TMU1 */
+               .dev_id         = "sh_tmu.1",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU0],
+       }, {
+               /* TMU2 */
+               .dev_id         = "sh_tmu.2",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU0],
+       }, {
+               /* TMU3 */
+               .dev_id         = "sh_tmu.3",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU1],
+       },
+       CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
+       CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
+       CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
+       {
+               /* TMU4 */
+               .dev_id         = "sh_tmu.4",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU1],
+       }, {
+               /* TMU5 */
+               .dev_id         = "sh_tmu.5",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[HWBLK_TMU1],
+       }, {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF0],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF1],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF2],
+       }, {
+               /* SCIF3 */
+               .dev_id         = "sh-sci.3",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF3],
+       }, {
+               /* SCIF4 */
+               .dev_id         = "sh-sci.4",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF4],
+       }, {
+               /* SCIF5 */
+               .dev_id         = "sh-sci.5",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[HWBLK_SCIF5],
+       },
+       CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
+       CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
+       CLKDEV_CON_ID("keysc0", &mstp_clks[HWBLK_KEYSC]),
+       CLKDEV_CON_ID("rtc0", &mstp_clks[HWBLK_RTC]),
+       CLKDEV_CON_ID("i2c0", &mstp_clks[HWBLK_IIC0]),
+       CLKDEV_CON_ID("i2c1", &mstp_clks[HWBLK_IIC1]),
+       CLKDEV_CON_ID("mmc0", &mstp_clks[HWBLK_MMC]),
+       CLKDEV_CON_ID("eth0", &mstp_clks[HWBLK_ETHER]),
+       CLKDEV_CON_ID("atapi0", &mstp_clks[HWBLK_ATAPI]),
+       CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]),
+       CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]),
+       CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]),
+       CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]),
+       CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]),
+       CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]),
+       CLKDEV_CON_ID("sdhi0", &mstp_clks[HWBLK_SDHI0]),
+       CLKDEV_CON_ID("sdhi1", &mstp_clks[HWBLK_SDHI1]),
+       CLKDEV_CON_ID("veu1", &mstp_clks[HWBLK_VEU1]),
+       CLKDEV_CON_ID("ceu1", &mstp_clks[HWBLK_CEU1]),
+       CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]),
+       CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
+       CLKDEV_CON_ID("spu0", &mstp_clks[HWBLK_SPU]),
+       CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
+       CLKDEV_CON_ID("vou0", &mstp_clks[HWBLK_VOU]),
+       CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
+       CLKDEV_CON_ID("ceu0", &mstp_clks[HWBLK_CEU0]),
+       CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU0]),
+       CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
+       CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
 };
 
 int __init arch_clk_init(void)
@@ -246,14 +367,16 @@ int __init arch_clk_init(void)
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
                ret = clk_register(main_clks[k]);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
        if (!ret)
-               ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
+               ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
        if (!ret)
-               ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
 
        return ret;
 }
index 86aae60..0a752bd 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
 
@@ -87,7 +88,6 @@ static struct clk_ops sh7757_shyway_clk_ops = {
 };
 
 static struct clk sh7757_shyway_clk = {
-       .name           = "shyway_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &sh7757_shyway_clk_ops,
 };
@@ -100,6 +100,13 @@ static struct clk *sh7757_onchip_clocks[] = {
        &sh7757_shyway_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("shyway_clk", &sh7757_shyway_clk),
+};
+
 static int __init sh7757_clk_init(void)
 {
        struct clk *clk = clk_get(NULL, "master_clk");
@@ -123,6 +130,8 @@ static int __init sh7757_clk_init(void)
 
        clk_put(clk);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        return 0;
 }
 
index 9f40116..1f1df48 100644 (file)
@@ -12,6 +12,8 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
 #include <asm/io.h>
@@ -77,7 +79,6 @@ static struct clk_ops sh7763_shyway_clk_ops = {
 };
 
 static struct clk sh7763_shyway_clk = {
-       .name           = "shyway_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &sh7763_shyway_clk_ops,
 };
@@ -90,6 +91,13 @@ static struct clk *sh7763_onchip_clocks[] = {
        &sh7763_shyway_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("shyway_clk", &sh7763_shyway_clk),
+};
+
 int __init arch_clk_init(void)
 {
        struct clk *clk;
@@ -107,5 +115,7 @@ int __init arch_clk_init(void)
 
        clk_put(clk);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        return ret;
 }
index 150963a..62d7063 100644 (file)
@@ -11,6 +11,8 @@
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
 #include <asm/io.h>
@@ -83,7 +85,6 @@ static struct clk_ops sh7780_shyway_clk_ops = {
 };
 
 static struct clk sh7780_shyway_clk = {
-       .name           = "shyway_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &sh7780_shyway_clk_ops,
 };
@@ -96,6 +97,13 @@ static struct clk *sh7780_onchip_clocks[] = {
        &sh7780_shyway_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("shyway_clk", &sh7780_shyway_clk),
+};
+
 int __init arch_clk_init(void)
 {
        struct clk *clk;
@@ -113,5 +121,7 @@ int __init arch_clk_init(void)
 
        clk_put(clk);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        return ret;
 }
index d997f0a..c3e458a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * SH7785 support for the clock framework
  *
- *  Copyright (C) 2007 - 2009  Paul Mundt
+ *  Copyright (C) 2007 - 2010  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -14,6 +14,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/cpufreq.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
 #include <cpu/sh7785.h>
@@ -23,8 +24,6 @@
  * from the platform code.
  */
 static struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -42,8 +41,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .parent         = &extal_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -69,48 +66,149 @@ static struct clk_div4_table div4_table = {
 enum { DIV4_I, DIV4_U, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_GA,
        DIV4_DU, DIV4_P, DIV4_NR };
 
-#define DIV4(_str, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags)
+#define DIV4(_bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_P] = DIV4("peripheral_clk", 0, 0x0f80, 0),
-       [DIV4_DU] = DIV4("du_clk", 4, 0x0ff0, 0),
-       [DIV4_GA] = DIV4("ga_clk", 8, 0x0030, 0),
-       [DIV4_DDR] = DIV4("ddr_clk", 12, 0x000c, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", 16, 0x0fe0, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", 20, 0x000c, CLK_ENABLE_ON_INIT),
-       [DIV4_U] = DIV4("umem_clk", 24, 0x000c, CLK_ENABLE_ON_INIT),
-       [DIV4_I] = DIV4("cpu_clk", 28, 0x000e, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(0, 0x0f80, 0),
+       [DIV4_DU] = DIV4(4, 0x0ff0, 0),
+       [DIV4_GA] = DIV4(8, 0x0030, 0),
+       [DIV4_DDR] = DIV4(12, 0x000c, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(16, 0x0fe0, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(20, 0x000c, CLK_ENABLE_ON_INIT),
+       [DIV4_U] = DIV4(24, 0x000c, CLK_ENABLE_ON_INIT),
+       [DIV4_I] = DIV4(28, 0x000e, CLK_ENABLE_ON_INIT),
 };
 
 #define MSTPCR0                0xffc80030
 #define MSTPCR1                0xffc80034
 
-static struct clk mstp_clks[] = {
+enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024,
+       MSTP021, MSTP020, MSTP017, MSTP016,
+       MSTP013, MSTP012, MSTP009, MSTP008, MSTP003, MSTP002,
+       MSTP119, MSTP117, MSTP105, MSTP104, MSTP100,
+       MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
        /* MSTPCR0 */
-       SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0),
-       SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0),
-       SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0),
-       SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0),
-       SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0),
-       SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0),
-       SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0),
-       SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0),
-       SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0),
-       SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0),
-       SH_CLK_MSTP32("mmcif_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 13, 0),
-       SH_CLK_MSTP32("flctl_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 12, 0),
-       SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0),
-       SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0),
-       SH_CLK_MSTP32("siof_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 3, 0),
-       SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0),
+       [MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0),
+       [MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0),
+       [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
+       [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
+       [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
+       [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
+       [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
+       [MSTP020] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
+       [MSTP017] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
+       [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0),
+       [MSTP013] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 13, 0),
+       [MSTP012] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 12, 0),
+       [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
+       [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
+       [MSTP003] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 3, 0),
+       [MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
 
        /* MSTPCR1 */
-       SH_CLK_MSTP32("hudi_fck", -1, NULL, MSTPCR1, 19, 0),
-       SH_CLK_MSTP32("ubc_fck", -1, NULL, MSTPCR1, 17, 0),
-       SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0),
-       SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0),
-       SH_CLK_MSTP32("gdta_fck", -1, NULL, MSTPCR1, 0, 0),
+       [MSTP119] = SH_CLK_MSTP32(NULL, MSTPCR1, 19, 0),
+       [MSTP117] = SH_CLK_MSTP32(NULL, MSTPCR1, 17, 0),
+       [MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
+       [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
+       [MSTP100] = SH_CLK_MSTP32(NULL, MSTPCR1, 0, 0),
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]),
+       CLKDEV_CON_ID("ga_clk", &div4_clks[DIV4_GA]),
+       CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("umem_clk", &div4_clks[DIV4_U]),
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+       /* MSTP32 clocks */
+       {
+               /* SCIF5 */
+               .dev_id         = "sh-sci.5",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP029],
+       }, {
+               /* SCIF4 */
+               .dev_id         = "sh-sci.4",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP028],
+       }, {
+               /* SCIF3 */
+               .dev_id         = "sh-sci.3",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP027],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP026],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP025],
+       }, {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP024],
+       },
+       CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]),
+       CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]),
+       CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]),
+       CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]),
+       CLKDEV_CON_ID("mmcif_fck", &mstp_clks[MSTP013]),
+       CLKDEV_CON_ID("flctl_fck", &mstp_clks[MSTP012]),
+       {
+               /* TMU0 */
+               .dev_id         = "sh_tmu.0",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP008],
+       }, {
+               /* TMU1 */
+               .dev_id         = "sh_tmu.1",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP008],
+       }, {
+               /* TMU2 */
+               .dev_id         = "sh_tmu.2",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP008],
+       }, {
+               /* TMU3 */
+               .dev_id         = "sh_tmu.3",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP009],
+       }, {
+               /* TMU4 */
+               .dev_id         = "sh_tmu.4",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP009],
+       }, {
+               /* TMU5 */
+               .dev_id         = "sh_tmu.5",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP009],
+       },
+       CLKDEV_CON_ID("siof_fck", &mstp_clks[MSTP003]),
+       CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]),
+       CLKDEV_CON_ID("hudi_fck", &mstp_clks[MSTP119]),
+       CLKDEV_CON_ID("ubc_fck", &mstp_clks[MSTP117]),
+       CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
+       CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
+       CLKDEV_CON_ID("gdta_fck", &mstp_clks[MSTP100]),
 };
 
 int __init arch_clk_init(void)
@@ -119,12 +217,14 @@ int __init arch_clk_init(void)
 
        for (i = 0; i < ARRAY_SIZE(clks); i++)
                ret |= clk_register(clks[i]);
+       for (i = 0; i < ARRAY_SIZE(lookups); i++)
+               clkdev_add(&lookups[i]);
 
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
                                           &div4_table);
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
        return ret;
 }
index af69fd4..105a6d4 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/clk.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
 
@@ -21,8 +23,6 @@
  * from the platform code.
  */
 static struct clk extal_clk = {
-       .name           = "extal",
-       .id             = -1,
        .rate           = 33333333,
 };
 
@@ -44,8 +44,6 @@ static struct clk_ops pll_clk_ops = {
 };
 
 static struct clk pll_clk = {
-       .name           = "pll_clk",
-       .id             = -1,
        .ops            = &pll_clk_ops,
        .parent         = &extal_clk,
        .flags          = CLK_ENABLE_ON_INIT,
@@ -70,54 +68,191 @@ static struct clk_div4_table div4_table = {
 
 enum { DIV4_I, DIV4_SH, DIV4_B, DIV4_DDR, DIV4_DU, DIV4_P, DIV4_NR };
 
-#define DIV4(_str, _bit, _mask, _flags) \
-  SH_CLK_DIV4(_str, &pll_clk, FRQMR1, _bit, _mask, _flags)
+#define DIV4(_bit, _mask, _flags) \
+  SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
 
 struct clk div4_clks[DIV4_NR] = {
-       [DIV4_P] = DIV4("peripheral_clk", 0, 0x0b40, 0),
-       [DIV4_DU] = DIV4("du_clk", 4, 0x0010, 0),
-       [DIV4_DDR] = DIV4("ddr_clk", 12, 0x0002, CLK_ENABLE_ON_INIT),
-       [DIV4_B] = DIV4("bus_clk", 16, 0x0360, CLK_ENABLE_ON_INIT),
-       [DIV4_SH] = DIV4("shyway_clk", 20, 0x0002, CLK_ENABLE_ON_INIT),
-       [DIV4_I] = DIV4("cpu_clk", 28, 0x0006, CLK_ENABLE_ON_INIT),
+       [DIV4_P] = DIV4(0, 0x0b40, 0),
+       [DIV4_DU] = DIV4(4, 0x0010, 0),
+       [DIV4_DDR] = DIV4(12, 0x0002, CLK_ENABLE_ON_INIT),
+       [DIV4_B] = DIV4(16, 0x0360, CLK_ENABLE_ON_INIT),
+       [DIV4_SH] = DIV4(20, 0x0002, CLK_ENABLE_ON_INIT),
+       [DIV4_I] = DIV4(28, 0x0006, CLK_ENABLE_ON_INIT),
 };
 
 #define MSTPCR0                0xffc40030
 #define MSTPCR1                0xffc40034
 
-static struct clk mstp_clks[] = {
+enum { MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024,
+       MSTP023, MSTP022, MSTP021, MSTP020, MSTP017, MSTP016,
+       MSTP015, MSTP014, MSTP011, MSTP010, MSTP009, MSTP008,
+       MSTP005, MSTP004, MSTP002,
+       MSTP112, MSTP110, MSTP109, MSTP108,
+       MSTP105, MSTP104, MSTP103, MSTP102,
+       MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
        /* MSTPCR0 */
-       SH_CLK_MSTP32("scif_fck", 5, &div4_clks[DIV4_P], MSTPCR0, 29, 0),
-       SH_CLK_MSTP32("scif_fck", 4, &div4_clks[DIV4_P], MSTPCR0, 28, 0),
-       SH_CLK_MSTP32("scif_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 27, 0),
-       SH_CLK_MSTP32("scif_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 26, 0),
-       SH_CLK_MSTP32("scif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 25, 0),
-       SH_CLK_MSTP32("scif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 24, 0),
-       SH_CLK_MSTP32("ssi_fck", 3, &div4_clks[DIV4_P], MSTPCR0, 23, 0),
-       SH_CLK_MSTP32("ssi_fck", 2, &div4_clks[DIV4_P], MSTPCR0, 22, 0),
-       SH_CLK_MSTP32("ssi_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 21, 0),
-       SH_CLK_MSTP32("ssi_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 20, 0),
-       SH_CLK_MSTP32("hac_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 17, 0),
-       SH_CLK_MSTP32("hac_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 16, 0),
-       SH_CLK_MSTP32("i2c_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 15, 0),
-       SH_CLK_MSTP32("i2c_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 14, 0),
-       SH_CLK_MSTP32("tmu9_11_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 11, 0),
-       SH_CLK_MSTP32("tmu678_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 10, 0),
-       SH_CLK_MSTP32("tmu345_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 9, 0),
-       SH_CLK_MSTP32("tmu012_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 8, 0),
-       SH_CLK_MSTP32("sdif_fck", 1, &div4_clks[DIV4_P], MSTPCR0, 5, 0),
-       SH_CLK_MSTP32("sdif_fck", 0, &div4_clks[DIV4_P], MSTPCR0, 4, 0),
-       SH_CLK_MSTP32("hspi_fck", -1, &div4_clks[DIV4_P], MSTPCR0, 2, 0),
+       [MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0),
+       [MSTP028] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 28, 0),
+       [MSTP027] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 27, 0),
+       [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0),
+       [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0),
+       [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0),
+       [MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0),
+       [MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0),
+       [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0),
+       [MSTP020] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 20, 0),
+       [MSTP017] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 17, 0),
+       [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0),
+       [MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0),
+       [MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0),
+       [MSTP011] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0),
+       [MSTP010] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0),
+       [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0),
+       [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0),
+       [MSTP005] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 5, 0),
+       [MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
+       [MSTP002] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 2, 0),
 
        /* MSTPCR1 */
-       SH_CLK_MSTP32("usb_fck", -1, NULL, MSTPCR1, 12, 0),
-       SH_CLK_MSTP32("pcie_fck", 2, NULL, MSTPCR1, 10, 0),
-       SH_CLK_MSTP32("pcie_fck", 1, NULL, MSTPCR1, 9, 0),
-       SH_CLK_MSTP32("pcie_fck", 0, NULL, MSTPCR1, 8, 0),
-       SH_CLK_MSTP32("dmac_11_6_fck", -1, NULL, MSTPCR1, 5, 0),
-       SH_CLK_MSTP32("dmac_5_0_fck", -1, NULL, MSTPCR1, 4, 0),
-       SH_CLK_MSTP32("du_fck", -1, NULL, MSTPCR1, 3, 0),
-       SH_CLK_MSTP32("ether_fck", -1, NULL, MSTPCR1, 2, 0),
+       [MSTP112] = SH_CLK_MSTP32(NULL, MSTPCR1, 12, 0),
+       [MSTP110] = SH_CLK_MSTP32(NULL, MSTPCR1, 10, 0),
+       [MSTP109] = SH_CLK_MSTP32(NULL, MSTPCR1, 9, 0),
+       [MSTP108] = SH_CLK_MSTP32(NULL, MSTPCR1, 8, 0),
+       [MSTP105] = SH_CLK_MSTP32(NULL, MSTPCR1, 5, 0),
+       [MSTP104] = SH_CLK_MSTP32(NULL, MSTPCR1, 4, 0),
+       [MSTP103] = SH_CLK_MSTP32(NULL, MSTPCR1, 3, 0),
+       [MSTP102] = SH_CLK_MSTP32(NULL, MSTPCR1, 2, 0),
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("extal", &extal_clk),
+       CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+       /* DIV4 clocks */
+       CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+       CLKDEV_CON_ID("du_clk", &div4_clks[DIV4_DU]),
+       CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_DDR]),
+       CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]),
+       CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+       CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+       /* MSTP32 clocks */
+       {
+               /* SCIF5 */
+               .dev_id         = "sh-sci.5",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP029],
+       }, {
+               /* SCIF4 */
+               .dev_id         = "sh-sci.4",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP028],
+       }, {
+               /* SCIF3 */
+               .dev_id         = "sh-sci.3",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP027],
+       }, {
+               /* SCIF2 */
+               .dev_id         = "sh-sci.2",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP026],
+       }, {
+               /* SCIF1 */
+               .dev_id         = "sh-sci.1",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP025],
+       }, {
+               /* SCIF0 */
+               .dev_id         = "sh-sci.0",
+               .con_id         = "sci_fck",
+               .clk            = &mstp_clks[MSTP024],
+       },
+       CLKDEV_CON_ID("ssi3_fck", &mstp_clks[MSTP023]),
+       CLKDEV_CON_ID("ssi2_fck", &mstp_clks[MSTP022]),
+       CLKDEV_CON_ID("ssi1_fck", &mstp_clks[MSTP021]),
+       CLKDEV_CON_ID("ssi0_fck", &mstp_clks[MSTP020]),
+       CLKDEV_CON_ID("hac1_fck", &mstp_clks[MSTP017]),
+       CLKDEV_CON_ID("hac0_fck", &mstp_clks[MSTP016]),
+       CLKDEV_CON_ID("i2c1_fck", &mstp_clks[MSTP015]),
+       CLKDEV_CON_ID("i2c0_fck", &mstp_clks[MSTP014]),
+       {
+               /* TMU0 */
+               .dev_id         = "sh_tmu.0",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP008],
+       }, {
+               /* TMU1 */
+               .dev_id         = "sh_tmu.1",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP008],
+       }, {
+               /* TMU2 */
+               .dev_id         = "sh_tmu.2",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP008],
+       }, {
+               /* TMU3 */
+               .dev_id         = "sh_tmu.3",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP009],
+       }, {
+               /* TMU4 */
+               .dev_id         = "sh_tmu.4",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP009],
+       }, {
+               /* TMU5 */
+               .dev_id         = "sh_tmu.5",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP009],
+       }, {
+               /* TMU6 */
+               .dev_id         = "sh_tmu.6",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP010],
+       }, {
+               /* TMU7 */
+               .dev_id         = "sh_tmu.7",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP010],
+       }, {
+               /* TMU8 */
+               .dev_id         = "sh_tmu.8",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP010],
+       }, {
+               /* TMU9 */
+               .dev_id         = "sh_tmu.9",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP011],
+       }, {
+               /* TMU10 */
+               .dev_id         = "sh_tmu.10",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP011],
+       }, {
+               /* TMU11 */
+               .dev_id         = "sh_tmu.11",
+               .con_id         = "tmu_fck",
+               .clk            = &mstp_clks[MSTP011],
+       },
+       CLKDEV_CON_ID("sdif1_fck", &mstp_clks[MSTP005]),
+       CLKDEV_CON_ID("sdif0_fck", &mstp_clks[MSTP004]),
+       CLKDEV_CON_ID("hspi_fck", &mstp_clks[MSTP002]),
+       CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP112]),
+       CLKDEV_CON_ID("pcie2_fck", &mstp_clks[MSTP110]),
+       CLKDEV_CON_ID("pcie1_fck", &mstp_clks[MSTP109]),
+       CLKDEV_CON_ID("pcie0_fck", &mstp_clks[MSTP108]),
+       CLKDEV_CON_ID("dmac_11_6_fck", &mstp_clks[MSTP105]),
+       CLKDEV_CON_ID("dmac_5_0_fck", &mstp_clks[MSTP104]),
+       CLKDEV_CON_ID("du_fck", &mstp_clks[MSTP103]),
+       CLKDEV_CON_ID("ether_fck", &mstp_clks[MSTP102]),
 };
 
 int __init arch_clk_init(void)
@@ -126,12 +261,14 @@ int __init arch_clk_init(void)
 
        for (i = 0; i < ARRAY_SIZE(clks); i++)
                ret |= clk_register(clks[i]);
+       for (i = 0; i < ARRAY_SIZE(lookups); i++)
+               clkdev_add(&lookups[i]);
 
        if (!ret)
                ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
                                           &div4_table);
        if (!ret)
-               ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+               ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
        return ret;
 }
index e75c57b..236a628 100644 (file)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/clkdev.h>
 #include <asm/clock.h>
 #include <asm/freq.h>
-#include <asm/io.h>
 
 static int ifc_divisors[] = { 1, 2, 4 ,6 };
 static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, 24, 32, 36, 48 };
@@ -94,7 +95,6 @@ static struct clk_ops shx3_shyway_clk_ops = {
 };
 
 static struct clk shx3_shyway_clk = {
-       .name           = "shyway_clk",
        .flags          = CLK_ENABLE_ON_INIT,
        .ops            = &shx3_shyway_clk_ops,
 };
@@ -107,6 +107,13 @@ static struct clk *shx3_onchip_clocks[] = {
        &shx3_shyway_clk,
 };
 
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+       /* main clocks */
+       CLKDEV_CON_ID("shyway_clk", &shx3_shyway_clk),
+};
+
 int __init arch_clk_init(void)
 {
        struct clk *clk;
@@ -124,5 +131,7 @@ int __init arch_clk_init(void)
 
        clk_put(clk);
 
+       clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
        return ret;
 }
index 45eb1bf..3681caf 100644 (file)
@@ -21,7 +21,6 @@ static struct plat_sci_port scif0_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
-       .clk            = "scif0",
 };
 
 static struct platform_device scif0_device = {
@@ -37,7 +36,6 @@ static struct plat_sci_port scif1_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
-       .clk            = "scif1",
 };
 
 static struct platform_device scif1_device = {
@@ -53,7 +51,6 @@ static struct plat_sci_port scif2_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
-       .clk            = "scif2",
 };
 
 static struct platform_device scif2_device = {
@@ -69,7 +66,6 @@ static struct plat_sci_port scif3_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 83, 83, 83, 83 },
-       .clk            = "scif3",
 };
 
 static struct platform_device scif3_device = {
@@ -207,17 +203,14 @@ static struct platform_device jpu_device = {
 };
 
 static struct sh_timer_config cmt_platform_data = {
-       .name = "CMT",
        .channel_offset = 0x60,
        .timer_bit = 5,
-       .clk = "cmt0",
        .clockevent_rating = 125,
        .clocksource_rating = 200,
 };
 
 static struct resource cmt_resources[] = {
        [0] = {
-               .name   = "CMT",
                .start  = 0x044a0060,
                .end    = 0x044a006b,
                .flags  = IORESOURCE_MEM,
@@ -239,16 +232,13 @@ static struct platform_device cmt_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu0",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -270,16 +260,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu0",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -301,15 +288,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu0",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002b,
                .flags  = IORESOURCE_MEM,
index c494c19..8dab9e1 100644 (file)
@@ -23,7 +23,6 @@ static struct plat_sci_port scif0_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
-       .clk            = "scif0",
 };
 
 static struct platform_device scif0_device = {
@@ -169,17 +168,14 @@ static struct platform_device veu1_device = {
 };
 
 static struct sh_timer_config cmt_platform_data = {
-       .name = "CMT",
        .channel_offset = 0x60,
        .timer_bit = 5,
-       .clk = "cmt0",
        .clockevent_rating = 125,
        .clocksource_rating = 200,
 };
 
 static struct resource cmt_resources[] = {
        [0] = {
-               .name   = "CMT",
                .start  = 0x044a0060,
                .end    = 0x044a006b,
                .flags  = IORESOURCE_MEM,
@@ -201,16 +197,13 @@ static struct platform_device cmt_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu0",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -232,16 +225,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu0",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -263,15 +253,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu0",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002b,
                .flags  = IORESOURCE_MEM,
index fd7e363..24c6167 100644 (file)
@@ -24,7 +24,7 @@
 #include <cpu/dma-register.h>
 #include <cpu/sh7722.h>
 
-static struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
+static const struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
        {
                .slave_id       = SHDMA_SLAVE_SCIF0_TX,
                .addr           = 0xffe0000c,
@@ -78,7 +78,7 @@ static struct sh_dmae_slave_config sh7722_dmae_slaves[] = {
        },
 };
 
-static struct sh_dmae_channel sh7722_dmae_channels[] = {
+static const struct sh_dmae_channel sh7722_dmae_channels[] = {
        {
                .offset = 0,
                .dmars = 0,
@@ -106,7 +106,7 @@ static struct sh_dmae_channel sh7722_dmae_channels[] = {
        }
 };
 
-static unsigned int ts_shift[] = TS_SHIFT;
+static const unsigned int ts_shift[] = TS_SHIFT;
 
 static struct sh_dmae_pdata dma_platform_data = {
        .slave          = sh7722_dmae_slaves,
@@ -174,7 +174,6 @@ static struct plat_sci_port scif0_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
-       .clk            = "scif0",
 };
 
 static struct platform_device scif0_device = {
@@ -190,7 +189,6 @@ static struct plat_sci_port scif1_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
-       .clk            = "scif1",
 };
 
 static struct platform_device scif1_device = {
@@ -206,7 +204,6 @@ static struct plat_sci_port scif2_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
-       .clk            = "scif2",
 };
 
 static struct platform_device scif2_device = {
@@ -401,17 +398,14 @@ static struct platform_device jpu_device = {
 };
 
 static struct sh_timer_config cmt_platform_data = {
-       .name = "CMT",
        .channel_offset = 0x60,
        .timer_bit = 5,
-       .clk = "cmt0",
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
 
 static struct resource cmt_resources[] = {
        [0] = {
-               .name   = "CMT",
                .start  = 0x044a0060,
                .end    = 0x044a006b,
                .flags  = IORESOURCE_MEM,
@@ -436,16 +430,13 @@ static struct platform_device cmt_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu0",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -470,16 +461,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu0",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -504,15 +492,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu0",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002b,
                .flags  = IORESOURCE_MEM,
index 85c61f6..0eadefd 100644 (file)
@@ -26,7 +26,6 @@ static struct plat_sci_port scif0_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
-       .clk            = "scif0",
 };
 
 static struct platform_device scif0_device = {
@@ -42,7 +41,6 @@ static struct plat_sci_port scif1_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
-       .clk            = "scif1",
 };
 
 static struct platform_device scif1_device = {
@@ -58,7 +56,6 @@ static struct plat_sci_port scif2_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
-       .clk            = "scif2",
 };
 
 static struct platform_device scif2_device = {
@@ -74,7 +71,6 @@ static struct plat_sci_port scif3_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIFA,
        .irqs           = { 56, 56, 56, 56 },
-       .clk            = "scif3",
 };
 
 static struct platform_device scif3_device = {
@@ -90,7 +86,6 @@ static struct plat_sci_port scif4_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIFA,
        .irqs           = { 88, 88, 88, 88 },
-       .clk            = "scif4",
 };
 
 static struct platform_device scif4_device = {
@@ -106,7 +101,6 @@ static struct plat_sci_port scif5_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIFA,
        .irqs           = { 109, 109, 109, 109 },
-       .clk            = "scif5",
 };
 
 static struct platform_device scif5_device = {
@@ -211,17 +205,14 @@ static struct platform_device veu1_device = {
 };
 
 static struct sh_timer_config cmt_platform_data = {
-       .name = "CMT",
        .channel_offset = 0x60,
        .timer_bit = 5,
-       .clk = "cmt0",
        .clockevent_rating = 125,
        .clocksource_rating = 125,
 };
 
 static struct resource cmt_resources[] = {
        [0] = {
-               .name   = "CMT",
                .start  = 0x044a0060,
                .end    = 0x044a006b,
                .flags  = IORESOURCE_MEM,
@@ -246,16 +237,13 @@ static struct platform_device cmt_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu0",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -280,16 +268,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu0",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -314,15 +299,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu0",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002b,
                .flags  = IORESOURCE_MEM,
@@ -347,15 +329,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu1",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffd90008,
                .end    = 0xffd90013,
                .flags  = IORESOURCE_MEM,
@@ -380,15 +359,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu1",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffd90014,
                .end    = 0xffd9001f,
                .flags  = IORESOURCE_MEM,
@@ -413,15 +389,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu1",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffd90020,
                .end    = 0xffd9002b,
                .flags  = IORESOURCE_MEM,
index e7fa2a9..89fe16d 100644 (file)
@@ -31,7 +31,7 @@
 #include <cpu/sh7724.h>
 
 /* DMA */
-static struct sh_dmae_channel sh7724_dmae0_channels[] = {
+static const struct sh_dmae_channel sh7724_dmae_channels[] = {
        {
                .offset = 0,
                .dmars = 0,
@@ -59,51 +59,11 @@ static struct sh_dmae_channel sh7724_dmae0_channels[] = {
        }
 };
 
-static struct sh_dmae_channel sh7724_dmae1_channels[] = {
-       {
-               .offset = 0,
-               .dmars = 0,
-               .dmars_bit = 0,
-       }, {
-               .offset = 0x10,
-               .dmars = 0,
-               .dmars_bit = 8,
-       }, {
-               .offset = 0x20,
-               .dmars = 4,
-               .dmars_bit = 0,
-       }, {
-               .offset = 0x30,
-               .dmars = 4,
-               .dmars_bit = 8,
-       }, {
-               .offset = 0x50,
-               .dmars = 8,
-               .dmars_bit = 0,
-       }, {
-               .offset = 0x60,
-               .dmars = 8,
-               .dmars_bit = 8,
-       }
-};
-
-static unsigned int ts_shift[] = TS_SHIFT;
-
-static struct sh_dmae_pdata dma0_platform_data = {
-       .channel        = sh7724_dmae0_channels,
-       .channel_num    = ARRAY_SIZE(sh7724_dmae0_channels),
-       .ts_low_shift   = CHCR_TS_LOW_SHIFT,
-       .ts_low_mask    = CHCR_TS_LOW_MASK,
-       .ts_high_shift  = CHCR_TS_HIGH_SHIFT,
-       .ts_high_mask   = CHCR_TS_HIGH_MASK,
-       .ts_shift       = ts_shift,
-       .ts_shift_num   = ARRAY_SIZE(ts_shift),
-       .dmaor_init     = DMAOR_INIT,
-};
+static const unsigned int ts_shift[] = TS_SHIFT;
 
-static struct sh_dmae_pdata dma1_platform_data = {
-       .channel        = sh7724_dmae1_channels,
-       .channel_num    = ARRAY_SIZE(sh7724_dmae1_channels),
+static struct sh_dmae_pdata dma_platform_data = {
+       .channel        = sh7724_dmae_channels,
+       .channel_num    = ARRAY_SIZE(sh7724_dmae_channels),
        .ts_low_shift   = CHCR_TS_LOW_SHIFT,
        .ts_low_mask    = CHCR_TS_LOW_MASK,
        .ts_high_shift  = CHCR_TS_HIGH_SHIFT,
@@ -187,7 +147,7 @@ static struct platform_device dma0_device = {
        .resource       = sh7724_dmae0_resources,
        .num_resources  = ARRAY_SIZE(sh7724_dmae0_resources),
        .dev            = {
-               .platform_data  = &dma0_platform_data,
+               .platform_data  = &dma_platform_data,
        },
        .archdata = {
                .hwblk_id = HWBLK_DMAC0,
@@ -200,7 +160,7 @@ static struct platform_device dma1_device = {
        .resource       = sh7724_dmae1_resources,
        .num_resources  = ARRAY_SIZE(sh7724_dmae1_resources),
        .dev            = {
-               .platform_data  = &dma1_platform_data,
+               .platform_data  = &dma_platform_data,
        },
        .archdata = {
                .hwblk_id = HWBLK_DMAC1,
@@ -213,7 +173,6 @@ static struct plat_sci_port scif0_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 80, 80, 80, 80 },
-       .clk            = "scif0",
 };
 
 static struct platform_device scif0_device = {
@@ -229,7 +188,6 @@ static struct plat_sci_port scif1_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 81, 81, 81, 81 },
-       .clk            = "scif1",
 };
 
 static struct platform_device scif1_device = {
@@ -245,7 +203,6 @@ static struct plat_sci_port scif2_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 82, 82, 82, 82 },
-       .clk            = "scif2",
 };
 
 static struct platform_device scif2_device = {
@@ -261,7 +218,6 @@ static struct plat_sci_port scif3_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIFA,
        .irqs           = { 56, 56, 56, 56 },
-       .clk            = "scif3",
 };
 
 static struct platform_device scif3_device = {
@@ -277,7 +233,6 @@ static struct plat_sci_port scif4_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIFA,
        .irqs           = { 88, 88, 88, 88 },
-       .clk            = "scif4",
 };
 
 static struct platform_device scif4_device = {
@@ -293,7 +248,6 @@ static struct plat_sci_port scif5_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIFA,
        .irqs           = { 109, 109, 109, 109 },
-       .clk            = "scif5",
 };
 
 static struct platform_device scif5_device = {
@@ -485,17 +439,14 @@ static struct platform_device veu1_device = {
 };
 
 static struct sh_timer_config cmt_platform_data = {
-       .name = "CMT",
        .channel_offset = 0x60,
        .timer_bit = 5,
-       .clk = "cmt0",
        .clockevent_rating = 125,
        .clocksource_rating = 200,
 };
 
 static struct resource cmt_resources[] = {
        [0] = {
-               .name   = "CMT",
                .start  = 0x044a0060,
                .end    = 0x044a006b,
                .flags  = IORESOURCE_MEM,
@@ -520,16 +471,13 @@ static struct platform_device cmt_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu0",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -554,16 +502,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu0",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -588,15 +533,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu0",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002b,
                .flags  = IORESOURCE_MEM,
@@ -622,15 +564,12 @@ static struct platform_device tmu2_device = {
 
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu1",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffd90008,
                .end    = 0xffd90013,
                .flags  = IORESOURCE_MEM,
@@ -655,15 +594,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu1",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffd90014,
                .end    = 0xffd9001f,
                .flags  = IORESOURCE_MEM,
@@ -688,15 +624,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu1",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffd90020,
                .end    = 0xffd9002b,
                .flags  = IORESOURCE_MEM,
index e75edf5..444aca9 100644 (file)
@@ -63,16 +63,13 @@ static struct platform_device scif4_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xfe430008,
                .end    = 0xfe430013,
                .flags  = IORESOURCE_MEM,
@@ -94,16 +91,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xfe430014,
                .end    = 0xfe43001f,
                .flags  = IORESOURCE_MEM,
index 7f6b0a5..5b5f6b0 100644 (file)
@@ -131,16 +131,13 @@ static struct platform_device usbf_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -162,16 +159,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -193,15 +187,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
@@ -223,15 +214,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffd88008,
                .end    = 0xffd88013,
                .flags  = IORESOURCE_MEM,
@@ -253,15 +241,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffd88014,
                .end    = 0xffd8801f,
                .flags  = IORESOURCE_MEM,
@@ -283,15 +268,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffd88020,
                .end    = 0xffd8802b,
                .flags  = IORESOURCE_MEM,
index 86d681e..7270d7f 100644 (file)
@@ -165,16 +165,13 @@ static struct platform_device scif9_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -196,16 +193,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -227,15 +221,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
@@ -257,15 +248,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffd81008,
                .end    = 0xffd81013,
                .flags  = IORESOURCE_MEM,
@@ -287,15 +275,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffd81014,
                .end    = 0xffd8101f,
                .flags  = IORESOURCE_MEM,
@@ -317,15 +302,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffd81020,
                .end    = 0xffd8102f,
                .flags  = IORESOURCE_MEM,
@@ -347,15 +329,12 @@ static struct platform_device tmu5_device = {
 };
 
 static struct sh_timer_config tmu6_platform_data = {
-       .name = "TMU6",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu6_resources[] = {
        [0] = {
-               .name   = "TMU6",
                .start  = 0xffd82008,
                .end    = 0xffd82013,
                .flags  = IORESOURCE_MEM,
@@ -377,15 +356,12 @@ static struct platform_device tmu6_device = {
 };
 
 static struct sh_timer_config tmu7_platform_data = {
-       .name = "TMU7",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu7_resources[] = {
        [0] = {
-               .name   = "TMU7",
                .start  = 0xffd82014,
                .end    = 0xffd8201f,
                .flags  = IORESOURCE_MEM,
@@ -407,15 +383,12 @@ static struct platform_device tmu7_device = {
 };
 
 static struct sh_timer_config tmu8_platform_data = {
-       .name = "TMU8",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu8_resources[] = {
        [0] = {
-               .name   = "TMU8",
                .start  = 0xffd82020,
                .end    = 0xffd8202b,
                .flags  = IORESOURCE_MEM,
index 02e792c..b12f537 100644 (file)
@@ -49,16 +49,13 @@ static struct platform_device scif1_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -80,16 +77,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -111,15 +105,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
@@ -141,15 +132,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffdc0008,
                .end    = 0xffdc0013,
                .flags  = IORESOURCE_MEM,
@@ -171,15 +159,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffdc0014,
                .end    = 0xffdc001f,
                .flags  = IORESOURCE_MEM,
@@ -201,15 +186,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffdc0020,
                .end    = 0xffdc002b,
                .flags  = IORESOURCE_MEM,
@@ -251,7 +233,7 @@ static struct platform_device rtc_device = {
 };
 
 /* DMA */
-static struct sh_dmae_channel sh7780_dmae0_channels[] = {
+static const struct sh_dmae_channel sh7780_dmae0_channels[] = {
        {
                .offset = 0,
                .dmars = 0,
@@ -279,7 +261,7 @@ static struct sh_dmae_channel sh7780_dmae0_channels[] = {
        }
 };
 
-static struct sh_dmae_channel sh7780_dmae1_channels[] = {
+static const struct sh_dmae_channel sh7780_dmae1_channels[] = {
        {
                .offset = 0,
        }, {
@@ -295,7 +277,7 @@ static struct sh_dmae_channel sh7780_dmae1_channels[] = {
        }
 };
 
-static unsigned int ts_shift[] = TS_SHIFT;
+static const unsigned int ts_shift[] = TS_SHIFT;
 
 static struct sh_dmae_pdata dma0_platform_data = {
        .channel        = sh7780_dmae0_channels,
index 1fcd88b..f3e3ea0 100644 (file)
@@ -25,7 +25,6 @@ static struct plat_sci_port scif0_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 40, 40, 40, 40 },
-       .clk            = "scif_fck",
 };
 
 static struct platform_device scif0_device = {
@@ -41,7 +40,6 @@ static struct plat_sci_port scif1_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 44, 44, 44, 44 },
-       .clk            = "scif_fck",
 };
 
 static struct platform_device scif1_device = {
@@ -57,7 +55,6 @@ static struct plat_sci_port scif2_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 60, 60, 60, 60 },
-       .clk            = "scif_fck",
 };
 
 static struct platform_device scif2_device = {
@@ -73,7 +70,6 @@ static struct plat_sci_port scif3_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 61, 61, 61, 61 },
-       .clk            = "scif_fck",
 };
 
 static struct platform_device scif3_device = {
@@ -89,7 +85,6 @@ static struct plat_sci_port scif4_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 62, 62, 62, 62 },
-       .clk            = "scif_fck",
 };
 
 static struct platform_device scif4_device = {
@@ -105,7 +100,6 @@ static struct plat_sci_port scif5_platform_data = {
        .flags          = UPF_BOOT_AUTOCONF,
        .type           = PORT_SCIF,
        .irqs           = { 63, 63, 63, 63 },
-       .clk            = "scif_fck",
 };
 
 static struct platform_device scif5_device = {
@@ -117,16 +111,13 @@ static struct platform_device scif5_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu012_fck",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -148,16 +139,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu012_fck",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -179,15 +167,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu012_fck",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
@@ -209,15 +194,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "tmu345_fck",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffdc0008,
                .end    = 0xffdc0013,
                .flags  = IORESOURCE_MEM,
@@ -239,15 +221,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "tmu345_fck",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffdc0014,
                .end    = 0xffdc001f,
                .flags  = IORESOURCE_MEM,
@@ -269,15 +248,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "tmu345_fck",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffdc0020,
                .end    = 0xffdc002b,
                .flags  = IORESOURCE_MEM,
@@ -299,7 +275,7 @@ static struct platform_device tmu5_device = {
 };
 
 /* DMA */
-static struct sh_dmae_channel sh7785_dmae0_channels[] = {
+static const struct sh_dmae_channel sh7785_dmae0_channels[] = {
        {
                .offset = 0,
                .dmars = 0,
@@ -327,7 +303,7 @@ static struct sh_dmae_channel sh7785_dmae0_channels[] = {
        }
 };
 
-static struct sh_dmae_channel sh7785_dmae1_channels[] = {
+static const struct sh_dmae_channel sh7785_dmae1_channels[] = {
        {
                .offset = 0,
        }, {
@@ -343,7 +319,7 @@ static struct sh_dmae_channel sh7785_dmae1_channels[] = {
        }
 };
 
-static unsigned int ts_shift[] = TS_SHIFT;
+static const unsigned int ts_shift[] = TS_SHIFT;
 
 static struct sh_dmae_pdata dma0_platform_data = {
        .channel        = sh7785_dmae0_channels,
index 7e58532..8165709 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SH7786 Setup
  *
- * Copyright (C) 2009  Renesas Solutions Corp.
+ * Copyright (C) 2009 - 2010  Renesas Solutions Corp.
  * Kuninori Morimoto <morimoto.kuninori@renesas.com>
  * Paul Mundt <paul.mundt@renesas.com>
  *
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
 #include <linux/sh_timer.h>
+#include <linux/sh_intc.h>
+#include <cpu/dma-register.h>
 #include <asm/mmzone.h>
+#include <asm/dmaengine.h>
 
 static struct plat_sci_port scif0_platform_data = {
        .mapbase        = 0xffea0000,
@@ -117,16 +120,13 @@ static struct platform_device scif5_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffd80008,
                .end    = 0xffd80013,
                .flags  = IORESOURCE_MEM,
@@ -148,16 +148,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffd80014,
                .end    = 0xffd8001f,
                .flags  = IORESOURCE_MEM,
@@ -179,15 +176,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffd80020,
                .end    = 0xffd8002f,
                .flags  = IORESOURCE_MEM,
@@ -209,15 +203,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffda0008,
                .end    = 0xffda0013,
                .flags  = IORESOURCE_MEM,
@@ -239,15 +230,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffda0014,
                .end    = 0xffda001f,
                .flags  = IORESOURCE_MEM,
@@ -269,15 +257,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffda0020,
                .end    = 0xffda002b,
                .flags  = IORESOURCE_MEM,
@@ -299,15 +284,12 @@ static struct platform_device tmu5_device = {
 };
 
 static struct sh_timer_config tmu6_platform_data = {
-       .name = "TMU6",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu6_resources[] = {
        [0] = {
-               .name   = "TMU6",
                .start  = 0xffdc0008,
                .end    = 0xffdc0013,
                .flags  = IORESOURCE_MEM,
@@ -329,15 +311,12 @@ static struct platform_device tmu6_device = {
 };
 
 static struct sh_timer_config tmu7_platform_data = {
-       .name = "TMU7",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu7_resources[] = {
        [0] = {
-               .name   = "TMU7",
                .start  = 0xffdc0014,
                .end    = 0xffdc001f,
                .flags  = IORESOURCE_MEM,
@@ -359,15 +338,12 @@ static struct platform_device tmu7_device = {
 };
 
 static struct sh_timer_config tmu8_platform_data = {
-       .name = "TMU8",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu8_resources[] = {
        [0] = {
-               .name   = "TMU8",
                .start  = 0xffdc0020,
                .end    = 0xffdc002b,
                .flags  = IORESOURCE_MEM,
@@ -389,15 +365,12 @@ static struct platform_device tmu8_device = {
 };
 
 static struct sh_timer_config tmu9_platform_data = {
-       .name = "TMU9",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu9_resources[] = {
        [0] = {
-               .name   = "TMU9",
                .start  = 0xffde0008,
                .end    = 0xffde0013,
                .flags  = IORESOURCE_MEM,
@@ -419,15 +392,12 @@ static struct platform_device tmu9_device = {
 };
 
 static struct sh_timer_config tmu10_platform_data = {
-       .name = "TMU10",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu10_resources[] = {
        [0] = {
-               .name   = "TMU10",
                .start  = 0xffde0014,
                .end    = 0xffde001f,
                .flags  = IORESOURCE_MEM,
@@ -449,15 +419,12 @@ static struct platform_device tmu10_device = {
 };
 
 static struct sh_timer_config tmu11_platform_data = {
-       .name = "TMU11",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu11_resources[] = {
        [0] = {
-               .name   = "TMU11",
                .start  = 0xffde0020,
                .end    = 0xffde002b,
                .flags  = IORESOURCE_MEM,
@@ -478,6 +445,83 @@ static struct platform_device tmu11_device = {
        .num_resources  = ARRAY_SIZE(tmu11_resources),
 };
 
+static const struct sh_dmae_channel dmac0_channels[] = {
+       {
+               .offset = 0,
+               .dmars = 0,
+               .dmars_bit = 0,
+       }, {
+               .offset = 0x10,
+               .dmars = 0,
+               .dmars_bit = 8,
+       }, {
+               .offset = 0x20,
+               .dmars = 4,
+               .dmars_bit = 0,
+       }, {
+               .offset = 0x30,
+               .dmars = 4,
+               .dmars_bit = 8,
+       }, {
+               .offset = 0x50,
+               .dmars = 8,
+               .dmars_bit = 0,
+       }, {
+               .offset = 0x60,
+               .dmars = 8,
+               .dmars_bit = 8,
+       }
+};
+
+static const unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma0_platform_data = {
+       .channel        = dmac0_channels,
+       .channel_num    = ARRAY_SIZE(dmac0_channels),
+       .ts_low_shift   = CHCR_TS_LOW_SHIFT,
+       .ts_low_mask    = CHCR_TS_LOW_MASK,
+       .ts_high_shift  = CHCR_TS_HIGH_SHIFT,
+       .ts_high_mask   = CHCR_TS_HIGH_MASK,
+       .ts_shift       = ts_shift,
+       .ts_shift_num   = ARRAY_SIZE(ts_shift),
+       .dmaor_init     = DMAOR_INIT,
+};
+
+/* Resource order important! */
+static struct resource dmac0_resources[] = {
+       {
+               /* Channel registers and DMAOR */
+               .start  = 0xfe008020,
+               .end    = 0xfe00808f,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               /* DMARSx */
+               .start  = 0xfe009000,
+               .end    = 0xfe00900b,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               /* DMA error IRQ */
+               .start  = evt2irq(0x5c0),
+               .end    = evt2irq(0x5c0),
+               .flags  = IORESOURCE_IRQ,
+       }, {
+               /* IRQ for channels 0-5 */
+               .start  = evt2irq(0x500),
+               .end    = evt2irq(0x5a0),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device dma0_device = {
+       .name           = "sh-dma-engine",
+       .id             = 0,
+       .resource       = dmac0_resources,
+       .num_resources  = ARRAY_SIZE(dmac0_resources),
+       .dev            = {
+               .platform_data  = &dma0_platform_data,
+       },
+};
+
 static struct resource usb_ohci_resources[] = {
        [0] = {
                .start  = 0xffe70400,
@@ -525,10 +569,10 @@ static struct platform_device *sh7786_early_devices[] __initdata = {
 };
 
 static struct platform_device *sh7786_devices[] __initdata = {
+       &dma0_device,
        &usb_ohci_device,
 };
 
-
 /*
  * Please call this function if your platform board
  * use external clock for USB
@@ -536,6 +580,7 @@ static struct platform_device *sh7786_devices[] __initdata = {
 #define USBCTL0                0xffe70858
 #define CLOCK_MODE_MASK 0xffffff7f
 #define EXT_CLOCK_MODE  0x00000080
+
 void __init sh7786_usb_use_exclock(void)
 {
        u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK;
@@ -553,6 +598,7 @@ void __init sh7786_usb_use_exclock(void)
 #define PLL_ENB                0x00000002
 #define PHY_RST                0x00000004
 #define ACT_PLL_STATUS 0xc0000000
+
 static void __init sh7786_usb_setup(void)
 {
        int i = 1000000;
@@ -708,9 +754,19 @@ static struct intc_vect vectors[] __initdata = {
 #define INTMSK2                0xfe410068
 #define INTMSKCLR2     0xfe41006c
 
+#define INTDISTCR0     0xfe4100b0
+#define INTDISTCR1     0xfe4100b4
+#define INTACK         0xfe4100b8
+#define INTACKCLR      0xfe4100bc
+#define INT2DISTCR0    0xfe410900
+#define INT2DISTCR1    0xfe410904
+#define INT2DISTCR2    0xfe410908
+#define INT2DISTCR3    0xfe41090c
+
 static struct intc_mask_reg mask_registers[] __initdata = {
        { CnINTMSK0, CnINTMSKCLR0, 32,
-         { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+         { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 },
+           INTC_SMP_BALANCING(INTDISTCR0) },
        { INTMSK2, INTMSKCLR2, 32,
          { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
            IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
@@ -722,7 +778,8 @@ static struct intc_mask_reg mask_registers[] __initdata = {
            IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
        { CnINT2MSKR0, CnINT2MSKCR0 , 32,
          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT } },
+           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT },
+           INTC_SMP_BALANCING(INT2DISTCR0) },
        { CnINT2MSKR1, CnINT2MSKCR1, 32,
          { TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0,
            DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
@@ -731,14 +788,14 @@ static struct intc_mask_reg mask_registers[] __initdata = {
            HPB_0, HPB_1, HPB_2,
            SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
            SCIF1,
-           TMU2, TMU3, 0, } },
+           TMU2, TMU3, 0, }, INTC_SMP_BALANCING(INT2DISTCR1) },
        { CnINT2MSKR2, CnINT2MSKCR2, 32,
          { 0, 0, SCIF2, SCIF3, SCIF4, SCIF5,
            Eth_0, Eth_1,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            PCIeC0_0, PCIeC0_1, PCIeC0_2,
            PCIeC1_0, PCIeC1_1, PCIeC1_2,
-           USB, 0, 0 } },
+           USB, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR2) },
        { CnINT2MSKR3, CnINT2MSKCR3, 32,
          { 0, 0, 0, 0, 0, 0,
            I2C0, I2C1,
@@ -747,7 +804,7 @@ static struct intc_mask_reg mask_registers[] __initdata = {
            HAC0, HAC1,
            FLCTL, 0,
            HSPI, GPIO0, GPIO1, Thermal,
-           0, 0, 0, 0, 0, 0, 0, 0 } },
+           0, 0, 0, 0, 0, 0, 0, 0 }, INTC_SMP_BALANCING(INT2DISTCR3) },
 };
 
 static struct intc_prio_reg prio_registers[] __initdata = {
@@ -863,6 +920,19 @@ static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
 #define INTC_INTMSK2   INTMSK2
 #define INTC_INTMSKCLR1        CnINTMSKCLR1
 #define INTC_INTMSKCLR2        INTMSKCLR2
+#define INTC_USERIMASK 0xfe411000
+
+#ifdef CONFIG_INTC_BALANCING
+unsigned int irq_lookup(unsigned int irq)
+{
+       return __raw_readl(INTACK) & 1 ? irq : NO_IRQ_IGNORE;
+}
+
+void irq_finish(unsigned int irq)
+{
+       __raw_writel(irq2evt(irq), INTACKCLR);
+}
+#endif
 
 void __init plat_irq_setup(void)
 {
@@ -877,6 +947,7 @@ void __init plat_irq_setup(void)
        __raw_writel(__raw_readl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
 
        register_intc_controller(&intc_desc);
+       register_intc_userimask(INTC_USERIMASK);
 }
 
 void __init plat_irq_setup_pins(int mode)
index 780ba17..9158bc5 100644 (file)
@@ -70,16 +70,13 @@ static struct platform_device scif2_device = {
 };
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = 0xffc10008,
                .end    = 0xffc10013,
                .flags  = IORESOURCE_MEM,
@@ -101,16 +98,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = 0xffc10014,
                .end    = 0xffc1001f,
                .flags  = IORESOURCE_MEM,
@@ -132,15 +126,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = 0xffc10020,
                .end    = 0xffc1002f,
                .flags  = IORESOURCE_MEM,
@@ -162,15 +153,12 @@ static struct platform_device tmu2_device = {
 };
 
 static struct sh_timer_config tmu3_platform_data = {
-       .name = "TMU3",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu3_resources[] = {
        [0] = {
-               .name   = "TMU3",
                .start  = 0xffc20008,
                .end    = 0xffc20013,
                .flags  = IORESOURCE_MEM,
@@ -192,15 +180,12 @@ static struct platform_device tmu3_device = {
 };
 
 static struct sh_timer_config tmu4_platform_data = {
-       .name = "TMU4",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu4_resources[] = {
        [0] = {
-               .name   = "TMU4",
                .start  = 0xffc20014,
                .end    = 0xffc2001f,
                .flags  = IORESOURCE_MEM,
@@ -222,15 +207,12 @@ static struct platform_device tmu4_device = {
 };
 
 static struct sh_timer_config tmu5_platform_data = {
-       .name = "TMU5",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu5_resources[] = {
        [0] = {
-               .name   = "TMU5",
                .start  = 0xffc20020,
                .end    = 0xffc2002b,
                .flags  = IORESOURCE_MEM,
index 11bf4c1..de865ca 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SH-X3 SMP
  *
- *  Copyright (C) 2007 - 2008  Paul Mundt
+ *  Copyright (C) 2007 - 2010  Paul Mundt
  *  Copyright (C) 2007  Magnus Damm
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -9,16 +9,22 @@
  * for more details.
  */
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/cpumask.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/cpu.h>
+#include <asm/sections.h>
 
 #define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
 #define RESET_REG(phys_id) (0xfe400008 | (phys_id << 12))
 
 #define STBCR_MSTP     0x00000001
 #define STBCR_RESET    0x00000002
+#define STBCR_SLEEP    0x00000004
 #define STBCR_LTSLP    0x80000000
 
 static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
@@ -37,7 +43,7 @@ static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-void __init plat_smp_setup(void)
+static void shx3_smp_setup(void)
 {
        unsigned int cpu = 0;
        int i, num;
@@ -63,7 +69,7 @@ void __init plat_smp_setup(void)
         printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
 }
 
-void __init plat_prepare_cpus(unsigned int max_cpus)
+static void shx3_prepare_cpus(unsigned int max_cpus)
 {
        int i;
 
@@ -72,11 +78,14 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
        BUILD_BUG_ON(SMP_MSG_NR >= 8);
 
        for (i = 0; i < SMP_MSG_NR; i++)
-               request_irq(104 + i, ipi_interrupt_handler, IRQF_DISABLED,
-                           "IPI", (void *)(long)i);
+               request_irq(104 + i, ipi_interrupt_handler,
+                           IRQF_DISABLED | IRQF_PERCPU, "IPI", (void *)(long)i);
+
+       for (i = 0; i < max_cpus; i++)
+               set_cpu_present(i, true);
 }
 
-void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
+static void shx3_start_cpu(unsigned int cpu, unsigned long entry_point)
 {
        if (__in_29bit_mode())
                __raw_writel(entry_point, RESET_REG(cpu));
@@ -93,12 +102,12 @@ void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
        __raw_writel(STBCR_RESET | STBCR_LTSLP, STBCR_REG(cpu));
 }
 
-int plat_smp_processor_id(void)
+static unsigned int shx3_smp_processor_id(void)
 {
        return __raw_readl(0xff000048); /* CPIDR */
 }
 
-void plat_send_ipi(unsigned int cpu, unsigned int message)
+static void shx3_send_ipi(unsigned int cpu, unsigned int message)
 {
        unsigned long addr = 0xfe410070 + (cpu * 4);
 
@@ -106,3 +115,52 @@ void plat_send_ipi(unsigned int cpu, unsigned int message)
 
        __raw_writel(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
 }
+
+static void shx3_update_boot_vector(unsigned int cpu)
+{
+       __raw_writel(STBCR_MSTP, STBCR_REG(cpu));
+       while (!(__raw_readl(STBCR_REG(cpu)) & STBCR_MSTP))
+               cpu_relax();
+       __raw_writel(STBCR_RESET, STBCR_REG(cpu));
+}
+
+static int __cpuinit
+shx3_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+       unsigned int cpu = (unsigned int)hcpu;
+
+       switch (action) {
+       case CPU_UP_PREPARE:
+               shx3_update_boot_vector(cpu);
+               break;
+       case CPU_ONLINE:
+               pr_info("CPU %u is now online\n", cpu);
+               break;
+       case CPU_DEAD:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata shx3_cpu_notifier = {
+       .notifier_call          = shx3_cpu_callback,
+};
+
+static int __cpuinit register_shx3_cpu_notifier(void)
+{
+       register_hotcpu_notifier(&shx3_cpu_notifier);
+       return 0;
+}
+late_initcall(register_shx3_cpu_notifier);
+
+struct plat_smp_ops shx3_smp_ops = {
+       .smp_setup              = shx3_smp_setup,
+       .prepare_cpus           = shx3_prepare_cpus,
+       .start_cpu              = shx3_start_cpu,
+       .smp_processor_id       = shx3_smp_processor_id,
+       .send_ipi               = shx3_send_ipi,
+       .cpu_die                = native_cpu_die,
+       .cpu_disable            = native_cpu_disable,
+       .play_dead              = native_play_dead,
+};
index 521d05b..9e88240 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/cache.h>
 #include <asm/tlb.h>
 
-int __init detect_cpu_and_cache_system(void)
+void __cpuinit cpu_probe(void)
 {
        unsigned long long cir;
 
@@ -72,6 +72,4 @@ int __init detect_cpu_and_cache_system(void)
 
        /* Setup some I/D TLB defaults */
        sh64_tlb_init();
-
-       return 0;
 }
index e7a3c1e..d910666 100644 (file)
@@ -68,16 +68,13 @@ static struct platform_device rtc_device = {
 #define TMU2_BASE      (TMU_BASE + 0x8 + (0xc * 0x2))
 
 static struct sh_timer_config tmu0_platform_data = {
-       .name = "TMU0",
        .channel_offset = 0x04,
        .timer_bit = 0,
-       .clk = "peripheral_clk",
        .clockevent_rating = 200,
 };
 
 static struct resource tmu0_resources[] = {
        [0] = {
-               .name   = "TMU0",
                .start  = TMU0_BASE,
                .end    = TMU0_BASE + 0xc - 1,
                .flags  = IORESOURCE_MEM,
@@ -99,16 +96,13 @@ static struct platform_device tmu0_device = {
 };
 
 static struct sh_timer_config tmu1_platform_data = {
-       .name = "TMU1",
        .channel_offset = 0x10,
        .timer_bit = 1,
-       .clk = "peripheral_clk",
        .clocksource_rating = 200,
 };
 
 static struct resource tmu1_resources[] = {
        [0] = {
-               .name   = "TMU1",
                .start  = TMU1_BASE,
                .end    = TMU1_BASE + 0xc - 1,
                .flags  = IORESOURCE_MEM,
@@ -130,15 +124,12 @@ static struct platform_device tmu1_device = {
 };
 
 static struct sh_timer_config tmu2_platform_data = {
-       .name = "TMU2",
        .channel_offset = 0x1c,
        .timer_bit = 2,
-       .clk = "peripheral_clk",
 };
 
 static struct resource tmu2_resources[] = {
        [0] = {
-               .name   = "TMU2",
                .start  = TMU2_BASE,
                .end    = TMU2_BASE + 0xc - 1,
                .flags  = IORESOURCE_MEM,
index 95d2162..37c97d4 100644 (file)
@@ -4,7 +4,6 @@
  *     Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
  *     Copyright (C) IBM Corporation, 2004. All rights reserved
  */
-
 #include <linux/errno.h>
 #include <linux/crash_dump.h>
 #include <linux/io.h>
 /* Stores the physical address of elf header of crash image. */
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
 
+/*
+ * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+ * is_kdump_kernel() to determine if we are booting after a panic. Hence
+ * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
+ *
+ * elfcorehdr= specifies the location of elf core header
+ * stored by the crashed kernel.
+ */
+static int __init parse_elfcorehdr(char *arg)
+{
+       if (!arg)
+               return -EINVAL;
+
+       elfcorehdr_addr = memparse(arg, &arg);
+
+       return 0;
+}
+early_param("elfcorehdr", parse_elfcorehdr);
+
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
index a8234b2..5ec1d18 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/elf.h>
 #include <linux/ftrace.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
index fe0b743..6e35f01 100644 (file)
@@ -131,6 +131,7 @@ ENTRY(_stext)
  *     r8 = scratch register
  *     r9 = scratch register
  *     r10 = number of PMB entries we've setup
+ *     r11 = scratch register
  */
 
        mov.l   .LMMUCR, r1     /* Flush the TLB */
@@ -167,8 +168,9 @@ ENTRY(_stext)
 
 .Lvalidate_existing_mappings:
 
+       mov.l   .LPMB_DATA_MASK, r11
        mov.l   @r7, r8
-       and     r0, r8
+       and     r11, r8
        cmp/eq  r0, r8          /* Check for valid __MEMORY_START mappings */
        bt      .Lpmb_done
 
@@ -335,12 +337,13 @@ ENTRY(stack_start)
 3:     .long   __bss_start
 4:     .long   _end
 5:     .long   start_kernel
-6:     .long   sh_cpu_init
+6:     .long   cpu_init
 7:     .long   init_thread_union
 
 #ifdef CONFIG_PMB
 .LPMB_ADDR:            .long   PMB_ADDR
 .LPMB_DATA:            .long   PMB_DATA
+.LPMB_DATA_MASK:       .long   PMB_PFN_MASK | PMB_V
 .LFIRST_ADDR_ENTRY:    .long   PAGE_OFFSET | PMB_V
 .LFIRST_DATA_ENTRY:    .long   __MEMORY_START | PMB_V
 .LMMUCR:               .long   MMUCR
index 675eea7..efae6ab 100644 (file)
@@ -119,26 +119,17 @@ static int get_hbp_len(u16 hbp_len)
        return len_in_bytes;
 }
 
-/*
- * Check for virtual address in user space.
- */
-int arch_check_va_in_userspace(unsigned long va, u16 hbp_len)
-{
-       unsigned int len;
-
-       len = get_hbp_len(hbp_len);
-
-       return (va <= TASK_SIZE - len);
-}
-
 /*
  * Check for virtual address in kernel space.
  */
-static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
 {
        unsigned int len;
+       unsigned long va;
+       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       len = get_hbp_len(hbp_len);
+       va = info->address;
+       len = get_hbp_len(info->len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
@@ -226,8 +217,7 @@ static int arch_build_bp_info(struct perf_event *bp)
 /*
  * Validate the arch-specific HW Breakpoint register settings
  */
-int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                 struct task_struct *tsk)
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
 {
        struct arch_hw_breakpoint *info = counter_arch_bp(bp);
        unsigned int align;
@@ -270,15 +260,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
        if (info->address & align)
                return -EINVAL;
 
-       /* Check that the virtual address is in the proper range */
-       if (tsk) {
-               if (!arch_check_va_in_userspace(info->address, info->len))
-                       return -EFAULT;
-       } else {
-               if (!arch_check_va_in_kernelspace(info->address, info->len))
-                       return -EFAULT;
-       }
-
        return 0;
 }
 
@@ -363,8 +344,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args)
                perf_bp_event(bp, args->regs);
 
                /* Deliver the signal to userspace */
-               if (arch_check_va_in_userspace(bp->attr.bp_addr,
-                                              bp->attr.bp_len)) {
+               if (!arch_check_bp_in_kernelspace(bp)) {
                        siginfo_t info;
 
                        info.si_signo = args->signr;
@@ -425,11 +405,6 @@ void hw_breakpoint_pmu_read(struct perf_event *bp)
        /* TODO */
 }
 
-void hw_breakpoint_pmu_unthrottle(struct perf_event *bp)
-{
-       /* TODO */
-}
-
 int register_sh_ubc(struct sh_ubc *ubc)
 {
        /* Bail if it's already assigned */
index 273f890..425d604 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
+#include <asm/smp.h>
 
 void (*pm_idle)(void) = NULL;
 
@@ -89,10 +90,13 @@ void cpu_idle(void)
        while (1) {
                tick_nohz_stop_sched_tick(1);
 
-               while (!need_resched() && cpu_online(cpu)) {
+               while (!need_resched()) {
                        check_pgt_cache();
                        rmb();
 
+                       if (cpu_is_offline(cpu))
+                               play_dead();
+
                        local_irq_disable();
                        /* Don't trace irqs off for idle */
                        stop_critical_timings();
@@ -133,7 +137,7 @@ static void do_nothing(void *unused)
 void stop_this_cpu(void *unused)
 {
        local_irq_disable();
-       cpu_clear(smp_processor_id(), cpu_online_map);
+       set_cpu_online(smp_processor_id(), false);
 
        for (;;)
                cpu_sleep();
index d2d41d0..257de1f 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
 #include <linux/ftrace.h>
+#include <linux/delay.h>
 #include <asm/processor.h>
 #include <asm/machvec.h>
 #include <asm/uaccess.h>
@@ -113,19 +114,14 @@ union irq_ctx {
 
 static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
 static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
-#endif
 
-asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs)
+static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
+static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
+
+static inline void handle_one_irq(unsigned int irq)
 {
-       struct pt_regs *old_regs = set_irq_regs(regs);
-#ifdef CONFIG_IRQSTACKS
        union irq_ctx *curctx, *irqctx;
-#endif
-
-       irq_enter();
-       irq = irq_demux(irq);
 
-#ifdef CONFIG_IRQSTACKS
        curctx = (union irq_ctx *)current_thread_info();
        irqctx = hardirq_ctx[smp_processor_id()];
 
@@ -164,20 +160,9 @@ asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs)
                          "r5", "r6", "r7", "r8", "t", "pr"
                );
        } else
-#endif
                generic_handle_irq(irq);
-
-       irq_exit();
-
-       set_irq_regs(old_regs);
-       return 1;
 }
 
-#ifdef CONFIG_IRQSTACKS
-static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
-
-static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
-
 /*
  * allocate per-cpu stacks for hardirq and for softirq processing
  */
@@ -257,8 +242,33 @@ asmlinkage void do_softirq(void)
 
        local_irq_restore(flags);
 }
+#else
+static inline void handle_one_irq(unsigned int irq)
+{
+       generic_handle_irq(irq);
+}
 #endif
 
+asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
+       irq_enter();
+
+       irq = irq_demux(irq_lookup(irq));
+
+       if (irq != NO_IRQ_IGNORE) {
+               handle_one_irq(irq);
+               irq_finish(irq);
+       }
+
+       irq_exit();
+
+       set_irq_regs(old_regs);
+
+       return IRQ_HANDLED;
+}
+
 void __init init_IRQ(void)
 {
        plat_irq_setup();
@@ -283,3 +293,44 @@ int __init arch_probe_nr_irqs(void)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
+{
+       printk(KERN_INFO "IRQ%u: moving from cpu%u to cpu%u\n",
+              irq, desc->node, cpu);
+
+       raw_spin_lock_irq(&desc->lock);
+       desc->chip->set_affinity(irq, cpumask_of(cpu));
+       raw_spin_unlock_irq(&desc->lock);
+}
+
+/*
+ * The CPU has been marked offline.  Migrate IRQs off this CPU.  If
+ * the affinity settings do not allow other CPUs, force them onto any
+ * available CPU.
+ */
+void migrate_irqs(void)
+{
+       struct irq_desc *desc;
+       unsigned int irq, cpu = smp_processor_id();
+
+       for_each_irq_desc(irq, desc) {
+               if (desc->node == cpu) {
+                       unsigned int newcpu = cpumask_any_and(desc->affinity,
+                                                             cpu_online_mask);
+                       if (newcpu >= nr_cpu_ids) {
+                               if (printk_ratelimit())
+                                       printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
+                                              irq, cpu);
+
+                               cpumask_setall(desc->affinity);
+                               newcpu = cpumask_any_and(desc->affinity,
+                                                        cpu_online_mask);
+                       }
+
+                       route_irq(desc, irq, newcpu);
+               }
+       }
+}
+#endif
index 0b04e7d..8bfc6df 100644 (file)
@@ -44,7 +44,7 @@ static void dummy_timer_set_mode(enum clock_event_mode mode,
 {
 }
 
-void __cpuinit local_timer_setup(unsigned int cpu)
+void local_timer_setup(unsigned int cpu)
 {
        struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
 
@@ -60,3 +60,7 @@ void __cpuinit local_timer_setup(unsigned int cpu)
 
        clockevents_register_device(clk);
 }
+
+void local_timer_stop(unsigned int cpu)
+{
+}
index 7672141..5a559e6 100644 (file)
@@ -8,7 +8,6 @@
  * This source code is licensed under the GNU General Public License,
  * Version 2.  See the file COPYING for more details.
  */
-
 #include <linux/mm.h>
 #include <linux/kexec.h>
 #include <linux/delay.h>
@@ -16,6 +15,7 @@
 #include <linux/numa.h>
 #include <linux/ftrace.h>
 #include <linux/suspend.h>
+#include <linux/lmb.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -147,4 +147,64 @@ void arch_crash_save_vmcoreinfo(void)
        VMCOREINFO_SYMBOL(node_data);
        VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
 #endif
+#ifdef CONFIG_X2TLB
+       VMCOREINFO_CONFIG(X2TLB);
+#endif
+}
+
+void __init reserve_crashkernel(void)
+{
+       unsigned long long crash_size, crash_base;
+       int ret;
+
+       /* this is necessary because of lmb_phys_mem_size() */
+       lmb_analyze();
+
+       ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+                       &crash_size, &crash_base);
+       if (ret == 0 && crash_size > 0) {
+               crashk_res.start = crash_base;
+               crashk_res.end = crash_base + crash_size - 1;
+       }
+
+       if (crashk_res.end == crashk_res.start)
+               goto disable;
+
+       crash_size = PAGE_ALIGN(crashk_res.end - crashk_res.start + 1);
+       if (!crashk_res.start) {
+               unsigned long max = lmb_end_of_DRAM() - memory_limit;
+               crashk_res.start = __lmb_alloc_base(crash_size, PAGE_SIZE, max);
+               if (!crashk_res.start) {
+                       pr_err("crashkernel allocation failed\n");
+                       goto disable;
+               }
+       } else {
+               ret = lmb_reserve(crashk_res.start, crash_size);
+               if (unlikely(ret < 0)) {
+                       pr_err("crashkernel reservation failed - "
+                              "memory is in use\n");
+                       goto disable;
+               }
+       }
+
+       crashk_res.end = crashk_res.start + crash_size - 1;
+
+       /*
+        * Crash kernel trumps memory limit
+        */
+       if ((lmb_end_of_DRAM() - memory_limit) <= crashk_res.end) {
+               memory_limit = 0;
+               pr_info("Disabled memory limit for crashkernel\n");
+       }
+
+       pr_info("Reserving %ldMB of memory at 0x%08lx "
+               "for crashkernel (System RAM: %ldMB)\n",
+               (unsigned long)(crash_size >> 20),
+               (unsigned long)(crashk_res.start),
+               (unsigned long)(lmb_phys_mem_size() >> 20));
+
+       return;
+
+disable:
+       crashk_res.start = crashk_res.end = 0;
 }
index 1652340..85cfaf9 100644 (file)
@@ -131,6 +131,7 @@ void __init sh_mv_setup(void)
        mv_set(ioport_unmap);
        mv_set(irq_demux);
        mv_set(mode_pins);
+       mv_set(mem_init);
 
        if (!sh_mv.mv_nr_irqs)
                sh_mv.mv_nr_irqs = NR_IRQS;
index 17f89aa..dcb126d 100644 (file)
@@ -90,7 +90,7 @@ void arch_task_cache_init(void)
 # define HAVE_SOFTFP   0
 #endif
 
-void init_thread_xstate(void)
+void __cpuinit init_thread_xstate(void)
 {
        if (boot_cpu_data.flags & CPU_HAS_FPU)
                xstate_size = sizeof(struct sh_fpu_hard_struct);
index 7759a9a..d4104ce 100644 (file)
@@ -85,7 +85,7 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr)
 
        bp = thread->ptrace_bps[0];
        if (!bp) {
-               hw_breakpoint_init(&attr);
+               ptrace_breakpoint_init(&attr);
 
                attr.bp_addr = addr;
                attr.bp_len = HW_BREAKPOINT_LEN_2;
index 8870d6b..2727346 100644 (file)
@@ -4,7 +4,7 @@
  * This file handles the architecture-dependent parts of initialization
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2002 - 2007 Paul Mundt
+ *  Copyright (C) 2002 - 2010 Paul Mundt
  */
 #include <linux/screen_info.h>
 #include <linux/ioport.h>
@@ -39,7 +39,9 @@
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/clock.h>
+#include <asm/smp.h>
 #include <asm/mmu_context.h>
+#include <asm/mmzone.h>
 
 /*
  * Initialize loops_per_jiffy as 10000000 (1000MIPS).
@@ -93,6 +95,7 @@ unsigned long memory_start;
 EXPORT_SYMBOL(memory_start);
 unsigned long memory_end = 0;
 EXPORT_SYMBOL(memory_end);
+unsigned long memory_limit = 0;
 
 static struct resource mem_resources[MAX_NUMNODES];
 
@@ -100,92 +103,73 @@ int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
 
 static int __init early_parse_mem(char *p)
 {
-       unsigned long size;
+       if (!p)
+               return 1;
 
-       memory_start = (unsigned long)__va(__MEMORY_START);
-       size = memparse(p, &p);
+       memory_limit = PAGE_ALIGN(memparse(p, &p));
 
-       if (size > __MEMORY_SIZE) {
-               printk(KERN_ERR
-                       "Using mem= to increase the size of kernel memory "
-                       "is not allowed.\n"
-                       "  Recompile the kernel with the correct value for "
-                       "CONFIG_MEMORY_SIZE.\n");
-               return 0;
-       }
-
-       memory_end = memory_start + size;
+       pr_notice("Memory limited to %ldMB\n", memory_limit >> 20);
 
        return 0;
 }
 early_param("mem", early_parse_mem);
 
-/*
- * Register fully available low RAM pages with the bootmem allocator.
- */
-static void __init register_bootmem_low_pages(void)
+void __init check_for_initrd(void)
 {
-       unsigned long curr_pfn, last_pfn, pages;
+#ifdef CONFIG_BLK_DEV_INITRD
+       unsigned long start, end;
+
+       /*
+        * Check for the rare cases where boot loaders adhere to the boot
+        * ABI.
+        */
+       if (!LOADER_TYPE || !INITRD_START || !INITRD_SIZE)
+               goto disable;
+
+       start = INITRD_START + __MEMORY_START;
+       end = start + INITRD_SIZE;
+
+       if (unlikely(end <= start))
+               goto disable;
+       if (unlikely(start & ~PAGE_MASK)) {
+               pr_err("initrd must be page aligned\n");
+               goto disable;
+       }
+
+       if (unlikely(start < PAGE_OFFSET)) {
+               pr_err("initrd start < PAGE_OFFSET\n");
+               goto disable;
+       }
+
+       if (unlikely(end > lmb_end_of_DRAM())) {
+               pr_err("initrd extends beyond end of memory "
+                      "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+                      end, (unsigned long)lmb_end_of_DRAM());
+               goto disable;
+       }
 
        /*
-        * We are rounding up the start address of usable memory:
+        * If we got this far inspite of the boot loader's best efforts
+        * to the contrary, assume we actually have a valid initrd and
+        * fix up the root dev.
         */
-       curr_pfn = PFN_UP(__MEMORY_START);
+       ROOT_DEV = Root_RAM0;
 
        /*
-        * ... and at the end of the usable range downwards:
+        * Address sanitization
         */
-       last_pfn = PFN_DOWN(__pa(memory_end));
+       initrd_start = (unsigned long)__va(__pa(start));
+       initrd_end = initrd_start + INITRD_SIZE;
 
-       if (last_pfn > max_low_pfn)
-               last_pfn = max_low_pfn;
+       lmb_reserve(__pa(initrd_start), INITRD_SIZE);
 
-       pages = last_pfn - curr_pfn;
-       free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
-}
+       return;
 
-#ifdef CONFIG_KEXEC
-static void __init reserve_crashkernel(void)
-{
-       unsigned long long free_mem;
-       unsigned long long crash_size, crash_base;
-       void *vp;
-       int ret;
-
-       free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
-
-       ret = parse_crashkernel(boot_command_line, free_mem,
-                       &crash_size, &crash_base);
-       if (ret == 0 && crash_size) {
-               if (crash_base <= 0) {
-                       vp = alloc_bootmem_nopanic(crash_size);
-                       if (!vp) {
-                               printk(KERN_INFO "crashkernel allocation "
-                                      "failed\n");
-                               return;
-                       }
-                       crash_base = __pa(vp);
-               } else if (reserve_bootmem(crash_base, crash_size,
-                                       BOOTMEM_EXCLUSIVE) < 0) {
-                       printk(KERN_INFO "crashkernel reservation failed - "
-                                       "memory is in use\n");
-                       return;
-               }
-
-               printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
-                               "for crashkernel (System RAM: %ldMB)\n",
-                               (unsigned long)(crash_size >> 20),
-                               (unsigned long)(crash_base >> 20),
-                               (unsigned long)(free_mem >> 20));
-               crashk_res.start = crash_base;
-               crashk_res.end   = crash_base + crash_size - 1;
-               insert_resource(&iomem_resource, &crashk_res);
-       }
-}
-#else
-static inline void __init reserve_crashkernel(void)
-{}
+disable:
+       pr_info("initrd disabled\n");
+       initrd_start = initrd_end = 0;
 #endif
+}
 
 void __cpuinit calibrate_delay(void)
 {
@@ -207,13 +191,18 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
                                                unsigned long end_pfn)
 {
        struct resource *res = &mem_resources[nid];
+       unsigned long start, end;
 
        WARN_ON(res->name); /* max one active range per node for now */
 
+       start = start_pfn << PAGE_SHIFT;
+       end = end_pfn << PAGE_SHIFT;
+
        res->name = "System RAM";
-       res->start = start_pfn << PAGE_SHIFT;
-       res->end = (end_pfn << PAGE_SHIFT) - 1;
+       res->start = start;
+       res->end = end - 1;
        res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
        if (request_resource(&iomem_resource, res)) {
                pr_err("unable to request memory_resource 0x%lx 0x%lx\n",
                       start_pfn, end_pfn);
@@ -229,138 +218,18 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
        request_resource(res, &data_resource);
        request_resource(res, &bss_resource);
 
-       add_active_range(nid, start_pfn, end_pfn);
-}
-
-void __init setup_bootmem_allocator(unsigned long free_pfn)
-{
-       unsigned long bootmap_size;
-       unsigned long bootmap_pages, bootmem_paddr;
-       u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
-       int i;
-
-       bootmap_pages = bootmem_bootmap_pages(total_pages);
-
-       bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
-
-       /*
-        * Find a proper area for the bootmem bitmap. After this
-        * bootstrap step all allocations (until the page allocator
-        * is intact) must be done via bootmem_alloc().
-        */
-       bootmap_size = init_bootmem_node(NODE_DATA(0),
-                                        bootmem_paddr >> PAGE_SHIFT,
-                                        min_low_pfn, max_low_pfn);
-
-       /* Add active regions with valid PFNs. */
-       for (i = 0; i < lmb.memory.cnt; i++) {
-               unsigned long start_pfn, end_pfn;
-               start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
-               end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
-               __add_active_range(0, start_pfn, end_pfn);
-       }
-
-       /*
-        * Add all physical memory to the bootmem map and mark each
-        * area as present.
-        */
-       register_bootmem_low_pages();
-
-       /* Reserve the sections we're already using. */
-       for (i = 0; i < lmb.reserved.cnt; i++)
-               reserve_bootmem(lmb.reserved.region[i].base,
-                               lmb_size_bytes(&lmb.reserved, i),
-                               BOOTMEM_DEFAULT);
-
-       node_set_online(0);
-
-       sparse_memory_present_with_active_regions(0);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-       ROOT_DEV = Root_RAM0;
-
-       if (LOADER_TYPE && INITRD_START) {
-               unsigned long initrd_start_phys = INITRD_START + __MEMORY_START;
-
-               if (initrd_start_phys + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
-                       reserve_bootmem(initrd_start_phys, INITRD_SIZE,
-                                       BOOTMEM_DEFAULT);
-                       initrd_start = (unsigned long)__va(initrd_start_phys);
-                       initrd_end = initrd_start + INITRD_SIZE;
-               } else {
-                       printk("initrd extends beyond end of memory "
-                              "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-                              initrd_start_phys + INITRD_SIZE,
-                              (unsigned long)PFN_PHYS(max_low_pfn));
-                       initrd_start = 0;
-               }
-       }
-#endif
-
-       reserve_crashkernel();
-}
-
-#ifndef CONFIG_NEED_MULTIPLE_NODES
-static void __init setup_memory(void)
-{
-       unsigned long start_pfn;
-       u64 base = min_low_pfn << PAGE_SHIFT;
-       u64 size = (max_low_pfn << PAGE_SHIFT) - base;
-
-       /*
-        * Partially used pages are not usable - thus
-        * we are rounding upwards:
-        */
-       start_pfn = PFN_UP(__pa(_end));
-
-       lmb_add(base, size);
-
-       /*
-        * Reserve the kernel text and
-        * Reserve the bootmem bitmap. We do this in two steps (first step
-        * was init_bootmem()), because this catches the (definitely buggy)
-        * case of us accidentally initializing the bootmem allocator with
-        * an invalid RAM area.
-        */
-       lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
-                   (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
-                   (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
-
        /*
-        * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
+        * Also make sure that there is a PMB mapping that covers this
+        * range before we attempt to activate it, to avoid reset by MMU.
+        * We can hit this path with NUMA or memory hot-add.
         */
-       if (CONFIG_ZERO_PAGE_OFFSET != 0)
-               lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
-
-       lmb_analyze();
-       lmb_dump_all();
+       pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
+                        PAGE_KERNEL);
 
-       setup_bootmem_allocator(start_pfn);
-}
-#else
-extern void __init setup_memory(void);
-#endif
-
-/*
- * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
- * is_kdump_kernel() to determine if we are booting after a panic. Hence
- * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
- */
-#ifdef CONFIG_CRASH_DUMP
-/* elfcorehdr= specifies the location of elf core header
- * stored by the crashed kernel.
- */
-static int __init parse_elfcorehdr(char *arg)
-{
-       if (!arg)
-               return -EINVAL;
-       elfcorehdr_addr = memparse(arg, &arg);
-       return 0;
+       add_active_range(nid, start_pfn, end_pfn);
 }
-early_param("elfcorehdr", parse_elfcorehdr);
-#endif
 
-void __init __attribute__ ((weak)) plat_early_device_setup(void)
+void __init __weak plat_early_device_setup(void)
 {
 }
 
@@ -401,10 +270,6 @@ void __init setup_arch(char **cmdline_p)
        bss_resource.start = virt_to_phys(__bss_start);
        bss_resource.end = virt_to_phys(_ebss)-1;
 
-       memory_start = (unsigned long)__va(__MEMORY_START);
-       if (!memory_end)
-               memory_end = memory_start + __MEMORY_SIZE;
-
 #ifdef CONFIG_CMDLINE_OVERWRITE
        strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
 #else
@@ -421,47 +286,24 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
-       uncached_init();
-
        plat_early_device_setup();
 
-       /* Let earlyprintk output early console messages */
-       early_platform_driver_probe("earlyprintk", 1, 1);
-
        sh_mv_setup();
 
-       /*
-        * Find the highest page frame number we have available
-        */
-       max_pfn = PFN_DOWN(__pa(memory_end));
-
-       /*
-        * Determine low and high memory ranges:
-        */
-       max_low_pfn = max_pfn;
-       min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
-
-       nodes_clear(node_online_map);
+       /* Let earlyprintk output early console messages */
+       early_platform_driver_probe("earlyprintk", 1, 1);
 
-       pmb_init();
-       lmb_init();
-       setup_memory();
-       sparse_init();
+       paging_init();
 
 #ifdef CONFIG_DUMMY_CONSOLE
        conswitchp = &dummy_con;
 #endif
-       paging_init();
-
-       ioremap_fixed_init();
 
        /* Perform the machine specific initialisation */
        if (likely(sh_mv.mv_setup))
                sh_mv.mv_setup(cmdline_p);
 
-#ifdef CONFIG_SMP
        plat_smp_setup();
-#endif
 }
 
 /* processor boot mode configuration */
index 002cc61..509b36b 100644 (file)
@@ -3,7 +3,7 @@
  *
  * SMP support for the SuperH processors.
  *
- * Copyright (C) 2002 - 2008 Paul Mundt
+ * Copyright (C) 2002 - 2010 Paul Mundt
  * Copyright (C) 2006 - 2007 Akio Idehara
  *
  * This file is subject to the terms and conditions of the GNU General Public
 int __cpu_number_map[NR_CPUS];         /* Map physical to logical */
 int __cpu_logical_map[NR_CPUS];                /* Map logical to physical */
 
-static inline void __init smp_store_cpu_info(unsigned int cpu)
+struct plat_smp_ops *mp_ops = NULL;
+
+/* State of each CPU */
+DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
+void __cpuinit register_smp_ops(struct plat_smp_ops *ops)
+{
+       if (mp_ops)
+               printk(KERN_WARNING "Overriding previously set SMP ops\n");
+
+       mp_ops = ops;
+}
+
+static inline void __cpuinit smp_store_cpu_info(unsigned int cpu)
 {
        struct sh_cpuinfo *c = cpu_data + cpu;
 
@@ -46,14 +59,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 
        init_new_context(current, &init_mm);
        current_thread_info()->cpu = cpu;
-       plat_prepare_cpus(max_cpus);
+       mp_ops->prepare_cpus(max_cpus);
 
 #ifndef CONFIG_HOTPLUG_CPU
        init_cpu_present(&cpu_possible_map);
 #endif
 }
 
-void __devinit smp_prepare_boot_cpu(void)
+void __init smp_prepare_boot_cpu(void)
 {
        unsigned int cpu = smp_processor_id();
 
@@ -62,37 +75,137 @@ void __devinit smp_prepare_boot_cpu(void)
 
        set_cpu_online(cpu, true);
        set_cpu_possible(cpu, true);
+
+       per_cpu(cpu_state, cpu) = CPU_ONLINE;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+void native_cpu_die(unsigned int cpu)
+{
+       unsigned int i;
+
+       for (i = 0; i < 10; i++) {
+               smp_rmb();
+               if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+                       if (system_state == SYSTEM_RUNNING)
+                               pr_info("CPU %u is now offline\n", cpu);
+
+                       return;
+               }
+
+               msleep(100);
+       }
+
+       pr_err("CPU %u didn't die...\n", cpu);
+}
+
+int native_cpu_disable(unsigned int cpu)
+{
+       return cpu == 0 ? -EPERM : 0;
+}
+
+void play_dead_common(void)
+{
+       idle_task_exit();
+       irq_ctx_exit(raw_smp_processor_id());
+       mb();
+
+       __get_cpu_var(cpu_state) = CPU_DEAD;
+       local_irq_disable();
+}
+
+void native_play_dead(void)
+{
+       play_dead_common();
 }
 
+int __cpu_disable(void)
+{
+       unsigned int cpu = smp_processor_id();
+       struct task_struct *p;
+       int ret;
+
+       ret = mp_ops->cpu_disable(cpu);
+       if (ret)
+               return ret;
+
+       /*
+        * Take this CPU offline.  Once we clear this, we can't return,
+        * and we must not schedule until we're ready to give up the cpu.
+        */
+       set_cpu_online(cpu, false);
+
+       /*
+        * OK - migrate IRQs away from this CPU
+        */
+       migrate_irqs();
+
+       /*
+        * Stop the local timer for this CPU.
+        */
+       local_timer_stop(cpu);
+
+       /*
+        * Flush user cache and TLB mappings, and then remove this CPU
+        * from the vm mask set of all processes.
+        */
+       flush_cache_all();
+       local_flush_tlb_all();
+
+       read_lock(&tasklist_lock);
+       for_each_process(p)
+               if (p->mm)
+                       cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
+       read_unlock(&tasklist_lock);
+
+       return 0;
+}
+#else /* ... !CONFIG_HOTPLUG_CPU */
+int native_cpu_disable(unsigned int cpu)
+{
+       return -ENOSYS;
+}
+
+void native_cpu_die(unsigned int cpu)
+{
+       /* We said "no" in __cpu_disable */
+       BUG();
+}
+
+void native_play_dead(void)
+{
+       BUG();
+}
+#endif
+
 asmlinkage void __cpuinit start_secondary(void)
 {
-       unsigned int cpu;
+       unsigned int cpu = smp_processor_id();
        struct mm_struct *mm = &init_mm;
 
        enable_mmu();
        atomic_inc(&mm->mm_count);
        atomic_inc(&mm->mm_users);
        current->active_mm = mm;
-       BUG_ON(current->mm);
        enter_lazy_tlb(mm, current);
+       local_flush_tlb_all();
 
        per_cpu_trap_init();
 
        preempt_disable();
 
-       notify_cpu_starting(smp_processor_id());
+       notify_cpu_starting(cpu);
 
        local_irq_enable();
 
-       cpu = smp_processor_id();
-
        /* Enable local timers */
        local_timer_setup(cpu);
        calibrate_delay();
 
        smp_store_cpu_info(cpu);
 
-       cpu_set(cpu, cpu_online_map);
+       set_cpu_online(cpu, true);
+       per_cpu(cpu_state, cpu) = CPU_ONLINE;
 
        cpu_idle();
 }
@@ -111,12 +224,19 @@ int __cpuinit __cpu_up(unsigned int cpu)
        struct task_struct *tsk;
        unsigned long timeout;
 
-       tsk = fork_idle(cpu);
-       if (IS_ERR(tsk)) {
-               printk(KERN_ERR "Failed forking idle task for cpu %d\n", cpu);
-               return PTR_ERR(tsk);
+       tsk = cpu_data[cpu].idle;
+       if (!tsk) {
+               tsk = fork_idle(cpu);
+               if (IS_ERR(tsk)) {
+                       pr_err("Failed forking idle task for cpu %d\n", cpu);
+                       return PTR_ERR(tsk);
+               }
+
+               cpu_data[cpu].idle = tsk;
        }
 
+       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
+
        /* Fill in data in head.S for secondary cpus */
        stack_start.sp = tsk->thread.sp;
        stack_start.thread_info = tsk->stack;
@@ -127,7 +247,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
                           (unsigned long)&stack_start + sizeof(stack_start));
        wmb();
 
-       plat_start_cpu(cpu, (unsigned long)_stext);
+       mp_ops->start_cpu(cpu, (unsigned long)_stext);
 
        timeout = jiffies + HZ;
        while (time_before(jiffies, timeout)) {
@@ -135,6 +255,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
                        break;
 
                udelay(10);
+               barrier();
        }
 
        if (cpu_online(cpu))
@@ -159,7 +280,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
 
 void smp_send_reschedule(int cpu)
 {
-       plat_send_ipi(cpu, SMP_MSG_RESCHEDULE);
+       mp_ops->send_ipi(cpu, SMP_MSG_RESCHEDULE);
 }
 
 void smp_send_stop(void)
@@ -172,12 +293,12 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
        int cpu;
 
        for_each_cpu(cpu, mask)
-               plat_send_ipi(cpu, SMP_MSG_FUNCTION);
+               mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION);
 }
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-       plat_send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
+       mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
 }
 
 void smp_timer_broadcast(const struct cpumask *mask)
@@ -185,7 +306,7 @@ void smp_timer_broadcast(const struct cpumask *mask)
        int cpu;
 
        for_each_cpu(cpu, mask)
-               plat_send_ipi(cpu, SMP_MSG_TIMER);
+               mp_ops->send_ipi(cpu, SMP_MSG_TIMER);
 }
 
 static void ipi_timer(void)
@@ -249,7 +370,6 @@ static void flush_tlb_mm_ipi(void *mm)
  * behalf of debugees, kswapd stealing pages from another process etc).
  * Kanoj 07/00.
  */
-
 void flush_tlb_mm(struct mm_struct *mm)
 {
        preempt_disable();
index 9b0b633..948fdb6 100644 (file)
@@ -52,7 +52,11 @@ static int __init topology_init(void)
 #endif
 
        for_each_present_cpu(i) {
-               ret = register_cpu(&per_cpu(cpu_devices, i), i);
+               struct cpu *c = &per_cpu(cpu_devices, i);
+
+               c->hotpluggable = 1;
+
+               ret = register_cpu(c, i);
                if (unlikely(ret))
                        printk(KERN_WARNING "%s: register_cpu %d failed (%d)\n",
                               __func__, i, ret);
index e3f92eb..e67e140 100644 (file)
@@ -944,3 +944,8 @@ asmlinkage void do_debug_interrupt(unsigned long code, struct pt_regs *regs)
        /* Clear all DEBUGINT causes */
        poke_real_address_q(DM_EXP_CAUSE_PHY, 0x0);
 }
+
+void __cpuinit per_cpu_trap_init(void)
+{
+       /* Nothing to do for now, VBR initialization later. */
+}
index 3dc8a8a..53f7c68 100644 (file)
@@ -10,6 +10,7 @@ cacheops-$(CONFIG_CPU_SH3)            := cache-sh3.o
 cacheops-$(CONFIG_CPU_SH4)             := cache-sh4.o flush-sh4.o
 cacheops-$(CONFIG_CPU_SH5)             := cache-sh5.o flush-sh4.o
 cacheops-$(CONFIG_SH7705_CACHE_32KB)   += cache-sh7705.o
+cacheops-$(CONFIG_CPU_SHX3)            += cache-shx3.o
 
 obj-y                  += $(cacheops-y)
 
@@ -18,13 +19,14 @@ mmu-$(CONFIG_MMU)   := extable_$(BITS).o fault_$(BITS).o \
                           ioremap.o kmap.o pgtable.o tlbflush_$(BITS).o
 
 obj-y                  += $(mmu-y)
-obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
 
-ifdef CONFIG_DEBUG_FS
-obj-$(CONFIG_CPU_SH4)  += cache-debugfs.o
+debugfs-y                      := asids-debugfs.o
+ifndef CONFIG_CACHE_OFF
+debugfs-$(CONFIG_CPU_SH4)      += cache-debugfs.o
 endif
 
 ifdef CONFIG_MMU
+debugfs-$(CONFIG_CPU_SH4)      += tlb-debugfs.o
 tlb-$(CONFIG_CPU_SH3)          := tlb-sh3.o
 tlb-$(CONFIG_CPU_SH4)          := tlb-sh4.o tlb-urb.o
 tlb-$(CONFIG_CPU_SH5)          := tlb-sh5.o
@@ -32,6 +34,7 @@ tlb-$(CONFIG_CPU_HAS_PTEAEX)  := tlb-pteaex.o tlb-urb.o
 obj-y                          += $(tlb-y)
 endif
 
+obj-$(CONFIG_DEBUG_FS)         += $(debugfs-y)
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
 obj-$(CONFIG_PMB)              += pmb.o
 obj-$(CONFIG_NUMA)             += numa.o
diff --git a/arch/sh/mm/cache-shx3.c b/arch/sh/mm/cache-shx3.c
new file mode 100644 (file)
index 0000000..c0adbee
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * arch/sh/mm/cache-shx3.c - SH-X3 optimized cache ops
+ *
+ * Copyright (C) 2010  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/cache.h>
+
+#define CCR_CACHE_SNM  0x40000         /* Hardware-assisted synonym avoidance */
+#define CCR_CACHE_IBE  0x1000000       /* ICBI broadcast */
+
+void __init shx3_cache_init(void)
+{
+       unsigned int ccr;
+
+       ccr = __raw_readl(CCR);
+
+       /*
+        * If we've got cache aliases, resolve them in hardware.
+        */
+       if (boot_cpu_data.dcache.n_aliases || boot_cpu_data.icache.n_aliases) {
+               ccr |= CCR_CACHE_SNM;
+
+               boot_cpu_data.icache.n_aliases = 0;
+               boot_cpu_data.dcache.n_aliases = 0;
+
+               pr_info("Enabling hardware synonym avoidance\n");
+       }
+
+#ifdef CONFIG_SMP
+       /*
+        * Broadcast I-cache block invalidations by default.
+        */
+       ccr |= CCR_CACHE_IBE;
+#endif
+
+       writel_uncached(ccr, CCR);
+}
index 0f4095d..ba401d1 100644 (file)
@@ -334,6 +334,13 @@ void __init cpu_cache_init(void)
                extern void __weak sh4_cache_init(void);
 
                sh4_cache_init();
+
+               if ((boot_cpu_data.type == CPU_SH7786) ||
+                   (boot_cpu_data.type == CPU_SHX3)) {
+                       extern void __weak shx3_cache_init(void);
+
+                       shx3_cache_init();
+               }
        }
 
        if (boot_cpu_data.family == CPU_FAMILY_SH5) {
index 8bf79e3..d4c34d7 100644 (file)
@@ -200,7 +200,6 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
-survive:
        fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0);
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM)
@@ -290,15 +289,10 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_global_init(current)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
-       printk("VM: killing process %s\n", tsk->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
-       goto no_context;
+       if (!user_mode(regs))
+               goto no_context;
+       pagefault_out_of_memory();
+       return;
 
 do_sigbus:
        up_read(&mm->mmap_sem);
index c505de6..46f84de 100644 (file)
@@ -2,7 +2,7 @@
  * linux/arch/sh/mm/init.c
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2002 - 2007  Paul Mundt
+ *  Copyright (C) 2002 - 2010  Paul Mundt
  *
  *  Based on linux/arch/i386/mm/init.c:
  *   Copyright (C) 1995  Linus Torvalds
 #include <linux/pagemap.h>
 #include <linux/percpu.h>
 #include <linux/io.h>
+#include <linux/lmb.h>
 #include <linux/dma-mapping.h>
 #include <asm/mmu_context.h>
+#include <asm/mmzone.h>
+#include <asm/kexec.h>
 #include <asm/tlb.h>
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
+#include <asm/setup.h>
 #include <asm/cache.h>
 #include <asm/sizes.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
+void __init generic_mem_init(void)
+{
+       lmb_add(__MEMORY_START, __MEMORY_SIZE);
+}
+
+void __init __weak plat_mem_setup(void)
+{
+       /* Nothing to see here, move along. */
+}
+
 #ifdef CONFIG_MMU
 static pte_t *__get_pte_phys(unsigned long addr)
 {
@@ -152,15 +166,166 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
 }
 #endif /* CONFIG_MMU */
 
-/*
- * paging_init() sets up the page tables
- */
+void __init allocate_pgdat(unsigned int nid)
+{
+       unsigned long start_pfn, end_pfn;
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+       unsigned long phys;
+#endif
+
+       get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+       phys = __lmb_alloc_base(sizeof(struct pglist_data),
+                               SMP_CACHE_BYTES, end_pfn << PAGE_SHIFT);
+       /* Retry with all of system memory */
+       if (!phys)
+               phys = __lmb_alloc_base(sizeof(struct pglist_data),
+                                       SMP_CACHE_BYTES, lmb_end_of_DRAM());
+       if (!phys)
+               panic("Can't allocate pgdat for node %d\n", nid);
+
+       NODE_DATA(nid) = __va(phys);
+       memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
+
+       NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
+#endif
+
+       NODE_DATA(nid)->node_start_pfn = start_pfn;
+       NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
+}
+
+static void __init bootmem_init_one_node(unsigned int nid)
+{
+       unsigned long total_pages, paddr;
+       unsigned long end_pfn;
+       struct pglist_data *p;
+       int i;
+
+       p = NODE_DATA(nid);
+
+       /* Nothing to do.. */
+       if (!p->node_spanned_pages)
+               return;
+
+       end_pfn = p->node_start_pfn + p->node_spanned_pages;
+
+       total_pages = bootmem_bootmap_pages(p->node_spanned_pages);
+
+       paddr = lmb_alloc(total_pages << PAGE_SHIFT, PAGE_SIZE);
+       if (!paddr)
+               panic("Can't allocate bootmap for nid[%d]\n", nid);
+
+       init_bootmem_node(p, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn);
+
+       free_bootmem_with_active_regions(nid, end_pfn);
+
+       /*
+        * XXX Handle initial reservations for the system memory node
+        * only for the moment, we'll refactor this later for handling
+        * reservations in other nodes.
+        */
+       if (nid == 0) {
+               /* Reserve the sections we're already using. */
+               for (i = 0; i < lmb.reserved.cnt; i++)
+                       reserve_bootmem(lmb.reserved.region[i].base,
+                                       lmb_size_bytes(&lmb.reserved, i),
+                                       BOOTMEM_DEFAULT);
+       }
+
+       sparse_memory_present_with_active_regions(nid);
+}
+
+static void __init do_init_bootmem(void)
+{
+       int i;
+
+       /* Add active regions with valid PFNs. */
+       for (i = 0; i < lmb.memory.cnt; i++) {
+               unsigned long start_pfn, end_pfn;
+               start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+               end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+               __add_active_range(0, start_pfn, end_pfn);
+       }
+
+       /* All of system RAM sits in node 0 for the non-NUMA case */
+       allocate_pgdat(0);
+       node_set_online(0);
+
+       plat_mem_setup();
+
+       for_each_online_node(i)
+               bootmem_init_one_node(i);
+
+       sparse_init();
+}
+
+static void __init early_reserve_mem(void)
+{
+       unsigned long start_pfn;
+
+       /*
+        * Partially used pages are not usable - thus
+        * we are rounding upwards:
+        */
+       start_pfn = PFN_UP(__pa(_end));
+
+       /*
+        * Reserve the kernel text and Reserve the bootmem bitmap. We do
+        * this in two steps (first step was init_bootmem()), because
+        * this catches the (definitely buggy) case of us accidentally
+        * initializing the bootmem allocator with an invalid RAM area.
+        */
+       lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+                   (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
+                   (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
+
+       /*
+        * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
+        */
+       if (CONFIG_ZERO_PAGE_OFFSET != 0)
+               lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
+
+       /*
+        * Handle additional early reservations
+        */
+       check_for_initrd();
+       reserve_crashkernel();
+}
+
 void __init paging_init(void)
 {
        unsigned long max_zone_pfns[MAX_NR_ZONES];
        unsigned long vaddr, end;
        int nid;
 
+       lmb_init();
+
+       sh_mv.mv_mem_init();
+
+       early_reserve_mem();
+
+       lmb_enforce_memory_limit(memory_limit);
+       lmb_analyze();
+
+       lmb_dump_all();
+
+       /*
+        * Determine low and high memory ranges:
+        */
+       max_low_pfn = max_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
+       min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
+
+       nodes_clear(node_online_map);
+
+       memory_start = (unsigned long)__va(__MEMORY_START);
+       memory_end = memory_start + (memory_limit ?: lmb_phys_mem_size());
+
+       uncached_init();
+       pmb_init();
+       do_init_bootmem();
+       ioremap_fixed_init();
+
        /* We don't need to map the kernel through the TLB, as
         * it is permanatly mapped using P1. So clear the
         * entire pgd. */
index 961b340..a2e645f 100644 (file)
@@ -24,44 +24,6 @@ EXPORT_SYMBOL_GPL(node_data);
  * latency. Each node's pgdat is node-local at the beginning of the node,
  * immediately followed by the node mem map.
  */
-void __init setup_memory(void)
-{
-       unsigned long free_pfn = PFN_UP(__pa(_end));
-       u64 base = min_low_pfn << PAGE_SHIFT;
-       u64 size = (max_low_pfn << PAGE_SHIFT) - base;
-
-       lmb_add(base, size);
-
-       /* Reserve the LMB regions used by the kernel, initrd, etc.. */
-       lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
-                   (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) -
-                   (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
-
-       /*
-        * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
-        */
-       if (CONFIG_ZERO_PAGE_OFFSET != 0)
-               lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
-
-       lmb_analyze();
-       lmb_dump_all();
-
-       /*
-        * Node 0 sets up its pgdat at the first available pfn,
-        * and bumps it up before setting up the bootmem allocator.
-        */
-       NODE_DATA(0) = pfn_to_kaddr(free_pfn);
-       memset(NODE_DATA(0), 0, sizeof(struct pglist_data));
-       free_pfn += PFN_UP(sizeof(struct pglist_data));
-       NODE_DATA(0)->bdata = &bootmem_node_data[0];
-
-       /* Set up node 0 */
-       setup_bootmem_allocator(free_pfn);
-
-       /* Give the platforms a chance to hook up their nodes */
-       plat_mem_setup();
-}
-
 void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 {
        unsigned long bootmap_pages;
index e43ec60..18623ba 100644 (file)
@@ -341,6 +341,8 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
        unsigned long flags, pmb_flags;
        int i, mapped;
 
+       if (size < SZ_16M)
+               return -EINVAL;
        if (!pmb_addr_valid(vaddr, size))
                return -EFAULT;
        if (pmb_mapping_exists(vaddr, phys, size))
@@ -680,7 +682,7 @@ static void __init pmb_merge(struct pmb_entry *head)
        /*
         * The merged page size must be valid.
         */
-       if (!pmb_size_valid(newsize))
+       if (!depth || !pmb_size_valid(newsize))
                return;
 
        head->flags &= ~PMB_SZ_MASK;
diff --git a/arch/sh/mm/tlb-debugfs.c b/arch/sh/mm/tlb-debugfs.c
new file mode 100644 (file)
index 0000000..229bf75
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * arch/sh/mm/tlb-debugfs.c
+ *
+ * debugfs ops for SH-4 ITLB/UTLBs.
+ *
+ * Copyright (C) 2010  Matt Fleming
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+
+enum tlb_type {
+       TLB_TYPE_ITLB,
+       TLB_TYPE_UTLB,
+};
+
+static struct {
+       int bits;
+       const char *size;
+} tlb_sizes[] = {
+       { 0x0, "  1KB" },
+       { 0x1, "  4KB" },
+       { 0x2, "  8KB" },
+       { 0x4, " 64KB" },
+       { 0x5, "256KB" },
+       { 0x7, "  1MB" },
+       { 0x8, "  4MB" },
+       { 0xc, " 64MB" },
+};
+
+static int tlb_seq_show(struct seq_file *file, void *iter)
+{
+       unsigned int tlb_type = (unsigned int)file->private;
+       unsigned long addr1, addr2, data1, data2;
+       unsigned long flags;
+       unsigned long mmucr;
+       unsigned int nentries, entry;
+       unsigned int urb;
+
+       mmucr = __raw_readl(MMUCR);
+       if ((mmucr & 0x1) == 0) {
+               seq_printf(file, "address translation disabled\n");
+               return 0;
+       }
+
+       if (tlb_type == TLB_TYPE_ITLB) {
+               addr1 = MMU_ITLB_ADDRESS_ARRAY;
+               addr2 = MMU_ITLB_ADDRESS_ARRAY2;
+               data1 = MMU_ITLB_DATA_ARRAY;
+               data2 = MMU_ITLB_DATA_ARRAY2;
+               nentries = 4;
+       } else {
+               addr1 = MMU_UTLB_ADDRESS_ARRAY;
+               addr2 = MMU_UTLB_ADDRESS_ARRAY2;
+               data1 = MMU_UTLB_DATA_ARRAY;
+               data2 = MMU_UTLB_DATA_ARRAY2;
+               nentries = 64;
+       }
+
+       local_irq_save(flags);
+       jump_to_uncached();
+
+       urb = (mmucr & MMUCR_URB) >> MMUCR_URB_SHIFT;
+
+       /* Make the "entry >= urb" test fail. */
+       if (urb == 0)
+               urb = MMUCR_URB_NENTRIES + 1;
+
+       if (tlb_type == TLB_TYPE_ITLB) {
+               addr1 = MMU_ITLB_ADDRESS_ARRAY;
+               addr2 = MMU_ITLB_ADDRESS_ARRAY2;
+               data1 = MMU_ITLB_DATA_ARRAY;
+               data2 = MMU_ITLB_DATA_ARRAY2;
+               nentries = 4;
+       } else {
+               addr1 = MMU_UTLB_ADDRESS_ARRAY;
+               addr2 = MMU_UTLB_ADDRESS_ARRAY2;
+               data1 = MMU_UTLB_DATA_ARRAY;
+               data2 = MMU_UTLB_DATA_ARRAY2;
+               nentries = 64;
+       }
+
+       seq_printf(file, "entry:     vpn        ppn     asid  size valid wired\n");
+
+       for (entry = 0; entry < nentries; entry++) {
+               unsigned long vpn, ppn, asid, size;
+               unsigned long valid;
+               unsigned long val;
+               const char *sz = "    ?";
+               int i;
+
+               val = __raw_readl(addr1 | (entry << MMU_TLB_ENTRY_SHIFT));
+               ctrl_barrier();
+               vpn = val & 0xfffffc00;
+               valid = val & 0x100;
+
+               val = __raw_readl(addr2 | (entry << MMU_TLB_ENTRY_SHIFT));
+               ctrl_barrier();
+               asid = val & MMU_CONTEXT_ASID_MASK;
+
+               val = __raw_readl(data1 | (entry << MMU_TLB_ENTRY_SHIFT));
+               ctrl_barrier();
+               ppn = (val & 0x0ffffc00) << 4;
+
+               val = __raw_readl(data2 | (entry << MMU_TLB_ENTRY_SHIFT));
+               ctrl_barrier();
+               size = (val & 0xf0) >> 4;
+
+               for (i = 0; i < ARRAY_SIZE(tlb_sizes); i++) {
+                       if (tlb_sizes[i].bits == size)
+                               break;
+               }
+
+               if (i != ARRAY_SIZE(tlb_sizes))
+                       sz = tlb_sizes[i].size;
+
+               seq_printf(file, "%2d:    0x%08lx 0x%08lx %5lu %s   %s     %s\n",
+                          entry, vpn, ppn, asid,
+                          sz, valid ? "V" : "-",
+                          (urb <= entry) ? "W" : "-");
+       }
+
+       back_to_cached();
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+static int tlb_debugfs_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, tlb_seq_show, inode->i_private);
+}
+
+static const struct file_operations tlb_debugfs_fops = {
+       .owner          = THIS_MODULE,
+       .open           = tlb_debugfs_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init tlb_debugfs_init(void)
+{
+       struct dentry *itlb, *utlb;
+
+       itlb = debugfs_create_file("itlb", S_IRUSR, sh_debugfs_root,
+                                  (unsigned int *)TLB_TYPE_ITLB,
+                                  &tlb_debugfs_fops);
+       if (unlikely(!itlb))
+               return -ENOMEM;
+       if (IS_ERR(itlb))
+               return PTR_ERR(itlb);
+
+       utlb = debugfs_create_file("utlb", S_IRUSR, sh_debugfs_root,
+                                  (unsigned int *)TLB_TYPE_UTLB,
+                                  &tlb_debugfs_fops);
+       if (unlikely(!utlb)) {
+               debugfs_remove(itlb);
+               return -ENOMEM;
+       }
+
+       if (IS_ERR(utlb)) {
+               debugfs_remove(itlb);
+               return PTR_ERR(utlb);
+       }
+
+       return 0;
+}
+module_init(tlb_debugfs_init);
+
+MODULE_LICENSE("GPL v2");
index 706da1d..03db41c 100644 (file)
@@ -189,7 +189,6 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
-survive:
        fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0);
        if (unlikely(fault & VM_FAULT_ERROR)) {
                if (fault & VM_FAULT_OOM)
@@ -294,22 +293,11 @@ no_context:
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
-       if (is_global_init(current)) {
-               panic("INIT out of memory\n");
-               yield();
-               goto survive;
-       }
-       printk("fault:Out of memory\n");
        up_read(&mm->mmap_sem);
-       if (is_global_init(current)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
-       printk("VM: killing process %s\n", tsk->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
-       goto no_context;
+       if (!user_mode(regs))
+               goto no_context;
+       pagefault_out_of_memory();
+       return;
 
 do_sigbus:
        printk("fault:Do sigbus\n");
index 6db5136..d6781ce 100644 (file)
@@ -37,6 +37,9 @@ config SPARC64
        def_bool 64BIT
        select ARCH_SUPPORTS_MSI
        select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FUNCTION_GRAPH_FP_TEST
+       select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_KRETPROBES
        select HAVE_KPROBES
        select HAVE_LMB
@@ -72,7 +75,7 @@ config ARCH_USES_GETTIMEOFFSET
 
 config GENERIC_CMOS_UPDATE
        bool
-       default y if SPARC64
+       default y
 
 config GENERIC_CLOCKEVENTS
        bool
index 9d3c889..1b4a831 100644 (file)
@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
        bool "D-cache flush debugging"
        depends on SPARC64 && DEBUG_KERNEL
 
-config STACK_DEBUG
-       bool "Stack Overflow Detection Support"
-
 config MCOUNT
        bool
        depends on SPARC64
-       depends on STACK_DEBUG || FUNCTION_TRACER
+       depends on FUNCTION_TRACER
        default y
 
 config FRAME_POINTER
index f0d343c..7ae128b 100644 (file)
@@ -25,7 +25,7 @@ extern int atomic_cmpxchg(atomic_t *, int, int);
 extern int atomic_add_unless(atomic_t *, int, int);
 extern void atomic_set(atomic_t *, int);
 
-#define atomic_read(v)          ((v)->counter)
+#define atomic_read(v)          (*(volatile int *)&(v)->counter)
 
 #define atomic_add(i, v)       ((void)__atomic_add_return( (int)(i), (v)))
 #define atomic_sub(i, v)       ((void)__atomic_add_return(-(int)(i), (v)))
index f2e4800..2050ca0 100644 (file)
@@ -13,8 +13,8 @@
 #define ATOMIC_INIT(i)         { (i) }
 #define ATOMIC64_INIT(i)       { (i) }
 
-#define atomic_read(v)         ((v)->counter)
-#define atomic64_read(v)       ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
+#define atomic64_read(v)       (*(volatile long *)&(v)->counter)
 
 #define atomic_set(v, i)       (((v)->counter) = i)
 #define atomic64_set(v, i)     (((v)->counter) = i)
index e72ac9c..766121a 100644 (file)
@@ -44,7 +44,7 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr);
 
 #ifdef ULTRA_HAS_POPULATION_COUNT
 
-static inline unsigned int hweight64(unsigned long w)
+static inline unsigned int __arch_hweight64(unsigned long w)
 {
        unsigned int res;
 
@@ -52,7 +52,7 @@ static inline unsigned int hweight64(unsigned long w)
        return res;
 }
 
-static inline unsigned int hweight32(unsigned int w)
+static inline unsigned int __arch_hweight32(unsigned int w)
 {
        unsigned int res;
 
@@ -60,7 +60,7 @@ static inline unsigned int hweight32(unsigned int w)
        return res;
 }
 
-static inline unsigned int hweight16(unsigned int w)
+static inline unsigned int __arch_hweight16(unsigned int w)
 {
        unsigned int res;
 
@@ -68,7 +68,7 @@ static inline unsigned int hweight16(unsigned int w)
        return res;
 }
 
-static inline unsigned int hweight8(unsigned int w)
+static inline unsigned int __arch_hweight8(unsigned int w)
 {
        unsigned int res;
 
@@ -78,9 +78,10 @@ static inline unsigned int hweight8(unsigned int w)
 
 #else
 
-#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/arch_hweight.h>
 
 #endif
+#include <asm-generic/bitops/const_hweight.h>
 #include <asm-generic/bitops/lock.h>
 #endif /* __KERNEL__ */
 
index 41f85ae..78b0700 100644 (file)
@@ -7,6 +7,8 @@
 #ifndef _SPARC_CACHE_H
 #define _SPARC_CACHE_H
 
+#define ARCH_SLAB_MINALIGN     __alignof__(unsigned long long)
+
 #define L1_CACHE_SHIFT 5
 #define L1_CACHE_BYTES 32
 #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)))
index 926397d..050ef35 100644 (file)
@@ -17,7 +17,7 @@ typedef struct {
        unsigned int    __nmi_count;
        unsigned long   clock_tick;     /* %tick's per second */
        unsigned long   __pad;
-       unsigned int    __pad1;
+       unsigned int    irq0_irqs;
        unsigned int    __pad2;
 
        /* Dcache line 2, rarely used */
index 8b49bf9..bfa1ea4 100644 (file)
@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void)
  */
 static inline unsigned long __raw_local_irq_save(void)
 {
-       unsigned long flags = __raw_local_save_flags();
-
-       raw_local_irq_disable();
+       unsigned long flags, tmp;
+
+       /* Disable interrupts to PIL_NORMAL_MAX unless we already
+        * are using PIL_NMI, in which case PIL_NMI is retained.
+        *
+        * The only values we ever program into the %pil are 0,
+        * PIL_NORMAL_MAX and PIL_NMI.
+        *
+        * Since PIL_NMI is the largest %pil value and all bits are
+        * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
+        * actually is.
+        */
+       __asm__ __volatile__(
+               "rdpr   %%pil, %0\n\t"
+               "or     %0, %2, %1\n\t"
+               "wrpr   %1, 0x0, %%pil"
+               : "=r" (flags), "=r" (tmp)
+               : "i" (PIL_NORMAL_MAX)
+               : "memory"
+       );
 
        return flags;
 }
index 9e2d944..4827a3a 100644 (file)
@@ -111,7 +111,7 @@ struct thread_info {
 #define THREAD_SHIFT PAGE_SHIFT
 #endif /* PAGE_SHIFT == 13 */
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
index c631614..0c2dc1f 100644 (file)
@@ -13,6 +13,14 @@ extra-y     += init_task.o
 CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
 extra-y              += vmlinux.lds
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o := -pg
+CFLAGS_REMOVE_time_$(BITS).o := -pg
+CFLAGS_REMOVE_perf_event.o := -pg
+CFLAGS_REMOVE_pcr.o := -pg
+endif
+
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS).o
 
 
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 
 obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o
index 9103a56..03ab022 100644 (file)
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
 
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
-       static u32 call;
+       u32 call;
        s32 off;
 
        off = ((s32)addr - (s32)ip);
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+       return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+       return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+                                   unsigned long self_addr,
+                                   unsigned long frame_pointer)
+{
+       unsigned long return_hooker = (unsigned long) &return_to_handler;
+       struct ftrace_graph_ent trace;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return parent + 8UL;
+
+       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+                                    frame_pointer) == -EBUSY)
+               return parent + 8UL;
+
+       trace.func = self_addr;
+
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace)) {
+               current->curr_ret_stack--;
+               return parent + 8UL;
+       }
+
+       return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
index e1cbdb9..830d70a 100644 (file)
@@ -20,7 +20,9 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/ftrace.h>
 #include <linux/irq.h>
+#include <linux/kmemleak.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -45,6 +47,7 @@
 
 #include "entry.h"
 #include "cpumap.h"
+#include "kstack.h"
 
 #define NUM_IVECS      (IMAP_INR + 1)
 
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
        bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
        if (unlikely(!bucket))
                return 0;
+
+       /* The only reference we store to the IRQ bucket is
+        * by physical address which kmemleak can't see, tell
+        * it that this object explicitly is not a leak and
+        * should be scanned.
+        */
+       kmemleak_not_leak(bucket);
+
        __flush_dcache_range((unsigned long) bucket,
                             ((unsigned long) bucket +
                              sizeof(struct ino_bucket)));
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
 void *hardirq_stack[NR_CPUS];
 void *softirq_stack[NR_CPUS];
 
-static __attribute__((always_inline)) void *set_hardirq_stack(void)
-{
-       void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
-
-       __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
-       if (orig_sp < sp ||
-           orig_sp > (sp + THREAD_SIZE)) {
-               sp += THREAD_SIZE - 192 - STACK_BIAS;
-               __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
-       }
-
-       return orig_sp;
-}
-static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
-{
-       __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
-}
-
-void handler_irq(int irq, struct pt_regs *regs)
+void __irq_entry handler_irq(int irq, struct pt_regs *regs)
 {
        unsigned long pstate, bucket_pa;
        struct pt_regs *old_regs;
index f5a0fd4..0a2bd0f 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/kgdb.h>
 #include <linux/kdebug.h>
+#include <linux/ftrace.h>
 
 #include <asm/kdebug.h>
 #include <asm/ptrace.h>
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 }
 
 #ifdef CONFIG_SMP
-void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
 {
        unsigned long flags;
 
index 5247283..53dfb92 100644 (file)
@@ -61,4 +61,23 @@ check_magic:
 
 }
 
+static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
+{
+       void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
+
+       __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
+       if (orig_sp < sp ||
+           orig_sp > (sp + THREAD_SIZE)) {
+               sp += THREAD_SIZE - 192 - STACK_BIAS;
+               __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
+       }
+
+       return orig_sp;
+}
+
+static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
+{
+       __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
+}
+
 #endif /* _KSTACK_H */
index b287b62..a4bd7ba 100644 (file)
@@ -23,6 +23,8 @@
 #include <asm/ptrace.h>
 #include <asm/pcr.h>
 
+#include "kstack.h"
+
 /* We don't have a real NMI on sparc64, but we can fake one
  * up using profiling counter overflow interrupts and interrupt
  * levels.
@@ -92,7 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
 notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 {
        unsigned int sum, touched = 0;
-       int cpu = smp_processor_id();
+       void *orig_sp;
 
        clear_softint(1 << irq);
 
@@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 
        nmi_enter();
 
+       orig_sp = set_hardirq_stack();
+
        if (notify_die(DIE_NMI, "nmi", regs, 0,
                       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
                touched = 1;
        else
                pcr_ops->write(PCR_PIC_PRIV);
 
-       sum = kstat_irqs_cpu(0, cpu);
+       sum = local_cpu_data().irq0_irqs;
        if (__get_cpu_var(nmi_touch)) {
                __get_cpu_var(nmi_touch) = 0;
                touched = 1;
@@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
                pcr_ops->write(pcr_enable);
        }
 
+       restore_hardirq_stack(orig_sp);
+
        nmi_exit();
 }
 
index b775658..8a00058 100644 (file)
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
                struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
 
                if (!rp) {
-                       prom_printf("Cannot allocate IOMMU resource.\n");
-                       prom_halt();
+                       pr_info("%s: Cannot allocate IOMMU resource.\n",
+                               pbm->name);
+                       return;
                }
                rp->name = "IOMMU";
                rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
                rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
                rp->flags = IORESOURCE_BUSY;
-               request_resource(&pbm->mem_space, rp);
+               if (request_resource(&pbm->mem_space, rp)) {
+                       pr_info("%s: Unable to request IOMMU resource.\n",
+                               pbm->name);
+                       kfree(rp);
+               }
        }
 }
 
index 2d94e7a..c4a6a50 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/irq.h>
 
 #include <linux/perf_event.h>
+#include <linux/ftrace.h>
 
 #include <asm/pil.h>
 #include <asm/pcr.h>
@@ -34,7 +35,7 @@ unsigned int picl_shift;
  * Therefore in such situations we defer the work by signalling
  * a lower level cpu IRQ.
  */
-void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
+void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
 
index e277193..34ce49f 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/perf_event.h>
 #include <linux/kprobes.h>
+#include <linux/ftrace.h>
 #include <linux/kernel.h>
 #include <linux/kdebug.h>
 #include <linux/mutex.h>
@@ -1276,6 +1277,9 @@ static void perf_callchain_kernel(struct pt_regs *regs,
                                  struct perf_callchain_entry *entry)
 {
        unsigned long ksp, fp;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       int graph = 0;
+#endif
 
        callchain_store(entry, PERF_CONTEXT_KERNEL);
        callchain_store(entry, regs->tpc);
@@ -1303,6 +1307,16 @@ static void perf_callchain_kernel(struct pt_regs *regs,
                        fp = (unsigned long)sf->fp + STACK_BIAS;
                }
                callchain_store(entry, pc);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+               if ((pc + 8UL) == (unsigned long) &return_to_handler) {
+                       int index = current->curr_ret_stack;
+                       if (current->ret_stack && index >= graph) {
+                               pc = current->ret_stack[index - graph].ret;
+                               callchain_store(entry, pc);
+                               graph++;
+                       }
+               }
+#endif
        } while (entry->nr < PERF_MAX_STACK_DEPTH);
 }
 
index a5cf386..dbe81a3 100644 (file)
@@ -202,6 +202,7 @@ void show_regs(struct pt_regs *regs)
               regs->u_regs[15]);
        printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
        show_regwindow(regs);
+       show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]);
 }
 
 struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
index 83f1873..090b9e9 100644 (file)
@@ -130,7 +130,17 @@ rtrap_xcall:
                 nop
                call                    trace_hardirqs_on
                 nop
-               wrpr                    %l4, %pil
+               /* Do not actually set the %pil here.  We will do that
+                * below after we clear PSTATE_IE in the %pstate register.
+                * If we re-enable interrupts here, we can recurse down
+                * the hardirq stack potentially endlessly, causing a
+                * stack overflow.
+                *
+                * It is tempting to put this test and trace_hardirqs_on
+                * call at the 'rt_continue' label, but that will not work
+                * as that path hits unconditionally and we do not want to
+                * execute this in NMI return paths, for example.
+                */
 #endif
 rtrap_no_irq_enable:
                andcc                   %l1, TSTATE_PRIV, %l3
index 4c53345..b6a2b8f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/profile.h>
 #include <linux/bootmem.h>
 #include <linux/vmalloc.h>
+#include <linux/ftrace.h>
 #include <linux/cpu.h>
 #include <linux/slab.h>
 
@@ -823,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu)
                      &cpumask_of_cpu(cpu));
 }
 
-void smp_call_function_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
        generic_smp_call_function_interrupt();
 }
 
-void smp_call_function_single_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
        generic_smp_call_function_single_interrupt();
@@ -965,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
        put_cpu();
 }
 
-void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
 {
        struct mm_struct *mm;
        unsigned long flags;
@@ -1149,7 +1150,7 @@ void smp_release(void)
  */
 extern void prom_world(int);
 
-void smp_penguin_jailcell(int irq, struct pt_regs *regs)
+void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 
@@ -1365,7 +1366,7 @@ void smp_send_reschedule(int cpu)
                      &cpumask_of_cpu(cpu));
 }
 
-void smp_receive_signal_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 }
index acb12f6..3e08153 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
 #include <linux/thread_info.h>
+#include <linux/ftrace.h>
 #include <linux/module.h>
 #include <asm/ptrace.h>
 #include <asm/stacktrace.h>
@@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp,
                               bool skip_sched)
 {
        unsigned long ksp, fp;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       struct task_struct *t;
+       int graph = 0;
+#endif
 
        if (tp == current_thread_info()) {
                stack_trace_flush();
@@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp,
        }
 
        fp = ksp + STACK_BIAS;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       t = tp->task;
+#endif
        do {
                struct sparc_stackf *sf;
                struct pt_regs *regs;
@@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp,
 
                if (trace->skip > 0)
                        trace->skip--;
-               else if (!skip_sched || !in_sched_functions(pc))
+               else if (!skip_sched || !in_sched_functions(pc)) {
                        trace->entries[trace->nr_entries++] = pc;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+                       if ((pc + 8UL) == (unsigned long) &return_to_handler) {
+                               int index = t->curr_ret_stack;
+                               if (t->ret_stack && index >= graph) {
+                                       pc = t->ret_stack[index - graph].ret;
+                                       if (trace->nr_entries <
+                                           trace->max_entries)
+                                               trace->entries[trace->nr_entries++] = pc;
+                                       graph++;
+                               }
+                       }
+#endif
+               }
        } while (trace->nr_entries < trace->max_entries);
 }
 
index 0d4c09b..4453003 100644 (file)
@@ -78,6 +78,11 @@ __volatile__ unsigned int *master_l10_counter;
 
 u32 (*do_arch_gettimeoffset)(void);
 
+int update_persistent_clock(struct timespec now)
+{
+       return set_rtc_mmss(now.tv_sec);
+}
+
 /*
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
@@ -87,9 +92,6 @@ u32 (*do_arch_gettimeoffset)(void);
 
 static irqreturn_t timer_interrupt(int dummy, void *dev_id)
 {
-       /* last time the cmos clock got updated */
-       static long last_rtc_update;
-
 #ifndef CONFIG_SMP
        profile_tick(CPU_PROFILING);
 #endif
@@ -101,16 +103,6 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)
 
        do_timer(1);
 
-       /* Determine when to update the Mostek clock. */
-       if (ntp_synced() &&
-           xtime.tv_sec > last_rtc_update + 660 &&
-           (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
-           (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
-         if (set_rtc_mmss(xtime.tv_sec) == 0)
-           last_rtc_update = xtime.tv_sec;
-         else
-           last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-       }
        write_sequnlock(&xtime_lock);
 
 #ifndef CONFIG_SMP
index 67e1651..c7bbe6c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/clocksource.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/ftrace.h>
 
 #include <asm/oplib.h>
 #include <asm/timer.h>
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = {
 };
 static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
 
-void timer_interrupt(int irq, struct pt_regs *regs)
+void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned long tick_mask = tick_ops->softint_mask;
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
 
        irq_enter();
 
+       local_cpu_data().irq0_irqs++;
        kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
 
        if (unlikely(!evt->event_handler)) {
index 837dfc2..42ad2ba 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/kdebug.h>
+#include <linux/ftrace.h>
 #include <linux/gfp.h>
 
 #include <asm/smp.h>
@@ -2154,6 +2155,9 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
        unsigned long fp, thread_base, ksp;
        struct thread_info *tp;
        int count = 0;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       int graph = 0;
+#endif
 
        ksp = (unsigned long) _ksp;
        if (!tsk)
@@ -2193,6 +2197,16 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
                }
 
                printk(" [%016lx] %pS\n", pc, (void *) pc);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+               if ((pc + 8UL) == (unsigned long) &return_to_handler) {
+                       int index = tsk->curr_ret_stack;
+                       if (tsk->ret_stack && index >= graph) {
+                               pc = tsk->ret_stack[index - graph].ret;
+                               printk(" [%016lx] %pS\n", pc, (void *) pc);
+                               graph++;
+                       }
+               }
+#endif
        } while (++count < 16);
 }
 
@@ -2203,27 +2217,6 @@ void dump_stack(void)
 
 EXPORT_SYMBOL(dump_stack);
 
-static inline int is_kernel_stack(struct task_struct *task,
-                                 struct reg_window *rw)
-{
-       unsigned long rw_addr = (unsigned long) rw;
-       unsigned long thread_base, thread_end;
-
-       if (rw_addr < PAGE_OFFSET) {
-               if (task != &init_task)
-                       return 0;
-       }
-
-       thread_base = (unsigned long) task_stack_page(task);
-       thread_end = thread_base + sizeof(union thread_union);
-       if (rw_addr >= thread_base &&
-           rw_addr < thread_end &&
-           !(rw_addr & 0x7UL))
-               return 1;
-
-       return 0;
-}
-
 static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
 {
        unsigned long fp = rw->ins[6];
@@ -2252,6 +2245,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
        show_regs(regs);
        add_taint(TAINT_DIE);
        if (regs->tstate & TSTATE_PRIV) {
+               struct thread_info *tp = current_thread_info();
                struct reg_window *rw = (struct reg_window *)
                        (regs->u_regs[UREG_FP] + STACK_BIAS);
 
@@ -2259,8 +2253,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
                 * find some badly aligned kernel stack.
                 */
                while (rw &&
-                      count++ < 30&&
-                      is_kernel_stack(current, rw)) {
+                      count++ < 30 &&
+                      kstack_valid(tp, (unsigned long) rw)) {
                        printk("Caller[%016lx]: %pS\n", rw->ins[7],
                               (void *) rw->ins[7]);
 
index ebce430..c752c4c 100644 (file)
@@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn)
 }
 
 /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
-static inline int decode_access_size(unsigned int insn)
+static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
 {
        unsigned int tmp;
 
@@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn)
                return 2;
        else {
                printk("Impossible unaligned trap. insn=%08x\n", insn);
-               die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
+               die_if_kernel("Byte sized unaligned access?!?!", regs);
 
                /* GCC should never warn that control reaches the end
                 * of this function without returning a value because
@@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs)
 asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
 {
        enum direction dir = decode_direction(insn);
-       int size = decode_access_size(insn);
+       int size = decode_access_size(regs, insn);
        int orig_asi, asi;
 
        current_thread_info()->kern_una_regs = regs;
index 4e59925..0c1e678 100644 (file)
@@ -46,11 +46,16 @@ SECTIONS
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
+               IRQENTRY_TEXT
                *(.gnu.warning)
        } = 0
        _etext = .;
 
        RO_DATA(PAGE_SIZE)
+
+       /* Start of data section */
+       _sdata = .;
+
        .data1 : {
                *(.data1)
        }
index 24b8b12..3ad6cbd 100644 (file)
@@ -7,26 +7,11 @@
 
 #include <linux/linkage.h>
 
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-
 /*
  * This is the main variant and is called by C code.  GCC's -pg option
  * automatically instruments every C function with a call to this.
  */
 
-#ifdef CONFIG_STACK_DEBUG
-
-#define OVSTACKSIZE    4096            /* lets hope this is enough */
-
-       .data
-       .align          8
-panicstring:
-       .asciz          "Stack overflow\n"
-       .align          8
-ovstack:
-       .skip           OVSTACKSIZE
-#endif
        .text
        .align          32
        .globl          _mcount
@@ -35,84 +20,48 @@ ovstack:
        .type           mcount,#function
 _mcount:
 mcount:
-#ifdef CONFIG_STACK_DEBUG
-       /*
-        * Check whether %sp is dangerously low.
-        */
-       ldub            [%g6 + TI_FPDEPTH], %g1
-       srl             %g1, 1, %g3
-       add             %g3, 1, %g3
-       sllx            %g3, 8, %g3                     ! each fpregs frame is 256b
-       add             %g3, 192, %g3
-       add             %g6, %g3, %g3                   ! where does task_struct+frame end?
-       sub             %g3, STACK_BIAS, %g3
-       cmp             %sp, %g3
-       bg,pt           %xcc, 1f
-        nop
-       lduh            [%g6 + TI_CPU], %g1
-       sethi           %hi(hardirq_stack), %g3
-       or              %g3, %lo(hardirq_stack), %g3
-       sllx            %g1, 3, %g1
-       ldx             [%g3 + %g1], %g7
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       bleu,pt         %xcc, 2f
-        sethi          %hi(THREAD_SIZE), %g3
-       add             %g7, %g3, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 1f
-2:      sethi          %hi(softirq_stack), %g3
-       or              %g3, %lo(softirq_stack), %g3
-       ldx             [%g3 + %g1], %g7
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       bleu,pt         %xcc, 3f
-        sethi          %hi(THREAD_SIZE), %g3
-       add             %g7, %g3, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 1f
-        nop
-       /* If we are already on ovstack, don't hop onto it
-        * again, we are already trying to output the stack overflow
-        * message.
-        */
-3:     sethi           %hi(ovstack), %g7               ! cant move to panic stack fast enough
-        or             %g7, %lo(ovstack), %g7
-       add             %g7, OVSTACKSIZE, %g3
-       sub             %g3, STACK_BIAS + 192, %g3
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 2f
-        cmp            %sp, %g3
-       bleu,pn         %xcc, 1f
-        nop
-2:     mov             %g3, %sp
-       sethi           %hi(panicstring), %g3
-       call            prom_printf
-        or             %g3, %lo(panicstring), %o0
-       call            prom_halt
-        nop
-1:
-#endif
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_DYNAMIC_FTRACE
-       mov             %o7, %o0
-       .globl          mcount_call
-mcount_call:
-       call            ftrace_stub
-        mov            %o0, %o7
+       /* Do nothing, the retl/nop below is all we need.  */
 #else
-       sethi           %hi(ftrace_trace_function), %g1
+       sethi           %hi(function_trace_stop), %g1
+       lduw            [%g1 + %lo(function_trace_stop)], %g2
+       brnz,pn         %g2, 2f
+        sethi          %hi(ftrace_trace_function), %g1
        sethi           %hi(ftrace_stub), %g2
        ldx             [%g1 + %lo(ftrace_trace_function)], %g1
        or              %g2, %lo(ftrace_stub), %g2
        cmp             %g1, %g2
        be,pn           %icc, 1f
-        mov            %i7, %o1
-       jmpl            %g1, %g0
-        mov            %o7, %o0
+        mov            %i7, %g3
+       save            %sp, -176, %sp
+       mov             %g3, %o1
+       jmpl            %g1, %o7
+        mov            %i7, %o0
+       ret
+        restore
        /* not reached */
 1:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       sethi           %hi(ftrace_graph_return), %g1
+       ldx             [%g1 + %lo(ftrace_graph_return)], %g3
+       cmp             %g2, %g3
+       bne,pn          %xcc, 5f
+        sethi          %hi(ftrace_graph_entry_stub), %g2
+       sethi           %hi(ftrace_graph_entry), %g1
+       or              %g2, %lo(ftrace_graph_entry_stub), %g2
+       ldx             [%g1 + %lo(ftrace_graph_entry)], %g1
+       cmp             %g1, %g2
+       be,pt           %xcc, 2f
+        nop
+5:     mov             %i7, %g2
+       mov             %fp, %g3
+       save            %sp, -176, %sp
+       mov             %g2, %l0
+       ba,pt           %xcc, ftrace_graph_caller
+        mov            %g3, %l1
+#endif
+2:
 #endif
 #endif
        retl
@@ -131,14 +80,50 @@ ftrace_stub:
        .globl          ftrace_caller
        .type           ftrace_caller,#function
 ftrace_caller:
-       mov             %i7, %o1
-       mov             %o7, %o0
+       sethi           %hi(function_trace_stop), %g1
+       mov             %i7, %g2
+       lduw            [%g1 + %lo(function_trace_stop)], %g1
+       brnz,pn         %g1, ftrace_stub
+        mov            %fp, %g3
+       save            %sp, -176, %sp
+       mov             %g2, %o1
+       mov             %g2, %l0
+       mov             %g3, %l1
        .globl          ftrace_call
 ftrace_call:
        call            ftrace_stub
-        mov            %o0, %o7
-       retl
+        mov            %i7, %o0
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .globl          ftrace_graph_call
+ftrace_graph_call:
+       call            ftrace_stub
         nop
+#endif
+       ret
+        restore
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .size           ftrace_graph_call,.-ftrace_graph_call
+#endif
+       .size           ftrace_call,.-ftrace_call
        .size           ftrace_caller,.-ftrace_caller
 #endif
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+       mov             %l0, %o0
+       mov             %i7, %o1
+       call            prepare_ftrace_return
+        mov            %l1, %o2
+       ret
+        restore        %o0, -8, %i7
+END(ftrace_graph_caller)
+
+ENTRY(return_to_handler)
+       save            %sp, -176, %sp
+       call            ftrace_return_to_handler
+        mov            %fp, %o0
+       jmpl            %o0 + 8, %g0
+        restore
+END(return_to_handler)
+#endif
index 64cda95..7a656bd 100644 (file)
@@ -6,6 +6,7 @@
 #include "linux/irqreturn.h"
 #include "linux/kd.h"
 #include "linux/sched.h"
+#include "linux/slab.h"
 #include "chan_kern.h"
 #include "irq_kern.h"
 #include "irq_user.h"
index 06d6ccf..b6b1096 100644 (file)
@@ -8,7 +8,6 @@
 #include <errno.h>
 #include <sched.h>
 #include <linux/limits.h>
-#include <linux/slab.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include "kern_constants.h"
index 9458685..a2d3a5f 100644 (file)
@@ -53,11 +53,15 @@ config X86
        select HAVE_KERNEL_LZMA
        select HAVE_KERNEL_LZO
        select HAVE_HW_BREAKPOINT
+       select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS
        select ANON_INODES
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
 
+config INSTRUCTION_DECODER
+       def_bool (KPROBES || PERF_EVENTS)
+
 config OUTPUT_FORMAT
        string
        default "elf32-i386" if X86_32
@@ -197,20 +201,17 @@ config HAVE_INTEL_TXT
 
 # Use the generic interrupt handling code in kernel/irq/:
 config GENERIC_HARDIRQS
-       bool
-       default y
+       def_bool y
 
 config GENERIC_HARDIRQS_NO__DO_IRQ
        def_bool y
 
 config GENERIC_IRQ_PROBE
-       bool
-       default y
+       def_bool y
 
 config GENERIC_PENDING_IRQ
-       bool
+       def_bool y
        depends on GENERIC_HARDIRQS && SMP
-       default y
 
 config USE_GENERIC_SMP_HELPERS
        def_bool y
@@ -225,19 +226,22 @@ config X86_64_SMP
        depends on X86_64 && SMP
 
 config X86_HT
-       bool
+       def_bool y
        depends on SMP
-       default y
 
 config X86_TRAMPOLINE
-       bool
+       def_bool y
        depends on SMP || (64BIT && ACPI_SLEEP)
-       default y
 
 config X86_32_LAZY_GS
        def_bool y
        depends on X86_32 && !CC_STACKPROTECTOR
 
+config ARCH_HWEIGHT_CFLAGS
+       string
+       default "-fcall-saved-ecx -fcall-saved-edx" if X86_32
+       default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64
+
 config KTIME_SCALAR
        def_bool X86_32
 source "init/Kconfig"
@@ -447,7 +451,7 @@ config X86_NUMAQ
          firmware with - send email to <Martin.Bligh@us.ibm.com>.
 
 config X86_SUPPORTS_MEMORY_FAILURE
-       bool
+       def_bool y
        # MCE code calls memory_failure():
        depends on X86_MCE
        # On 32-bit this adds too big of NODES_SHIFT and we run out of page flags:
@@ -455,7 +459,6 @@ config X86_SUPPORTS_MEMORY_FAILURE
        # On 32-bit SPARSEMEM adds too big of SECTIONS_WIDTH:
        depends on X86_64 || !SPARSEMEM
        select ARCH_SUPPORTS_MEMORY_FAILURE
-       default y
 
 config X86_VISWS
        bool "SGI 320/540 (Visual Workstation)"
@@ -570,7 +573,6 @@ config PARAVIRT_SPINLOCKS
 
 config PARAVIRT_CLOCK
        bool
-       default n
 
 endif
 
@@ -749,7 +751,6 @@ config MAXSMP
        bool "Configure Maximum number of SMP Processors and NUMA Nodes"
        depends on X86_64 && SMP && DEBUG_KERNEL && EXPERIMENTAL
        select CPUMASK_OFFSTACK
-       default n
        ---help---
          Configure maximum number of CPUS and NUMA Nodes for this architecture.
          If unsure, say N.
@@ -829,7 +830,6 @@ config X86_VISWS_APIC
 
 config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
        bool "Reroute for broken boot IRQs"
-       default n
        depends on X86_IO_APIC
        ---help---
          This option enables a workaround that fixes a source of
@@ -876,9 +876,8 @@ config X86_MCE_AMD
           the DRAM Error Threshold.
 
 config X86_ANCIENT_MCE
-       def_bool n
+       bool "Support for old Pentium 5 / WinChip machine checks"
        depends on X86_32 && X86_MCE
-       prompt "Support for old Pentium 5 / WinChip machine checks"
        ---help---
          Include support for machine check handling on old Pentium 5 or WinChip
          systems. These typically need to be enabled explicitely on the command
@@ -886,8 +885,7 @@ config X86_ANCIENT_MCE
 
 config X86_MCE_THRESHOLD
        depends on X86_MCE_AMD || X86_MCE_INTEL
-       bool
-       default y
+       def_bool y
 
 config X86_MCE_INJECT
        depends on X86_MCE
@@ -1026,8 +1024,8 @@ config X86_CPUID
 
 choice
        prompt "High Memory Support"
-       default HIGHMEM4G if !X86_NUMAQ
        default HIGHMEM64G if X86_NUMAQ
+       default HIGHMEM4G
        depends on X86_32
 
 config NOHIGHMEM
@@ -1285,7 +1283,7 @@ source "mm/Kconfig"
 
 config HIGHPTE
        bool "Allocate 3rd-level pagetables from highmem"
-       depends on X86_32 && (HIGHMEM4G || HIGHMEM64G)
+       depends on HIGHMEM
        ---help---
          The VM uses one page table entry for each page of physical memory.
          For systems with a lot of RAM, this can be wasteful of precious
@@ -1369,8 +1367,7 @@ config MATH_EMULATION
          kernel, it won't hurt.
 
 config MTRR
-       bool
-       default y
+       def_bool y
        prompt "MTRR (Memory Type Range Register) support" if EMBEDDED
        ---help---
          On Intel P6 family processors (Pentium Pro, Pentium II and later)
@@ -1436,8 +1433,7 @@ config MTRR_SANITIZER_SPARE_REG_NR_DEFAULT
          mtrr_spare_reg_nr=N on the kernel command line.
 
 config X86_PAT
-       bool
-       default y
+       def_bool y
        prompt "x86 PAT support" if EMBEDDED
        depends on MTRR
        ---help---
@@ -1605,8 +1601,7 @@ config X86_NEED_RELOCS
        depends on X86_32 && RELOCATABLE
 
 config PHYSICAL_ALIGN
-       hex
-       prompt "Alignment value to which kernel should be aligned" if X86_32
+       hex "Alignment value to which kernel should be aligned" if X86_32
        default "0x1000000"
        range 0x2000 0x1000000
        ---help---
@@ -1653,7 +1648,6 @@ config COMPAT_VDSO
 
 config CMDLINE_BOOL
        bool "Built-in kernel command line"
-       default n
        ---help---
          Allow for specifying boot arguments to the kernel at
          build time.  On some systems (e.g. embedded ones), it is
@@ -1687,7 +1681,6 @@ config CMDLINE
 
 config CMDLINE_OVERRIDE
        bool "Built-in command line overrides boot loader arguments"
-       default n
        depends on CMDLINE_BOOL
        ---help---
          Set this option to 'Y' to have the kernel ignore the boot loader
@@ -1723,8 +1716,7 @@ source "drivers/acpi/Kconfig"
 source "drivers/sfi/Kconfig"
 
 config X86_APM_BOOT
-       bool
-       default y
+       def_bool y
        depends on APM || APM_MODULE
 
 menuconfig APM
@@ -1953,8 +1945,7 @@ config DMAR_DEFAULT_ON
          experimental.
 
 config DMAR_BROKEN_GFX_WA
-       def_bool n
-       prompt "Workaround broken graphics drivers (going away soon)"
+       bool "Workaround broken graphics drivers (going away soon)"
        depends on DMAR && BROKEN
        ---help---
          Current Graphics drivers tend to use physical address
@@ -2052,7 +2043,6 @@ config SCx200HR_TIMER
 config OLPC
        bool "One Laptop Per Child support"
        select GPIOLIB
-       default n
        ---help---
          Add support for detecting the unique features of the OLPC
          XO hardware.
index a198293..2ac9069 100644 (file)
@@ -338,6 +338,10 @@ config X86_F00F_BUG
        def_bool y
        depends on M586MMX || M586TSC || M586 || M486 || M386
 
+config X86_INVD_BUG
+       def_bool y
+       depends on M486 || M386
+
 config X86_WP_WORKS_OK
        def_bool y
        depends on !M386
@@ -502,23 +506,3 @@ config CPU_SUP_UMC_32
          CPU might render the kernel unbootable.
 
          If unsure, say N.
-
-config X86_DS
-       def_bool X86_PTRACE_BTS
-       depends on X86_DEBUGCTLMSR
-       select HAVE_HW_BRANCH_TRACER
-
-config X86_PTRACE_BTS
-       bool "Branch Trace Store"
-       default y
-       depends on X86_DEBUGCTLMSR
-       depends on BROKEN
-       ---help---
-         This adds a ptrace interface to the hardware's branch trace store.
-
-         Debuggers may use it to collect an execution trace of the debugged
-         application in order to answer the question 'how did I get here?'.
-         Debuggers may trace user mode as well as kernel mode.
-
-         Say Y unless there is no application development on this machine
-         and you want to save a small amount of code size.
index bc01e3e..7508508 100644 (file)
@@ -45,7 +45,6 @@ config EARLY_PRINTK
 
 config EARLY_PRINTK_DBGP
        bool "Early printk via EHCI debug port"
-       default n
        depends on EARLY_PRINTK && PCI
        ---help---
          Write kernel log output directly into the EHCI debug port.
@@ -76,7 +75,6 @@ config DEBUG_PER_CPU_MAPS
        bool "Debug access to per_cpu maps"
        depends on DEBUG_KERNEL
        depends on SMP
-       default n
        ---help---
          Say Y to verify that the per_cpu map being accessed has
          been setup.  Adds a fair amount of code to kernel memory
@@ -174,15 +172,6 @@ config IOMMU_LEAK
          Add a simple leak tracer to the IOMMU code. This is useful when you
          are debugging a buggy device driver that leaks IOMMU mappings.
 
-config X86_DS_SELFTEST
-    bool "DS selftest"
-    default y
-    depends on DEBUG_KERNEL
-    depends on X86_DS
-       ---help---
-         Perform Debug Store selftests at boot time.
-         If in doubt, say "N".
-
 config HAVE_MMIOTRACE_SUPPORT
        def_bool y
 
index 0a43dc5..8aa1b59 100644 (file)
@@ -95,8 +95,9 @@ sp-$(CONFIG_X86_64) := rsp
 cfi := $(call as-instr,.cfi_startproc\n.cfi_rel_offset $(sp-y)$(comma)0\n.cfi_endproc,-DCONFIG_AS_CFI=1)
 # is .cfi_signal_frame supported too?
 cfi-sigframe := $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1)
-KBUILD_AFLAGS += $(cfi) $(cfi-sigframe)
-KBUILD_CFLAGS += $(cfi) $(cfi-sigframe)
+cfi-sections := $(call as-instr,.cfi_sections .debug_frame,-DCONFIG_AS_CFI_SECTIONS=1)
+KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
+KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections)
 
 LDFLAGS := -m elf_$(UTS_MACHINE)
 
index 59b4556..e790bc1 100644 (file)
@@ -626,7 +626,7 @@ ia32_sys_call_table:
        .quad stub32_sigreturn
        .quad stub32_clone              /* 120 */
        .quad sys_setdomainname
-       .quad sys_uname
+       .quad sys_newuname
        .quad sys_modify_ldt
        .quad compat_sys_adjtimex
        .quad sys32_mprotect            /* 125 */
index b97f786..a63a68b 100644 (file)
@@ -6,8 +6,8 @@
        .macro LOCK_PREFIX
 1:     lock
        .section .smp_locks,"a"
-       _ASM_ALIGN
-       _ASM_PTR 1b
+       .balign 4
+       .long 1b - .
        .previous
        .endm
 #else
index b09ec55..03b6bb5 100644 (file)
  */
 
 #ifdef CONFIG_SMP
-#define LOCK_PREFIX \
+#define LOCK_PREFIX_HERE \
                ".section .smp_locks,\"a\"\n"   \
-               _ASM_ALIGN "\n"                 \
-               _ASM_PTR "661f\n" /* address */ \
+               ".balign 4\n"                   \
+               ".long 671f - .\n" /* offset */ \
                ".previous\n"                   \
-               "661:\n\tlock; "
+               "671:"
+
+#define LOCK_PREFIX LOCK_PREFIX_HERE "\n\tlock; "
 
 #else /* ! CONFIG_SMP */
+#define LOCK_PREFIX_HERE ""
 #define LOCK_PREFIX ""
 #endif
 
-/* This must be included *after* the definition of LOCK_PREFIX */
-#include <asm/cpufeature.h>
-
 struct alt_instr {
        u8 *instr;              /* original instruction */
        u8 *replacement;
@@ -95,6 +95,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
       "663:\n\t" newinstr "\n664:\n"           /* replacement     */   \
       ".previous"
 
+/*
+ * This must be included *after* the definition of ALTERNATIVE due to
+ * <asm/arch_hweight.h>
+ */
+#include <asm/cpufeature.h>
+
 /*
  * Alternative instructions for different CPU types or capabilities.
  *
index ba19ad4..7014e88 100644 (file)
@@ -21,6 +21,7 @@
 #define _ASM_X86_AMD_IOMMU_TYPES_H
 
 #include <linux/types.h>
+#include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
 
 /* constants to configure the command buffer */
 #define CMD_BUFFER_SIZE    8192
+#define CMD_BUFFER_UNINITIALIZED 1
 #define CMD_BUFFER_ENTRIES 512
 #define MMIO_CMD_SIZE_SHIFT 56
 #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
                                (~((1ULL << (12 + ((lvl) * 9))) - 1)))
 #define PM_ALIGNED(lvl, addr)  ((PM_MAP_MASK(lvl) & (addr)) == (addr))
 
+/*
+ * Returns the page table level to use for a given page size
+ * Pagesize is expected to be a power-of-two
+ */
+#define PAGE_SIZE_LEVEL(pagesize) \
+               ((__ffs(pagesize) - 12) / 9)
+/*
+ * Returns the number of ptes to use for a given page size
+ * Pagesize is expected to be a power-of-two
+ */
+#define PAGE_SIZE_PTE_COUNT(pagesize) \
+               (1ULL << ((__ffs(pagesize) - 12) % 9))
+
+/*
+ * Aligns a given io-virtual address to a given page size
+ * Pagesize is expected to be a power-of-two
+ */
+#define PAGE_SIZE_ALIGN(address, pagesize) \
+               ((address) & ~((pagesize) - 1))
+/*
+ * Creates an IOMMU PTE for an address an a given pagesize
+ * The PTE has no permission bits set
+ * Pagesize is expected to be a power-of-two larger than 4096
+ */
+#define PAGE_SIZE_PTE(address, pagesize)               \
+               (((address) | ((pagesize) - 1)) &       \
+                (~(pagesize >> 1)) & PM_ADDR_MASK)
+
+/*
+ * Takes a PTE value with mode=0x07 and returns the page size it maps
+ */
+#define PTE_PAGE_SIZE(pte) \
+       (1ULL << (1 + ffz(((pte) | 0xfffULL))))
+
 #define IOMMU_PTE_P  (1ULL << 0)
 #define IOMMU_PTE_TV (1ULL << 1)
 #define IOMMU_PTE_U  (1ULL << 59)
@@ -237,6 +273,7 @@ struct protection_domain {
        struct list_head list;  /* for list of all protection domains */
        struct list_head dev_list; /* List of all devices in this domain */
        spinlock_t lock;        /* mostly used to lock the page table*/
+       struct mutex api_lock;  /* protect page tables in the iommu-api path */
        u16 id;                 /* the domain id written to the device table */
        int mode;               /* paging mode (0-6 levels) */
        u64 *pt_root;           /* page table root pointer */
index b4ac2cd..1fa03e0 100644 (file)
@@ -373,6 +373,7 @@ extern atomic_t init_deasserted;
 extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
 #endif
 
+#ifdef CONFIG_X86_LOCAL_APIC
 static inline u32 apic_read(u32 reg)
 {
        return apic->read(reg);
@@ -403,10 +404,19 @@ static inline u32 safe_apic_wait_icr_idle(void)
        return apic->safe_wait_icr_idle();
 }
 
+#else /* CONFIG_X86_LOCAL_APIC */
+
+static inline u32 apic_read(u32 reg) { return 0; }
+static inline void apic_write(u32 reg, u32 val) { }
+static inline u64 apic_icr_read(void) { return 0; }
+static inline void apic_icr_write(u32 low, u32 high) { }
+static inline void apic_wait_icr_idle(void) { }
+static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
+
+#endif /* CONFIG_X86_LOCAL_APIC */
 
 static inline void ack_APIC_irq(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        /*
         * ack_APIC_irq() actually gets compiled as a single instruction
         * ... yummie.
@@ -414,7 +424,6 @@ static inline void ack_APIC_irq(void)
 
        /* Docs say use 0 for future compatibility */
        apic_write(APIC_EOI, 0);
-#endif
 }
 
 static inline unsigned default_get_apic_id(unsigned long x)
diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h
new file mode 100644 (file)
index 0000000..9686c3d
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _ASM_X86_HWEIGHT_H
+#define _ASM_X86_HWEIGHT_H
+
+#ifdef CONFIG_64BIT
+/* popcnt %edi, %eax -- redundant REX prefix for alignment */
+#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
+/* popcnt %rdi, %rax */
+#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"
+#define REG_IN "D"
+#define REG_OUT "a"
+#else
+/* popcnt %eax, %eax */
+#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0"
+#define REG_IN "a"
+#define REG_OUT "a"
+#endif
+
+/*
+ * __sw_hweightXX are called from within the alternatives below
+ * and callee-clobbered registers need to be taken care of. See
+ * ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective
+ * compiler switches.
+ */
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+       unsigned int res = 0;
+
+       asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT)
+                    : "="REG_OUT (res)
+                    : REG_IN (w));
+
+       return res;
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+       return __arch_hweight32(w & 0xffff);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+       return __arch_hweight32(w & 0xff);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+       unsigned long res = 0;
+
+#ifdef CONFIG_X86_32
+       return  __arch_hweight32((u32)w) +
+               __arch_hweight32((u32)(w >> 32));
+#else
+       asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
+                    : "="REG_OUT (res)
+                    : REG_IN (w));
+#endif /* CONFIG_X86_32 */
+
+       return res;
+}
+
+#endif
index 8f8217b..952a826 100644 (file)
@@ -22,7 +22,7 @@
  */
 static inline int atomic_read(const atomic_t *v)
 {
-       return v->counter;
+       return (*(volatile int *)&(v)->counter);
 }
 
 /**
@@ -246,6 +246,29 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
 
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
+/*
+ * atomic_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+       int c, old, dec;
+       c = atomic_read(v);
+       for (;;) {
+               dec = c - 1;
+               if (unlikely(dec < 0))
+                       break;
+               old = atomic_cmpxchg((v), c, dec);
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return dec;
+}
+
 /**
  * atomic_inc_short - increment of a short integer
  * @v: pointer to type int
index 03027bf..2a934aa 100644 (file)
@@ -14,109 +14,193 @@ typedef struct {
 
 #define ATOMIC64_INIT(val)     { (val) }
 
-extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
+#ifdef CONFIG_X86_CMPXCHG64
+#define ATOMIC64_ALTERNATIVE_(f, g) "call atomic64_" #g "_cx8"
+#else
+#define ATOMIC64_ALTERNATIVE_(f, g) ALTERNATIVE("call atomic64_" #f "_386", "call atomic64_" #g "_cx8", X86_FEATURE_CX8)
+#endif
+
+#define ATOMIC64_ALTERNATIVE(f) ATOMIC64_ALTERNATIVE_(f, f)
+
+/**
+ * atomic64_cmpxchg - cmpxchg atomic64 variable
+ * @p: pointer to type atomic64_t
+ * @o: expected value
+ * @n: new value
+ *
+ * Atomically sets @v to @n if it was equal to @o and returns
+ * the old value.
+ */
+
+static inline long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n)
+{
+       return cmpxchg64(&v->counter, o, n);
+}
 
 /**
  * atomic64_xchg - xchg atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
+ * @v: pointer to type atomic64_t
+ * @n: value to assign
  *
- * Atomically xchgs the value of @ptr to @new_val and returns
+ * Atomically xchgs the value of @v to @n and returns
  * the old value.
  */
-extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
+static inline long long atomic64_xchg(atomic64_t *v, long long n)
+{
+       long long o;
+       unsigned high = (unsigned)(n >> 32);
+       unsigned low = (unsigned)n;
+       asm volatile(ATOMIC64_ALTERNATIVE(xchg)
+                    : "=A" (o), "+b" (low), "+c" (high)
+                    : "S" (v)
+                    : "memory"
+                    );
+       return o;
+}
 
 /**
  * atomic64_set - set atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
+ * @v: pointer to type atomic64_t
+ * @n: value to assign
  *
- * Atomically sets the value of @ptr to @new_val.
+ * Atomically sets the value of @v to @n.
  */
-extern void atomic64_set(atomic64_t *ptr, u64 new_val);
+static inline void atomic64_set(atomic64_t *v, long long i)
+{
+       unsigned high = (unsigned)(i >> 32);
+       unsigned low = (unsigned)i;
+       asm volatile(ATOMIC64_ALTERNATIVE(set)
+                    : "+b" (low), "+c" (high)
+                    : "S" (v)
+                    : "eax", "edx", "memory"
+                    );
+}
 
 /**
  * atomic64_read - read atomic64 variable
- * @ptr:      pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically reads the value of @ptr and returns it.
+ * Atomically reads the value of @v and returns it.
  */
-static inline u64 atomic64_read(atomic64_t *ptr)
+static inline long long atomic64_read(atomic64_t *v)
 {
-       u64 res;
-
-       /*
-        * Note, we inline this atomic64_t primitive because
-        * it only clobbers EAX/EDX and leaves the others
-        * untouched. We also (somewhat subtly) rely on the
-        * fact that cmpxchg8b returns the current 64-bit value
-        * of the memory location we are touching:
-        */
-       asm volatile(
-               "mov %%ebx, %%eax\n\t"
-               "mov %%ecx, %%edx\n\t"
-               LOCK_PREFIX "cmpxchg8b %1\n"
-                       : "=&A" (res)
-                       : "m" (*ptr)
-               );
-
-       return res;
-}
-
-extern u64 atomic64_read(atomic64_t *ptr);
+       long long r;
+       asm volatile(ATOMIC64_ALTERNATIVE(read)
+                    : "=A" (r), "+c" (v)
+                    : : "memory"
+                    );
+       return r;
+ }
 
 /**
  * atomic64_add_return - add and return
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
  *
- * Atomically adds @delta to @ptr and returns @delta + *@ptr
+ * Atomically adds @i to @v and returns @i + *@v
  */
-extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
+static inline long long atomic64_add_return(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE(add_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
 
 /*
  * Other variants with different arithmetic operators:
  */
-extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
-extern u64 atomic64_inc_return(atomic64_t *ptr);
-extern u64 atomic64_dec_return(atomic64_t *ptr);
+static inline long long atomic64_sub_return(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE(sub_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
+
+static inline long long atomic64_inc_return(atomic64_t *v)
+{
+       long long a;
+       asm volatile(ATOMIC64_ALTERNATIVE(inc_return)
+                    : "=A" (a)
+                    : "S" (v)
+                    : "memory", "ecx"
+                    );
+       return a;
+}
+
+static inline long long atomic64_dec_return(atomic64_t *v)
+{
+       long long a;
+       asm volatile(ATOMIC64_ALTERNATIVE(dec_return)
+                    : "=A" (a)
+                    : "S" (v)
+                    : "memory", "ecx"
+                    );
+       return a;
+}
 
 /**
  * atomic64_add - add integer to atomic64 variable
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
  *
- * Atomically adds @delta to @ptr.
+ * Atomically adds @i to @v.
  */
-extern void atomic64_add(u64 delta, atomic64_t *ptr);
+static inline long long atomic64_add(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(add, add_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
 
 /**
  * atomic64_sub - subtract the atomic64 variable
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
  *
- * Atomically subtracts @delta from @ptr.
+ * Atomically subtracts @i from @v.
  */
-extern void atomic64_sub(u64 delta, atomic64_t *ptr);
+static inline long long atomic64_sub(long long i, atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(sub, sub_return)
+                    : "+A" (i), "+c" (v)
+                    : : "memory"
+                    );
+       return i;
+}
 
 /**
  * atomic64_sub_and_test - subtract value from variable and test result
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr and returns
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
 *
+ * Atomically subtracts @i from @v and returns
  * true if the result is zero, or false for all
  * other cases.
  */
-extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
+static inline int atomic64_sub_and_test(long long i, atomic64_t *v)
+{
+       return atomic64_sub_return(i, v) == 0;
+}
 
 /**
  * atomic64_inc - increment atomic64 variable
- * @ptr: pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically increments @ptr by 1.
+ * Atomically increments @v by 1.
  */
-extern void atomic64_inc(atomic64_t *ptr);
+static inline void atomic64_inc(atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(inc, inc_return)
+                    : : "S" (v)
+                    : "memory", "eax", "ecx", "edx"
+                    );
+}
 
 /**
  * atomic64_dec - decrement atomic64 variable
@@ -124,37 +208,97 @@ extern void atomic64_inc(atomic64_t *ptr);
  *
  * Atomically decrements @ptr by 1.
  */
-extern void atomic64_dec(atomic64_t *ptr);
+static inline void atomic64_dec(atomic64_t *v)
+{
+       asm volatile(ATOMIC64_ALTERNATIVE_(dec, dec_return)
+                    : : "S" (v)
+                    : "memory", "eax", "ecx", "edx"
+                    );
+}
 
 /**
  * atomic64_dec_and_test - decrement and test
- * @ptr: pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically decrements @ptr by 1 and
+ * Atomically decrements @v by 1 and
  * returns true if the result is 0, or false for all other
  * cases.
  */
-extern int atomic64_dec_and_test(atomic64_t *ptr);
+static inline int atomic64_dec_and_test(atomic64_t *v)
+{
+       return atomic64_dec_return(v) == 0;
+}
 
 /**
  * atomic64_inc_and_test - increment and test
- * @ptr: pointer to type atomic64_t
+ * @v: pointer to type atomic64_t
  *
- * Atomically increments @ptr by 1
+ * Atomically increments @v by 1
  * and returns true if the result is zero, or false for all
  * other cases.
  */
-extern int atomic64_inc_and_test(atomic64_t *ptr);
+static inline int atomic64_inc_and_test(atomic64_t *v)
+{
+       return atomic64_inc_return(v) == 0;
+}
 
 /**
  * atomic64_add_negative - add and test if negative
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
  *
- * Atomically adds @delta to @ptr and returns true
+ * Atomically adds @i to @v and returns true
  * if the result is negative, or false when
  * result is greater than or equal to zero.
  */
-extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
+static inline int atomic64_add_negative(long long i, atomic64_t *v)
+{
+       return atomic64_add_return(i, v) < 0;
+}
+
+/**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+{
+       unsigned low = (unsigned)u;
+       unsigned high = (unsigned)(u >> 32);
+       asm volatile(ATOMIC64_ALTERNATIVE(add_unless) "\n\t"
+                    : "+A" (a), "+c" (v), "+S" (low), "+D" (high)
+                    : : "memory");
+       return (int)a;
+}
+
+
+static inline int atomic64_inc_not_zero(atomic64_t *v)
+{
+       int r;
+       asm volatile(ATOMIC64_ALTERNATIVE(inc_not_zero)
+                    : "=a" (r)
+                    : "S" (v)
+                    : "ecx", "edx", "memory"
+                    );
+       return r;
+}
+
+static inline long long atomic64_dec_if_positive(atomic64_t *v)
+{
+       long long r;
+       asm volatile(ATOMIC64_ALTERNATIVE(dec_if_positive)
+                    : "=A" (r)
+                    : "S" (v)
+                    : "ecx", "memory"
+                    );
+       return r;
+}
+
+#undef ATOMIC64_ALTERNATIVE
+#undef ATOMIC64_ALTERNATIVE_
 
 #endif /* _ASM_X86_ATOMIC64_32_H */
index 51c5b40..49fd1ea 100644 (file)
@@ -18,7 +18,7 @@
  */
 static inline long atomic64_read(const atomic64_t *v)
 {
-       return v->counter;
+       return (*(volatile long *)&(v)->counter);
 }
 
 /**
@@ -221,4 +221,27 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
 
 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 
+/*
+ * atomic64_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+static inline long atomic64_dec_if_positive(atomic64_t *v)
+{
+       long c, old, dec;
+       c = atomic64_read(v);
+       for (;;) {
+               dec = c - 1;
+               if (unlikely(dec < 0))
+                       break;
+               old = atomic64_cmpxchg((v), c, dec);
+               if (likely(old == c))
+                       break;
+               c = old;
+       }
+       return dec;
+}
+
 #endif /* _ASM_X86_ATOMIC64_64_H */
index 02b47a6..545776e 100644 (file)
@@ -444,7 +444,9 @@ static inline int fls(int x)
 
 #define ARCH_HAS_FAST_MULTIPLIER 1
 
-#include <asm-generic/bitops/hweight.h>
+#include <asm/arch_hweight.h>
+
+#include <asm-generic/bitops/const_hweight.h>
 
 #endif /* __KERNEL__ */
 
index 7a10659..3b62ab5 100644 (file)
@@ -24,7 +24,7 @@
 #define MIN_KERNEL_ALIGN       (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2)
 
 #if (CONFIG_PHYSICAL_ALIGN & (CONFIG_PHYSICAL_ALIGN-1)) || \
-       (CONFIG_PHYSICAL_ALIGN < (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2))
+       (CONFIG_PHYSICAL_ALIGN < MIN_KERNEL_ALIGN)
 #error "Invalid value for CONFIG_PHYSICAL_ALIGN"
 #endif
 
index 634c40a..c70068d 100644 (file)
@@ -44,9 +44,6 @@ static inline void copy_from_user_page(struct vm_area_struct *vma,
        memcpy(dst, src, len);
 }
 
-#define PG_WC                          PG_arch_1
-PAGEFLAG(WC, WC)
-
 #ifdef CONFIG_X86_PAT
 /*
  * X86 PAT uses page flags WC and Uncached together to keep track of
@@ -55,16 +52,24 @@ PAGEFLAG(WC, WC)
  * _PAGE_CACHE_UC_MINUS and fourth state where page's memory type has not
  * been changed from its default (value of -1 used to denote this).
  * Note we do not support _PAGE_CACHE_UC here.
- *
- * Caller must hold memtype_lock for atomicity.
  */
+
+#define _PGMT_DEFAULT          0
+#define _PGMT_WC               (1UL << PG_arch_1)
+#define _PGMT_UC_MINUS         (1UL << PG_uncached)
+#define _PGMT_WB               (1UL << PG_uncached | 1UL << PG_arch_1)
+#define _PGMT_MASK             (1UL << PG_uncached | 1UL << PG_arch_1)
+#define _PGMT_CLEAR_MASK       (~_PGMT_MASK)
+
 static inline unsigned long get_page_memtype(struct page *pg)
 {
-       if (!PageUncached(pg) && !PageWC(pg))
+       unsigned long pg_flags = pg->flags & _PGMT_MASK;
+
+       if (pg_flags == _PGMT_DEFAULT)
                return -1;
-       else if (!PageUncached(pg) && PageWC(pg))
+       else if (pg_flags == _PGMT_WC)
                return _PAGE_CACHE_WC;
-       else if (PageUncached(pg) && !PageWC(pg))
+       else if (pg_flags == _PGMT_UC_MINUS)
                return _PAGE_CACHE_UC_MINUS;
        else
                return _PAGE_CACHE_WB;
@@ -72,25 +77,26 @@ static inline unsigned long get_page_memtype(struct page *pg)
 
 static inline void set_page_memtype(struct page *pg, unsigned long memtype)
 {
+       unsigned long memtype_flags = _PGMT_DEFAULT;
+       unsigned long old_flags;
+       unsigned long new_flags;
+
        switch (memtype) {
        case _PAGE_CACHE_WC:
-               ClearPageUncached(pg);
-               SetPageWC(pg);
+               memtype_flags = _PGMT_WC;
                break;
        case _PAGE_CACHE_UC_MINUS:
-               SetPageUncached(pg);
-               ClearPageWC(pg);
+               memtype_flags = _PGMT_UC_MINUS;
                break;
        case _PAGE_CACHE_WB:
-               SetPageUncached(pg);
-               SetPageWC(pg);
-               break;
-       default:
-       case -1:
-               ClearPageUncached(pg);
-               ClearPageWC(pg);
+               memtype_flags = _PGMT_WB;
                break;
        }
+
+       do {
+               old_flags = pg->flags;
+               new_flags = (old_flags & _PGMT_CLEAR_MASK) | memtype_flags;
+       } while (cmpxchg(&pg->flags, old_flags, new_flags) != old_flags);
 }
 #else
 static inline unsigned long get_page_memtype(struct page *pg) { return -1; }
index ffb9bb6..8859e12 100644 (file)
@@ -271,7 +271,8 @@ extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
        __typeof__(*(ptr)) __ret;                               \
        __typeof__(*(ptr)) __old = (o);                         \
        __typeof__(*(ptr)) __new = (n);                         \
-       alternative_io("call cmpxchg8b_emu",                    \
+       alternative_io(LOCK_PREFIX_HERE                         \
+                       "call cmpxchg8b_emu",                   \
                        "lock; cmpxchg8b (%%esi)" ,             \
                       X86_FEATURE_CX8,                         \
                       "=A" (__ret),                            \
index 0cd82d0..dca9c54 100644 (file)
  */
 #define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
 #define X86_FEATURE_ARAT       (7*32+ 1) /* Always Running APIC Timer */
+#define X86_FEATURE_CPB                (7*32+ 2) /* AMD Core Performance Boost */
 
 /* Virtualization flags: Linux defined */
 #define X86_FEATURE_TPR_SHADOW  (8*32+ 0) /* Intel TPR Shadow */
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
+#include <asm/asm.h>
 #include <linux/bitops.h>
 
 extern const char * const x86_cap_flags[NCAPINTS*32];
@@ -283,6 +285,62 @@ extern const char * const x86_power_flags[32];
 
 #endif /* CONFIG_X86_64 */
 
+/*
+ * Static testing of CPU features.  Used the same as boot_cpu_has().
+ * These are only valid after alternatives have run, but will statically
+ * patch the target code for additional performance.
+ *
+ */
+static __always_inline __pure bool __static_cpu_has(u8 bit)
+{
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+               asm goto("1: jmp %l[t_no]\n"
+                        "2:\n"
+                        ".section .altinstructions,\"a\"\n"
+                        _ASM_ALIGN "\n"
+                        _ASM_PTR "1b\n"
+                        _ASM_PTR "0\n"         /* no replacement */
+                        " .byte %P0\n"         /* feature bit */
+                        " .byte 2b - 1b\n"     /* source len */
+                        " .byte 0\n"           /* replacement len */
+                        " .byte 0xff + 0 - (2b-1b)\n"  /* padding */
+                        ".previous\n"
+                        : : "i" (bit) : : t_no);
+               return true;
+       t_no:
+               return false;
+#else
+               u8 flag;
+               /* Open-coded due to __stringify() in ALTERNATIVE() */
+               asm volatile("1: movb $0,%0\n"
+                            "2:\n"
+                            ".section .altinstructions,\"a\"\n"
+                            _ASM_ALIGN "\n"
+                            _ASM_PTR "1b\n"
+                            _ASM_PTR "3f\n"
+                            " .byte %P1\n"             /* feature bit */
+                            " .byte 2b - 1b\n"         /* source len */
+                            " .byte 4f - 3f\n"         /* replacement len */
+                            " .byte 0xff + (4f-3f) - (2b-1b)\n" /* padding */
+                            ".previous\n"
+                            ".section .altinstr_replacement,\"ax\"\n"
+                            "3: movb $1,%0\n"
+                            "4:\n"
+                            ".previous\n"
+                            : "=qm" (flag) : "i" (bit));
+               return flag;
+#endif
+}
+
+#define static_cpu_has(bit)                                    \
+(                                                              \
+       __builtin_constant_p(boot_cpu_has(bit)) ?               \
+               boot_cpu_has(bit) :                             \
+       (__builtin_constant_p(bit) && !((bit) & ~0xff)) ?       \
+               __static_cpu_has(bit) :                         \
+               boot_cpu_has(bit)                               \
+)
+
 #endif /* defined(__KERNEL__) && !defined(__ASSEMBLY__) */
 
 #endif /* _ASM_X86_CPUFEATURE_H */
diff --git a/arch/x86/include/asm/ds.h b/arch/x86/include/asm/ds.h
deleted file mode 100644 (file)
index 70dac19..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Debug Store (DS) support
- *
- * This provides a low-level interface to the hardware's Debug Store
- * feature that is used for branch trace store (BTS) and
- * precise-event based sampling (PEBS).
- *
- * It manages:
- * - DS and BTS hardware configuration
- * - buffer overflow handling (to be done)
- * - buffer access
- *
- * It does not do:
- * - security checking (is the caller allowed to trace the task)
- * - buffer allocation (memory accounting)
- *
- *
- * Copyright (C) 2007-2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
- */
-
-#ifndef _ASM_X86_DS_H
-#define _ASM_X86_DS_H
-
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/err.h>
-
-
-#ifdef CONFIG_X86_DS
-
-struct task_struct;
-struct ds_context;
-struct ds_tracer;
-struct bts_tracer;
-struct pebs_tracer;
-
-typedef void (*bts_ovfl_callback_t)(struct bts_tracer *);
-typedef void (*pebs_ovfl_callback_t)(struct pebs_tracer *);
-
-
-/*
- * A list of features plus corresponding macros to talk about them in
- * the ds_request function's flags parameter.
- *
- * We use the enum to index an array of corresponding control bits;
- * we use the macro to index a flags bit-vector.
- */
-enum ds_feature {
-       dsf_bts = 0,
-       dsf_bts_kernel,
-#define BTS_KERNEL (1 << dsf_bts_kernel)
-       /* trace kernel-mode branches */
-
-       dsf_bts_user,
-#define BTS_USER (1 << dsf_bts_user)
-       /* trace user-mode branches */
-
-       dsf_bts_overflow,
-       dsf_bts_max,
-       dsf_pebs = dsf_bts_max,
-
-       dsf_pebs_max,
-       dsf_ctl_max = dsf_pebs_max,
-       dsf_bts_timestamps = dsf_ctl_max,
-#define BTS_TIMESTAMPS (1 << dsf_bts_timestamps)
-       /* add timestamps into BTS trace */
-
-#define BTS_USER_FLAGS (BTS_KERNEL | BTS_USER | BTS_TIMESTAMPS)
-};
-
-
-/*
- * Request BTS or PEBS
- *
- * Due to alignement constraints, the actual buffer may be slightly
- * smaller than the requested or provided buffer.
- *
- * Returns a pointer to a tracer structure on success, or
- * ERR_PTR(errcode) on failure.
- *
- * The interrupt threshold is independent from the overflow callback
- * to allow users to use their own overflow interrupt handling mechanism.
- *
- * The function might sleep.
- *
- * task: the task to request recording for
- * cpu:  the cpu to request recording for
- * base: the base pointer for the (non-pageable) buffer;
- * size: the size of the provided buffer in bytes
- * ovfl: pointer to a function to be called on buffer overflow;
- *       NULL if cyclic buffer requested
- * th: the interrupt threshold in records from the end of the buffer;
- *     -1 if no interrupt threshold is requested.
- * flags: a bit-mask of the above flags
- */
-extern struct bts_tracer *ds_request_bts_task(struct task_struct *task,
-                                             void *base, size_t size,
-                                             bts_ovfl_callback_t ovfl,
-                                             size_t th, unsigned int flags);
-extern struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
-                                            bts_ovfl_callback_t ovfl,
-                                            size_t th, unsigned int flags);
-extern struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
-                                               void *base, size_t size,
-                                               pebs_ovfl_callback_t ovfl,
-                                               size_t th, unsigned int flags);
-extern struct pebs_tracer *ds_request_pebs_cpu(int cpu,
-                                              void *base, size_t size,
-                                              pebs_ovfl_callback_t ovfl,
-                                              size_t th, unsigned int flags);
-
-/*
- * Release BTS or PEBS resources
- * Suspend and resume BTS or PEBS tracing
- *
- * Must be called with irq's enabled.
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern void ds_release_bts(struct bts_tracer *tracer);
-extern void ds_suspend_bts(struct bts_tracer *tracer);
-extern void ds_resume_bts(struct bts_tracer *tracer);
-extern void ds_release_pebs(struct pebs_tracer *tracer);
-extern void ds_suspend_pebs(struct pebs_tracer *tracer);
-extern void ds_resume_pebs(struct pebs_tracer *tracer);
-
-/*
- * Release BTS or PEBS resources
- * Suspend and resume BTS or PEBS tracing
- *
- * Cpu tracers must call this on the traced cpu.
- * Task tracers must call ds_release_~_noirq() for themselves.
- *
- * May be called with irq's disabled.
- *
- * Returns 0 if successful;
- * -EPERM if the cpu tracer does not trace the current cpu.
- * -EPERM if the task tracer does not trace itself.
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern int ds_release_bts_noirq(struct bts_tracer *tracer);
-extern int ds_suspend_bts_noirq(struct bts_tracer *tracer);
-extern int ds_resume_bts_noirq(struct bts_tracer *tracer);
-extern int ds_release_pebs_noirq(struct pebs_tracer *tracer);
-extern int ds_suspend_pebs_noirq(struct pebs_tracer *tracer);
-extern int ds_resume_pebs_noirq(struct pebs_tracer *tracer);
-
-
-/*
- * The raw DS buffer state as it is used for BTS and PEBS recording.
- *
- * This is the low-level, arch-dependent interface for working
- * directly on the raw trace data.
- */
-struct ds_trace {
-       /* the number of bts/pebs records */
-       size_t n;
-       /* the size of a bts/pebs record in bytes */
-       size_t size;
-       /* pointers into the raw buffer:
-          - to the first entry */
-       void *begin;
-       /* - one beyond the last entry */
-       void *end;
-       /* - one beyond the newest entry */
-       void *top;
-       /* - the interrupt threshold */
-       void *ith;
-       /* flags given on ds_request() */
-       unsigned int flags;
-};
-
-/*
- * An arch-independent view on branch trace data.
- */
-enum bts_qualifier {
-       bts_invalid,
-#define BTS_INVALID bts_invalid
-
-       bts_branch,
-#define BTS_BRANCH bts_branch
-
-       bts_task_arrives,
-#define BTS_TASK_ARRIVES bts_task_arrives
-
-       bts_task_departs,
-#define BTS_TASK_DEPARTS bts_task_departs
-
-       bts_qual_bit_size = 4,
-       bts_qual_max = (1 << bts_qual_bit_size),
-};
-
-struct bts_struct {
-       __u64 qualifier;
-       union {
-               /* BTS_BRANCH */
-               struct {
-                       __u64 from;
-                       __u64 to;
-               } lbr;
-               /* BTS_TASK_ARRIVES or BTS_TASK_DEPARTS */
-               struct {
-                       __u64 clock;
-                       pid_t pid;
-               } event;
-       } variant;
-};
-
-
-/*
- * The BTS state.
- *
- * This gives access to the raw DS state and adds functions to provide
- * an arch-independent view of the BTS data.
- */
-struct bts_trace {
-       struct ds_trace ds;
-
-       int (*read)(struct bts_tracer *tracer, const void *at,
-                   struct bts_struct *out);
-       int (*write)(struct bts_tracer *tracer, const struct bts_struct *in);
-};
-
-
-/*
- * The PEBS state.
- *
- * This gives access to the raw DS state and the PEBS-specific counter
- * reset value.
- */
-struct pebs_trace {
-       struct ds_trace ds;
-
-       /* the number of valid counters in the below array */
-       unsigned int counters;
-
-#define MAX_PEBS_COUNTERS 4
-       /* the counter reset value */
-       unsigned long long counter_reset[MAX_PEBS_COUNTERS];
-};
-
-
-/*
- * Read the BTS or PEBS trace.
- *
- * Returns a view on the trace collected for the parameter tracer.
- *
- * The view remains valid as long as the traced task is not running or
- * the tracer is suspended.
- * Writes into the trace buffer are not reflected.
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern const struct bts_trace *ds_read_bts(struct bts_tracer *tracer);
-extern const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer);
-
-
-/*
- * Reset the write pointer of the BTS/PEBS buffer.
- *
- * Returns 0 on success; -Eerrno on error
- *
- * tracer: the tracer handle returned from ds_request_~()
- */
-extern int ds_reset_bts(struct bts_tracer *tracer);
-extern int ds_reset_pebs(struct pebs_tracer *tracer);
-
-/*
- * Set the PEBS counter reset value.
- *
- * Returns 0 on success; -Eerrno on error
- *
- * tracer: the tracer handle returned from ds_request_pebs()
- * counter: the index of the counter
- * value: the new counter reset value
- */
-extern int ds_set_pebs_reset(struct pebs_tracer *tracer,
-                            unsigned int counter, u64 value);
-
-/*
- * Initialization
- */
-struct cpuinfo_x86;
-extern void __cpuinit ds_init_intel(struct cpuinfo_x86 *);
-
-/*
- * Context switch work
- */
-extern void ds_switch_to(struct task_struct *prev, struct task_struct *next);
-
-#else /* CONFIG_X86_DS */
-
-struct cpuinfo_x86;
-static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
-static inline void ds_switch_to(struct task_struct *prev,
-                               struct task_struct *next) {}
-
-#endif /* CONFIG_X86_DS */
-#endif /* _ASM_X86_DS_H */
index ae6253a..733f7e9 100644 (file)
 #define CFI_SIGNAL_FRAME
 #endif
 
+#if defined(CONFIG_AS_CFI_SECTIONS) && defined(__ASSEMBLY__)
+       /*
+        * Emit CFI data in .debug_frame sections, not .eh_frame sections.
+        * The latter we currently just discard since we don't do DWARF
+        * unwinding at runtime.  So only the offline DWARF information is
+        * useful to anyone.  Note we should not use this directive if this
+        * file is used in the vDSO assembly, or if vmlinux.lds.S gets
+        * changed so it doesn't discard .eh_frame.
+        */
+       .cfi_sections .debug_frame
+#endif
+
 #else
 
 /*
index 0e22296..ec8a52d 100644 (file)
 #define E820_NVS       4
 #define E820_UNUSABLE  5
 
-/* reserved RAM used by kernel itself */
+/*
+ * reserved RAM used by kernel itself
+ * if CONFIG_INTEL_TXT is enabled, memory of this type will be
+ * included in the S3 integrity calculation and so should not include
+ * any memory that BIOS might alter over the S3 transition
+ */
 #define E820_RESERVED_KERN        128
 
 #ifndef __ASSEMBLY__
index 0f85764..aeab29a 100644 (file)
@@ -35,7 +35,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 
 #define __ARCH_IRQ_STAT
 
-#define inc_irq_stat(member)   percpu_add(irq_stat.member, 1)
+#define inc_irq_stat(member)   percpu_inc(irq_stat.member)
 
 #define local_softirq_pending()        percpu_read(irq_stat.__softirq_pending)
 
index 1d5c08a..004e6e2 100644 (file)
@@ -68,6 +68,7 @@ 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 2a1bd8f..9422553 100644 (file)
@@ -41,12 +41,16 @@ struct arch_hw_breakpoint {
 /* Total number of available HW breakpoint registers */
 #define HBP_NUM 4
 
+static inline int hw_breakpoint_slots(int type)
+{
+       return HBP_NUM;
+}
+
 struct perf_event;
 struct pmu;
 
-extern int arch_check_va_in_userspace(unsigned long va, u8 hbp_len);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                        struct task_struct *tsk);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
index e153a2b..5df477a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _ASM_X86_KVM_HYPERV_H
-#define _ASM_X86_KVM_HYPERV_H
+#ifndef _ASM_X86_HYPERV_H
+#define _ASM_X86_HYPERV_H
 
 #include <linux/types.h>
 
 #define HYPERV_CPUID_ENLIGHTMENT_INFO          0x40000004
 #define HYPERV_CPUID_IMPLEMENT_LIMITS          0x40000005
 
+#define HYPERV_HYPERVISOR_PRESENT_BIT          0x80000000
+#define HYPERV_CPUID_MIN                       0x40000005
+#define HYPERV_CPUID_MAX                       0x4000ffff
+
 /*
  * Feature identification. EAX indicates which features are available
  * to the partition based upon the current partition privileges.
 /* MSR used to provide vcpu index */
 #define HV_X64_MSR_VP_INDEX                    0x40000002
 
+/* MSR used to read the per-partition time reference counter */
+#define HV_X64_MSR_TIME_REF_COUNT              0x40000020
+
 /* Define the virtual APIC registers */
 #define HV_X64_MSR_EOI                         0x40000070
 #define HV_X64_MSR_ICR                         0x40000071
index b78c094..70abda7 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
-#ifndef ASM_X86__HYPERVISOR_H
-#define ASM_X86__HYPERVISOR_H
+#ifndef _ASM_X86_HYPERVISOR_H
+#define _ASM_X86_HYPERVISOR_H
 
 extern void init_hypervisor(struct cpuinfo_x86 *c);
 extern void init_hypervisor_platform(void);
 
+/*
+ * x86 hypervisor information
+ */
+struct hypervisor_x86 {
+       /* Hypervisor name */
+       const char      *name;
+
+       /* Detection routine */
+       bool            (*detect)(void);
+
+       /* Adjust CPU feature bits (run once per CPU) */
+       void            (*set_cpu_features)(struct cpuinfo_x86 *);
+
+       /* Platform setup (run once per boot) */
+       void            (*init_platform)(void);
+};
+
+extern const struct hypervisor_x86 *x86_hyper;
+
+/* Recognized hypervisors */
+extern const struct hypervisor_x86 x86_hyper_vmware;
+extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
+
 #endif
index da29309..c991b3a 100644 (file)
@@ -16,7 +16,9 @@
 #include <linux/kernel_stat.h>
 #include <linux/regset.h>
 #include <linux/hardirq.h>
+#include <linux/slab.h>
 #include <asm/asm.h>
+#include <asm/cpufeature.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
 #include <asm/user.h>
@@ -56,6 +58,11 @@ extern int restore_i387_xstate_ia32(void __user *buf);
 
 #define X87_FSW_ES (1 << 7)    /* Exception Summary */
 
+static __always_inline __pure bool use_xsave(void)
+{
+       return static_cpu_has(X86_FEATURE_XSAVE);
+}
+
 #ifdef CONFIG_X86_64
 
 /* Ignore delayed exceptions from user space */
@@ -91,15 +98,15 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
    values. The kernel data segment can be sometimes 0 and sometimes
    new user value. Both should be ok.
    Use the PDA as safe address because it should be already in L1. */
-static inline void clear_fpu_state(struct task_struct *tsk)
+static inline void fpu_clear(struct fpu *fpu)
 {
-       struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
-       struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+       struct xsave_struct *xstate = &fpu->state->xsave;
+       struct i387_fxsave_struct *fx = &fpu->state->fxsave;
 
        /*
         * xsave header may indicate the init state of the FP.
         */
-       if ((task_thread_info(tsk)->status & TS_XSAVE) &&
+       if (use_xsave() &&
            !(xstate->xsave_hdr.xstate_bv & XSTATE_FP))
                return;
 
@@ -111,6 +118,11 @@ static inline void clear_fpu_state(struct task_struct *tsk)
                          X86_FEATURE_FXSAVE_LEAK);
 }
 
+static inline void clear_fpu_state(struct task_struct *tsk)
+{
+       fpu_clear(&tsk->thread.fpu);
+}
+
 static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
 {
        int err;
@@ -135,7 +147,7 @@ static inline int fxsave_user(struct i387_fxsave_struct __user *fx)
        return err;
 }
 
-static inline void fxsave(struct task_struct *tsk)
+static inline void fpu_fxsave(struct fpu *fpu)
 {
        /* Using "rex64; fxsave %0" is broken because, if the memory operand
           uses any extended registers for addressing, a second REX prefix
@@ -145,42 +157,45 @@ static inline void fxsave(struct task_struct *tsk)
        /* Using "fxsaveq %0" would be the ideal choice, but is only supported
           starting with gas 2.16. */
        __asm__ __volatile__("fxsaveq %0"
-                            : "=m" (tsk->thread.xstate->fxsave));
+                            : "=m" (fpu->state->fxsave));
 #elif 0
        /* Using, as a workaround, the properly prefixed form below isn't
           accepted by any binutils version so far released, complaining that
           the same type of prefix is used twice if an extended register is
           needed for addressing (fix submitted to mainline 2005-11-21). */
        __asm__ __volatile__("rex64/fxsave %0"
-                            : "=m" (tsk->thread.xstate->fxsave));
+                            : "=m" (fpu->state->fxsave));
 #else
        /* This, however, we can work around by forcing the compiler to select
           an addressing mode that doesn't require extended registers. */
        __asm__ __volatile__("rex64/fxsave (%1)"
-                            : "=m" (tsk->thread.xstate->fxsave)
-                            : "cdaSDb" (&tsk->thread.xstate->fxsave));
+                            : "=m" (fpu->state->fxsave)
+                            : "cdaSDb" (&fpu->state->fxsave));
 #endif
 }
 
-static inline void __save_init_fpu(struct task_struct *tsk)
+static inline void fpu_save_init(struct fpu *fpu)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE)
-               xsave(tsk);
+       if (use_xsave())
+               fpu_xsave(fpu);
        else
-               fxsave(tsk);
+               fpu_fxsave(fpu);
+
+       fpu_clear(fpu);
+}
 
-       clear_fpu_state(tsk);
+static inline void __save_init_fpu(struct task_struct *tsk)
+{
+       fpu_save_init(&tsk->thread.fpu);
        task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
 #else  /* CONFIG_X86_32 */
 
 #ifdef CONFIG_MATH_EMULATION
-extern void finit_task(struct task_struct *tsk);
+extern void finit_soft_fpu(struct i387_soft_struct *soft);
 #else
-static inline void finit_task(struct task_struct *tsk)
-{
-}
+static inline void finit_soft_fpu(struct i387_soft_struct *soft) {}
 #endif
 
 static inline void tolerant_fwait(void)
@@ -216,13 +231,13 @@ static inline int fxrstor_checking(struct i387_fxsave_struct *fx)
 /*
  * These must be called with preempt disabled
  */
-static inline void __save_init_fpu(struct task_struct *tsk)
+static inline void fpu_save_init(struct fpu *fpu)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE) {
-               struct xsave_struct *xstate = &tsk->thread.xstate->xsave;
-               struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+       if (use_xsave()) {
+               struct xsave_struct *xstate = &fpu->state->xsave;
+               struct i387_fxsave_struct *fx = &fpu->state->fxsave;
 
-               xsave(tsk);
+               fpu_xsave(fpu);
 
                /*
                 * xsave header may indicate the init state of the FP.
@@ -246,8 +261,8 @@ static inline void __save_init_fpu(struct task_struct *tsk)
                "fxsave %[fx]\n"
                "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
                X86_FEATURE_FXSR,
-               [fx] "m" (tsk->thread.xstate->fxsave),
-               [fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory");
+               [fx] "m" (fpu->state->fxsave),
+               [fsw] "m" (fpu->state->fxsave.swd) : "memory");
 clear_state:
        /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
           is pending.  Clear the x87 state here by setting it to fixed
@@ -259,17 +274,34 @@ clear_state:
                X86_FEATURE_FXSAVE_LEAK,
                [addr] "m" (safe_address));
 end:
+       ;
+}
+
+static inline void __save_init_fpu(struct task_struct *tsk)
+{
+       fpu_save_init(&tsk->thread.fpu);
        task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
+
 #endif /* CONFIG_X86_64 */
 
-static inline int restore_fpu_checking(struct task_struct *tsk)
+static inline int fpu_fxrstor_checking(struct fpu *fpu)
 {
-       if (task_thread_info(tsk)->status & TS_XSAVE)
-               return xrstor_checking(&tsk->thread.xstate->xsave);
+       return fxrstor_checking(&fpu->state->fxsave);
+}
+
+static inline int fpu_restore_checking(struct fpu *fpu)
+{
+       if (use_xsave())
+               return fpu_xrstor_checking(fpu);
        else
-               return fxrstor_checking(&tsk->thread.xstate->fxsave);
+               return fpu_fxrstor_checking(fpu);
+}
+
+static inline int restore_fpu_checking(struct task_struct *tsk)
+{
+       return fpu_restore_checking(&tsk->thread.fpu);
 }
 
 /*
@@ -397,30 +429,59 @@ static inline void clear_fpu(struct task_struct *tsk)
 static inline unsigned short get_fpu_cwd(struct task_struct *tsk)
 {
        if (cpu_has_fxsr) {
-               return tsk->thread.xstate->fxsave.cwd;
+               return tsk->thread.fpu.state->fxsave.cwd;
        } else {
-               return (unsigned short)tsk->thread.xstate->fsave.cwd;
+               return (unsigned short)tsk->thread.fpu.state->fsave.cwd;
        }
 }
 
 static inline unsigned short get_fpu_swd(struct task_struct *tsk)
 {
        if (cpu_has_fxsr) {
-               return tsk->thread.xstate->fxsave.swd;
+               return tsk->thread.fpu.state->fxsave.swd;
        } else {
-               return (unsigned short)tsk->thread.xstate->fsave.swd;
+               return (unsigned short)tsk->thread.fpu.state->fsave.swd;
        }
 }
 
 static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
 {
        if (cpu_has_xmm) {
-               return tsk->thread.xstate->fxsave.mxcsr;
+               return tsk->thread.fpu.state->fxsave.mxcsr;
        } else {
                return MXCSR_DEFAULT;
        }
 }
 
+static bool fpu_allocated(struct fpu *fpu)
+{
+       return fpu->state != NULL;
+}
+
+static inline int fpu_alloc(struct fpu *fpu)
+{
+       if (fpu_allocated(fpu))
+               return 0;
+       fpu->state = kmem_cache_alloc(task_xstate_cachep, GFP_KERNEL);
+       if (!fpu->state)
+               return -ENOMEM;
+       WARN_ON((unsigned long)fpu->state & 15);
+       return 0;
+}
+
+static inline void fpu_free(struct fpu *fpu)
+{
+       if (fpu->state) {
+               kmem_cache_free(task_xstate_cachep, fpu->state);
+               fpu->state = NULL;
+       }
+}
+
+static inline void fpu_copy(struct fpu *dst, struct fpu *src)
+{
+       memcpy(dst->state, src->state, xstate_size);
+}
+
 #endif /* __ASSEMBLY__ */
 
 #define PSHUFB_XMM5_XMM0 .byte 0x66, 0x0f, 0x38, 0x00, 0xc5
index 1edbf89..fc1f579 100644 (file)
@@ -6,7 +6,7 @@
 #define PIT_CH0                        0x40
 #define PIT_CH2                        0x42
 
-extern spinlock_t i8253_lock;
+extern raw_spinlock_t i8253_lock;
 
 extern struct clock_event_device *global_clock_event;
 
index 96c2e0a..88c765e 100644 (file)
@@ -68,6 +68,8 @@ struct insn {
        const insn_byte_t *next_byte;
 };
 
+#define MAX_INSN_SIZE  16
+
 #define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
 #define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
 #define X86_MODRM_RM(modrm) ((modrm) & 0x07)
index a1dcfa3..30a3e97 100644 (file)
@@ -347,6 +347,7 @@ extern void __iomem *early_ioremap(resource_size_t phys_addr,
 extern void __iomem *early_memremap(resource_size_t phys_addr,
                                    unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
+extern void fixup_early_ioremap(void);
 
 #define IO_SPACE_LIMIT 0xffff
 
index 35832a0..63cb409 100644 (file)
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
                 struct io_apic_irq_attr *irq_attr);
 void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
 extern void ioapic_insert_resources(void);
 
@@ -180,12 +179,13 @@ extern void ioapic_write_entry(int apic, int pin,
 extern void setup_ioapic_ids_from_mpc(void);
 
 struct mp_ioapic_gsi{
-       int gsi_base;
-       int gsi_end;
+       u32 gsi_base;
+       u32 gsi_end;
 };
 extern struct mp_ioapic_gsi  mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+extern u32 gsi_end;
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void __init pre_init_apic_IRQ0(void);
 
@@ -197,7 +197,8 @@ static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)  { }
 static inline void ioapic_insert_resources(void) { }
 static inline void probe_nr_irqs_gsi(void)     { }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+#define gsi_end (NR_IRQS_LEGACY - 1)
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
 
 struct io_apic_irq_attr;
 static inline int io_apic_set_pci_routing(struct device *dev, int irq,
index f70e600..af00bd1 100644 (file)
@@ -16,11 +16,16 @@ extern int k8_numa_init(unsigned long start_pfn, unsigned long end_pfn);
 extern int k8_scan_nodes(void);
 
 #ifdef CONFIG_K8_NB
+extern int num_k8_northbridges;
+
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
 {
        return (node < num_k8_northbridges) ? k8_northbridges[node] : NULL;
 }
+
 #else
+#define num_k8_northbridges 0
+
 static inline struct pci_dev *node_to_k8_nb_misc(int node)
 {
        return NULL;
index 4ffa345..5478825 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/percpu.h>
+#include <asm/insn.h>
 
 #define  __ARCH_WANT_KPROBES_INSN_SLOT
 
@@ -36,7 +37,6 @@ typedef u8 kprobe_opcode_t;
 #define RELATIVEJUMP_SIZE 5
 #define RELATIVECALL_OPCODE 0xe8
 #define RELATIVE_ADDR_SIZE 4
-#define MAX_INSN_SIZE 16
 #define MAX_STACK_SIZE 64
 #define MIN_STACK_SIZE(ADDR)                                          \
        (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
index ba0eed8..b60f292 100644 (file)
 
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
-#include <asm/kvm_para.h>
 
 /*G:030
  * But first, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.
  *
- * We use the KVM hypercall mechanism, though completely different hypercall
- * numbers. Seventeen hypercalls are available: the hypercall number is put in
- * the %eax register, and the arguments (when required) are placed in %ebx,
- * %ecx, %edx and %esi.  If a return value makes sense, it's returned in %eax.
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %ebx, %ecx, %edx and %esi.
+ * If a return value makes sense, it's returned in %eax.
  *
  * Grossly invalid calls result in Sudden Death at the hands of the vengeful
  * Host, rather than returning failure.  This reflects Winston Churchill's
  * definition of a gentleman: "someone who is only rude intentionally".
-:*/
+ */
+static inline unsigned long
+hcall(unsigned long call,
+      unsigned long arg1, unsigned long arg2, unsigned long arg3,
+      unsigned long arg4)
+{
+       /* "int" is the Intel instruction to trigger a trap. */
+       asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
+                    /* The call in %eax (aka "a") might be overwritten */
+                    : "=a"(call)
+                      /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */
+                    : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4)
+                      /* "memory" means this might write somewhere in memory.
+                       * This isn't true for all calls, but it's safe to tell
+                       * gcc that it might happen so it doesn't get clever. */
+                    : "memory");
+       return call;
+}
 
 /* Can't use our min() macro here: needs to be a constant */
 #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
index d8bf23a..c82868e 100644 (file)
@@ -105,16 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
 struct device;
 extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
                                 int active_high_low);
-extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
-       return 0;
-}
 #endif /* CONFIG_ACPI */
 
 #define PHYSID_ARRAY_SIZE      BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
new file mode 100644 (file)
index 0000000..79ce568
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _ASM_X86_MSHYPER_H
+#define _ASM_X86_MSHYPER_H
+
+#include <linux/types.h>
+#include <asm/hyperv.h>
+
+struct ms_hyperv_info {
+       u32 features;
+       u32 hints;
+};
+
+extern struct ms_hyperv_info ms_hyperv;
+
+#endif
index 4604e6a..bc473ac 100644 (file)
 #define MSR_IA32_LASTINTTOIP           0x000001de
 
 /* DEBUGCTLMSR bits (others vary by model): */
-#define _DEBUGCTLMSR_LBR       0 /* last branch recording */
-#define _DEBUGCTLMSR_BTF       1 /* single-step on branches */
-
-#define DEBUGCTLMSR_LBR                (1UL << _DEBUGCTLMSR_LBR)
-#define DEBUGCTLMSR_BTF                (1UL << _DEBUGCTLMSR_BTF)
+#define DEBUGCTLMSR_LBR                        (1UL <<  0) /* last branch recording */
+#define DEBUGCTLMSR_BTF                        (1UL <<  1) /* single-step on branches */
+#define DEBUGCTLMSR_TR                 (1UL <<  6)
+#define DEBUGCTLMSR_BTS                        (1UL <<  7)
+#define DEBUGCTLMSR_BTINT              (1UL <<  8)
+#define DEBUGCTLMSR_BTS_OFF_OS         (1UL <<  9)
+#define DEBUGCTLMSR_BTS_OFF_USR                (1UL << 10)
+#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
 
 #define MSR_IA32_MC0_CTL               0x00000400
 #define MSR_IA32_MC0_STATUS            0x00000401
 #define MSR_P4_U2L_ESCR0               0x000003b0
 #define MSR_P4_U2L_ESCR1               0x000003b1
 
+#define MSR_P4_PEBS_MATRIX_VERT                0x000003f2
+
 /* Intel Core-based CPU performance counters */
 #define MSR_CORE_PERF_FIXED_CTR0       0x00000309
 #define MSR_CORE_PERF_FIXED_CTR1       0x0000030a
index 66a272d..0ec6d12 100644 (file)
@@ -190,6 +190,29 @@ do {                                                                       \
        pfo_ret__;                                      \
 })
 
+#define percpu_unary_op(op, var)                       \
+({                                                     \
+       switch (sizeof(var)) {                          \
+       case 1:                                         \
+               asm(op "b "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       case 2:                                         \
+               asm(op "w "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       case 4:                                         \
+               asm(op "l "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       case 8:                                         \
+               asm(op "q "__percpu_arg(0)              \
+                   : "+m" (var));                      \
+               break;                                  \
+       default: __bad_percpu_size();                   \
+       }                                               \
+})
+
 /*
  * percpu_read() makes gcc load the percpu variable every time it is
  * accessed while percpu_read_stable() allows the value to be cached.
@@ -207,6 +230,7 @@ do {                                                                        \
 #define percpu_and(var, val)           percpu_to_op("and", var, val)
 #define percpu_or(var, val)            percpu_to_op("or", var, val)
 #define percpu_xor(var, val)           percpu_to_op("xor", var, val)
+#define percpu_inc(var)                percpu_unary_op("inc", var)
 
 #define __this_cpu_read_1(pcp)         percpu_from_op("mov", (pcp), "m"(pcp))
 #define __this_cpu_read_2(pcp)         percpu_from_op("mov", (pcp), "m"(pcp))
index db6109a..254883d 100644 (file)
@@ -5,7 +5,7 @@
  * Performance event hw details:
  */
 
-#define X86_PMC_MAX_GENERIC                                    8
+#define X86_PMC_MAX_GENERIC                                   32
 #define X86_PMC_MAX_FIXED                                      3
 
 #define X86_PMC_IDX_GENERIC                                    0
 #define MSR_ARCH_PERFMON_EVENTSEL0                          0x186
 #define MSR_ARCH_PERFMON_EVENTSEL1                          0x187
 
-#define ARCH_PERFMON_EVENTSEL_ENABLE                     (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_ANY                        (1 << 21)
-#define ARCH_PERFMON_EVENTSEL_INT                        (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS                         (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR                        (1 << 16)
-
-/*
- * Includes eventsel and unit mask as well:
- */
-
-
-#define INTEL_ARCH_EVTSEL_MASK         0x000000FFULL
-#define INTEL_ARCH_UNIT_MASK           0x0000FF00ULL
-#define INTEL_ARCH_EDGE_MASK           0x00040000ULL
-#define INTEL_ARCH_INV_MASK            0x00800000ULL
-#define INTEL_ARCH_CNT_MASK            0xFF000000ULL
-#define INTEL_ARCH_EVENT_MASK  (INTEL_ARCH_UNIT_MASK|INTEL_ARCH_EVTSEL_MASK)
-
-/*
- * filter mask to validate fixed counter events.
- * the following filters disqualify for fixed counters:
- *  - inv
- *  - edge
- *  - cnt-mask
- *  The other filters are supported by fixed counters.
- *  The any-thread option is supported starting with v3.
- */
-#define INTEL_ARCH_FIXED_MASK \
-       (INTEL_ARCH_CNT_MASK| \
-        INTEL_ARCH_INV_MASK| \
-        INTEL_ARCH_EDGE_MASK|\
-        INTEL_ARCH_UNIT_MASK|\
-        INTEL_ARCH_EVENT_MASK)
+#define ARCH_PERFMON_EVENTSEL_EVENT                    0x000000FFULL
+#define ARCH_PERFMON_EVENTSEL_UMASK                    0x0000FF00ULL
+#define ARCH_PERFMON_EVENTSEL_USR                      (1ULL << 16)
+#define ARCH_PERFMON_EVENTSEL_OS                       (1ULL << 17)
+#define ARCH_PERFMON_EVENTSEL_EDGE                     (1ULL << 18)
+#define ARCH_PERFMON_EVENTSEL_INT                      (1ULL << 20)
+#define ARCH_PERFMON_EVENTSEL_ANY                      (1ULL << 21)
+#define ARCH_PERFMON_EVENTSEL_ENABLE                   (1ULL << 22)
+#define ARCH_PERFMON_EVENTSEL_INV                      (1ULL << 23)
+#define ARCH_PERFMON_EVENTSEL_CMASK                    0xFF000000ULL
+
+#define AMD64_EVENTSEL_EVENT   \
+       (ARCH_PERFMON_EVENTSEL_EVENT | (0x0FULL << 32))
+#define INTEL_ARCH_EVENT_MASK  \
+       (ARCH_PERFMON_EVENTSEL_UMASK | ARCH_PERFMON_EVENTSEL_EVENT)
+
+#define X86_RAW_EVENT_MASK             \
+       (ARCH_PERFMON_EVENTSEL_EVENT |  \
+        ARCH_PERFMON_EVENTSEL_UMASK |  \
+        ARCH_PERFMON_EVENTSEL_EDGE  |  \
+        ARCH_PERFMON_EVENTSEL_INV   |  \
+        ARCH_PERFMON_EVENTSEL_CMASK)
+#define AMD64_RAW_EVENT_MASK           \
+       (X86_RAW_EVENT_MASK          |  \
+        AMD64_EVENTSEL_EVENT)
 
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL                0x3c
 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK                (0x00 << 8)
@@ -67,7 +59,7 @@
 union cpuid10_eax {
        struct {
                unsigned int version_id:8;
-               unsigned int num_events:8;
+               unsigned int num_counters:8;
                unsigned int bit_width:8;
                unsigned int mask_length:8;
        } split;
@@ -76,7 +68,7 @@ union cpuid10_eax {
 
 union cpuid10_edx {
        struct {
-               unsigned int num_events_fixed:4;
+               unsigned int num_counters_fixed:4;
                unsigned int reserved:28;
        } split;
        unsigned int full;
@@ -136,6 +128,18 @@ extern void perf_events_lapic_init(void);
 
 #define PERF_EVENT_INDEX_OFFSET                        0
 
+/*
+ * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups.
+ * This flag is otherwise unused and ABI specified to be 0, so nobody should
+ * care what we do with it.
+ */
+#define PERF_EFLAGS_EXACT      (1UL << 3)
+
+struct pt_regs;
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+#define perf_misc_flags(regs)  perf_misc_flags(regs)
+
 #else
 static inline void init_hw_perf_events(void)           { }
 static inline void perf_events_lapic_init(void)        { }
diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h
new file mode 100644 (file)
index 0000000..b05400a
--- /dev/null
@@ -0,0 +1,794 @@
+/*
+ * Netburst Perfomance Events (P4, old Xeon)
+ */
+
+#ifndef PERF_EVENT_P4_H
+#define PERF_EVENT_P4_H
+
+#include <linux/cpu.h>
+#include <linux/bitops.h>
+
+/*
+ * NetBurst has perfomance MSRs shared between
+ * threads if HT is turned on, ie for both logical
+ * processors (mem: in turn in Atom with HT support
+ * perf-MSRs are not shared and every thread has its
+ * own perf-MSRs set)
+ */
+#define ARCH_P4_TOTAL_ESCR     (46)
+#define ARCH_P4_RESERVED_ESCR  (2) /* IQ_ESCR(0,1) not always present */
+#define ARCH_P4_MAX_ESCR       (ARCH_P4_TOTAL_ESCR - ARCH_P4_RESERVED_ESCR)
+#define ARCH_P4_MAX_CCCR       (18)
+#define ARCH_P4_MAX_COUNTER    (ARCH_P4_MAX_CCCR / 2)
+
+#define P4_ESCR_EVENT_MASK     0x7e000000U
+#define P4_ESCR_EVENT_SHIFT    25
+#define P4_ESCR_EVENTMASK_MASK 0x01fffe00U
+#define P4_ESCR_EVENTMASK_SHIFT        9
+#define P4_ESCR_TAG_MASK       0x000001e0U
+#define P4_ESCR_TAG_SHIFT      5
+#define P4_ESCR_TAG_ENABLE     0x00000010U
+#define P4_ESCR_T0_OS          0x00000008U
+#define P4_ESCR_T0_USR         0x00000004U
+#define P4_ESCR_T1_OS          0x00000002U
+#define P4_ESCR_T1_USR         0x00000001U
+
+#define P4_ESCR_EVENT(v)       ((v) << P4_ESCR_EVENT_SHIFT)
+#define P4_ESCR_EMASK(v)       ((v) << P4_ESCR_EVENTMASK_SHIFT)
+#define P4_ESCR_TAG(v)         ((v) << P4_ESCR_TAG_SHIFT)
+
+/* Non HT mask */
+#define P4_ESCR_MASK                   \
+       (P4_ESCR_EVENT_MASK     |       \
+       P4_ESCR_EVENTMASK_MASK  |       \
+       P4_ESCR_TAG_MASK        |       \
+       P4_ESCR_TAG_ENABLE      |       \
+       P4_ESCR_T0_OS           |       \
+       P4_ESCR_T0_USR)
+
+/* HT mask */
+#define P4_ESCR_MASK_HT                        \
+       (P4_ESCR_MASK | P4_ESCR_T1_OS | P4_ESCR_T1_USR)
+
+#define P4_CCCR_OVF                    0x80000000U
+#define P4_CCCR_CASCADE                        0x40000000U
+#define P4_CCCR_OVF_PMI_T0             0x04000000U
+#define P4_CCCR_OVF_PMI_T1             0x08000000U
+#define P4_CCCR_FORCE_OVF              0x02000000U
+#define P4_CCCR_EDGE                   0x01000000U
+#define P4_CCCR_THRESHOLD_MASK         0x00f00000U
+#define P4_CCCR_THRESHOLD_SHIFT                20
+#define P4_CCCR_COMPLEMENT             0x00080000U
+#define P4_CCCR_COMPARE                        0x00040000U
+#define P4_CCCR_ESCR_SELECT_MASK       0x0000e000U
+#define P4_CCCR_ESCR_SELECT_SHIFT      13
+#define P4_CCCR_ENABLE                 0x00001000U
+#define P4_CCCR_THREAD_SINGLE          0x00010000U
+#define P4_CCCR_THREAD_BOTH            0x00020000U
+#define P4_CCCR_THREAD_ANY             0x00030000U
+#define P4_CCCR_RESERVED               0x00000fffU
+
+#define P4_CCCR_THRESHOLD(v)           ((v) << P4_CCCR_THRESHOLD_SHIFT)
+#define P4_CCCR_ESEL(v)                        ((v) << P4_CCCR_ESCR_SELECT_SHIFT)
+
+/* Custom bits in reerved CCCR area */
+#define P4_CCCR_CACHE_OPS_MASK         0x0000003fU
+
+
+/* Non HT mask */
+#define P4_CCCR_MASK                           \
+       (P4_CCCR_OVF                    |       \
+       P4_CCCR_CASCADE                 |       \
+       P4_CCCR_OVF_PMI_T0              |       \
+       P4_CCCR_FORCE_OVF               |       \
+       P4_CCCR_EDGE                    |       \
+       P4_CCCR_THRESHOLD_MASK          |       \
+       P4_CCCR_COMPLEMENT              |       \
+       P4_CCCR_COMPARE                 |       \
+       P4_CCCR_ESCR_SELECT_MASK        |       \
+       P4_CCCR_ENABLE)
+
+/* HT mask */
+#define P4_CCCR_MASK_HT        (P4_CCCR_MASK | P4_CCCR_THREAD_ANY)
+
+#define P4_GEN_ESCR_EMASK(class, name, bit)    \
+       class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT)
+#define P4_ESCR_EMASK_BIT(class, name)         class##__##name
+
+/*
+ * config field is 64bit width and consists of
+ * HT << 63 | ESCR << 32 | CCCR
+ * where HT is HyperThreading bit (since ESCR
+ * has it reserved we may use it for own purpose)
+ *
+ * note that this is NOT the addresses of respective
+ * ESCR and CCCR but rather an only packed value should
+ * be unpacked and written to a proper addresses
+ *
+ * the base idea is to pack as much info as
+ * possible
+ */
+#define p4_config_pack_escr(v)         (((u64)(v)) << 32)
+#define p4_config_pack_cccr(v)         (((u64)(v)) & 0xffffffffULL)
+#define p4_config_unpack_escr(v)       (((u64)(v)) >> 32)
+#define p4_config_unpack_cccr(v)       (((u64)(v)) & 0xffffffffULL)
+
+#define p4_config_unpack_emask(v)                      \
+       ({                                              \
+               u32 t = p4_config_unpack_escr((v));     \
+               t = t &  P4_ESCR_EVENTMASK_MASK;        \
+               t = t >> P4_ESCR_EVENTMASK_SHIFT;       \
+               t;                                      \
+       })
+
+#define p4_config_unpack_event(v)                      \
+       ({                                              \
+               u32 t = p4_config_unpack_escr((v));     \
+               t = t &  P4_ESCR_EVENT_MASK;            \
+               t = t >> P4_ESCR_EVENT_SHIFT;           \
+               t;                                      \
+       })
+
+#define p4_config_unpack_cache_event(v)        (((u64)(v)) & P4_CCCR_CACHE_OPS_MASK)
+
+#define P4_CONFIG_HT_SHIFT             63
+#define P4_CONFIG_HT                   (1ULL << P4_CONFIG_HT_SHIFT)
+
+static inline bool p4_is_event_cascaded(u64 config)
+{
+       u32 cccr = p4_config_unpack_cccr(config);
+       return !!(cccr & P4_CCCR_CASCADE);
+}
+
+static inline int p4_ht_config_thread(u64 config)
+{
+       return !!(config & P4_CONFIG_HT);
+}
+
+static inline u64 p4_set_ht_bit(u64 config)
+{
+       return config | P4_CONFIG_HT;
+}
+
+static inline u64 p4_clear_ht_bit(u64 config)
+{
+       return config & ~P4_CONFIG_HT;
+}
+
+static inline int p4_ht_active(void)
+{
+#ifdef CONFIG_SMP
+       return smp_num_siblings > 1;
+#endif
+       return 0;
+}
+
+static inline int p4_ht_thread(int cpu)
+{
+#ifdef CONFIG_SMP
+       if (smp_num_siblings == 2)
+               return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
+#endif
+       return 0;
+}
+
+static inline int p4_should_swap_ts(u64 config, int cpu)
+{
+       return p4_ht_config_thread(config) ^ p4_ht_thread(cpu);
+}
+
+static inline u32 p4_default_cccr_conf(int cpu)
+{
+       /*
+        * Note that P4_CCCR_THREAD_ANY is "required" on
+        * non-HT machines (on HT machines we count TS events
+        * regardless the state of second logical processor
+        */
+       u32 cccr = P4_CCCR_THREAD_ANY;
+
+       if (!p4_ht_thread(cpu))
+               cccr |= P4_CCCR_OVF_PMI_T0;
+       else
+               cccr |= P4_CCCR_OVF_PMI_T1;
+
+       return cccr;
+}
+
+static inline u32 p4_default_escr_conf(int cpu, int exclude_os, int exclude_usr)
+{
+       u32 escr = 0;
+
+       if (!p4_ht_thread(cpu)) {
+               if (!exclude_os)
+                       escr |= P4_ESCR_T0_OS;
+               if (!exclude_usr)
+                       escr |= P4_ESCR_T0_USR;
+       } else {
+               if (!exclude_os)
+                       escr |= P4_ESCR_T1_OS;
+               if (!exclude_usr)
+                       escr |= P4_ESCR_T1_USR;
+       }
+
+       return escr;
+}
+
+enum P4_EVENTS {
+       P4_EVENT_TC_DELIVER_MODE,
+       P4_EVENT_BPU_FETCH_REQUEST,
+       P4_EVENT_ITLB_REFERENCE,
+       P4_EVENT_MEMORY_CANCEL,
+       P4_EVENT_MEMORY_COMPLETE,
+       P4_EVENT_LOAD_PORT_REPLAY,
+       P4_EVENT_STORE_PORT_REPLAY,
+       P4_EVENT_MOB_LOAD_REPLAY,
+       P4_EVENT_PAGE_WALK_TYPE,
+       P4_EVENT_BSQ_CACHE_REFERENCE,
+       P4_EVENT_IOQ_ALLOCATION,
+       P4_EVENT_IOQ_ACTIVE_ENTRIES,
+       P4_EVENT_FSB_DATA_ACTIVITY,
+       P4_EVENT_BSQ_ALLOCATION,
+       P4_EVENT_BSQ_ACTIVE_ENTRIES,
+       P4_EVENT_SSE_INPUT_ASSIST,
+       P4_EVENT_PACKED_SP_UOP,
+       P4_EVENT_PACKED_DP_UOP,
+       P4_EVENT_SCALAR_SP_UOP,
+       P4_EVENT_SCALAR_DP_UOP,
+       P4_EVENT_64BIT_MMX_UOP,
+       P4_EVENT_128BIT_MMX_UOP,
+       P4_EVENT_X87_FP_UOP,
+       P4_EVENT_TC_MISC,
+       P4_EVENT_GLOBAL_POWER_EVENTS,
+       P4_EVENT_TC_MS_XFER,
+       P4_EVENT_UOP_QUEUE_WRITES,
+       P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE,
+       P4_EVENT_RETIRED_BRANCH_TYPE,
+       P4_EVENT_RESOURCE_STALL,
+       P4_EVENT_WC_BUFFER,
+       P4_EVENT_B2B_CYCLES,
+       P4_EVENT_BNR,
+       P4_EVENT_SNOOP,
+       P4_EVENT_RESPONSE,
+       P4_EVENT_FRONT_END_EVENT,
+       P4_EVENT_EXECUTION_EVENT,
+       P4_EVENT_REPLAY_EVENT,
+       P4_EVENT_INSTR_RETIRED,
+       P4_EVENT_UOPS_RETIRED,
+       P4_EVENT_UOP_TYPE,
+       P4_EVENT_BRANCH_RETIRED,
+       P4_EVENT_MISPRED_BRANCH_RETIRED,
+       P4_EVENT_X87_ASSIST,
+       P4_EVENT_MACHINE_CLEAR,
+       P4_EVENT_INSTR_COMPLETED,
+};
+
+#define P4_OPCODE(event)               event##_OPCODE
+#define P4_OPCODE_ESEL(opcode)         ((opcode & 0x00ff) >> 0)
+#define P4_OPCODE_EVNT(opcode)         ((opcode & 0xff00) >> 8)
+#define P4_OPCODE_PACK(event, sel)     (((event) << 8) | sel)
+
+/*
+ * Comments below the event represent ESCR restriction
+ * for this event and counter index per ESCR
+ *
+ * MSR_P4_IQ_ESCR0 and MSR_P4_IQ_ESCR1 are available only on early
+ * processor builds (family 0FH, models 01H-02H). These MSRs
+ * are not available on later versions, so that we don't use
+ * them completely
+ *
+ * Also note that CCCR1 do not have P4_CCCR_ENABLE bit properly
+ * working so that we should not use this CCCR and respective
+ * counter as result
+ */
+enum P4_EVENT_OPCODES {
+       P4_OPCODE(P4_EVENT_TC_DELIVER_MODE)             = P4_OPCODE_PACK(0x01, 0x01),
+       /*
+        * MSR_P4_TC_ESCR0:     4, 5
+        * MSR_P4_TC_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST)           = P4_OPCODE_PACK(0x03, 0x00),
+       /*
+        * MSR_P4_BPU_ESCR0:    0, 1
+        * MSR_P4_BPU_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_ITLB_REFERENCE)              = P4_OPCODE_PACK(0x18, 0x03),
+       /*
+        * MSR_P4_ITLB_ESCR0:   0, 1
+        * MSR_P4_ITLB_ESCR1:   2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_MEMORY_CANCEL)               = P4_OPCODE_PACK(0x02, 0x05),
+       /*
+        * MSR_P4_DAC_ESCR0:    8, 9
+        * MSR_P4_DAC_ESCR1:    10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_MEMORY_COMPLETE)             = P4_OPCODE_PACK(0x08, 0x02),
+       /*
+        * MSR_P4_SAAT_ESCR0:   8, 9
+        * MSR_P4_SAAT_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY)            = P4_OPCODE_PACK(0x04, 0x02),
+       /*
+        * MSR_P4_SAAT_ESCR0:   8, 9
+        * MSR_P4_SAAT_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY)           = P4_OPCODE_PACK(0x05, 0x02),
+       /*
+        * MSR_P4_SAAT_ESCR0:   8, 9
+        * MSR_P4_SAAT_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY)             = P4_OPCODE_PACK(0x03, 0x02),
+       /*
+        * MSR_P4_MOB_ESCR0:    0, 1
+        * MSR_P4_MOB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE)              = P4_OPCODE_PACK(0x01, 0x04),
+       /*
+        * MSR_P4_PMH_ESCR0:    0, 1
+        * MSR_P4_PMH_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE)         = P4_OPCODE_PACK(0x0c, 0x07),
+       /*
+        * MSR_P4_BSU_ESCR0:    0, 1
+        * MSR_P4_BSU_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_IOQ_ALLOCATION)              = P4_OPCODE_PACK(0x03, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES)          = P4_OPCODE_PACK(0x1a, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY)           = P4_OPCODE_PACK(0x17, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_BSQ_ALLOCATION)              = P4_OPCODE_PACK(0x05, 0x07),
+       /*
+        * MSR_P4_BSU_ESCR0:    0, 1
+        */
+
+       P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES)          = P4_OPCODE_PACK(0x06, 0x07),
+       /*
+        * NOTE: no ESCR name in docs, it's guessed
+        * MSR_P4_BSU_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST)            = P4_OPCODE_PACK(0x34, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_PACKED_SP_UOP)               = P4_OPCODE_PACK(0x08, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_PACKED_DP_UOP)               = P4_OPCODE_PACK(0x0c, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_SCALAR_SP_UOP)               = P4_OPCODE_PACK(0x0a, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_SCALAR_DP_UOP)               = P4_OPCODE_PACK(0x0e, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_64BIT_MMX_UOP)               = P4_OPCODE_PACK(0x02, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_128BIT_MMX_UOP)              = P4_OPCODE_PACK(0x1a, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_X87_FP_UOP)                  = P4_OPCODE_PACK(0x04, 0x01),
+       /*
+        * MSR_P4_FIRM_ESCR0:   8, 9
+        * MSR_P4_FIRM_ESCR1:   10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_TC_MISC)                     = P4_OPCODE_PACK(0x06, 0x01),
+       /*
+        * MSR_P4_TC_ESCR0:     4, 5
+        * MSR_P4_TC_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS)         = P4_OPCODE_PACK(0x13, 0x06),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_TC_MS_XFER)                  = P4_OPCODE_PACK(0x05, 0x00),
+       /*
+        * MSR_P4_MS_ESCR0:     4, 5
+        * MSR_P4_MS_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES)            = P4_OPCODE_PACK(0x09, 0x00),
+       /*
+        * MSR_P4_MS_ESCR0:     4, 5
+        * MSR_P4_MS_ESCR1:     6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE) = P4_OPCODE_PACK(0x05, 0x02),
+       /*
+        * MSR_P4_TBPU_ESCR0:   4, 5
+        * MSR_P4_TBPU_ESCR1:   6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE)         = P4_OPCODE_PACK(0x04, 0x02),
+       /*
+        * MSR_P4_TBPU_ESCR0:   4, 5
+        * MSR_P4_TBPU_ESCR1:   6, 7
+        */
+
+       P4_OPCODE(P4_EVENT_RESOURCE_STALL)              = P4_OPCODE_PACK(0x01, 0x01),
+       /*
+        * MSR_P4_ALF_ESCR0:    12, 13, 16
+        * MSR_P4_ALF_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_WC_BUFFER)                   = P4_OPCODE_PACK(0x05, 0x05),
+       /*
+        * MSR_P4_DAC_ESCR0:    8, 9
+        * MSR_P4_DAC_ESCR1:    10, 11
+        */
+
+       P4_OPCODE(P4_EVENT_B2B_CYCLES)                  = P4_OPCODE_PACK(0x16, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_BNR)                         = P4_OPCODE_PACK(0x08, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_SNOOP)                       = P4_OPCODE_PACK(0x06, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_RESPONSE)                    = P4_OPCODE_PACK(0x04, 0x03),
+       /*
+        * MSR_P4_FSB_ESCR0:    0, 1
+        * MSR_P4_FSB_ESCR1:    2, 3
+        */
+
+       P4_OPCODE(P4_EVENT_FRONT_END_EVENT)             = P4_OPCODE_PACK(0x08, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_EXECUTION_EVENT)             = P4_OPCODE_PACK(0x0c, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_REPLAY_EVENT)                = P4_OPCODE_PACK(0x09, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_INSTR_RETIRED)               = P4_OPCODE_PACK(0x02, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_UOPS_RETIRED)                = P4_OPCODE_PACK(0x01, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_UOP_TYPE)                    = P4_OPCODE_PACK(0x02, 0x02),
+       /*
+        * MSR_P4_RAT_ESCR0:    12, 13, 16
+        * MSR_P4_RAT_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_BRANCH_RETIRED)              = P4_OPCODE_PACK(0x06, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED)      = P4_OPCODE_PACK(0x03, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_X87_ASSIST)                  = P4_OPCODE_PACK(0x03, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_MACHINE_CLEAR)               = P4_OPCODE_PACK(0x02, 0x05),
+       /*
+        * MSR_P4_CRU_ESCR2:    12, 13, 16
+        * MSR_P4_CRU_ESCR3:    14, 15, 17
+        */
+
+       P4_OPCODE(P4_EVENT_INSTR_COMPLETED)             = P4_OPCODE_PACK(0x07, 0x04),
+       /*
+        * MSR_P4_CRU_ESCR0:    12, 13, 16
+        * MSR_P4_CRU_ESCR1:    14, 15, 17
+        */
+};
+
+/*
+ * a caller should use P4_ESCR_EMASK_NAME helper to
+ * pick the EventMask needed, for example
+ *
+ *     P4_ESCR_EMASK_NAME(P4_EVENT_TC_DELIVER_MODE, DD)
+ */
+enum P4_ESCR_EMASKS {
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DD, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DB, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, DI, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BD, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BB, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, BI, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_DELIVER_MODE, ID, 6),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BPU_FETCH_REQUEST, TCMISS, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, MISS, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_ITLB_REFERENCE, HIT_UK, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, ST_RB_FULL, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_CANCEL, 64K_CONF, 3),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, LSC, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MEMORY_COMPLETE, SSC, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_LOAD_PORT_REPLAY, SPLIT_LD, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_STORE_PORT_REPLAY, SPLIT_ST, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STA, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, NO_STD, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, PARTIAL_DATA, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MOB_LOAD_REPLAY, UNALGN_ADDR, 5),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, DTMISS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_PAGE_WALK_TYPE, ITMISS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS, 10),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, DEFAULT, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_READ, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, ALL_WRITE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_UC, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WC, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WT, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WP, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, MEM_WB, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OWN, 13),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, OTHER, 14),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ALLOCATION, PREFETCH, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, DEFAULT, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_READ, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, ALL_WRITE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_UC, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WC, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WT, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WP, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, MEM_WB, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OWN, 13),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, OTHER, 14),
+       P4_GEN_ESCR_EMASK(P4_EVENT_IOQ_ACTIVE_ENTRIES, PREFETCH, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OTHER, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_DRV, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OWN, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FSB_DATA_ACTIVITY, DBSY_OTHER, 5),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE0, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_TYPE1, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN0, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LEN1, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_IO_TYPE, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_LOCK_TYPE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_CACHE_TYPE, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_SPLIT_TYPE, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_DEM_TYPE, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, REQ_ORD_TYPE, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE0, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE1, 12),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ALLOCATION, MEM_TYPE2, 13),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE0, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_TYPE1, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN0, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LEN1, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_IO_TYPE, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_LOCK_TYPE, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_CACHE_TYPE, 7),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_SPLIT_TYPE, 8),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_DEM_TYPE, 9),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, REQ_ORD_TYPE, 10),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE0, 11),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE1, 12),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BSQ_ACTIVE_ENTRIES, MEM_TYPE2, 13),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_SSE_INPUT_ASSIST, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_SP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_PACKED_DP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_SP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_SCALAR_DP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_64BIT_MMX_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_128BIT_MMX_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_FP_UOP, ALL, 15),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_MISC, FLUSH, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_TC_MS_XFER, CISC, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_BUILD, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_TC_DELIVER, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_QUEUE_WRITES, FROM_ROM, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CONDITIONAL, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, CALL, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, RETURN, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE, INDIRECT, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, CALL, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_RESOURCE_STALL, SBFULL, 5),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_EVICTS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_WC_BUFFER, WCB_FULL_EVICTS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_FRONT_END_EVENT, BOGUS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS0, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS1, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS2, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, NBOGUS3, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS0, 4),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS1, 5),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS2, 6),
+       P4_GEN_ESCR_EMASK(P4_EVENT_EXECUTION_EVENT, BOGUS3, 7),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_REPLAY_EVENT, BOGUS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, NBOGUSTAG, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSNTAG, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_RETIRED, BOGUSTAG, 3),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOPS_RETIRED, BOGUS, 1),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGLOADS, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_UOP_TYPE, TAGSTORES, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNP, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMNM, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTP, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_BRANCH_RETIRED, MMTM, 3),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS, 0),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSU, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, FPSO, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAO, 2),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, POAU, 3),
+       P4_GEN_ESCR_EMASK(P4_EVENT_X87_ASSIST, PREA, 4),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, CLEAR, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, MOCLEAR, 1),
+       P4_GEN_ESCR_EMASK(P4_EVENT_MACHINE_CLEAR, SMCLEAR, 2),
+
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, NBOGUS, 0),
+       P4_GEN_ESCR_EMASK(P4_EVENT_INSTR_COMPLETED, BOGUS, 1),
+};
+
+/* P4 PEBS: stale for a while */
+#define P4_PEBS_METRIC_MASK    0x00001fffU
+#define P4_PEBS_UOB_TAG                0x01000000U
+#define P4_PEBS_ENABLE         0x02000000U
+
+/* Replay metrics for MSR_IA32_PEBS_ENABLE and MSR_P4_PEBS_MATRIX_VERT */
+#define P4_PEBS__1stl_cache_load_miss_retired  0x3000001
+#define P4_PEBS__2ndl_cache_load_miss_retired  0x3000002
+#define P4_PEBS__dtlb_load_miss_retired                0x3000004
+#define P4_PEBS__dtlb_store_miss_retired       0x3000004
+#define P4_PEBS__dtlb_all_miss_retired         0x3000004
+#define P4_PEBS__tagged_mispred_branch         0x3018000
+#define P4_PEBS__mob_load_replay_retired       0x3000200
+#define P4_PEBS__split_load_retired            0x3000400
+#define P4_PEBS__split_store_retired           0x3000400
+
+#define P4_VERT__1stl_cache_load_miss_retired  0x0000001
+#define P4_VERT__2ndl_cache_load_miss_retired  0x0000001
+#define P4_VERT__dtlb_load_miss_retired                0x0000001
+#define P4_VERT__dtlb_store_miss_retired       0x0000002
+#define P4_VERT__dtlb_all_miss_retired         0x0000003
+#define P4_VERT__tagged_mispred_branch         0x0000010
+#define P4_VERT__mob_load_replay_retired       0x0000001
+#define P4_VERT__split_load_retired            0x0000001
+#define P4_VERT__split_store_retired           0x0000002
+
+enum P4_CACHE_EVENTS {
+       P4_CACHE__NONE,
+
+       P4_CACHE__1stl_cache_load_miss_retired,
+       P4_CACHE__2ndl_cache_load_miss_retired,
+       P4_CACHE__dtlb_load_miss_retired,
+       P4_CACHE__dtlb_store_miss_retired,
+       P4_CACHE__itlb_reference_hit,
+       P4_CACHE__itlb_reference_miss,
+
+       P4_CACHE__MAX
+};
+
+#endif /* PERF_EVENT_P4_H */
index b753ea5..5a51379 100644 (file)
@@ -21,7 +21,6 @@ struct mm_struct;
 #include <asm/msr.h>
 #include <asm/desc_defs.h>
 #include <asm/nops.h>
-#include <asm/ds.h>
 
 #include <linux/personality.h>
 #include <linux/cpumask.h>
@@ -29,6 +28,7 @@ struct mm_struct;
 #include <linux/threads.h>
 #include <linux/math64.h>
 #include <linux/init.h>
+#include <linux/err.h>
 
 #define HBP_NUM 4
 /*
@@ -113,7 +113,6 @@ struct cpuinfo_x86 {
        /* Index into per_cpu list: */
        u16                     cpu_index;
 #endif
-       unsigned int            x86_hyper_vendor;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL       0
@@ -127,9 +126,6 @@ struct cpuinfo_x86 {
 
 #define X86_VENDOR_UNKNOWN     0xff
 
-#define X86_HYPER_VENDOR_NONE  0
-#define X86_HYPER_VENDOR_VMWARE 1
-
 /*
  * capabilities of CPUs
  */
@@ -380,6 +376,10 @@ union thread_xstate {
        struct xsave_struct             xsave;
 };
 
+struct fpu {
+       union thread_xstate *state;
+};
+
 #ifdef CONFIG_X86_64
 DECLARE_PER_CPU(struct orig_ist, orig_ist);
 
@@ -457,7 +457,7 @@ struct thread_struct {
        unsigned long           trap_no;
        unsigned long           error_code;
        /* floating point and extended processor state */
-       union thread_xstate     *xstate;
+       struct fpu              fpu;
 #ifdef CONFIG_X86_32
        /* Virtual 86 mode info */
        struct vm86_struct __user *vm86_info;
@@ -473,10 +473,6 @@ struct thread_struct {
        unsigned long           iopl;
        /* Max allowed port in the bitmap, in bytes: */
        unsigned                io_bitmap_max;
-/* MSR_IA32_DEBUGCTLMSR value to switch in if TIF_DEBUGCTLMSR is set.  */
-       unsigned long   debugctlmsr;
-       /* Debug Store context; see asm/ds.h */
-       struct ds_context       *ds_ctx;
 };
 
 static inline unsigned long native_get_debugreg(int regno)
@@ -803,7 +799,7 @@ extern void cpu_init(void);
 
 static inline unsigned long get_debugctlmsr(void)
 {
-    unsigned long debugctlmsr = 0;
+       unsigned long debugctlmsr = 0;
 
 #ifndef CONFIG_X86_DEBUGCTLMSR
        if (boot_cpu_data.x86 < 6)
@@ -811,21 +807,6 @@ static inline unsigned long get_debugctlmsr(void)
 #endif
        rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
 
-    return debugctlmsr;
-}
-
-static inline unsigned long get_debugctlmsr_on_cpu(int cpu)
-{
-       u64 debugctlmsr = 0;
-       u32 val1, val2;
-
-#ifndef CONFIG_X86_DEBUGCTLMSR
-       if (boot_cpu_data.x86 < 6)
-               return 0;
-#endif
-       rdmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR, &val1, &val2);
-       debugctlmsr = val1 | ((u64)val2 << 32);
-
        return debugctlmsr;
 }
 
@@ -838,18 +819,6 @@ static inline void update_debugctlmsr(unsigned long debugctlmsr)
        wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
 }
 
-static inline void update_debugctlmsr_on_cpu(int cpu,
-                                            unsigned long debugctlmsr)
-{
-#ifndef CONFIG_X86_DEBUGCTLMSR
-       if (boot_cpu_data.x86 < 6)
-               return;
-#endif
-       wrmsr_on_cpu(cpu, MSR_IA32_DEBUGCTLMSR,
-                    (u32)((u64)debugctlmsr),
-                    (u32)((u64)debugctlmsr >> 32));
-}
-
 /*
  * from system description table in BIOS. Mostly for MCA use, but
  * others may find it useful:
index 8672303..52b098a 100644 (file)
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
-
-/* configuration/status structure used in PTRACE_BTS_CONFIG and
-   PTRACE_BTS_STATUS commands.
-*/
-struct ptrace_bts_config {
-       /* requested or actual size of BTS buffer in bytes */
-       __u32 size;
-       /* bitmask of below flags */
-       __u32 flags;
-       /* buffer overflow signal */
-       __u32 signal;
-       /* actual size of bts_struct in bytes */
-       __u32 bts_size;
-};
-#endif /* __ASSEMBLY__ */
-
-#define PTRACE_BTS_O_TRACE     0x1 /* branch trace */
-#define PTRACE_BTS_O_SCHED     0x2 /* scheduling events w/ jiffies */
-#define PTRACE_BTS_O_SIGNAL     0x4 /* send SIG<signal> on buffer overflow
-                                      instead of wrapping around */
-#define PTRACE_BTS_O_ALLOC     0x8 /* (re)allocate buffer */
-
-#define PTRACE_BTS_CONFIG      40
-/* Configure branch trace recording.
-   ADDR points to a struct ptrace_bts_config.
-   DATA gives the size of that buffer.
-   A new buffer is allocated, if requested in the flags.
-   An overflow signal may only be requested for new buffers.
-   Returns the number of bytes read.
-*/
-#define PTRACE_BTS_STATUS      41
-/* Return the current configuration in a struct ptrace_bts_config
-   pointed to by ADDR; DATA gives the size of that buffer.
-   Returns the number of bytes written.
-*/
-#define PTRACE_BTS_SIZE                42
-/* Return the number of available BTS records for draining.
-   DATA and ADDR are ignored.
-*/
-#define PTRACE_BTS_GET         43
-/* Get a single BTS record.
-   DATA defines the index into the BTS array, where 0 is the newest
-   entry, and higher indices refer to older entries.
-   ADDR is pointing to struct bts_struct (see asm/ds.h).
-*/
-#define PTRACE_BTS_CLEAR       44
-/* Clear the BTS buffer.
-   DATA and ADDR are ignored.
-*/
-#define PTRACE_BTS_DRAIN       45
-/* Read all available BTS records and clear the buffer.
-   ADDR points to an array of struct bts_struct.
-   DATA gives the size of that buffer.
-   BTS records are read from oldest to newest.
-   Returns number of BTS records drained.
-*/
+#endif
 
 #endif /* _ASM_X86_PTRACE_ABI_H */
index 69a686a..78cd1ea 100644 (file)
@@ -289,12 +289,6 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
 extern int do_set_thread_area(struct task_struct *p, int idx,
                              struct user_desc __user *info, int can_allocate);
 
-#ifdef CONFIG_X86_PTRACE_BTS
-extern void ptrace_bts_untrace(struct task_struct *tsk);
-
-#define arch_ptrace_untrace(tsk)       ptrace_bts_untrace(tsk)
-#endif /* CONFIG_X86_PTRACE_BTS */
-
 #endif /* __KERNEL__ */
 
 #endif /* !__ASSEMBLY__ */
index e0d2890..d4092fa 100644 (file)
@@ -92,8 +92,7 @@ struct thread_info {
 #define TIF_IO_BITMAP          22      /* uses I/O bitmap */
 #define TIF_FREEZE             23      /* is freezing for suspend */
 #define TIF_FORCED_TF          24      /* true if TF in eflags artificially */
-#define TIF_DEBUGCTLMSR                25      /* uses thread_struct.debugctlmsr */
-#define TIF_DS_AREA_MSR                26      /* uses thread_struct.ds_area_msr */
+#define TIF_BLOCKSTEP          25      /* set when we want DEBUGCTLMSR_BTF */
 #define TIF_LAZY_MMU_UPDATES   27      /* task is updating the mmu lazily */
 #define TIF_SYSCALL_TRACEPOINT 28      /* syscall tracepoint instrumentation */
 
@@ -115,8 +114,7 @@ struct thread_info {
 #define _TIF_IO_BITMAP         (1 << TIF_IO_BITMAP)
 #define _TIF_FREEZE            (1 << TIF_FREEZE)
 #define _TIF_FORCED_TF         (1 << TIF_FORCED_TF)
-#define _TIF_DEBUGCTLMSR       (1 << TIF_DEBUGCTLMSR)
-#define _TIF_DS_AREA_MSR       (1 << TIF_DS_AREA_MSR)
+#define _TIF_BLOCKSTEP         (1 << TIF_BLOCKSTEP)
 #define _TIF_LAZY_MMU_UPDATES  (1 << TIF_LAZY_MMU_UPDATES)
 #define _TIF_SYSCALL_TRACEPOINT        (1 << TIF_SYSCALL_TRACEPOINT)
 
@@ -147,7 +145,7 @@ struct thread_info {
 
 /* flags to check in __switch_to() */
 #define _TIF_WORK_CTXSW                                                        \
-       (_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_NOTSC)
+       (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP)
 
 #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY)
 #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)
@@ -244,7 +242,6 @@ static inline struct thread_info *current_thread_info(void)
 #define TS_POLLING             0x0004  /* true if in idle loop
                                           and not sleeping */
 #define TS_RESTORE_SIGMASK     0x0008  /* restore signal mask in do_signal() */
-#define TS_XSAVE               0x0010  /* Use xsave/xrstor */
 
 #define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
 
index 4da91ad..f66cda5 100644 (file)
@@ -79,7 +79,7 @@ static inline int get_si_code(unsigned long condition)
 
 extern int panic_on_unrecovered_nmi;
 
-void math_error(void __user *);
+void math_error(struct pt_regs *, int, int);
 void math_emulate(struct math_emu_info *);
 #ifndef CONFIG_X86_32
 asmlinkage void smp_thermal_interrupt(void);
index b414d2b..aa558ac 100644 (file)
  * set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on.
  *
  * We will use 31 sets, one for sending BAU messages from each of the 32
- * cpu's on the node.
+ * cpu's on the uvhub.
  *
  * TLB shootdown will use the first of the 8 descriptors of each set.
  * Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set).
  */
 
 #define UV_ITEMS_PER_DESCRIPTOR                8
+#define MAX_BAU_CONCURRENT             3
 #define UV_CPUS_PER_ACT_STATUS         32
 #define UV_ACT_STATUS_MASK             0x3
 #define UV_ACT_STATUS_SIZE             2
@@ -45,6 +46,9 @@
 #define UV_PAYLOADQ_PNODE_SHIFT                49
 #define UV_PTC_BASENAME                        "sgi_uv/ptc_statistics"
 #define uv_physnodeaddr(x)             ((__pa((unsigned long)(x)) & uv_mmask))
+#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL
 
 /*
  * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1
 #define DESC_STATUS_SOURCE_TIMEOUT     3
 
 /*
- * source side thresholds at which message retries print a warning
+ * source side threshholds at which message retries print a warning
  */
 #define SOURCE_TIMEOUT_LIMIT           20
 #define DESTINATION_TIMEOUT_LIMIT      20
 
+/*
+ * misc. delays, in microseconds
+ */
+#define THROTTLE_DELAY                 10
+#define TIMEOUT_DELAY                  10
+#define BIOS_TO                                1000
+/* BIOS is assumed to set the destination timeout to 1003520 nanoseconds */
+
+/*
+ * threshholds at which to use IPI to free resources
+ */
+#define PLUGSB4RESET 100
+#define TIMEOUTSB4RESET 100
+
 /*
  * number of entries in the destination side payload queue
  */
-#define DEST_Q_SIZE                    17
+#define DEST_Q_SIZE                    20
 /*
  * number of destination side software ack resources
  */
 /*
  * completion statuses for sending a TLB flush message
  */
-#define        FLUSH_RETRY                     1
-#define        FLUSH_GIVEUP                    2
-#define        FLUSH_COMPLETE                  3
+#define FLUSH_RETRY_PLUGGED            1
+#define FLUSH_RETRY_TIMEOUT            2
+#define FLUSH_GIVEUP                   3
+#define FLUSH_COMPLETE                 4
 
 /*
  * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor)
  * 'base_dest_nodeid' field of the header corresponds to the
  * destination nodeID associated with that specified bit.
  */
-struct bau_target_nodemask {
-       unsigned long bits[BITS_TO_LONGS(256)];
+struct bau_target_uvhubmask {
+       unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)];
 };
 
 /*
- * mask of cpu's on a node
+ * mask of cpu's on a uvhub
  * (during initialization we need to check that unsigned long has
- *  enough bits for max. cpu's per node)
+ *  enough bits for max. cpu's per uvhub)
  */
 struct bau_local_cpumask {
        unsigned long bits;
@@ -135,8 +154,8 @@ struct bau_msg_payload {
 struct bau_msg_header {
        unsigned int dest_subnodeid:6;  /* must be 0x10, for the LB */
        /* bits 5:0 */
-       unsigned int base_dest_nodeid:15; /* nasid>>1 (pnode) of */
-       /* bits 20:6 */                   /* first bit in node_map */
+       unsigned int base_dest_nodeid:15; /* nasid (pnode<<1) of */
+       /* bits 20:6 */                   /* first bit in uvhub map */
        unsigned int command:8; /* message type */
        /* bits 28:21 */
                                /* 0x38: SN3net EndPoint Message */
@@ -146,26 +165,38 @@ struct bau_msg_header {
        unsigned int rsvd_2:9;  /* must be zero */
        /* bits 40:32 */
                                /* Suppl_A is 56-41 */
-       unsigned int payload_2a:8;/* becomes byte 16 of msg */
-       /* bits 48:41 */        /* not currently using */
-       unsigned int payload_2b:8;/* becomes byte 17 of msg */
-       /* bits 56:49 */        /* not currently using */
+       unsigned int sequence:16;/* message sequence number */
+       /* bits 56:41 */        /* becomes bytes 16-17 of msg */
                                /* Address field (96:57) is never used as an
                                   address (these are address bits 42:3) */
+
        unsigned int rsvd_3:1;  /* must be zero */
        /* bit 57 */
                                /* address bits 27:4 are payload */
-                               /* these 24 bits become bytes 12-14 of msg */
+       /* these next 24  (58-81) bits become bytes 12-14 of msg */
+
+       /* bits 65:58 land in byte 12 */
        unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */
        /* bit 58 */
-
-       unsigned int payload_1a:5;/* not currently used */
-       /* bits 63:59 */
-       unsigned int payload_1b:8;/* not currently used */
-       /* bits 71:64 */
-       unsigned int payload_1c:8;/* not currently used */
-       /* bits 79:72 */
-       unsigned int payload_1d:2;/* not currently used */
+       unsigned int msg_type:3; /* software type of the message*/
+       /* bits 61:59 */
+       unsigned int canceled:1; /* message canceled, resource to be freed*/
+       /* bit 62 */
+       unsigned int payload_1a:1;/* not currently used */
+       /* bit 63 */
+       unsigned int payload_1b:2;/* not currently used */
+       /* bits 65:64 */
+
+       /* bits 73:66 land in byte 13 */
+       unsigned int payload_1ca:6;/* not currently used */
+       /* bits 71:66 */
+       unsigned int payload_1c:2;/* not currently used */
+       /* bits 73:72 */
+
+       /* bits 81:74 land in byte 14 */
+       unsigned int payload_1d:6;/* not currently used */
+       /* bits 79:74 */
+       unsigned int payload_1e:2;/* not currently used */
        /* bits 81:80 */
 
        unsigned int rsvd_4:7;  /* must be zero */
@@ -178,7 +209,7 @@ struct bau_msg_header {
        /* bits 95:90 */
        unsigned int rsvd_6:5;  /* must be zero */
        /* bits 100:96 */
-       unsigned int int_both:1;/* if 1, interrupt both sockets on the blade */
+       unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */
        /* bit 101*/
        unsigned int fairness:3;/* usually zero */
        /* bits 104:102 */
@@ -191,13 +222,18 @@ struct bau_msg_header {
        /* bits 127:107 */
 };
 
+/* see msg_type: */
+#define MSG_NOOP 0
+#define MSG_REGULAR 1
+#define MSG_RETRY 2
+
 /*
  * The activation descriptor:
  * The format of the message to send, plus all accompanying control
  * Should be 64 bytes
  */
 struct bau_desc {
-       struct bau_target_nodemask distribution;
+       struct bau_target_uvhubmask distribution;
        /*
         * message template, consisting of header and payload:
         */
@@ -237,19 +273,25 @@ struct bau_payload_queue_entry {
        unsigned short acknowledge_count; /* filled in by destination */
        /* 16 bits, bytes 10-11 */
 
-       unsigned short replied_to:1;    /* sent as 0 by the source */
-       /* 1 bit */
-       unsigned short unused1:7;       /* not currently using */
-       /* 7 bits: byte 12) */
+       /* these next 3 bytes come from bits 58-81 of the message header */
+       unsigned short replied_to:1;    /* sent as 0 by the source */
+       unsigned short msg_type:3;      /* software message type */
+       unsigned short canceled:1;      /* sent as 0 by the source */
+       unsigned short unused1:3;       /* not currently using */
+       /* byte 12 */
 
-       unsigned char unused2[2];       /* not currently using */
-       /* bytes 13-14 */
+       unsigned char unused2a;         /* not currently using */
+       /* byte 13 */
+       unsigned char unused2;          /* not currently using */
+       /* byte 14 */
 
        unsigned char sw_ack_vector;    /* filled in by the hardware */
        /* byte 15 (bits 127:120) */
 
-       unsigned char unused4[3];       /* not currently using bytes 17-19 */
-       /* bytes 17-19 */
+       unsigned short sequence;        /* message sequence number */
+       /* bytes 16-17 */
+       unsigned char unused4[2];       /* not currently using bytes 18-19 */
+       /* bytes 18-19 */
 
        int number_of_cpus;             /* filled in at destination */
        /* 32 bits, bytes 20-23 (aligned) */
@@ -259,63 +301,93 @@ struct bau_payload_queue_entry {
 };
 
 /*
- * one for every slot in the destination payload queue
- */
-struct bau_msg_status {
-       struct bau_local_cpumask seen_by;       /* map of cpu's */
-};
-
-/*
- * one for every slot in the destination software ack resources
- */
-struct bau_sw_ack_status {
-       struct bau_payload_queue_entry *msg;    /* associated message */
-       int watcher;                            /* cpu monitoring, or -1 */
-};
-
-/*
- * one on every node and per-cpu; to locate the software tables
+ * one per-cpu; to locate the software tables
  */
 struct bau_control {
        struct bau_desc *descriptor_base;
-       struct bau_payload_queue_entry *bau_msg_head;
        struct bau_payload_queue_entry *va_queue_first;
        struct bau_payload_queue_entry *va_queue_last;
-       struct bau_msg_status *msg_statuses;
-       int *watching; /* pointer to array */
+       struct bau_payload_queue_entry *bau_msg_head;
+       struct bau_control *uvhub_master;
+       struct bau_control *socket_master;
+       unsigned long timeout_interval;
+       atomic_t active_descriptor_count;
+       int max_concurrent;
+       int max_concurrent_constant;
+       int retry_message_scans;
+       int plugged_tries;
+       int timeout_tries;
+       int ipi_attempts;
+       int conseccompletes;
+       short cpu;
+       short uvhub_cpu;
+       short uvhub;
+       short cpus_in_socket;
+       short cpus_in_uvhub;
+       unsigned short message_number;
+       unsigned short uvhub_quiesce;
+       short socket_acknowledge_count[DEST_Q_SIZE];
+       cycles_t send_message;
+       spinlock_t masks_lock;
+       spinlock_t uvhub_lock;
+       spinlock_t queue_lock;
 };
 
 /*
  * This structure is allocated per_cpu for UV TLB shootdown statistics.
  */
 struct ptc_stats {
-       unsigned long ptc_i;    /* number of IPI-style flushes */
-       unsigned long requestor;        /* number of nodes this cpu sent to */
-       unsigned long requestee;        /* times cpu was remotely requested */
-       unsigned long alltlb;   /* times all tlb's on this cpu were flushed */
-       unsigned long onetlb;   /* times just one tlb on this cpu was flushed */
-       unsigned long s_retry;  /* retries on source side timeouts */
-       unsigned long d_retry;  /* retries on destination side timeouts */
-       unsigned long sflush;   /* cycles spent in uv_flush_tlb_others */
-       unsigned long dflush;   /* cycles spent on destination side */
-       unsigned long retriesok; /* successes on retries */
-       unsigned long nomsg;    /* interrupts with no message */
-       unsigned long multmsg;  /* interrupts with multiple messages */
-       unsigned long ntargeted;/* nodes targeted */
+       /* sender statistics */
+       unsigned long s_giveup; /* number of fall backs to IPI-style flushes */
+       unsigned long s_requestor; /* number of shootdown requests */
+       unsigned long s_stimeout; /* source side timeouts */
+       unsigned long s_dtimeout; /* destination side timeouts */
+       unsigned long s_time; /* time spent in sending side */
+       unsigned long s_retriesok; /* successful retries */
+       unsigned long s_ntargcpu; /* number of cpus targeted */
+       unsigned long s_ntarguvhub; /* number of uvhubs targeted */
+       unsigned long s_ntarguvhub16; /* number of times >= 16 target hubs */
+       unsigned long s_ntarguvhub8; /* number of times >= 8 target hubs */
+       unsigned long s_ntarguvhub4; /* number of times >= 4 target hubs */
+       unsigned long s_ntarguvhub2; /* number of times >= 2 target hubs */
+       unsigned long s_ntarguvhub1; /* number of times == 1 target hub */
+       unsigned long s_resets_plug; /* ipi-style resets from plug state */
+       unsigned long s_resets_timeout; /* ipi-style resets from timeouts */
+       unsigned long s_busy; /* status stayed busy past s/w timer */
+       unsigned long s_throttles; /* waits in throttle */
+       unsigned long s_retry_messages; /* retry broadcasts */
+       /* destination statistics */
+       unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */
+       unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */
+       unsigned long d_multmsg; /* interrupts with multiple messages */
+       unsigned long d_nomsg; /* interrupts with no message */
+       unsigned long d_time; /* time spent on destination side */
+       unsigned long d_requestee; /* number of messages processed */
+       unsigned long d_retries; /* number of retry messages processed */
+       unsigned long d_canceled; /* number of messages canceled by retries */
+       unsigned long d_nocanceled; /* retries that found nothing to cancel */
+       unsigned long d_resets; /* number of ipi-style requests processed */
+       unsigned long d_rcanceled; /* number of messages canceled by resets */
 };
 
-static inline int bau_node_isset(int node, struct bau_target_nodemask *dstp)
+static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp)
 {
-       return constant_test_bit(node, &dstp->bits[0]);
+       return constant_test_bit(uvhub, &dstp->bits[0]);
 }
-static inline void bau_node_set(int node, struct bau_target_nodemask *dstp)
+static inline void bau_uvhub_set(int uvhub, struct bau_target_uvhubmask *dstp)
 {
-       __set_bit(node, &dstp->bits[0]);
+       __set_bit(uvhub, &dstp->bits[0]);
 }
-static inline void bau_nodes_clear(struct bau_target_nodemask *dstp, int nbits)
+static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp,
+                                   int nbits)
 {
        bitmap_zero(&dstp->bits[0], nbits);
 }
+static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp)
+{
+       return bitmap_weight((unsigned long *)&dstp->bits[0],
+                               UV_DISTRIBUTION_SIZE);
+}
 
 static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits)
 {
@@ -328,4 +400,35 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits)
 extern void uv_bau_message_intr1(void);
 extern void uv_bau_timeout_intr1(void);
 
+struct atomic_short {
+       short counter;
+};
+
+/**
+ * atomic_read_short - read a short atomic variable
+ * @v: pointer of type atomic_short
+ *
+ * Atomically reads the value of @v.
+ */
+static inline int atomic_read_short(const struct atomic_short *v)
+{
+       return v->counter;
+}
+
+/**
+ * atomic_add_short_return - add and return a short int
+ * @i: short value to add
+ * @v: pointer of type atomic_short
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline int atomic_add_short_return(short i, struct atomic_short *v)
+{
+       short __i = i;
+       asm volatile(LOCK_PREFIX "xaddw %0, %1"
+                       : "+r" (i), "+m" (v->counter)
+                       : : "memory");
+       return i + __i;
+}
+
 #endif /* _ASM_X86_UV_UV_BAU_H */
index 14cc74b..bf6b88e 100644 (file)
@@ -307,7 +307,7 @@ static inline unsigned long uv_read_global_mmr32(int pnode, unsigned long offset
  * Access Global MMR space using the MMR space located at the top of physical
  * memory.
  */
-static inline unsigned long *uv_global_mmr64_address(int pnode, unsigned long offset)
+static inline volatile void __iomem *uv_global_mmr64_address(int pnode, unsigned long offset)
 {
        return __va(UV_GLOBAL_MMR64_BASE |
                    UV_GLOBAL_MMR64_PNODE_BITS(pnode) | offset);
index 2cae46c..b2f2d2e 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
 
 #define UV_MMR_ENABLE          (1UL << 63)
 
+/* ========================================================================= */
+/*                          UVH_BAU_DATA_BROADCAST                           */
+/* ========================================================================= */
+#define UVH_BAU_DATA_BROADCAST 0x61688UL
+#define UVH_BAU_DATA_BROADCAST_32 0x0440
+
+#define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0
+#define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL
+
+union uvh_bau_data_broadcast_u {
+    unsigned long      v;
+    struct uvh_bau_data_broadcast_s {
+       unsigned long   enable :  1;  /* RW */
+       unsigned long   rsvd_1_63: 63;  /*    */
+    } s;
+};
+
 /* ========================================================================= */
 /*                           UVH_BAU_DATA_CONFIG                             */
 /* ========================================================================= */
-#define UVH_LB_BAU_MISC_CONTROL 0x320170UL
-#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL
-/* 1011 timebase 7 (168millisec) * 3 ticks -> 500ms */
 #define UVH_BAU_DATA_CONFIG 0x61680UL
 #define UVH_BAU_DATA_CONFIG_32 0x0438
 
@@ -603,6 +614,68 @@ union uvh_lb_bau_intd_software_acknowledge_u {
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70
 
+/* ========================================================================= */
+/*                         UVH_LB_BAU_MISC_CONTROL                           */
+/* ========================================================================= */
+#define UVH_LB_BAU_MISC_CONTROL 0x320170UL
+#define UVH_LB_BAU_MISC_CONTROL_32 0x00a10
+
+#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0
+#define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL
+#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8
+#define UVH_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL
+#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9
+#define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL
+#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10
+#define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL
+#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_SHFT 11
+#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL
+#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14
+#define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL
+#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15
+#define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL
+#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16
+#define UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL
+#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20
+#define UVH_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL
+#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21
+#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL
+#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22
+#define UVH_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL
+#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23
+#define UVH_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL
+#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24
+#define UVH_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL
+#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27
+#define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL
+#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28
+#define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL
+#define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48
+#define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL
+
+union uvh_lb_bau_misc_control_u {
+    unsigned long      v;
+    struct uvh_lb_bau_misc_control_s {
+       unsigned long   rejection_delay                    :  8;  /* RW */
+       unsigned long   apic_mode                          :  1;  /* RW */
+       unsigned long   force_broadcast                    :  1;  /* RW */
+       unsigned long   force_lock_nop                     :  1;  /* RW */
+       unsigned long   csi_agent_presence_vector          :  3;  /* RW */
+       unsigned long   descriptor_fetch_mode              :  1;  /* RW */
+       unsigned long   enable_intd_soft_ack_mode          :  1;  /* RW */
+       unsigned long   intd_soft_ack_timeout_period       :  4;  /* RW */
+       unsigned long   enable_dual_mapping_mode           :  1;  /* RW */
+       unsigned long   vga_io_port_decode_enable          :  1;  /* RW */
+       unsigned long   vga_io_port_16_bit_decode          :  1;  /* RW */
+       unsigned long   suppress_dest_registration         :  1;  /* RW */
+       unsigned long   programmed_initial_priority        :  3;  /* RW */
+       unsigned long   use_incoming_priority              :  1;  /* RW */
+       unsigned long   enable_programmed_initial_priority :  1;  /* RW */
+       unsigned long   rsvd_29_47                         : 19;  /*    */
+       unsigned long   fun                                : 16;  /* RW */
+    } s;
+};
+
 /* ========================================================================= */
 /*                     UVH_LB_BAU_SB_ACTIVATION_CONTROL                      */
 /* ========================================================================= */
@@ -680,334 +753,6 @@ union uvh_lb_bau_sb_descriptor_base_u {
     } s;
 };
 
-/* ========================================================================= */
-/*                      UVH_LB_MCAST_AOERR0_RPT_ENABLE                       */
-/* ========================================================================= */
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE 0x50b20UL
-
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_OBESE_MSG_SHFT 0
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_OBESE_MSG_MASK 0x0000000000000001UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_DATA_SB_ERR_SHFT 1
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_DATA_SB_ERR_MASK 0x0000000000000002UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_NACK_BUFF_PARITY_SHFT 2
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_NACK_BUFF_PARITY_MASK 0x0000000000000004UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_TIMEOUT_SHFT 3
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_TIMEOUT_MASK 0x0000000000000008UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_INACTIVE_REPLY_SHFT 4
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_INACTIVE_REPLY_MASK 0x0000000000000010UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_UPGRADE_ERROR_SHFT 5
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_UPGRADE_ERROR_MASK 0x0000000000000020UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REG_COUNT_UNDERFLOW_SHFT 6
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REG_COUNT_UNDERFLOW_MASK 0x0000000000000040UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REP_OBESE_MSG_SHFT 7
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MCAST_REP_OBESE_MSG_MASK 0x0000000000000080UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_RUNT_MSG_SHFT 8
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_RUNT_MSG_MASK 0x0000000000000100UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_OBESE_MSG_SHFT 9
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_OBESE_MSG_MASK 0x0000000000000200UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_DATA_SB_ERR_SHFT 10
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REQ_DATA_SB_ERR_MASK 0x0000000000000400UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_RUNT_MSG_SHFT 11
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_RUNT_MSG_MASK 0x0000000000000800UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_OBESE_MSG_SHFT 12
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_OBESE_MSG_MASK 0x0000000000001000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_DATA_SB_ERR_SHFT 13
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_DATA_SB_ERR_MASK 0x0000000000002000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_COMMAND_ERR_SHFT 14
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_REP_COMMAND_ERR_MASK 0x0000000000004000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_PEND_TIMEOUT_SHFT 15
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_UCACHE_PEND_TIMEOUT_MASK 0x0000000000008000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_RUNT_MSG_SHFT 16
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_RUNT_MSG_MASK 0x0000000000010000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_OBESE_MSG_SHFT 17
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_OBESE_MSG_MASK 0x0000000000020000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_DATA_SB_ERR_SHFT 18
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REQ_DATA_SB_ERR_MASK 0x0000000000040000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_RUNT_MSG_SHFT 19
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_RUNT_MSG_MASK 0x0000000000080000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_SHFT 20
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_OBESE_MSG_MASK 0x0000000000100000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_SHFT 21
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_REP_DATA_SB_ERR_MASK 0x0000000000200000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_SHFT 22
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_AMO_TIMEOUT_MASK 0x0000000000400000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_SHFT 23
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_PUT_TIMEOUT_MASK 0x0000000000800000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_SHFT 24
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_MACC_SPURIOUS_EVENT_MASK 0x0000000001000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_SHFT 25
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IOH_DESTINATION_TABLE_PARITY_MASK 0x0000000002000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_SHFT 26
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_HAD_ERROR_REPLY_MASK 0x0000000004000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_SHFT 27
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_GET_TIMEOUT_MASK 0x0000000008000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_SHFT 28
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_LOCK_MANAGER_HAD_ERROR_REPLY_MASK 0x0000000010000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_SHFT 29
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_HAD_ERROR_REPLY_MASK 0x0000000020000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_SHFT 30
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_PUT_TIMEOUT_MASK 0x0000000040000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_SHFT 31
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SB_ACTIVATION_OVERRUN_MASK 0x0000000080000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_SHFT 32
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_HAD_ERROR_REPLY_MASK 0x0000000100000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_SHFT 33
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_COMPLETED_GB_ACTIVATION_TIMEOUT_MASK 0x0000000200000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_SHFT 34
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_0_PARITY_MASK 0x0000000400000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_SHFT 35
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_DESCRIPTOR_BUFFER_1_PARITY_MASK 0x0000000800000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_SHFT 36
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_SOCKET_DESTINATION_TABLE_PARITY_MASK 0x0000001000000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_SHFT 37
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_BAU_REPLY_PAYLOAD_CORRUPTION_MASK 0x0000002000000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_SHFT 38
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_IO_PORT_DESTINATION_TABLE_PARITY_MASK 0x0000004000000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_SHFT 39
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INTD_SOFT_ACK_TIMEOUT_MASK 0x0000008000000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_SHFT 40
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_OBESE_MSG_MASK 0x0000010000000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_SHFT 41
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_REP_COMMAND_ERR_MASK 0x0000020000000000UL
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_SHFT 42
-#define UVH_LB_MCAST_AOERR0_RPT_ENABLE_INT_TIMEOUT_MASK 0x0000040000000000UL
-
-union uvh_lb_mcast_aoerr0_rpt_enable_u {
-    unsigned long      v;
-    struct uvh_lb_mcast_aoerr0_rpt_enable_s {
-       unsigned long   mcast_obese_msg                         :  1;  /* RW */
-       unsigned long   mcast_data_sb_err                       :  1;  /* RW */
-       unsigned long   mcast_nack_buff_parity                  :  1;  /* RW */
-       unsigned long   mcast_timeout                           :  1;  /* RW */
-       unsigned long   mcast_inactive_reply                    :  1;  /* RW */
-       unsigned long   mcast_upgrade_error                     :  1;  /* RW */
-       unsigned long   mcast_reg_count_underflow               :  1;  /* RW */
-       unsigned long   mcast_rep_obese_msg                     :  1;  /* RW */
-       unsigned long   ucache_req_runt_msg                     :  1;  /* RW */
-       unsigned long   ucache_req_obese_msg                    :  1;  /* RW */
-       unsigned long   ucache_req_data_sb_err                  :  1;  /* RW */
-       unsigned long   ucache_rep_runt_msg                     :  1;  /* RW */
-       unsigned long   ucache_rep_obese_msg                    :  1;  /* RW */
-       unsigned long   ucache_rep_data_sb_err                  :  1;  /* RW */
-       unsigned long   ucache_rep_command_err                  :  1;  /* RW */
-       unsigned long   ucache_pend_timeout                     :  1;  /* RW */
-       unsigned long   macc_req_runt_msg                       :  1;  /* RW */
-       unsigned long   macc_req_obese_msg                      :  1;  /* RW */
-       unsigned long   macc_req_data_sb_err                    :  1;  /* RW */
-       unsigned long   macc_rep_runt_msg                       :  1;  /* RW */
-       unsigned long   macc_rep_obese_msg                      :  1;  /* RW */
-       unsigned long   macc_rep_data_sb_err                    :  1;  /* RW */
-       unsigned long   macc_amo_timeout                        :  1;  /* RW */
-       unsigned long   macc_put_timeout                        :  1;  /* RW */
-       unsigned long   macc_spurious_event                     :  1;  /* RW */
-       unsigned long   ioh_destination_table_parity            :  1;  /* RW */
-       unsigned long   get_had_error_reply                     :  1;  /* RW */
-       unsigned long   get_timeout                             :  1;  /* RW */
-       unsigned long   lock_manager_had_error_reply            :  1;  /* RW */
-       unsigned long   put_had_error_reply                     :  1;  /* RW */
-       unsigned long   put_timeout                             :  1;  /* RW */
-       unsigned long   sb_activation_overrun                   :  1;  /* RW */
-       unsigned long   completed_gb_activation_had_error_reply :  1;  /* RW */
-       unsigned long   completed_gb_activation_timeout         :  1;  /* RW */
-       unsigned long   descriptor_buffer_0_parity              :  1;  /* RW */
-       unsigned long   descriptor_buffer_1_parity              :  1;  /* RW */
-       unsigned long   socket_destination_table_parity         :  1;  /* RW */
-       unsigned long   bau_reply_payload_corruption            :  1;  /* RW */
-       unsigned long   io_port_destination_table_parity        :  1;  /* RW */
-       unsigned long   intd_soft_ack_timeout                   :  1;  /* RW */
-       unsigned long   int_rep_obese_msg                       :  1;  /* RW */
-       unsigned long   int_rep_command_err                     :  1;  /* RW */
-       unsigned long   int_timeout                             :  1;  /* RW */
-       unsigned long   rsvd_43_63                              : 21;  /*    */
-    } s;
-};
-
-/* ========================================================================= */
-/*                          UVH_LOCAL_INT0_CONFIG                            */
-/* ========================================================================= */
-#define UVH_LOCAL_INT0_CONFIG 0x61000UL
-
-#define UVH_LOCAL_INT0_CONFIG_VECTOR_SHFT 0
-#define UVH_LOCAL_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_LOCAL_INT0_CONFIG_DM_SHFT 8
-#define UVH_LOCAL_INT0_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_LOCAL_INT0_CONFIG_DESTMODE_SHFT 11
-#define UVH_LOCAL_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_LOCAL_INT0_CONFIG_STATUS_SHFT 12
-#define UVH_LOCAL_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_LOCAL_INT0_CONFIG_P_SHFT 13
-#define UVH_LOCAL_INT0_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_LOCAL_INT0_CONFIG_T_SHFT 15
-#define UVH_LOCAL_INT0_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_LOCAL_INT0_CONFIG_M_SHFT 16
-#define UVH_LOCAL_INT0_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_LOCAL_INT0_CONFIG_APIC_ID_SHFT 32
-#define UVH_LOCAL_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_local_int0_config_u {
-    unsigned long      v;
-    struct uvh_local_int0_config_s {
-       unsigned long   vector_  :  8;  /* RW */
-       unsigned long   dm       :  3;  /* RW */
-       unsigned long   destmode :  1;  /* RW */
-       unsigned long   status   :  1;  /* RO */
-       unsigned long   p        :  1;  /* RO */
-       unsigned long   rsvd_14  :  1;  /*    */
-       unsigned long   t        :  1;  /* RO */
-       unsigned long   m        :  1;  /* RW */
-       unsigned long   rsvd_17_31: 15;  /*    */
-       unsigned long   apic_id  : 32;  /* RW */
-    } s;
-};
-
-/* ========================================================================= */
-/*                          UVH_LOCAL_INT0_ENABLE                            */
-/* ========================================================================= */
-#define UVH_LOCAL_INT0_ENABLE 0x65000UL
-
-#define UVH_LOCAL_INT0_ENABLE_LB_HCERR_SHFT 0
-#define UVH_LOCAL_INT0_ENABLE_LB_HCERR_MASK 0x0000000000000001UL
-#define UVH_LOCAL_INT0_ENABLE_GR0_HCERR_SHFT 1
-#define UVH_LOCAL_INT0_ENABLE_GR0_HCERR_MASK 0x0000000000000002UL
-#define UVH_LOCAL_INT0_ENABLE_GR1_HCERR_SHFT 2
-#define UVH_LOCAL_INT0_ENABLE_GR1_HCERR_MASK 0x0000000000000004UL
-#define UVH_LOCAL_INT0_ENABLE_LH_HCERR_SHFT 3
-#define UVH_LOCAL_INT0_ENABLE_LH_HCERR_MASK 0x0000000000000008UL
-#define UVH_LOCAL_INT0_ENABLE_RH_HCERR_SHFT 4
-#define UVH_LOCAL_INT0_ENABLE_RH_HCERR_MASK 0x0000000000000010UL
-#define UVH_LOCAL_INT0_ENABLE_XN_HCERR_SHFT 5
-#define UVH_LOCAL_INT0_ENABLE_XN_HCERR_MASK 0x0000000000000020UL
-#define UVH_LOCAL_INT0_ENABLE_SI_HCERR_SHFT 6
-#define UVH_LOCAL_INT0_ENABLE_SI_HCERR_MASK 0x0000000000000040UL
-#define UVH_LOCAL_INT0_ENABLE_LB_AOERR0_SHFT 7
-#define UVH_LOCAL_INT0_ENABLE_LB_AOERR0_MASK 0x0000000000000080UL
-#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR0_SHFT 8
-#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR0_MASK 0x0000000000000100UL
-#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR0_SHFT 9
-#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR0_MASK 0x0000000000000200UL
-#define UVH_LOCAL_INT0_ENABLE_LH_AOERR0_SHFT 10
-#define UVH_LOCAL_INT0_ENABLE_LH_AOERR0_MASK 0x0000000000000400UL
-#define UVH_LOCAL_INT0_ENABLE_RH_AOERR0_SHFT 11
-#define UVH_LOCAL_INT0_ENABLE_RH_AOERR0_MASK 0x0000000000000800UL
-#define UVH_LOCAL_INT0_ENABLE_XN_AOERR0_SHFT 12
-#define UVH_LOCAL_INT0_ENABLE_XN_AOERR0_MASK 0x0000000000001000UL
-#define UVH_LOCAL_INT0_ENABLE_SI_AOERR0_SHFT 13
-#define UVH_LOCAL_INT0_ENABLE_SI_AOERR0_MASK 0x0000000000002000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_AOERR1_SHFT 14
-#define UVH_LOCAL_INT0_ENABLE_LB_AOERR1_MASK 0x0000000000004000UL
-#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR1_SHFT 15
-#define UVH_LOCAL_INT0_ENABLE_GR0_AOERR1_MASK 0x0000000000008000UL
-#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR1_SHFT 16
-#define UVH_LOCAL_INT0_ENABLE_GR1_AOERR1_MASK 0x0000000000010000UL
-#define UVH_LOCAL_INT0_ENABLE_LH_AOERR1_SHFT 17
-#define UVH_LOCAL_INT0_ENABLE_LH_AOERR1_MASK 0x0000000000020000UL
-#define UVH_LOCAL_INT0_ENABLE_RH_AOERR1_SHFT 18
-#define UVH_LOCAL_INT0_ENABLE_RH_AOERR1_MASK 0x0000000000040000UL
-#define UVH_LOCAL_INT0_ENABLE_XN_AOERR1_SHFT 19
-#define UVH_LOCAL_INT0_ENABLE_XN_AOERR1_MASK 0x0000000000080000UL
-#define UVH_LOCAL_INT0_ENABLE_SI_AOERR1_SHFT 20
-#define UVH_LOCAL_INT0_ENABLE_SI_AOERR1_MASK 0x0000000000100000UL
-#define UVH_LOCAL_INT0_ENABLE_RH_VPI_INT_SHFT 21
-#define UVH_LOCAL_INT0_ENABLE_RH_VPI_INT_MASK 0x0000000000200000UL
-#define UVH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_SHFT 22
-#define UVH_LOCAL_INT0_ENABLE_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_0_SHFT 23
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_0_MASK 0x0000000000800000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_1_SHFT 24
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_1_MASK 0x0000000001000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_2_SHFT 25
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_2_MASK 0x0000000002000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_3_SHFT 26
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_3_MASK 0x0000000004000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_4_SHFT 27
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_4_MASK 0x0000000008000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_5_SHFT 28
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_5_MASK 0x0000000010000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_6_SHFT 29
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_6_MASK 0x0000000020000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_7_SHFT 30
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_7_MASK 0x0000000040000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_8_SHFT 31
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_8_MASK 0x0000000080000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_9_SHFT 32
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_9_MASK 0x0000000100000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_10_SHFT 33
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_10_MASK 0x0000000200000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_11_SHFT 34
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_11_MASK 0x0000000400000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_12_SHFT 35
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_12_MASK 0x0000000800000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_13_SHFT 36
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_13_MASK 0x0000001000000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_14_SHFT 37
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_14_MASK 0x0000002000000000UL
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_15_SHFT 38
-#define UVH_LOCAL_INT0_ENABLE_LB_IRQ_INT_15_MASK 0x0000004000000000UL
-#define UVH_LOCAL_INT0_ENABLE_L1_NMI_INT_SHFT 39
-#define UVH_LOCAL_INT0_ENABLE_L1_NMI_INT_MASK 0x0000008000000000UL
-#define UVH_LOCAL_INT0_ENABLE_STOP_CLOCK_SHFT 40
-#define UVH_LOCAL_INT0_ENABLE_STOP_CLOCK_MASK 0x0000010000000000UL
-#define UVH_LOCAL_INT0_ENABLE_ASIC_TO_L1_SHFT 41
-#define UVH_LOCAL_INT0_ENABLE_ASIC_TO_L1_MASK 0x0000020000000000UL
-#define UVH_LOCAL_INT0_ENABLE_L1_TO_ASIC_SHFT 42
-#define UVH_LOCAL_INT0_ENABLE_L1_TO_ASIC_MASK 0x0000040000000000UL
-#define UVH_LOCAL_INT0_ENABLE_LTC_INT_SHFT 43
-#define UVH_LOCAL_INT0_ENABLE_LTC_INT_MASK 0x0000080000000000UL
-#define UVH_LOCAL_INT0_ENABLE_LA_SEQ_TRIGGER_SHFT 44
-#define UVH_LOCAL_INT0_ENABLE_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL
-
-union uvh_local_int0_enable_u {
-    unsigned long      v;
-    struct uvh_local_int0_enable_s {
-       unsigned long   lb_hcerr            :  1;  /* RW */
-       unsigned long   gr0_hcerr           :  1;  /* RW */
-       unsigned long   gr1_hcerr           :  1;  /* RW */
-       unsigned long   lh_hcerr            :  1;  /* RW */
-       unsigned long   rh_hcerr            :  1;  /* RW */
-       unsigned long   xn_hcerr            :  1;  /* RW */
-       unsigned long   si_hcerr            :  1;  /* RW */
-       unsigned long   lb_aoerr0           :  1;  /* RW */
-       unsigned long   gr0_aoerr0          :  1;  /* RW */
-       unsigned long   gr1_aoerr0          :  1;  /* RW */
-       unsigned long   lh_aoerr0           :  1;  /* RW */
-       unsigned long   rh_aoerr0           :  1;  /* RW */
-       unsigned long   xn_aoerr0           :  1;  /* RW */
-       unsigned long   si_aoerr0           :  1;  /* RW */
-       unsigned long   lb_aoerr1           :  1;  /* RW */
-       unsigned long   gr0_aoerr1          :  1;  /* RW */
-       unsigned long   gr1_aoerr1          :  1;  /* RW */
-       unsigned long   lh_aoerr1           :  1;  /* RW */
-       unsigned long   rh_aoerr1           :  1;  /* RW */
-       unsigned long   xn_aoerr1           :  1;  /* RW */
-       unsigned long   si_aoerr1           :  1;  /* RW */
-       unsigned long   rh_vpi_int          :  1;  /* RW */
-       unsigned long   system_shutdown_int :  1;  /* RW */
-       unsigned long   lb_irq_int_0        :  1;  /* RW */
-       unsigned long   lb_irq_int_1        :  1;  /* RW */
-       unsigned long   lb_irq_int_2        :  1;  /* RW */
-       unsigned long   lb_irq_int_3        :  1;  /* RW */
-       unsigned long   lb_irq_int_4        :  1;  /* RW */
-       unsigned long   lb_irq_int_5        :  1;  /* RW */
-       unsigned long   lb_irq_int_6        :  1;  /* RW */
-       unsigned long   lb_irq_int_7        :  1;  /* RW */
-       unsigned long   lb_irq_int_8        :  1;  /* RW */
-       unsigned long   lb_irq_int_9        :  1;  /* RW */
-       unsigned long   lb_irq_int_10       :  1;  /* RW */
-       unsigned long   lb_irq_int_11       :  1;  /* RW */
-       unsigned long   lb_irq_int_12       :  1;  /* RW */
-       unsigned long   lb_irq_int_13       :  1;  /* RW */
-       unsigned long   lb_irq_int_14       :  1;  /* RW */
-       unsigned long   lb_irq_int_15       :  1;  /* RW */
-       unsigned long   l1_nmi_int          :  1;  /* RW */
-       unsigned long   stop_clock          :  1;  /* RW */
-       unsigned long   asic_to_l1          :  1;  /* RW */
-       unsigned long   l1_to_asic          :  1;  /* RW */
-       unsigned long   ltc_int             :  1;  /* RW */
-       unsigned long   la_seq_trigger      :  1;  /* RW */
-       unsigned long   rsvd_45_63          : 19;  /*    */
-    } s;
-};
-
 /* ========================================================================= */
 /*                               UVH_NODE_ID                                 */
 /* ========================================================================= */
@@ -1111,26 +856,6 @@ union uvh_rh_gam_alias210_redirect_config_2_mmr_u {
     } s;
 };
 
-/* ========================================================================= */
-/*                    UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR                      */
-/* ========================================================================= */
-#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR 0x1600020UL
-
-#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_SHFT 26
-#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL
-#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
-#define UVH_RH_GAM_CFG_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
-
-union uvh_rh_gam_cfg_overlay_config_mmr_u {
-    unsigned long      v;
-    struct uvh_rh_gam_cfg_overlay_config_mmr_s {
-       unsigned long   rsvd_0_25: 26;  /*    */
-       unsigned long   base   : 20;  /* RW */
-       unsigned long   rsvd_46_62: 17;  /*    */
-       unsigned long   enable :  1;  /* RW */
-    } s;
-};
-
 /* ========================================================================= */
 /*                    UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR                      */
 /* ========================================================================= */
@@ -1262,101 +987,6 @@ union uvh_rtc1_int_config_u {
     } s;
 };
 
-/* ========================================================================= */
-/*                           UVH_RTC2_INT_CONFIG                             */
-/* ========================================================================= */
-#define UVH_RTC2_INT_CONFIG 0x61600UL
-
-#define UVH_RTC2_INT_CONFIG_VECTOR_SHFT 0
-#define UVH_RTC2_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_RTC2_INT_CONFIG_DM_SHFT 8
-#define UVH_RTC2_INT_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_RTC2_INT_CONFIG_DESTMODE_SHFT 11
-#define UVH_RTC2_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_RTC2_INT_CONFIG_STATUS_SHFT 12
-#define UVH_RTC2_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_RTC2_INT_CONFIG_P_SHFT 13
-#define UVH_RTC2_INT_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_RTC2_INT_CONFIG_T_SHFT 15
-#define UVH_RTC2_INT_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_RTC2_INT_CONFIG_M_SHFT 16
-#define UVH_RTC2_INT_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_RTC2_INT_CONFIG_APIC_ID_SHFT 32
-#define UVH_RTC2_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_rtc2_int_config_u {
-    unsigned long      v;
-    struct uvh_rtc2_int_config_s {
-       unsigned long   vector_  :  8;  /* RW */
-       unsigned long   dm       :  3;  /* RW */
-       unsigned long   destmode :  1;  /* RW */
-       unsigned long   status   :  1;  /* RO */
-       unsigned long   p        :  1;  /* RO */
-       unsigned long   rsvd_14  :  1;  /*    */
-       unsigned long   t        :  1;  /* RO */
-       unsigned long   m        :  1;  /* RW */
-       unsigned long   rsvd_17_31: 15;  /*    */
-       unsigned long   apic_id  : 32;  /* RW */
-    } s;
-};
-
-/* ========================================================================= */
-/*                           UVH_RTC3_INT_CONFIG                             */
-/* ========================================================================= */
-#define UVH_RTC3_INT_CONFIG 0x61640UL
-
-#define UVH_RTC3_INT_CONFIG_VECTOR_SHFT 0
-#define UVH_RTC3_INT_CONFIG_VECTOR_MASK 0x00000000000000ffUL
-#define UVH_RTC3_INT_CONFIG_DM_SHFT 8
-#define UVH_RTC3_INT_CONFIG_DM_MASK 0x0000000000000700UL
-#define UVH_RTC3_INT_CONFIG_DESTMODE_SHFT 11
-#define UVH_RTC3_INT_CONFIG_DESTMODE_MASK 0x0000000000000800UL
-#define UVH_RTC3_INT_CONFIG_STATUS_SHFT 12
-#define UVH_RTC3_INT_CONFIG_STATUS_MASK 0x0000000000001000UL
-#define UVH_RTC3_INT_CONFIG_P_SHFT 13
-#define UVH_RTC3_INT_CONFIG_P_MASK 0x0000000000002000UL
-#define UVH_RTC3_INT_CONFIG_T_SHFT 15
-#define UVH_RTC3_INT_CONFIG_T_MASK 0x0000000000008000UL
-#define UVH_RTC3_INT_CONFIG_M_SHFT 16
-#define UVH_RTC3_INT_CONFIG_M_MASK 0x0000000000010000UL
-#define UVH_RTC3_INT_CONFIG_APIC_ID_SHFT 32
-#define UVH_RTC3_INT_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
-
-union uvh_rtc3_int_config_u {
-    unsigned long      v;
-    struct uvh_rtc3_int_config_s {
-       unsigned long   vector_  :  8;  /* RW */
-       unsigned long   dm       :  3;  /* RW */
-       unsigned long   destmode :  1;  /* RW */
-       unsigned long   status   :  1;  /* RO */
-       unsigned long   p        :  1;  /* RO */
-       unsigned long   rsvd_14  :  1;  /*    */
-       unsigned long   t        :  1;  /* RO */
-       unsigned long   m        :  1;  /* RW */
-       unsigned long   rsvd_17_31: 15;  /*    */
-       unsigned long   apic_id  : 32;  /* RW */
-    } s;
-};
-
-/* ========================================================================= */
-/*                            UVH_RTC_INC_RATIO                              */
-/* ========================================================================= */
-#define UVH_RTC_INC_RATIO 0x350000UL
-
-#define UVH_RTC_INC_RATIO_FRACTION_SHFT 0
-#define UVH_RTC_INC_RATIO_FRACTION_MASK 0x00000000000fffffUL
-#define UVH_RTC_INC_RATIO_RATIO_SHFT 20
-#define UVH_RTC_INC_RATIO_RATIO_MASK 0x0000000000700000UL
-
-union uvh_rtc_inc_ratio_u {
-    unsigned long      v;
-    struct uvh_rtc_inc_ratio_s {
-       unsigned long   fraction : 20;  /* RW */
-       unsigned long   ratio    :  3;  /* RW */
-       unsigned long   rsvd_23_63: 41;  /*    */
-    } s;
-};
-
 /* ========================================================================= */
 /*                          UVH_SI_ADDR_MAP_CONFIG                           */
 /* ========================================================================= */
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
deleted file mode 100644 (file)
index e49ed6d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008, VMware, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- */
-#ifndef ASM_X86__VMWARE_H
-#define ASM_X86__VMWARE_H
-
-extern void vmware_platform_setup(void);
-extern int vmware_platform(void);
-extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
-
-#endif
index ddc04cc..2c4390c 100644 (file)
@@ -37,8 +37,9 @@ extern int check_for_xstate(struct i387_fxsave_struct __user *buf,
                            void __user *fpstate,
                            struct _fpx_sw_bytes *sw);
 
-static inline int xrstor_checking(struct xsave_struct *fx)
+static inline int fpu_xrstor_checking(struct fpu *fpu)
 {
+       struct xsave_struct *fx = &fpu->state->xsave;
        int err;
 
        asm volatile("1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n\t"
@@ -110,12 +111,12 @@ static inline void xrstor_state(struct xsave_struct *fx, u64 mask)
                     :   "memory");
 }
 
-static inline void xsave(struct task_struct *tsk)
+static inline void fpu_xsave(struct fpu *fpu)
 {
        /* This, however, we can work around by forcing the compiler to select
           an addressing mode that doesn't require extended registers. */
        __asm__ __volatile__(".byte " REX_PREFIX "0x0f,0xae,0x27"
-                            : : "D" (&(tsk->thread.xstate->xsave)),
+                            : : "D" (&(fpu->state->xsave)),
                                 "a" (-1), "d"(-1) : "memory");
 }
 #endif
index 4c58352..e77b220 100644 (file)
@@ -47,8 +47,6 @@ obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
 obj-y                          += process.o
 obj-y                          += i387.o xsave.o
 obj-y                          += ptrace.o
-obj-$(CONFIG_X86_DS)           += ds.o
-obj-$(CONFIG_X86_DS_SELFTEST)          += ds_selftest.o
 obj-$(CONFIG_X86_32)           += tls.o
 obj-$(CONFIG_IA32_EMULATION)   += tls.o
 obj-y                          += step.o
index cd40aba..9a5ed58 100644 (file)
@@ -93,6 +93,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
 
 
+/*
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+       0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+       unsigned int irq = gsi + NR_IRQS_LEGACY;
+       unsigned int i;
+
+       for (i = 0; i < NR_IRQS_LEGACY; i++) {
+               if (isa_irq_to_gsi[i] == gsi) {
+                       return i;
+               }
+       }
+
+       /* Provide an identity mapping of gsi == irq
+        * except on truly weird platforms that have
+        * non isa irqs in the first 16 gsis.
+        */
+       if (gsi >= NR_IRQS_LEGACY)
+               irq = gsi;
+       else
+               irq = gsi_end + 1 + gsi;
+
+       return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+       unsigned int gsi;
+
+       if (irq < NR_IRQS_LEGACY)
+               gsi = isa_irq_to_gsi[irq];
+       else if (irq <= gsi_end)
+               gsi = irq;
+       else if (irq <= (gsi_end + NR_IRQS_LEGACY))
+               gsi = irq - gsi_end;
+       else
+               gsi = 0xffffffff;
+
+       return gsi;
+}
+
 /*
  * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  * to map the target physical address. The problem is that set_fixmap()
@@ -313,7 +360,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 /*
  * Parse Interrupt Source Override for the ACPI SCI
  */
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
 {
        if (trigger == 0)       /* compatible SCI trigger is level */
                trigger = 3;
@@ -333,7 +380,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
         * If GSI is < 16, this will update its flags,
         * else it will create a new mp_irqs[] entry.
         */
-       mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+       mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
 
        /*
         * stash over-ride to indicate we've been here
@@ -357,9 +404,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
        acpi_table_print_madt_entry(header);
 
        if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
-               acpi_sci_ioapic_setup(intsrc->global_irq,
+               acpi_sci_ioapic_setup(intsrc->source_irq,
                                      intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
-                                     (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+                                     (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+                                     intsrc->global_irq);
                return 0;
        }
 
@@ -448,7 +496,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
 {
-       *irq = gsi;
+       *irq = gsi_to_irq(gsi);
 
 #ifdef CONFIG_X86_IO_APIC
        if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -458,6 +506,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
        return 0;
 }
 
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+       if (isa_irq >= 16)
+               return -1;
+       *gsi = irq_to_gsi(isa_irq);
+       return 0;
+}
+
 /*
  * success: return IRQ number (>=0)
  * failure: return < 0
@@ -482,7 +538,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
                plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
        }
 #endif
-       irq = plat_gsi;
+       irq = gsi_to_irq(plat_gsi);
 
        return irq;
 }
@@ -867,29 +923,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
 extern int es7000_plat;
 #endif
 
-int __init acpi_probe_gsi(void)
-{
-       int idx;
-       int gsi;
-       int max_gsi = 0;
-
-       if (acpi_disabled)
-               return 0;
-
-       if (!acpi_ioapic)
-               return 0;
-
-       max_gsi = 0;
-       for (idx = 0; idx < nr_ioapics; idx++) {
-               gsi = mp_gsi_routing[idx].gsi_end;
-
-               if (gsi > max_gsi)
-                       max_gsi = gsi;
-       }
-
-       return max_gsi + 1;
-}
-
 static void assign_to_mp_irq(struct mpc_intsrc *m,
                                    struct mpc_intsrc *mp_irq)
 {
@@ -947,13 +980,13 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
        mp_irq.dstirq = pin;    /* INTIN# */
 
        save_mp_irq(&mp_irq);
+
+       isa_irq_to_gsi[bus_irq] = gsi;
 }
 
 void __init mp_config_acpi_legacy_irqs(void)
 {
        int i;
-       int ioapic;
-       unsigned int dstapic;
        struct mpc_intsrc mp_irq;
 
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -973,20 +1006,28 @@ void __init mp_config_acpi_legacy_irqs(void)
                return;
 #endif
 
-       /*
-        * Locate the IOAPIC that manages the ISA IRQs (0-15).
-        */
-       ioapic = mp_find_ioapic(0);
-       if (ioapic < 0)
-               return;
-       dstapic = mp_ioapics[ioapic].apicid;
-
        /*
         * Use the default configuration for the IRQs 0-15.  Unless
         * overridden by (MADT) interrupt source override entries.
         */
        for (i = 0; i < 16; i++) {
+               int ioapic, pin;
+               unsigned int dstapic;
                int idx;
+               u32 gsi;
+
+               /* Locate the gsi that irq i maps to. */
+               if (acpi_isa_irq_to_gsi(i, &gsi))
+                       continue;
+
+               /*
+                * Locate the IOAPIC that manages the ISA IRQ.
+                */
+               ioapic = mp_find_ioapic(gsi);
+               if (ioapic < 0)
+                       continue;
+               pin = mp_find_ioapic_pin(ioapic, gsi);
+               dstapic = mp_ioapics[ioapic].apicid;
 
                for (idx = 0; idx < mp_irq_entries; idx++) {
                        struct mpc_intsrc *irq = mp_irqs + idx;
@@ -996,7 +1037,7 @@ void __init mp_config_acpi_legacy_irqs(void)
                                break;
 
                        /* Do we already have a mapping for this IOAPIC pin */
-                       if (irq->dstapic == dstapic && irq->dstirq == i)
+                       if (irq->dstapic == dstapic && irq->dstirq == pin)
                                break;
                }
 
@@ -1011,7 +1052,7 @@ void __init mp_config_acpi_legacy_irqs(void)
                mp_irq.dstapic = dstapic;
                mp_irq.irqtype = mp_INT;
                mp_irq.srcbusirq = i; /* Identity mapped */
-               mp_irq.dstirq = i;
+               mp_irq.dstirq = pin;
 
                save_mp_irq(&mp_irq);
        }
@@ -1076,11 +1117,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
 
        ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
 
-#ifdef CONFIG_X86_32
-       if (ioapic_renumber_irq)
-               gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
        if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
                printk(KERN_ERR "Invalid reference to IOAPIC pin "
                       "%d-%d\n", mp_ioapics[ioapic].apicid,
@@ -1094,7 +1130,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
        set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
                             trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
                             polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
-       io_apic_set_pci_routing(dev, gsi, &irq_attr);
+       io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
 
        return gsi;
 }
@@ -1154,7 +1190,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
         * pretend we got one so we can set the SCI flags.
         */
        if (!acpi_sci_override_gsi)
-               acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+               acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+                                     acpi_gbl_FADT.sci_interrupt);
 
        /* Fill in identity legacy mappings where no override */
        mp_config_acpi_legacy_irqs();
index 1a160d5..7023773 100644 (file)
@@ -194,7 +194,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len)
 }
 
 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-extern u8 *__smp_locks[], *__smp_locks_end[];
+extern s32 __smp_locks[], __smp_locks_end[];
 static void *text_poke_early(void *addr, const void *opcode, size_t len);
 
 /* Replace instructions with better alternatives for this CPU type.
@@ -235,37 +235,41 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
 
 #ifdef CONFIG_SMP
 
-static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
+static void alternatives_smp_lock(const s32 *start, const s32 *end,
+                                 u8 *text, u8 *text_end)
 {
-       u8 **ptr;
+       const s32 *poff;
 
        mutex_lock(&text_mutex);
-       for (ptr = start; ptr < end; ptr++) {
-               if (*ptr < text)
-                       continue;
-               if (*ptr > text_end)
+       for (poff = start; poff < end; poff++) {
+               u8 *ptr = (u8 *)poff + *poff;
+
+               if (!*poff || ptr < text || ptr >= text_end)
                        continue;
                /* turn DS segment override prefix into lock prefix */
-               text_poke(*ptr, ((unsigned char []){0xf0}), 1);
+               if (*ptr == 0x3e)
+                       text_poke(ptr, ((unsigned char []){0xf0}), 1);
        };
        mutex_unlock(&text_mutex);
 }
 
-static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
+static void alternatives_smp_unlock(const s32 *start, const s32 *end,
+                                   u8 *text, u8 *text_end)
 {
-       u8 **ptr;
+       const s32 *poff;
 
        if (noreplace_smp)
                return;
 
        mutex_lock(&text_mutex);
-       for (ptr = start; ptr < end; ptr++) {
-               if (*ptr < text)
-                       continue;
-               if (*ptr > text_end)
+       for (poff = start; poff < end; poff++) {
+               u8 *ptr = (u8 *)poff + *poff;
+
+               if (!*poff || ptr < text || ptr >= text_end)
                        continue;
                /* turn lock prefix into DS segment override prefix */
-               text_poke(*ptr, ((unsigned char []){0x3E}), 1);
+               if (*ptr == 0xf0)
+                       text_poke(ptr, ((unsigned char []){0x3E}), 1);
        };
        mutex_unlock(&text_mutex);
 }
@@ -276,8 +280,8 @@ struct smp_alt_module {
        char            *name;
 
        /* ptrs to lock prefixes */
-       u8              **locks;
-       u8              **locks_end;
+       const s32       *locks;
+       const s32       *locks_end;
 
        /* .text segment, needed to avoid patching init code ;) */
        u8              *text;
@@ -398,16 +402,19 @@ void alternatives_smp_switch(int smp)
 int alternatives_text_reserved(void *start, void *end)
 {
        struct smp_alt_module *mod;
-       u8 **ptr;
+       const s32 *poff;
        u8 *text_start = start;
        u8 *text_end = end;
 
        list_for_each_entry(mod, &smp_alt_modules, next) {
                if (mod->text > text_end || mod->text_end < text_start)
                        continue;
-               for (ptr = mod->locks; ptr < mod->locks_end; ptr++)
-                       if (text_start <= *ptr && text_end >= *ptr)
+               for (poff = mod->locks; poff < mod->locks_end; poff++) {
+                       const u8 *ptr = (const u8 *)poff + *poff;
+
+                       if (text_start <= ptr && text_end > ptr)
                                return 1;
+               }
        }
 
        return 0;
index f3dadb5..fa5a147 100644 (file)
@@ -118,7 +118,7 @@ static bool check_device(struct device *dev)
                return false;
 
        /* No device or no PCI device */
-       if (!dev || dev->bus != &pci_bus_type)
+       if (dev->bus != &pci_bus_type)
                return false;
 
        devid = get_device_id(dev);
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
        u32 tail, head;
        u8 *target;
 
+       WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
        tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
        target = iommu->cmd_buf + tail;
        memcpy_toio(target, cmd, sizeof(*cmd));
@@ -730,18 +731,22 @@ static bool increase_address_space(struct protection_domain *domain,
 
 static u64 *alloc_pte(struct protection_domain *domain,
                      unsigned long address,
-                     int end_lvl,
+                     unsigned long page_size,
                      u64 **pte_page,
                      gfp_t gfp)
 {
+       int level, end_lvl;
        u64 *pte, *page;
-       int level;
+
+       BUG_ON(!is_power_of_2(page_size));
 
        while (address > PM_LEVEL_SIZE(domain->mode))
                increase_address_space(domain, gfp);
 
-       level =  domain->mode - 1;
-       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+       level   = domain->mode - 1;
+       pte     = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+       address = PAGE_SIZE_ALIGN(address, page_size);
+       end_lvl = PAGE_SIZE_LEVEL(page_size);
 
        while (level > end_lvl) {
                if (!IOMMU_PTE_PRESENT(*pte)) {
@@ -751,6 +756,10 @@ static u64 *alloc_pte(struct protection_domain *domain,
                        *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
                }
 
+               /* No level skipping support yet */
+               if (PM_PTE_LEVEL(*pte) != level)
+                       return NULL;
+
                level -= 1;
 
                pte = IOMMU_PTE_PAGE(*pte);
@@ -768,28 +777,47 @@ static u64 *alloc_pte(struct protection_domain *domain,
  * This function checks if there is a PTE for a given dma address. If
  * there is one, it returns the pointer to it.
  */
-static u64 *fetch_pte(struct protection_domain *domain,
-                     unsigned long address, int map_size)
+static u64 *fetch_pte(struct protection_domain *domain, unsigned long address)
 {
        int level;
        u64 *pte;
 
-       level =  domain->mode - 1;
-       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+       if (address > PM_LEVEL_SIZE(domain->mode))
+               return NULL;
+
+       level   =  domain->mode - 1;
+       pte     = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
 
-       while (level > map_size) {
+       while (level > 0) {
+
+               /* Not Present */
                if (!IOMMU_PTE_PRESENT(*pte))
                        return NULL;
 
+               /* Large PTE */
+               if (PM_PTE_LEVEL(*pte) == 0x07) {
+                       unsigned long pte_mask, __pte;
+
+                       /*
+                        * If we have a series of large PTEs, make
+                        * sure to return a pointer to the first one.
+                        */
+                       pte_mask = PTE_PAGE_SIZE(*pte);
+                       pte_mask = ~((PAGE_SIZE_PTE_COUNT(pte_mask) << 3) - 1);
+                       __pte    = ((unsigned long)pte) & pte_mask;
+
+                       return (u64 *)__pte;
+               }
+
+               /* No level skipping support yet */
+               if (PM_PTE_LEVEL(*pte) != level)
+                       return NULL;
+
                level -= 1;
 
+               /* Walk to the next level */
                pte = IOMMU_PTE_PAGE(*pte);
                pte = &pte[PM_LEVEL_INDEX(level, address)];
-
-               if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
-                       pte = NULL;
-                       break;
-               }
        }
 
        return pte;
@@ -806,44 +834,84 @@ static int iommu_map_page(struct protection_domain *dom,
                          unsigned long bus_addr,
                          unsigned long phys_addr,
                          int prot,
-                         int map_size)
+                         unsigned long page_size)
 {
        u64 __pte, *pte;
-
-       bus_addr  = PAGE_ALIGN(bus_addr);
-       phys_addr = PAGE_ALIGN(phys_addr);
-
-       BUG_ON(!PM_ALIGNED(map_size, bus_addr));
-       BUG_ON(!PM_ALIGNED(map_size, phys_addr));
+       int i, count;
 
        if (!(prot & IOMMU_PROT_MASK))
                return -EINVAL;
 
-       pte = alloc_pte(dom, bus_addr, map_size, NULL, GFP_KERNEL);
+       bus_addr  = PAGE_ALIGN(bus_addr);
+       phys_addr = PAGE_ALIGN(phys_addr);
+       count     = PAGE_SIZE_PTE_COUNT(page_size);
+       pte       = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL);
+
+       for (i = 0; i < count; ++i)
+               if (IOMMU_PTE_PRESENT(pte[i]))
+                       return -EBUSY;
 
-       if (IOMMU_PTE_PRESENT(*pte))
-               return -EBUSY;
+       if (page_size > PAGE_SIZE) {
+               __pte = PAGE_SIZE_PTE(phys_addr, page_size);
+               __pte |= PM_LEVEL_ENC(7) | IOMMU_PTE_P | IOMMU_PTE_FC;
+       } else
+               __pte = phys_addr | IOMMU_PTE_P | IOMMU_PTE_FC;
 
-       __pte = phys_addr | IOMMU_PTE_P;
        if (prot & IOMMU_PROT_IR)
                __pte |= IOMMU_PTE_IR;
        if (prot & IOMMU_PROT_IW)
                __pte |= IOMMU_PTE_IW;
 
-       *pte = __pte;
+       for (i = 0; i < count; ++i)
+               pte[i] = __pte;
 
        update_domain(dom);
 
        return 0;
 }
 
-static void iommu_unmap_page(struct protection_domain *dom,
-                            unsigned long bus_addr, int map_size)
+static unsigned long iommu_unmap_page(struct protection_domain *dom,
+                                     unsigned long bus_addr,
+                                     unsigned long page_size)
 {
-       u64 *pte = fetch_pte(dom, bus_addr, map_size);
+       unsigned long long unmap_size, unmapped;
+       u64 *pte;
+
+       BUG_ON(!is_power_of_2(page_size));
+
+       unmapped = 0;
 
-       if (pte)
-               *pte = 0;
+       while (unmapped < page_size) {
+
+               pte = fetch_pte(dom, bus_addr);
+
+               if (!pte) {
+                       /*
+                        * No PTE for this address
+                        * move forward in 4kb steps
+                        */
+                       unmap_size = PAGE_SIZE;
+               } else if (PM_PTE_LEVEL(*pte) == 0) {
+                       /* 4kb PTE found for this address */
+                       unmap_size = PAGE_SIZE;
+                       *pte       = 0ULL;
+               } else {
+                       int count, i;
+
+                       /* Large PTE found which maps this address */
+                       unmap_size = PTE_PAGE_SIZE(*pte);
+                       count      = PAGE_SIZE_PTE_COUNT(unmap_size);
+                       for (i = 0; i < count; i++)
+                               pte[i] = 0ULL;
+               }
+
+               bus_addr  = (bus_addr & ~(unmap_size - 1)) + unmap_size;
+               unmapped += unmap_size;
+       }
+
+       BUG_ON(!is_power_of_2(unmapped));
+
+       return unmapped;
 }
 
 /*
@@ -877,7 +945,7 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
        for (addr = e->address_start; addr < e->address_end;
             addr += PAGE_SIZE) {
                ret = iommu_map_page(&dma_dom->domain, addr, addr, e->prot,
-                                    PM_MAP_4k);
+                                    PAGE_SIZE);
                if (ret)
                        return ret;
                /*
@@ -1005,7 +1073,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom,
                u64 *pte, *pte_page;
 
                for (i = 0; i < num_ptes; ++i) {
-                       pte = alloc_pte(&dma_dom->domain, address, PM_MAP_4k,
+                       pte = alloc_pte(&dma_dom->domain, address, PAGE_SIZE,
                                        &pte_page, gfp);
                        if (!pte)
                                goto out_free;
@@ -1041,7 +1109,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom,
        for (i = dma_dom->aperture[index]->offset;
             i < dma_dom->aperture_size;
             i += PAGE_SIZE) {
-               u64 *pte = fetch_pte(&dma_dom->domain, i, PM_MAP_4k);
+               u64 *pte = fetch_pte(&dma_dom->domain, i);
                if (!pte || !IOMMU_PTE_PRESENT(*pte))
                        continue;
 
@@ -1711,7 +1779,7 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
 
        pte = aperture->pte_pages[APERTURE_PAGE_INDEX(address)];
        if (!pte) {
-               pte = alloc_pte(&dom->domain, address, PM_MAP_4k, &pte_page,
+               pte = alloc_pte(&dom->domain, address, PAGE_SIZE, &pte_page,
                                GFP_ATOMIC);
                aperture->pte_pages[APERTURE_PAGE_INDEX(address)] = pte_page;
        } else
@@ -2186,7 +2254,7 @@ static void prealloc_protection_domains(void)
        struct dma_ops_domain *dma_dom;
        u16 devid;
 
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
 
                /* Do we handle this device? */
                if (!check_device(&dev->dev))
@@ -2298,7 +2366,7 @@ static void cleanup_domain(struct protection_domain *domain)
        list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
                struct device *dev = dev_data->dev;
 
-               do_detach(dev);
+               __detach_device(dev);
                atomic_set(&dev_data->bind, 0);
        }
 
@@ -2327,6 +2395,7 @@ static struct protection_domain *protection_domain_alloc(void)
                return NULL;
 
        spin_lock_init(&domain->lock);
+       mutex_init(&domain->api_lock);
        domain->id = domain_id_alloc();
        if (!domain->id)
                goto out_err;
@@ -2379,9 +2448,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
 
        free_pagetable(domain);
 
-       domain_id_free(domain->id);
-
-       kfree(domain);
+       protection_domain_free(domain);
 
        dom->priv = NULL;
 }
@@ -2439,12 +2506,11 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
        return ret;
 }
 
-static int amd_iommu_map_range(struct iommu_domain *dom,
-                              unsigned long iova, phys_addr_t paddr,
-                              size_t size, int iommu_prot)
+static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
+                        phys_addr_t paddr, int gfp_order, int iommu_prot)
 {
+       unsigned long page_size = 0x1000UL << gfp_order;
        struct protection_domain *domain = dom->priv;
-       unsigned long i,  npages = iommu_num_pages(paddr, size, PAGE_SIZE);
        int prot = 0;
        int ret;
 
@@ -2453,53 +2519,50 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
        if (iommu_prot & IOMMU_WRITE)
                prot |= IOMMU_PROT_IW;
 
-       iova  &= PAGE_MASK;
-       paddr &= PAGE_MASK;
+       mutex_lock(&domain->api_lock);
+       ret = iommu_map_page(domain, iova, paddr, prot, page_size);
+       mutex_unlock(&domain->api_lock);
 
-       for (i = 0; i < npages; ++i) {
-               ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
-               if (ret)
-                       return ret;
-
-               iova  += PAGE_SIZE;
-               paddr += PAGE_SIZE;
-       }
-
-       return 0;
+       return ret;
 }
 
-static void amd_iommu_unmap_range(struct iommu_domain *dom,
-                                 unsigned long iova, size_t size)
+static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
+                          int gfp_order)
 {
-
        struct protection_domain *domain = dom->priv;
-       unsigned long i,  npages = iommu_num_pages(iova, size, PAGE_SIZE);
+       unsigned long page_size, unmap_size;
 
-       iova  &= PAGE_MASK;
+       page_size  = 0x1000UL << gfp_order;
 
-       for (i = 0; i < npages; ++i) {
-               iommu_unmap_page(domain, iova, PM_MAP_4k);
-               iova  += PAGE_SIZE;
-       }
+       mutex_lock(&domain->api_lock);
+       unmap_size = iommu_unmap_page(domain, iova, page_size);
+       mutex_unlock(&domain->api_lock);
 
        iommu_flush_tlb_pde(domain);
+
+       return get_order(unmap_size);
 }
 
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
                                          unsigned long iova)
 {
        struct protection_domain *domain = dom->priv;
-       unsigned long offset = iova & ~PAGE_MASK;
+       unsigned long offset_mask;
        phys_addr_t paddr;
-       u64 *pte;
+       u64 *pte, __pte;
 
-       pte = fetch_pte(domain, iova, PM_MAP_4k);
+       pte = fetch_pte(domain, iova);
 
        if (!pte || !IOMMU_PTE_PRESENT(*pte))
                return 0;
 
-       paddr  = *pte & IOMMU_PAGE_MASK;
-       paddr |= offset;
+       if (PM_PTE_LEVEL(*pte) == 0)
+               offset_mask = PAGE_SIZE - 1;
+       else
+               offset_mask = PTE_PAGE_SIZE(*pte) - 1;
+
+       __pte = *pte & PM_ADDR_MASK;
+       paddr = (__pte & ~offset_mask) | (iova & offset_mask);
 
        return paddr;
 }
@@ -2515,8 +2578,8 @@ static struct iommu_ops amd_iommu_ops = {
        .domain_destroy = amd_iommu_domain_destroy,
        .attach_dev = amd_iommu_attach_device,
        .detach_dev = amd_iommu_detach_device,
-       .map = amd_iommu_map_range,
-       .unmap = amd_iommu_unmap_range,
+       .map = amd_iommu_map,
+       .unmap = amd_iommu_unmap,
        .iova_to_phys = amd_iommu_iova_to_phys,
        .domain_has_cap = amd_iommu_domain_has_cap,
 };
index 42f5350..3bacb4d 100644 (file)
@@ -120,6 +120,7 @@ struct ivmd_header {
 bool amd_iommu_dump;
 
 static int __initdata amd_iommu_detected;
+static bool __initdata amd_iommu_disabled;
 
 u16 amd_iommu_last_bdf;                        /* largest PCI device id we have
                                           to handle */
@@ -138,9 +139,9 @@ int amd_iommus_present;
 bool amd_iommu_np_cache __read_mostly;
 
 /*
- * Set to true if ACPI table parsing and hardware intialization went properly
+ * The ACPI table parsing functions set this variable on an error
  */
-static bool amd_iommu_initialized;
+static int __initdata amd_iommu_init_err;
 
 /*
  * List of protection domains - used during resume
@@ -391,9 +392,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
         */
        for (i = 0; i < table->length; ++i)
                checksum += p[i];
-       if (checksum != 0)
+       if (checksum != 0) {
                /* ACPI table corrupt */
-               return -ENODEV;
+               amd_iommu_init_err = -ENODEV;
+               return 0;
+       }
 
        p += IVRS_HEADER_LENGTH;
 
@@ -436,7 +439,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
        if (cmd_buf == NULL)
                return NULL;
 
-       iommu->cmd_buf_size = CMD_BUFFER_SIZE;
+       iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;
 
        return cmd_buf;
 }
@@ -472,12 +475,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
                    &entry, sizeof(entry));
 
        amd_iommu_reset_cmd_buffer(iommu);
+       iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);
 }
 
 static void __init free_command_buffer(struct amd_iommu *iommu)
 {
        free_pages((unsigned long)iommu->cmd_buf,
-                  get_order(iommu->cmd_buf_size));
+                  get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));
 }
 
 /* allocates the memory where the IOMMU will log its events to */
@@ -920,11 +924,16 @@ static int __init init_iommu_all(struct acpi_table_header *table)
                                    h->mmio_phys);
 
                        iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
-                       if (iommu == NULL)
-                               return -ENOMEM;
+                       if (iommu == NULL) {
+                               amd_iommu_init_err = -ENOMEM;
+                               return 0;
+                       }
+
                        ret = init_iommu_one(iommu, h);
-                       if (ret)
-                               return ret;
+                       if (ret) {
+                               amd_iommu_init_err = ret;
+                               return 0;
+                       }
                        break;
                default:
                        break;
@@ -934,8 +943,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
        }
        WARN_ON(p != end);
 
-       amd_iommu_initialized = true;
-
        return 0;
 }
 
@@ -1211,6 +1218,10 @@ static int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
                return -ENODEV;
 
+       ret = amd_iommu_init_err;
+       if (ret)
+               goto out;
+
        dev_table_size     = tbl_size(DEV_TABLE_ENTRY_SIZE);
        alias_table_size   = tbl_size(ALIAS_TABLE_ENTRY_SIZE);
        rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE);
@@ -1270,12 +1281,19 @@ static int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", init_iommu_all) != 0)
                goto free;
 
-       if (!amd_iommu_initialized)
+       if (amd_iommu_init_err) {
+               ret = amd_iommu_init_err;
                goto free;
+       }
 
        if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
                goto free;
 
+       if (amd_iommu_init_err) {
+               ret = amd_iommu_init_err;
+               goto free;
+       }
+
        ret = sysdev_class_register(&amd_iommu_sysdev_class);
        if (ret)
                goto free;
@@ -1288,6 +1306,8 @@ static int __init amd_iommu_init(void)
        if (ret)
                goto free;
 
+       enable_iommus();
+
        if (iommu_pass_through)
                ret = amd_iommu_init_passthrough();
        else
@@ -1300,8 +1320,6 @@ static int __init amd_iommu_init(void)
 
        amd_iommu_init_notifier();
 
-       enable_iommus();
-
        if (iommu_pass_through)
                goto out;
 
@@ -1315,6 +1333,7 @@ out:
        return ret;
 
 free:
+       disable_iommus();
 
        amd_iommu_uninit_devices();
 
@@ -1354,6 +1373,9 @@ void __init amd_iommu_detect(void)
        if (no_iommu || (iommu_detected && !gart_iommu_aperture))
                return;
 
+       if (amd_iommu_disabled)
+               return;
+
        if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
                iommu_detected = 1;
                amd_iommu_detected = 1;
@@ -1383,6 +1405,8 @@ static int __init parse_amd_iommu_options(char *str)
        for (; *str; ++str) {
                if (strncmp(str, "fullflush", 9) == 0)
                        amd_iommu_unmap_flush = true;
+               if (strncmp(str, "off", 3) == 0)
+                       amd_iommu_disabled = true;
        }
 
        return 1;
index ff469e4..a353475 100644 (file)
@@ -429,7 +429,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n,
 
 static __init int apbt_late_init(void)
 {
-       if (disable_apbt_percpu)
+       if (disable_apbt_percpu || !apb_timer_block_enabled)
                return 0;
        /* This notifier should be called after workqueue is ready */
        hotcpu_notifier(apbt_cpuhp_notify, -20);
index 3704997..b5d8b0b 100644 (file)
@@ -393,6 +393,7 @@ void __init gart_iommu_hole_init(void)
        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
                int bus;
                int dev_base, dev_limit;
+               u32 ctl;
 
                bus = bus_dev_ranges[i].bus;
                dev_base = bus_dev_ranges[i].dev_base;
@@ -406,7 +407,19 @@ void __init gart_iommu_hole_init(void)
                        gart_iommu_aperture = 1;
                        x86_init.iommu.iommu_init = gart_iommu_init;
 
-                       aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
+                       ctl = read_pci_config(bus, slot, 3,
+                                             AMD64_GARTAPERTURECTL);
+
+                       /*
+                        * Before we do anything else disable the GART. It may
+                        * still be enabled if we boot into a crash-kernel here.
+                        * Reconfiguring the GART while it is enabled could have
+                        * unknown side-effects.
+                        */
+                       ctl &= ~GARTEN;
+                       write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
+
+                       aper_order = (ctl >> 1) & 7;
                        aper_size = (32 * 1024 * 1024) << aper_order;
                        aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
                        aper_base <<= 25;
index 03ba1b8..425e53a 100644 (file)
@@ -131,24 +131,6 @@ int                                        es7000_plat;
 
 static unsigned int                    base;
 
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
-       if (es7000_plat == ES7000_ZORRO)
-               return gsi;
-
-       if (!base) {
-               int i;
-               for (i = 0; i < nr_ioapics; i++)
-                       base += nr_ioapic_registers[i];
-       }
-
-       if (!ioapic && (gsi < 16))
-               gsi += base;
-
-       return gsi;
-}
-
 static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 {
        unsigned long vect = 0, psaival = 0;
@@ -190,7 +172,6 @@ static void setup_unisys(void)
                es7000_plat = ES7000_ZORRO;
        else
                es7000_plat = ES7000_CLASSIC;
-       ioapic_renumber_irq = es7000_rename_gsi;
 }
 
 /*
index 127b871..33f3563 100644 (file)
@@ -89,6 +89,9 @@ int nr_ioapics;
 /* IO APIC gsi routing info */
 struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
 
+/* The last gsi number used */
+u32 gsi_end;
+
 /* MP IRQ source entries */
 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
@@ -1013,10 +1016,9 @@ static inline int irq_trigger(int idx)
        return MPBIOS_trigger(idx);
 }
 
-int (*ioapic_renumber_irq)(int ioapic, int irq);
 static int pin_2_irq(int idx, int apic, int pin)
 {
-       int irq, i;
+       int irq;
        int bus = mp_irqs[idx].srcbus;
 
        /*
@@ -1028,18 +1030,12 @@ static int pin_2_irq(int idx, int apic, int pin)
        if (test_bit(bus, mp_bus_not_pci)) {
                irq = mp_irqs[idx].srcbusirq;
        } else {
-               /*
-                * PCI IRQs are mapped in order
-                */
-               i = irq = 0;
-               while (i < apic)
-                       irq += nr_ioapic_registers[i++];
-               irq += pin;
-               /*
-                 * For MPS mode, so far only needed by ES7000 platform
-                 */
-               if (ioapic_renumber_irq)
-                       irq = ioapic_renumber_irq(apic, irq);
+               u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
+
+               if (gsi >= NR_IRQS_LEGACY)
+                       irq = gsi;
+               else
+                       irq = gsi_end + 1 + gsi;
        }
 
 #ifdef CONFIG_X86_32
@@ -1950,20 +1946,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
 
 void __init enable_IO_APIC(void)
 {
-       union IO_APIC_reg_01 reg_01;
        int i8259_apic, i8259_pin;
        int apic;
-       unsigned long flags;
-
-       /*
-        * The number of IO-APIC IRQ registers (== #pins):
-        */
-       for (apic = 0; apic < nr_ioapics; apic++) {
-               raw_spin_lock_irqsave(&ioapic_lock, flags);
-               reg_01.raw = io_apic_read(apic, 1);
-               raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-               nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-       }
 
        if (!legacy_pic->nr_legacy_irqs)
                return;
@@ -2545,6 +2529,9 @@ void irq_force_complete_move(int irq)
        struct irq_desc *desc = irq_to_desc(irq);
        struct irq_cfg *cfg = desc->chip_data;
 
+       if (!cfg)
+               return;
+
        __irq_complete_move(&desc, cfg->vector);
 }
 #else
@@ -3855,27 +3842,20 @@ int __init io_apic_get_redir_entries (int ioapic)
        reg_01.raw = io_apic_read(ioapic, 1);
        raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
-       return reg_01.bits.entries;
+       /* The register returns the maximum index redir index
+        * supported, which is one less than the total number of redir
+        * entries.
+        */
+       return reg_01.bits.entries + 1;
 }
 
 void __init probe_nr_irqs_gsi(void)
 {
-       int nr = 0;
+       int nr;
 
-       nr = acpi_probe_gsi();
-       if (nr > nr_irqs_gsi) {
+       nr = gsi_end + 1 + NR_IRQS_LEGACY;
+       if (nr > nr_irqs_gsi)
                nr_irqs_gsi = nr;
-       } else {
-               /* for acpi=off or acpi is not compiled in */
-               int idx;
-
-               nr = 0;
-               for (idx = 0; idx < nr_ioapics; idx++)
-                       nr += io_apic_get_redir_entries(idx) + 1;
-
-               if (nr > nr_irqs_gsi)
-                       nr_irqs_gsi = nr;
-       }
 
        printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
 }
@@ -4082,22 +4062,27 @@ int __init io_apic_get_version(int ioapic)
        return reg_01.bits.version;
 }
 
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
 {
-       int i;
+       int ioapic, pin, idx;
 
        if (skip_ioapic_setup)
                return -1;
 
-       for (i = 0; i < mp_irq_entries; i++)
-               if (mp_irqs[i].irqtype == mp_INT &&
-                   mp_irqs[i].srcbusirq == bus_irq)
-                       break;
-       if (i >= mp_irq_entries)
+       ioapic = mp_find_ioapic(gsi);
+       if (ioapic < 0)
                return -1;
 
-       *trigger = irq_trigger(i);
-       *polarity = irq_polarity(i);
+       pin = mp_find_ioapic_pin(ioapic, gsi);
+       if (pin < 0)
+               return -1;
+
+       idx = find_irq_entry(ioapic, pin, mp_INT);
+       if (idx < 0)
+               return -1;
+
+       *trigger = irq_trigger(idx);
+       *polarity = irq_polarity(idx);
        return 0;
 }
 
@@ -4238,7 +4223,7 @@ void __init ioapic_insert_resources(void)
        }
 }
 
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
 {
        int i = 0;
 
@@ -4253,7 +4238,7 @@ int mp_find_ioapic(int gsi)
        return -1;
 }
 
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
        if (WARN_ON(ioapic == -1))
                return -1;
@@ -4281,6 +4266,7 @@ static int bad_ioapic(unsigned long address)
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
        int idx = 0;
+       int entries;
 
        if (bad_ioapic(address))
                return;
@@ -4299,9 +4285,17 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
         * Build basic GSI lookup table to facilitate gsi->io_apic lookups
         * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
         */
+       entries = io_apic_get_redir_entries(idx);
        mp_gsi_routing[idx].gsi_base = gsi_base;
-       mp_gsi_routing[idx].gsi_end = gsi_base +
-           io_apic_get_redir_entries(idx);
+       mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
+
+       /*
+        * The number of IO-APIC IRQ registers (== #pins):
+        */
+       nr_ioapic_registers[idx] = entries;
+
+       if (mp_gsi_routing[idx].gsi_end > gsi_end)
+               gsi_end = mp_gsi_routing[idx].gsi_end;
 
        printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
               "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
index c085d52..e46f98f 100644 (file)
@@ -735,9 +735,6 @@ void __init uv_system_init(void)
                uv_node_to_blade[nid] = blade;
                uv_cpu_to_blade[cpu] = blade;
                max_pnode = max(pnode, max_pnode);
-
-               printk(KERN_DEBUG "UV: cpu %d, apicid 0x%x, pnode %d, nid %d, lcpu %d, blade %d\n",
-                       cpu, apicid, pnode, nid, lcpu, blade);
        }
 
        /* Add blade/pnode info for nodes without cpus */
index 031aa88..c4f9182 100644 (file)
@@ -1224,7 +1224,7 @@ static void reinit_timer(void)
 #ifdef INIT_TIMER_AFTER_SUSPEND
        unsigned long flags;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        /* set the clock to HZ */
        outb_pit(0x34, PIT_MODE);               /* binary, mode 2, LSB/MSB, ch 0 */
        udelay(10);
@@ -1232,7 +1232,7 @@ static void reinit_timer(void)
        udelay(10);
        outb_pit(LATCH >> 8, PIT_CH0);  /* MSB */
        udelay(10);
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 #endif
 }
 
index c202b62..3a785da 100644 (file)
@@ -14,7 +14,7 @@ CFLAGS_common.o               := $(nostackp)
 
 obj-y                  := intel_cacheinfo.o addon_cpuid_features.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
-obj-y                  += vmware.o hypervisor.o sched.o
+obj-y                  += vmware.o hypervisor.o sched.o mshyperv.o
 
 obj-$(CONFIG_X86_32)   += bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)   += bugs_64.o
index 97ad79c..10fa568 100644 (file)
@@ -30,12 +30,14 @@ 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_IDA, CR_EAX, 1, 0x00000006 },
-               { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
-               { X86_FEATURE_NPT,   CR_EDX, 0, 0x8000000a },
-               { X86_FEATURE_LBRV,  CR_EDX, 1, 0x8000000a },
-               { X86_FEATURE_SVML,  CR_EDX, 2, 0x8000000a },
-               { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a },
+               { X86_FEATURE_IDA,              CR_EAX, 1, 0x00000006 },
+               { X86_FEATURE_ARAT,             CR_EAX, 2, 0x00000006 },
+               { X86_FEATURE_APERFMPERF,       CR_ECX, 0, 0x00000006 },
+               { X86_FEATURE_CPB,              CR_EDX, 9, 0x80000007 },
+               { X86_FEATURE_NPT,              CR_EDX, 0, 0x8000000a },
+               { X86_FEATURE_LBRV,             CR_EDX, 1, 0x8000000a },
+               { X86_FEATURE_SVML,             CR_EDX, 2, 0x8000000a },
+               { X86_FEATURE_NRIPS,            CR_EDX, 3, 0x8000000a },
                { 0, 0, 0, 0 }
        };
 
index 01a2652..c39576c 100644 (file)
@@ -86,7 +86,7 @@ static void __init check_fpu(void)
 
 static void __init check_hlt(void)
 {
-       if (paravirt_enabled())
+       if (boot_cpu_data.x86 >= 5 || paravirt_enabled())
                return;
 
        printk(KERN_INFO "Checking 'hlt' instruction... ");
index 4868e4a..c1c00d0 100644 (file)
@@ -1243,10 +1243,7 @@ void __cpuinit cpu_init(void)
        /*
         * Force FPU initialization:
         */
-       if (cpu_has_xsave)
-               current_thread_info()->status = TS_XSAVE;
-       else
-               current_thread_info()->status = 0;
+       current_thread_info()->status = 0;
        clear_used_math();
        mxcsr_feature_mask_init();
 
index 1840c0a..bd54bf6 100644 (file)
@@ -2,8 +2,8 @@
 # K8 systems. ACPI is preferred to all other hardware-specific drivers.
 # speedstep-* is preferred over p4-clockmod.
 
-obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o
+obj-$(CONFIG_X86_POWERNOW_K8)          += powernow-k8.o mperf.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ)         += acpi-cpufreq.o mperf.o
 obj-$(CONFIG_X86_PCC_CPUFREQ)          += pcc-cpufreq.o
 obj-$(CONFIG_X86_POWERNOW_K6)          += powernow-k6.o
 obj-$(CONFIG_X86_POWERNOW_K7)          += powernow-k7.o
index 4591680..1d3cdda 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
+#include "mperf.h"
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
                "acpi-cpufreq", msg)
@@ -71,8 +72,6 @@ struct acpi_cpufreq_data {
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
 
-static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
-
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance *acpi_perf_data;
 
@@ -240,45 +239,6 @@ static u32 get_cur_val(const struct cpumask *mask)
        return cmd.val;
 }
 
-/* Called via smp_call_function_single(), on the target CPU */
-static void read_measured_perf_ctrs(void *_cur)
-{
-       struct aperfmperf *am = _cur;
-
-       get_aperfmperf(am);
-}
-
-/*
- * Return the measured active (C0) frequency on this CPU since last call
- * to this function.
- * Input: cpu number
- * Return: Average CPU frequency in terms of max frequency (zero on error)
- *
- * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
- * over a period of time, while CPU is in C0 state.
- * IA32_MPERF counts at the rate of max advertised frequency
- * IA32_APERF counts at the rate of actual CPU frequency
- * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
- * no meaning should be associated with absolute values of these MSRs.
- */
-static unsigned int get_measured_perf(struct cpufreq_policy *policy,
-                                     unsigned int cpu)
-{
-       struct aperfmperf perf;
-       unsigned long ratio;
-       unsigned int retval;
-
-       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
-               return 0;
-
-       ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
-       per_cpu(acfreq_old_perf, cpu) = perf;
-
-       retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
-
-       return retval;
-}
-
 static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
 {
        struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
@@ -702,7 +662,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        /* Check for APERF/MPERF support in hardware */
        if (cpu_has(c, X86_FEATURE_APERFMPERF))
-               acpi_cpufreq_driver.getavg = get_measured_perf;
+               acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
 
        dprintk("CPU%u - ACPI performance management activated.\n", cpu);
        for (i = 0; i < perf->state_count; i++)
diff --git a/arch/x86/kernel/cpu/cpufreq/mperf.c b/arch/x86/kernel/cpu/cpufreq/mperf.c
new file mode 100644 (file)
index 0000000..911e193
--- /dev/null
@@ -0,0 +1,51 @@
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include "mperf.h"
+
+static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
+
+/* Called via smp_call_function_single(), on the target CPU */
+static void read_measured_perf_ctrs(void *_cur)
+{
+       struct aperfmperf *am = _cur;
+
+       get_aperfmperf(am);
+}
+
+/*
+ * Return the measured active (C0) frequency on this CPU since last call
+ * to this function.
+ * Input: cpu number
+ * Return: Average CPU frequency in terms of max frequency (zero on error)
+ *
+ * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
+ * over a period of time, while CPU is in C0 state.
+ * IA32_MPERF counts at the rate of max advertised frequency
+ * IA32_APERF counts at the rate of actual CPU frequency
+ * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
+ * no meaning should be associated with absolute values of these MSRs.
+ */
+unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
+                                       unsigned int cpu)
+{
+       struct aperfmperf perf;
+       unsigned long ratio;
+       unsigned int retval;
+
+       if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
+               return 0;
+
+       ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
+       per_cpu(acfreq_old_perf, cpu) = perf;
+
+       retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
+
+       return retval;
+}
+EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf);
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/mperf.h b/arch/x86/kernel/cpu/cpufreq/mperf.h
new file mode 100644 (file)
index 0000000..5dbf295
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ *  (c) 2010 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See "COPYING" or
+ *  http://www.gnu.org/licenses/gpl.html
+ */
+
+unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
+                                       unsigned int cpu);
index d360b56..6f3dc8f 100644 (file)
@@ -1,6 +1,5 @@
-
 /*
- *   (c) 2003-2006 Advanced Micro Devices, Inc.
+ *   (c) 2003-2010 Advanced Micro Devices, Inc.
  *  Your use of this code is subject to the terms and conditions of the
  *  GNU general public license version 2. See "COPYING" or
  *  http://www.gnu.org/licenses/gpl.html
@@ -46,6 +45,7 @@
 #define PFX "powernow-k8: "
 #define VERSION "version 2.20.00"
 #include "powernow-k8.h"
+#include "mperf.h"
 
 /* serialize freq changes  */
 static DEFINE_MUTEX(fidvid_mutex);
@@ -54,6 +54,12 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
 
 static int cpu_family = CPU_OPTERON;
 
+/* core performance boost */
+static bool cpb_capable, cpb_enabled;
+static struct msr __percpu *msrs;
+
+static struct cpufreq_driver cpufreq_amd64_driver;
+
 #ifndef CONFIG_SMP
 static inline const struct cpumask *cpu_core_mask(int cpu)
 {
@@ -929,7 +935,8 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
                powernow_table[i].index = index;
 
                /* Frequency may be rounded for these */
-               if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
+               if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
+                                || boot_cpu_data.x86 == 0x11) {
                        powernow_table[i].frequency =
                                freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
                } else
@@ -1248,6 +1255,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
        struct powernow_k8_data *data;
        struct init_on_cpu init_on_cpu;
        int rc;
+       struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
 
        if (!cpu_online(pol->cpu))
                return -ENODEV;
@@ -1322,6 +1330,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
                return -EINVAL;
        }
 
+       /* Check for APERF/MPERF support in hardware */
+       if (cpu_has(c, X86_FEATURE_APERFMPERF))
+               cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
+
        cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
 
        if (cpu_family == CPU_HW_PSTATE)
@@ -1393,8 +1405,77 @@ out:
        return khz;
 }
 
+static void _cpb_toggle_msrs(bool t)
+{
+       int cpu;
+
+       get_online_cpus();
+
+       rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+       for_each_cpu(cpu, cpu_online_mask) {
+               struct msr *reg = per_cpu_ptr(msrs, cpu);
+               if (t)
+                       reg->l &= ~BIT(25);
+               else
+                       reg->l |= BIT(25);
+       }
+       wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+       put_online_cpus();
+}
+
+/*
+ * Switch on/off core performance boosting.
+ *
+ * 0=disable
+ * 1=enable.
+ */
+static void cpb_toggle(bool t)
+{
+       if (!cpb_capable)
+               return;
+
+       if (t && !cpb_enabled) {
+               cpb_enabled = true;
+               _cpb_toggle_msrs(t);
+               printk(KERN_INFO PFX "Core Boosting enabled.\n");
+       } else if (!t && cpb_enabled) {
+               cpb_enabled = false;
+               _cpb_toggle_msrs(t);
+               printk(KERN_INFO PFX "Core Boosting disabled.\n");
+       }
+}
+
+static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
+                                size_t count)
+{
+       int ret = -EINVAL;
+       unsigned long val = 0;
+
+       ret = strict_strtoul(buf, 10, &val);
+       if (!ret && (val == 0 || val == 1) && cpb_capable)
+               cpb_toggle(val);
+       else
+               return -EINVAL;
+
+       return count;
+}
+
+static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
+{
+       return sprintf(buf, "%u\n", cpb_enabled);
+}
+
+#define define_one_rw(_name) \
+static struct freq_attr _name = \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+define_one_rw(cpb);
+
 static struct freq_attr *powernow_k8_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
+       &cpb,
        NULL,
 };
 
@@ -1410,10 +1491,51 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
        .attr           = powernow_k8_attr,
 };
 
+/*
+ * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
+ * cannot block the remaining ones from boosting. On the CPU_UP path we
+ * simply keep the boost-disable flag in sync with the current global
+ * state.
+ */
+static int __cpuinit cpb_notify(struct notifier_block *nb, unsigned long action,
+                               void *hcpu)
+{
+       unsigned cpu = (long)hcpu;
+       u32 lo, hi;
+
+       switch (action) {
+       case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
+
+               if (!cpb_enabled) {
+                       rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+                       lo |= BIT(25);
+                       wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
+               }
+               break;
+
+       case CPU_DOWN_PREPARE:
+       case CPU_DOWN_PREPARE_FROZEN:
+               rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+               lo &= ~BIT(25);
+               wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
+               break;
+
+       default:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata cpb_nb = {
+       .notifier_call          = cpb_notify,
+};
+
 /* driver entry point for init */
 static int __cpuinit powernowk8_init(void)
 {
-       unsigned int i, supported_cpus = 0;
+       unsigned int i, supported_cpus = 0, cpu;
 
        for_each_online_cpu(i) {
                int rc;
@@ -1422,15 +1544,36 @@ static int __cpuinit powernowk8_init(void)
                        supported_cpus++;
        }
 
-       if (supported_cpus == num_online_cpus()) {
-               printk(KERN_INFO PFX "Found %d %s "
-                       "processors (%d cpu cores) (" VERSION ")\n",
-                       num_online_nodes(),
-                       boot_cpu_data.x86_model_id, supported_cpus);
-               return cpufreq_register_driver(&cpufreq_amd64_driver);
+       if (supported_cpus != num_online_cpus())
+               return -ENODEV;
+
+       printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
+               num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
+
+       if (boot_cpu_has(X86_FEATURE_CPB)) {
+
+               cpb_capable = true;
+
+               register_cpu_notifier(&cpb_nb);
+
+               msrs = msrs_alloc();
+               if (!msrs) {
+                       printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
+                       return -ENOMEM;
+               }
+
+               rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+               for_each_cpu(cpu, cpu_online_mask) {
+                       struct msr *reg = per_cpu_ptr(msrs, cpu);
+                       cpb_enabled |= !(!!(reg->l & BIT(25)));
+               }
+
+               printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
+                       (cpb_enabled ? "on" : "off"));
        }
 
-       return -ENODEV;
+       return cpufreq_register_driver(&cpufreq_amd64_driver);
 }
 
 /* driver entry point for term */
@@ -1438,6 +1581,13 @@ static void __exit powernowk8_exit(void)
 {
        dprintk("exit\n");
 
+       if (boot_cpu_has(X86_FEATURE_CPB)) {
+               msrs_free(msrs);
+               msrs = NULL;
+
+               unregister_cpu_notifier(&cpb_nb);
+       }
+
        cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
index 02ce824..df3529b 100644 (file)
@@ -5,7 +5,6 @@
  *  http://www.gnu.org/licenses/gpl.html
  */
 
-
 enum pstate {
        HW_PSTATE_INVALID = 0xff,
        HW_PSTATE_0 = 0,
@@ -55,7 +54,6 @@ struct powernow_k8_data {
        struct cpumask *available_cores;
 };
 
-
 /* processor's cpuid instruction support */
 #define CPUID_PROCESSOR_SIGNATURE      1       /* function 1 */
 #define CPUID_XFAM                     0x0ff00000      /* extended family */
index 08be922..dd531cc 100644 (file)
  *
  */
 
+#include <linux/module.h>
 #include <asm/processor.h>
-#include <asm/vmware.h>
 #include <asm/hypervisor.h>
 
-static inline void __cpuinit
-detect_hypervisor_vendor(struct cpuinfo_x86 *c)
+/*
+ * Hypervisor detect order.  This is specified explicitly here because
+ * some hypervisors might implement compatibility modes for other
+ * hypervisors and therefore need to be detected in specific sequence.
+ */
+static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
-       if (vmware_platform())
-               c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
-       else
-               c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
-}
+       &x86_hyper_vmware,
+       &x86_hyper_ms_hyperv,
+};
 
-static inline void __cpuinit
-hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
+const struct hypervisor_x86 *x86_hyper;
+EXPORT_SYMBOL(x86_hyper);
+
+static inline void __init
+detect_hypervisor_vendor(void)
 {
-       if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) {
-               vmware_set_feature_bits(c);
-               return;
+       const struct hypervisor_x86 *h, * const *p;
+
+       for (p = hypervisors; p < hypervisors + ARRAY_SIZE(hypervisors); p++) {
+               h = *p;
+               if (h->detect()) {
+                       x86_hyper = h;
+                       printk(KERN_INFO "Hypervisor detected: %s\n", h->name);
+                       break;
+               }
        }
 }
 
 void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
 {
-       detect_hypervisor_vendor(c);
-       hypervisor_set_feature_bits(c);
+       if (x86_hyper && x86_hyper->set_cpu_features)
+               x86_hyper->set_cpu_features(c);
 }
 
 void __init init_hypervisor_platform(void)
 {
+
+       detect_hypervisor_vendor();
+
+       if (!x86_hyper)
+               return;
+
        init_hypervisor(&boot_cpu_data);
-       if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
-               vmware_platform_setup();
+
+       if (x86_hyper->init_platform)
+               x86_hyper->init_platform();
 }
index 7e1cca1..85f69cd 100644 (file)
@@ -12,7 +12,6 @@
 #include <asm/processor.h>
 #include <asm/pgtable.h>
 #include <asm/msr.h>
-#include <asm/ds.h>
 #include <asm/bugs.h>
 #include <asm/cpu.h>
 
@@ -47,6 +46,27 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
                (c->x86 == 0x6 && c->x86_model >= 0x0e))
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
 
+       /*
+        * Atom erratum AAE44/AAF40/AAG38/AAH41:
+        *
+        * A race condition between speculative fetches and invalidating
+        * a large page.  This is worked around in microcode, but we
+        * need the microcode to have already been loaded... so if it is
+        * not, recommend a BIOS update and disable large pages.
+        */
+       if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_mask <= 2) {
+               u32 ucode, junk;
+
+               wrmsr(MSR_IA32_UCODE_REV, 0, 0);
+               sync_core();
+               rdmsr(MSR_IA32_UCODE_REV, junk, ucode);
+
+               if (ucode < 0x20e) {
+                       printk(KERN_WARNING "Atom PSE erratum detected, BIOS microcode update recommended\n");
+                       clear_cpu_cap(c, X86_FEATURE_PSE);
+               }
+       }
+
 #ifdef CONFIG_X86_64
        set_cpu_cap(c, X86_FEATURE_SYSENTER32);
 #else
@@ -352,12 +372,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
        }
 
-       if (c->cpuid_level > 6) {
-               unsigned ecx = cpuid_ecx(6);
-               if (ecx & 0x01)
-                       set_cpu_cap(c, X86_FEATURE_APERFMPERF);
-       }
-
        if (cpu_has_xmm2)
                set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
        if (cpu_has_ds) {
@@ -367,7 +381,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_BTS);
                if (!(l1 & (1<<12)))
                        set_cpu_cap(c, X86_FEATURE_PEBS);
-               ds_init_intel(c);
        }
 
        if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush)
index b3eeb66..33eae20 100644 (file)
@@ -148,13 +148,19 @@ union _cpuid4_leaf_ecx {
        u32 full;
 };
 
+struct amd_l3_cache {
+       struct   pci_dev *dev;
+       bool     can_disable;
+       unsigned indices;
+       u8       subcaches[4];
+};
+
 struct _cpuid4_info {
        union _cpuid4_leaf_eax eax;
        union _cpuid4_leaf_ebx ebx;
        union _cpuid4_leaf_ecx ecx;
        unsigned long size;
-       bool can_disable;
-       unsigned int l3_indices;
+       struct amd_l3_cache *l3;
        DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
 };
 
@@ -164,8 +170,7 @@ struct _cpuid4_info_regs {
        union _cpuid4_leaf_ebx ebx;
        union _cpuid4_leaf_ecx ecx;
        unsigned long size;
-       bool can_disable;
-       unsigned int l3_indices;
+       struct amd_l3_cache *l3;
 };
 
 unsigned short                 num_cache_leaves;
@@ -302,87 +307,163 @@ struct _cache_attr {
 };
 
 #ifdef CONFIG_CPU_SUP_AMD
-static unsigned int __cpuinit amd_calc_l3_indices(void)
+
+/*
+ * L3 cache descriptors
+ */
+static struct amd_l3_cache **__cpuinitdata l3_caches;
+
+static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
 {
-       /*
-        * We're called over smp_call_function_single() and therefore
-        * are on the correct cpu.
-        */
-       int cpu = smp_processor_id();
-       int node = cpu_to_node(cpu);
-       struct pci_dev *dev = node_to_k8_nb_misc(node);
        unsigned int sc0, sc1, sc2, sc3;
        u32 val = 0;
 
-       pci_read_config_dword(dev, 0x1C4, &val);
+       pci_read_config_dword(l3->dev, 0x1C4, &val);
 
        /* calculate subcache sizes */
-       sc0 = !(val & BIT(0));
-       sc1 = !(val & BIT(4));
-       sc2 = !(val & BIT(8))  + !(val & BIT(9));
-       sc3 = !(val & BIT(12)) + !(val & BIT(13));
+       l3->subcaches[0] = sc0 = !(val & BIT(0));
+       l3->subcaches[1] = sc1 = !(val & BIT(4));
+       l3->subcaches[2] = sc2 = !(val & BIT(8))  + !(val & BIT(9));
+       l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
 
-       return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+       l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+}
+
+static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
+{
+       struct amd_l3_cache *l3;
+       struct pci_dev *dev = node_to_k8_nb_misc(node);
+
+       l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC);
+       if (!l3) {
+               printk(KERN_WARNING "Error allocating L3 struct\n");
+               return NULL;
+       }
+
+       l3->dev = dev;
+
+       amd_calc_l3_indices(l3);
+
+       return l3;
 }
 
 static void __cpuinit
 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 {
-       if (index < 3)
+       int node;
+
+       if (boot_cpu_data.x86 != 0x10)
                return;
 
-       if (boot_cpu_data.x86 == 0x11)
+       if (index < 3)
                return;
 
        /* see errata #382 and #388 */
-       if ((boot_cpu_data.x86 == 0x10) &&
-           ((boot_cpu_data.x86_model < 0x8) ||
-            (boot_cpu_data.x86_mask  < 0x1)))
+       if (boot_cpu_data.x86_model < 0x8)
+               return;
+
+       if ((boot_cpu_data.x86_model == 0x8 ||
+            boot_cpu_data.x86_model == 0x9)
+               &&
+            boot_cpu_data.x86_mask < 0x1)
+                       return;
+
+       /* not in virtualized environments */
+       if (num_k8_northbridges == 0)
                return;
 
-       this_leaf->can_disable = true;
-       this_leaf->l3_indices  = amd_calc_l3_indices();
+       /*
+        * Strictly speaking, the amount in @size below is leaked since it is
+        * never freed but this is done only on shutdown so it doesn't matter.
+        */
+       if (!l3_caches) {
+               int size = num_k8_northbridges * sizeof(struct amd_l3_cache *);
+
+               l3_caches = kzalloc(size, GFP_ATOMIC);
+               if (!l3_caches)
+                       return;
+       }
+
+       node = amd_get_nb_id(smp_processor_id());
+
+       if (!l3_caches[node]) {
+               l3_caches[node] = amd_init_l3_cache(node);
+               l3_caches[node]->can_disable = true;
+       }
+
+       WARN_ON(!l3_caches[node]);
+
+       this_leaf->l3 = l3_caches[node];
 }
 
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
-                                 unsigned int index)
+                                 unsigned int slot)
 {
-       int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-       int node = amd_get_nb_id(cpu);
-       struct pci_dev *dev = node_to_k8_nb_misc(node);
+       struct pci_dev *dev = this_leaf->l3->dev;
        unsigned int reg = 0;
 
-       if (!this_leaf->can_disable)
+       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
        if (!dev)
                return -EINVAL;
 
-       pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
+       pci_read_config_dword(dev, 0x1BC + slot * 4, &reg);
        return sprintf(buf, "0x%08x\n", reg);
 }
 
-#define SHOW_CACHE_DISABLE(index)                                      \
+#define SHOW_CACHE_DISABLE(slot)                                       \
 static ssize_t                                                         \
-show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf)  \
+show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf)   \
 {                                                                      \
-       return show_cache_disable(this_leaf, buf, index);               \
+       return show_cache_disable(this_leaf, buf, slot);                \
 }
 SHOW_CACHE_DISABLE(0)
 SHOW_CACHE_DISABLE(1)
 
+static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
+                                unsigned slot, unsigned long idx)
+{
+       int i;
+
+       idx |= BIT(30);
+
+       /*
+        *  disable index in all 4 subcaches
+        */
+       for (i = 0; i < 4; i++) {
+               u32 reg = idx | (i << 20);
+
+               if (!l3->subcaches[i])
+                       continue;
+
+               pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
+
+               /*
+                * We need to WBINVD on a core on the node containing the L3
+                * cache which indices we disable therefore a simple wbinvd()
+                * is not sufficient.
+                */
+               wbinvd_on_cpu(cpu);
+
+               reg |= BIT(31);
+               pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
+       }
+}
+
+
 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
-       const char *buf, size_t count, unsigned int index)
+                                  const char *buf, size_t count,
+                                  unsigned int slot)
 {
+       struct pci_dev *dev = this_leaf->l3->dev;
        int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-       int node = amd_get_nb_id(cpu);
-       struct pci_dev *dev = node_to_k8_nb_misc(node);
        unsigned long val = 0;
 
 #define SUBCACHE_MASK  (3UL << 20)
 #define SUBCACHE_INDEX 0xfff
 
-       if (!this_leaf->can_disable)
+       if (!this_leaf->l3 || !this_leaf->l3->can_disable)
                return -EINVAL;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -396,26 +477,20 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
 
        /* do not allow writes outside of allowed bits */
        if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
-           ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
+           ((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
                return -EINVAL;
 
-       val |= BIT(30);
-       pci_write_config_dword(dev, 0x1BC + index * 4, val);
-       /*
-        * We need to WBINVD on a core on the node containing the L3 cache which
-        * indices we disable therefore a simple wbinvd() is not sufficient.
-        */
-       wbinvd_on_cpu(cpu);
-       pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
+       amd_l3_disable_index(this_leaf->l3, cpu, slot, val);
+
        return count;
 }
 
-#define STORE_CACHE_DISABLE(index)                                     \
+#define STORE_CACHE_DISABLE(slot)                                      \
 static ssize_t                                                         \
-store_cache_disable_##index(struct _cpuid4_info *this_leaf,            \
+store_cache_disable_##slot(struct _cpuid4_info *this_leaf,             \
                            const char *buf, size_t count)              \
 {                                                                      \
-       return store_cache_disable(this_leaf, buf, count, index);       \
+       return store_cache_disable(this_leaf, buf, count, slot);        \
 }
 STORE_CACHE_DISABLE(0)
 STORE_CACHE_DISABLE(1)
@@ -443,8 +518,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
 
        if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
                amd_cpuid4(index, &eax, &ebx, &ecx);
-               if (boot_cpu_data.x86 >= 0x10)
-                       amd_check_l3_disable(index, this_leaf);
+               amd_check_l3_disable(index, this_leaf);
        } else {
                cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
        }
@@ -701,6 +775,7 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
        for (i = 0; i < num_cache_leaves; i++)
                cache_remove_shared_cpu_map(cpu, i);
 
+       kfree(per_cpu(ici_cpuid4_info, cpu)->l3);
        kfree(per_cpu(ici_cpuid4_info, cpu));
        per_cpu(ici_cpuid4_info, cpu) = NULL;
 }
@@ -985,7 +1060,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 
                this_leaf = CPUID4_INFO_IDX(cpu, i);
 
-               if (this_leaf->can_disable)
+               if (this_leaf->l3 && this_leaf->l3->can_disable)
                        ktype_cache.default_attrs = default_l3_attrs;
                else
                        ktype_cache.default_attrs = default_attrs;
index 8a6f0af..7a355dd 100644 (file)
@@ -539,7 +539,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
        struct mce m;
        int i;
 
-       __get_cpu_var(mce_poll_count)++;
+       percpu_inc(mce_poll_count);
 
        mce_setup(&m);
 
@@ -934,7 +934,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 
        atomic_inc(&mce_entry);
 
-       __get_cpu_var(mce_exception_count)++;
+       percpu_inc(mce_exception_count);
 
        if (notify_die(DIE_NMI, "machine check", regs, error_code,
                           18, SIGKILL) == NOTIFY_STOP)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
new file mode 100644 (file)
index 0000000..16f41bb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * HyperV  Detection code.
+ *
+ * Copyright (C) 2010, Novell, Inc.
+ * Author : K. Y. Srinivasan <ksrinivasan@novell.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; version 2 of the License.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+#include <asm/hypervisor.h>
+#include <asm/hyperv.h>
+#include <asm/mshyperv.h>
+
+struct ms_hyperv_info ms_hyperv;
+
+static bool __init ms_hyperv_platform(void)
+{
+       u32 eax;
+       u32 hyp_signature[3];
+
+       if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
+               return false;
+
+       cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS,
+             &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]);
+
+       return eax >= HYPERV_CPUID_MIN &&
+               eax <= HYPERV_CPUID_MAX &&
+               !memcmp("Microsoft Hv", hyp_signature, 12);
+}
+
+static void __init ms_hyperv_init_platform(void)
+{
+       /*
+        * Extract the features and hints
+        */
+       ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES);
+       ms_hyperv.hints    = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO);
+
+       printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n",
+              ms_hyperv.features, ms_hyperv.hints);
+}
+
+const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
+       .name                   = "Microsoft HyperV",
+       .detect                 = ms_hyperv_platform,
+       .init_platform          = ms_hyperv_init_platform,
+};
+EXPORT_SYMBOL(x86_hyper_ms_hyperv);
index db5bdc8..fd4db0d 100644 (file)
 #include <asm/nmi.h>
 #include <asm/compat.h>
 
-static u64 perf_event_mask __read_mostly;
+#if 0
+#undef wrmsrl
+#define wrmsrl(msr, val)                                       \
+do {                                                           \
+       trace_printk("wrmsrl(%lx, %lx)\n", (unsigned long)(msr),\
+                       (unsigned long)(val));                  \
+       native_write_msr((msr), (u32)((u64)(val)),              \
+                       (u32)((u64)(val) >> 32));               \
+} while (0)
+#endif
 
-/* The maximal number of PEBS events: */
-#define MAX_PEBS_EVENTS        4
+/*
+ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
+ */
+static unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+       unsigned long offset, addr = (unsigned long)from;
+       int type = in_nmi() ? KM_NMI : KM_IRQ0;
+       unsigned long size, len = 0;
+       struct page *page;
+       void *map;
+       int ret;
 
-/* The size of a BTS record in bytes: */
-#define BTS_RECORD_SIZE                24
+       do {
+               ret = __get_user_pages_fast(addr, 1, 0, &page);
+               if (!ret)
+                       break;
 
-/* The size of a per-cpu BTS buffer in bytes: */
-#define BTS_BUFFER_SIZE                (BTS_RECORD_SIZE * 2048)
+               offset = addr & (PAGE_SIZE - 1);
+               size = min(PAGE_SIZE - offset, n - len);
 
-/* The BTS overflow threshold in bytes from the end of the buffer: */
-#define BTS_OVFL_TH            (BTS_RECORD_SIZE * 128)
+               map = kmap_atomic(page, type);
+               memcpy(to, map+offset, size);
+               kunmap_atomic(map, type);
+               put_page(page);
 
+               len  += size;
+               to   += size;
+               addr += size;
 
-/*
- * Bits in the debugctlmsr controlling branch tracing.
- */
-#define X86_DEBUGCTL_TR                        (1 << 6)
-#define X86_DEBUGCTL_BTS               (1 << 7)
-#define X86_DEBUGCTL_BTINT             (1 << 8)
-#define X86_DEBUGCTL_BTS_OFF_OS                (1 << 9)
-#define X86_DEBUGCTL_BTS_OFF_USR       (1 << 10)
+       } while (len < n);
 
-/*
- * A debug store configuration.
- *
- * We only support architectures that use 64bit fields.
- */
-struct debug_store {
-       u64     bts_buffer_base;
-       u64     bts_index;
-       u64     bts_absolute_maximum;
-       u64     bts_interrupt_threshold;
-       u64     pebs_buffer_base;
-       u64     pebs_index;
-       u64     pebs_absolute_maximum;
-       u64     pebs_interrupt_threshold;
-       u64     pebs_event_reset[MAX_PEBS_EVENTS];
-};
+       return len;
+}
 
 struct event_constraint {
        union {
@@ -89,18 +94,41 @@ struct amd_nb {
        struct event_constraint event_constraints[X86_PMC_IDX_MAX];
 };
 
+#define MAX_LBR_ENTRIES                16
+
 struct cpu_hw_events {
+       /*
+        * Generic x86 PMC bits
+        */
        struct perf_event       *events[X86_PMC_IDX_MAX]; /* in counter order */
        unsigned long           active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-       unsigned long           interrupts;
        int                     enabled;
-       struct debug_store      *ds;
 
        int                     n_events;
        int                     n_added;
        int                     assign[X86_PMC_IDX_MAX]; /* event to counter assignment */
        u64                     tags[X86_PMC_IDX_MAX];
        struct perf_event       *event_list[X86_PMC_IDX_MAX]; /* in enabled order */
+
+       unsigned int            group_flag;
+
+       /*
+        * Intel DebugStore bits
+        */
+       struct debug_store      *ds;
+       u64                     pebs_enabled;
+
+       /*
+        * Intel LBR bits
+        */
+       int                             lbr_users;
+       void                            *lbr_context;
+       struct perf_branch_stack        lbr_stack;
+       struct perf_branch_entry        lbr_entries[MAX_LBR_ENTRIES];
+
+       /*
+        * AMD specific bits
+        */
        struct amd_nb           *amd_nb;
 };
 
@@ -114,44 +142,75 @@ struct cpu_hw_events {
 #define EVENT_CONSTRAINT(c, n, m)      \
        __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n))
 
+/*
+ * Constraint on the Event code.
+ */
 #define INTEL_EVENT_CONSTRAINT(c, n)   \
-       EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVTSEL_MASK)
+       EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)
 
+/*
+ * Constraint on the Event code + UMask + fixed-mask
+ *
+ * filter mask to validate fixed counter events.
+ * the following filters disqualify for fixed counters:
+ *  - inv
+ *  - edge
+ *  - cnt-mask
+ *  The other filters are supported by fixed counters.
+ *  The any-thread option is supported starting with v3.
+ */
 #define FIXED_EVENT_CONSTRAINT(c, n)   \
-       EVENT_CONSTRAINT(c, (1ULL << (32+n)), INTEL_ARCH_FIXED_MASK)
+       EVENT_CONSTRAINT(c, (1ULL << (32+n)), X86_RAW_EVENT_MASK)
+
+/*
+ * Constraint on the Event code + UMask
+ */
+#define PEBS_EVENT_CONSTRAINT(c, n)    \
+       EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
 
 #define EVENT_CONSTRAINT_END           \
        EVENT_CONSTRAINT(0, 0, 0)
 
 #define for_each_event_constraint(e, c)        \
-       for ((e) = (c); (e)->cmask; (e)++)
+       for ((e) = (c); (e)->weight; (e)++)
+
+union perf_capabilities {
+       struct {
+               u64     lbr_format    : 6;
+               u64     pebs_trap     : 1;
+               u64     pebs_arch_reg : 1;
+               u64     pebs_format   : 4;
+               u64     smm_freeze    : 1;
+       };
+       u64     capabilities;
+};
 
 /*
  * struct x86_pmu - generic x86 pmu
  */
 struct x86_pmu {
+       /*
+        * Generic x86 PMC bits
+        */
        const char      *name;
        int             version;
        int             (*handle_irq)(struct pt_regs *);
        void            (*disable_all)(void);
-       void            (*enable_all)(void);
+       void            (*enable_all)(int added);
        void            (*enable)(struct perf_event *);
        void            (*disable)(struct perf_event *);
+       int             (*hw_config)(struct perf_event *event);
+       int             (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
        unsigned        eventsel;
        unsigned        perfctr;
        u64             (*event_map)(int);
-       u64             (*raw_event)(u64);
        int             max_events;
-       int             num_events;
-       int             num_events_fixed;
-       int             event_bits;
-       u64             event_mask;
+       int             num_counters;
+       int             num_counters_fixed;
+       int             cntval_bits;
+       u64             cntval_mask;
        int             apic;
        u64             max_period;
-       u64             intel_ctrl;
-       void            (*enable_bts)(u64 config);
-       void            (*disable_bts)(void);
-
        struct event_constraint *
                        (*get_event_constraints)(struct cpu_hw_events *cpuc,
                                                 struct perf_event *event);
@@ -159,11 +218,32 @@ struct x86_pmu {
        void            (*put_event_constraints)(struct cpu_hw_events *cpuc,
                                                 struct perf_event *event);
        struct event_constraint *event_constraints;
+       void            (*quirks)(void);
 
        int             (*cpu_prepare)(int cpu);
        void            (*cpu_starting)(int cpu);
        void            (*cpu_dying)(int cpu);
        void            (*cpu_dead)(int cpu);
+
+       /*
+        * Intel Arch Perfmon v2+
+        */
+       u64                     intel_ctrl;
+       union perf_capabilities intel_cap;
+
+       /*
+        * Intel DebugStore bits
+        */
+       int             bts, pebs;
+       int             pebs_record_size;
+       void            (*drain_pebs)(struct pt_regs *regs);
+       struct event_constraint *pebs_constraints;
+
+       /*
+        * Intel LBR
+        */
+       unsigned long   lbr_tos, lbr_from, lbr_to; /* MSR base regs       */
+       int             lbr_nr;                    /* hardware stack size */
 };
 
 static struct x86_pmu x86_pmu __read_mostly;
@@ -198,7 +278,7 @@ static u64
 x86_perf_event_update(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
-       int shift = 64 - x86_pmu.event_bits;
+       int shift = 64 - x86_pmu.cntval_bits;
        u64 prev_raw_count, new_raw_count;
        int idx = hwc->idx;
        s64 delta;
@@ -241,33 +321,32 @@ again:
 static atomic_t active_events;
 static DEFINE_MUTEX(pmc_reserve_mutex);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+
 static bool reserve_pmc_hardware(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        int i;
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
                disable_lapic_nmi_watchdog();
 
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                if (!reserve_perfctr_nmi(x86_pmu.perfctr + i))
                        goto perfctr_fail;
        }
 
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
                        goto eventsel_fail;
        }
-#endif
 
        return true;
 
-#ifdef CONFIG_X86_LOCAL_APIC
 eventsel_fail:
        for (i--; i >= 0; i--)
                release_evntsel_nmi(x86_pmu.eventsel + i);
 
-       i = x86_pmu.num_events;
+       i = x86_pmu.num_counters;
 
 perfctr_fail:
        for (i--; i >= 0; i--)
@@ -277,128 +356,36 @@ perfctr_fail:
                enable_lapic_nmi_watchdog();
 
        return false;
-#endif
 }
 
 static void release_pmc_hardware(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        int i;
 
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                release_perfctr_nmi(x86_pmu.perfctr + i);
                release_evntsel_nmi(x86_pmu.eventsel + i);
        }
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
                enable_lapic_nmi_watchdog();
-#endif
-}
-
-static inline bool bts_available(void)
-{
-       return x86_pmu.enable_bts != NULL;
 }
 
-static void init_debug_store_on_cpu(int cpu)
-{
-       struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-       if (!ds)
-               return;
-
-       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
-                    (u32)((u64)(unsigned long)ds),
-                    (u32)((u64)(unsigned long)ds >> 32));
-}
-
-static void fini_debug_store_on_cpu(int cpu)
-{
-       if (!per_cpu(cpu_hw_events, cpu).ds)
-               return;
-
-       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
-}
-
-static void release_bts_hardware(void)
-{
-       int cpu;
-
-       if (!bts_available())
-               return;
-
-       get_online_cpus();
-
-       for_each_online_cpu(cpu)
-               fini_debug_store_on_cpu(cpu);
-
-       for_each_possible_cpu(cpu) {
-               struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
-
-               if (!ds)
-                       continue;
-
-               per_cpu(cpu_hw_events, cpu).ds = NULL;
-
-               kfree((void *)(unsigned long)ds->bts_buffer_base);
-               kfree(ds);
-       }
-
-       put_online_cpus();
-}
-
-static int reserve_bts_hardware(void)
-{
-       int cpu, err = 0;
-
-       if (!bts_available())
-               return 0;
-
-       get_online_cpus();
-
-       for_each_possible_cpu(cpu) {
-               struct debug_store *ds;
-               void *buffer;
-
-               err = -ENOMEM;
-               buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
-               if (unlikely(!buffer))
-                       break;
-
-               ds = kzalloc(sizeof(*ds), GFP_KERNEL);
-               if (unlikely(!ds)) {
-                       kfree(buffer);
-                       break;
-               }
-
-               ds->bts_buffer_base = (u64)(unsigned long)buffer;
-               ds->bts_index = ds->bts_buffer_base;
-               ds->bts_absolute_maximum =
-                       ds->bts_buffer_base + BTS_BUFFER_SIZE;
-               ds->bts_interrupt_threshold =
-                       ds->bts_absolute_maximum - BTS_OVFL_TH;
-
-               per_cpu(cpu_hw_events, cpu).ds = ds;
-               err = 0;
-       }
+#else
 
-       if (err)
-               release_bts_hardware();
-       else {
-               for_each_online_cpu(cpu)
-                       init_debug_store_on_cpu(cpu);
-       }
+static bool reserve_pmc_hardware(void) { return true; }
+static void release_pmc_hardware(void) {}
 
-       put_online_cpus();
+#endif
 
-       return err;
-}
+static int reserve_ds_buffers(void);
+static void release_ds_buffers(void);
 
 static void hw_perf_event_destroy(struct perf_event *event)
 {
        if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
                release_pmc_hardware();
-               release_bts_hardware();
+               release_ds_buffers();
                mutex_unlock(&pmc_reserve_mutex);
        }
 }
@@ -441,54 +428,11 @@ set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr)
        return 0;
 }
 
-/*
- * Setup the hardware configuration for a given attr_type
- */
-static int __hw_perf_event_init(struct perf_event *event)
+static int x86_setup_perfctr(struct perf_event *event)
 {
        struct perf_event_attr *attr = &event->attr;
        struct hw_perf_event *hwc = &event->hw;
        u64 config;
-       int err;
-
-       if (!x86_pmu_initialized())
-               return -ENODEV;
-
-       err = 0;
-       if (!atomic_inc_not_zero(&active_events)) {
-               mutex_lock(&pmc_reserve_mutex);
-               if (atomic_read(&active_events) == 0) {
-                       if (!reserve_pmc_hardware())
-                               err = -EBUSY;
-                       else
-                               err = reserve_bts_hardware();
-               }
-               if (!err)
-                       atomic_inc(&active_events);
-               mutex_unlock(&pmc_reserve_mutex);
-       }
-       if (err)
-               return err;
-
-       event->destroy = hw_perf_event_destroy;
-
-       /*
-        * Generate PMC IRQs:
-        * (keep 'enabled' bit clear for now)
-        */
-       hwc->config = ARCH_PERFMON_EVENTSEL_INT;
-
-       hwc->idx = -1;
-       hwc->last_cpu = -1;
-       hwc->last_tag = ~0ULL;
-
-       /*
-        * Count user and OS events unless requested not to.
-        */
-       if (!attr->exclude_user)
-               hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
-       if (!attr->exclude_kernel)
-               hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
 
        if (!hwc->sample_period) {
                hwc->sample_period = x86_pmu.max_period;
@@ -505,16 +449,8 @@ static int __hw_perf_event_init(struct perf_event *event)
                        return -EOPNOTSUPP;
        }
 
-       /*
-        * Raw hw_event type provide the config in the hw_event structure
-        */
-       if (attr->type == PERF_TYPE_RAW) {
-               hwc->config |= x86_pmu.raw_event(attr->config);
-               if ((hwc->config & ARCH_PERFMON_EVENTSEL_ANY) &&
-                   perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
-                       return -EACCES;
+       if (attr->type == PERF_TYPE_RAW)
                return 0;
-       }
 
        if (attr->type == PERF_TYPE_HW_CACHE)
                return set_ext_hw_attr(hwc, attr);
@@ -539,11 +475,11 @@ static int __hw_perf_event_init(struct perf_event *event)
        if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
            (hwc->sample_period == 1)) {
                /* BTS is not supported by this architecture. */
-               if (!bts_available())
+               if (!x86_pmu.bts)
                        return -EOPNOTSUPP;
 
                /* BTS is currently only allowed for user-mode. */
-               if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+               if (!attr->exclude_kernel)
                        return -EOPNOTSUPP;
        }
 
@@ -552,12 +488,87 @@ static int __hw_perf_event_init(struct perf_event *event)
        return 0;
 }
 
+static int x86_pmu_hw_config(struct perf_event *event)
+{
+       if (event->attr.precise_ip) {
+               int precise = 0;
+
+               /* Support for constant skid */
+               if (x86_pmu.pebs)
+                       precise++;
+
+               /* Support for IP fixup */
+               if (x86_pmu.lbr_nr)
+                       precise++;
+
+               if (event->attr.precise_ip > precise)
+                       return -EOPNOTSUPP;
+       }
+
+       /*
+        * Generate PMC IRQs:
+        * (keep 'enabled' bit clear for now)
+        */
+       event->hw.config = ARCH_PERFMON_EVENTSEL_INT;
+
+       /*
+        * Count user and OS events unless requested not to
+        */
+       if (!event->attr.exclude_user)
+               event->hw.config |= ARCH_PERFMON_EVENTSEL_USR;
+       if (!event->attr.exclude_kernel)
+               event->hw.config |= ARCH_PERFMON_EVENTSEL_OS;
+
+       if (event->attr.type == PERF_TYPE_RAW)
+               event->hw.config |= event->attr.config & X86_RAW_EVENT_MASK;
+
+       return x86_setup_perfctr(event);
+}
+
+/*
+ * Setup the hardware configuration for a given attr_type
+ */
+static int __hw_perf_event_init(struct perf_event *event)
+{
+       int err;
+
+       if (!x86_pmu_initialized())
+               return -ENODEV;
+
+       err = 0;
+       if (!atomic_inc_not_zero(&active_events)) {
+               mutex_lock(&pmc_reserve_mutex);
+               if (atomic_read(&active_events) == 0) {
+                       if (!reserve_pmc_hardware())
+                               err = -EBUSY;
+                       else {
+                               err = reserve_ds_buffers();
+                               if (err)
+                                       release_pmc_hardware();
+                       }
+               }
+               if (!err)
+                       atomic_inc(&active_events);
+               mutex_unlock(&pmc_reserve_mutex);
+       }
+       if (err)
+               return err;
+
+       event->destroy = hw_perf_event_destroy;
+
+       event->hw.idx = -1;
+       event->hw.last_cpu = -1;
+       event->hw.last_tag = ~0ULL;
+
+       return x86_pmu.hw_config(event);
+}
+
 static void x86_pmu_disable_all(void)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        int idx;
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                u64 val;
 
                if (!test_bit(idx, cpuc->active_mask))
@@ -587,12 +598,12 @@ void hw_perf_disable(void)
        x86_pmu.disable_all();
 }
 
-static void x86_pmu_enable_all(void)
+static void x86_pmu_enable_all(int added)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        int idx;
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                struct perf_event *event = cpuc->events[idx];
                u64 val;
 
@@ -667,14 +678,14 @@ static int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
         * assign events to counters starting with most
         * constrained events.
         */
-       wmax = x86_pmu.num_events;
+       wmax = x86_pmu.num_counters;
 
        /*
         * when fixed event counters are present,
         * wmax is incremented by 1 to account
         * for one more choice
         */
-       if (x86_pmu.num_events_fixed)
+       if (x86_pmu.num_counters_fixed)
                wmax++;
 
        for (w = 1, num = n; num && w <= wmax; w++) {
@@ -724,7 +735,7 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader,
        struct perf_event *event;
        int n, max_count;
 
-       max_count = x86_pmu.num_events + x86_pmu.num_events_fixed;
+       max_count = x86_pmu.num_counters + x86_pmu.num_counters_fixed;
 
        /* current number of events already accepted */
        n = cpuc->n_events;
@@ -795,7 +806,7 @@ void hw_perf_enable(void)
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        struct perf_event *event;
        struct hw_perf_event *hwc;
-       int i;
+       int i, added = cpuc->n_added;
 
        if (!x86_pmu_initialized())
                return;
@@ -847,19 +858,20 @@ void hw_perf_enable(void)
        cpuc->enabled = 1;
        barrier();
 
-       x86_pmu.enable_all();
+       x86_pmu.enable_all(added);
 }
 
-static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc)
+static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
+                                         u64 enable_mask)
 {
-       (void)checking_wrmsrl(hwc->config_base + hwc->idx,
-                             hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE);
+       wrmsrl(hwc->config_base + hwc->idx, hwc->config | enable_mask);
 }
 
 static inline void x86_pmu_disable_event(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
-       (void)checking_wrmsrl(hwc->config_base + hwc->idx, hwc->config);
+
+       wrmsrl(hwc->config_base + hwc->idx, hwc->config);
 }
 
 static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
@@ -874,7 +886,7 @@ x86_perf_event_set_period(struct perf_event *event)
        struct hw_perf_event *hwc = &event->hw;
        s64 left = atomic64_read(&hwc->period_left);
        s64 period = hwc->sample_period;
-       int err, ret = 0, idx = hwc->idx;
+       int ret = 0, idx = hwc->idx;
 
        if (idx == X86_PMC_IDX_FIXED_BTS)
                return 0;
@@ -912,8 +924,8 @@ x86_perf_event_set_period(struct perf_event *event)
         */
        atomic64_set(&hwc->prev_count, (u64)-left);
 
-       err = checking_wrmsrl(hwc->event_base + idx,
-                            (u64)(-left) & x86_pmu.event_mask);
+       wrmsrl(hwc->event_base + idx,
+                       (u64)(-left) & x86_pmu.cntval_mask);
 
        perf_event_update_userpage(event);
 
@@ -924,7 +936,8 @@ static void x86_pmu_enable_event(struct perf_event *event)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
        if (cpuc->enabled)
-               __x86_pmu_enable_event(&event->hw);
+               __x86_pmu_enable_event(&event->hw,
+                                      ARCH_PERFMON_EVENTSEL_ENABLE);
 }
 
 /*
@@ -950,7 +963,15 @@ static int x86_pmu_enable(struct perf_event *event)
        if (n < 0)
                return n;
 
-       ret = x86_schedule_events(cpuc, n, assign);
+       /*
+        * If group events scheduling transaction was started,
+        * skip the schedulability test here, it will be peformed
+        * at commit time(->commit_txn) as a whole
+        */
+       if (cpuc->group_flag & PERF_EVENT_TXN_STARTED)
+               goto out;
+
+       ret = x86_pmu.schedule_events(cpuc, n, assign);
        if (ret)
                return ret;
        /*
@@ -959,6 +980,7 @@ static int x86_pmu_enable(struct perf_event *event)
         */
        memcpy(cpuc->assign, assign, n*sizeof(int));
 
+out:
        cpuc->n_events = n;
        cpuc->n_added += n - n0;
 
@@ -991,11 +1013,12 @@ static void x86_pmu_unthrottle(struct perf_event *event)
 void perf_event_print_debug(void)
 {
        u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
+       u64 pebs;
        struct cpu_hw_events *cpuc;
        unsigned long flags;
        int cpu, idx;
 
-       if (!x86_pmu.num_events)
+       if (!x86_pmu.num_counters)
                return;
 
        local_irq_save(flags);
@@ -1008,16 +1031,18 @@ void perf_event_print_debug(void)
                rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
                rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
                rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
+               rdmsrl(MSR_IA32_PEBS_ENABLE, pebs);
 
                pr_info("\n");
                pr_info("CPU#%d: ctrl:       %016llx\n", cpu, ctrl);
                pr_info("CPU#%d: status:     %016llx\n", cpu, status);
                pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
                pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
+               pr_info("CPU#%d: pebs:       %016llx\n", cpu, pebs);
        }
-       pr_info("CPU#%d: active:       %016llx\n", cpu, *(u64 *)cpuc->active_mask);
+       pr_info("CPU#%d: active:     %016llx\n", cpu, *(u64 *)cpuc->active_mask);
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
                rdmsrl(x86_pmu.perfctr  + idx, pmc_count);
 
@@ -1030,7 +1055,7 @@ void perf_event_print_debug(void)
                pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
                        cpu, idx, prev_left);
        }
-       for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
                rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
 
                pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
@@ -1095,7 +1120,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
 
        cpuc = &__get_cpu_var(cpu_hw_events);
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                if (!test_bit(idx, cpuc->active_mask))
                        continue;
 
@@ -1103,7 +1128,7 @@ static int x86_pmu_handle_irq(struct pt_regs *regs)
                hwc = &event->hw;
 
                val = x86_perf_event_update(event);
-               if (val & (1ULL << (x86_pmu.event_bits - 1)))
+               if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
                        continue;
 
                /*
@@ -1146,7 +1171,6 @@ void set_perf_event_pending(void)
 
 void perf_events_lapic_init(void)
 {
-#ifdef CONFIG_X86_LOCAL_APIC
        if (!x86_pmu.apic || !x86_pmu_initialized())
                return;
 
@@ -1154,7 +1178,6 @@ void perf_events_lapic_init(void)
         * Always use NMI for PMU
         */
        apic_write(APIC_LVTPC, APIC_DM_NMI);
-#endif
 }
 
 static int __kprobes
@@ -1178,9 +1201,7 @@ perf_event_nmi_handler(struct notifier_block *self,
 
        regs = args->regs;
 
-#ifdef CONFIG_X86_LOCAL_APIC
        apic_write(APIC_LVTPC, APIC_DM_NMI);
-#endif
        /*
         * Can't rely on the handled return value to say it was our NMI, two
         * events could trigger 'simultaneously' raising two back-to-back NMIs.
@@ -1217,118 +1238,11 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
        return &unconstrained;
 }
 
-static int x86_event_sched_in(struct perf_event *event,
-                         struct perf_cpu_context *cpuctx)
-{
-       int ret = 0;
-
-       event->state = PERF_EVENT_STATE_ACTIVE;
-       event->oncpu = smp_processor_id();
-       event->tstamp_running += event->ctx->time - event->tstamp_stopped;
-
-       if (!is_x86_event(event))
-               ret = event->pmu->enable(event);
-
-       if (!ret && !is_software_event(event))
-               cpuctx->active_oncpu++;
-
-       if (!ret && event->attr.exclusive)
-               cpuctx->exclusive = 1;
-
-       return ret;
-}
-
-static void x86_event_sched_out(struct perf_event *event,
-                           struct perf_cpu_context *cpuctx)
-{
-       event->state = PERF_EVENT_STATE_INACTIVE;
-       event->oncpu = -1;
-
-       if (!is_x86_event(event))
-               event->pmu->disable(event);
-
-       event->tstamp_running -= event->ctx->time - event->tstamp_stopped;
-
-       if (!is_software_event(event))
-               cpuctx->active_oncpu--;
-
-       if (event->attr.exclusive || !cpuctx->active_oncpu)
-               cpuctx->exclusive = 0;
-}
-
-/*
- * Called to enable a whole group of events.
- * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
- * Assumes the caller has disabled interrupts and has
- * frozen the PMU with hw_perf_save_disable.
- *
- * called with PMU disabled. If successful and return value 1,
- * then guaranteed to call perf_enable() and hw_perf_enable()
- */
-int hw_perf_group_sched_in(struct perf_event *leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct perf_event *sub;
-       int assign[X86_PMC_IDX_MAX];
-       int n0, n1, ret;
-
-       /* n0 = total number of events */
-       n0 = collect_events(cpuc, leader, true);
-       if (n0 < 0)
-               return n0;
-
-       ret = x86_schedule_events(cpuc, n0, assign);
-       if (ret)
-               return ret;
-
-       ret = x86_event_sched_in(leader, cpuctx);
-       if (ret)
-               return ret;
-
-       n1 = 1;
-       list_for_each_entry(sub, &leader->sibling_list, group_entry) {
-               if (sub->state > PERF_EVENT_STATE_OFF) {
-                       ret = x86_event_sched_in(sub, cpuctx);
-                       if (ret)
-                               goto undo;
-                       ++n1;
-               }
-       }
-       /*
-        * copy new assignment, now we know it is possible
-        * will be used by hw_perf_enable()
-        */
-       memcpy(cpuc->assign, assign, n0*sizeof(int));
-
-       cpuc->n_events  = n0;
-       cpuc->n_added  += n1;
-       ctx->nr_active += n1;
-
-       /*
-        * 1 means successful and events are active
-        * This is not quite true because we defer
-        * actual activation until hw_perf_enable() but
-        * this way we* ensure caller won't try to enable
-        * individual events
-        */
-       return 1;
-undo:
-       x86_event_sched_out(leader, cpuctx);
-       n0  = 1;
-       list_for_each_entry(sub, &leader->sibling_list, group_entry) {
-               if (sub->state == PERF_EVENT_STATE_ACTIVE) {
-                       x86_event_sched_out(sub, cpuctx);
-                       if (++n0 == n1)
-                               break;
-               }
-       }
-       return ret;
-}
-
 #include "perf_event_amd.c"
 #include "perf_event_p6.c"
+#include "perf_event_p4.c"
+#include "perf_event_intel_lbr.c"
+#include "perf_event_intel_ds.c"
 #include "perf_event_intel.c"
 
 static int __cpuinit
@@ -1402,48 +1316,50 @@ void __init init_hw_perf_events(void)
 
        pr_cont("%s PMU driver.\n", x86_pmu.name);
 
-       if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
+       if (x86_pmu.quirks)
+               x86_pmu.quirks();
+
+       if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) {
                WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
-                    x86_pmu.num_events, X86_PMC_MAX_GENERIC);
-               x86_pmu.num_events = X86_PMC_MAX_GENERIC;
+                    x86_pmu.num_counters, X86_PMC_MAX_GENERIC);
+               x86_pmu.num_counters = X86_PMC_MAX_GENERIC;
        }
-       perf_event_mask = (1 << x86_pmu.num_events) - 1;
-       perf_max_events = x86_pmu.num_events;
+       x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+       perf_max_events = x86_pmu.num_counters;
 
-       if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) {
+       if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) {
                WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
-                    x86_pmu.num_events_fixed, X86_PMC_MAX_FIXED);
-               x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED;
+                    x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED);
+               x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED;
        }
 
-       perf_event_mask |=
-               ((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED;
-       x86_pmu.intel_ctrl = perf_event_mask;
+       x86_pmu.intel_ctrl |=
+               ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED;
 
        perf_events_lapic_init();
        register_die_notifier(&perf_event_nmi_notifier);
 
        unconstrained = (struct event_constraint)
-               __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_events) - 1,
-                                  0, x86_pmu.num_events);
+               __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
+                                  0, x86_pmu.num_counters);
 
        if (x86_pmu.event_constraints) {
                for_each_event_constraint(c, x86_pmu.event_constraints) {
-                       if (c->cmask != INTEL_ARCH_FIXED_MASK)
+                       if (c->cmask != X86_RAW_EVENT_MASK)
                                continue;
 
-                       c->idxmsk64 |= (1ULL << x86_pmu.num_events) - 1;
-                       c->weight += x86_pmu.num_events;
+                       c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
+                       c->weight += x86_pmu.num_counters;
                }
        }
 
        pr_info("... version:                %d\n",     x86_pmu.version);
-       pr_info("... bit width:              %d\n",     x86_pmu.event_bits);
-       pr_info("... generic registers:      %d\n",     x86_pmu.num_events);
-       pr_info("... value mask:             %016Lx\n", x86_pmu.event_mask);
+       pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
+       pr_info("... generic registers:      %d\n",     x86_pmu.num_counters);
+       pr_info("... value mask:             %016Lx\n", x86_pmu.cntval_mask);
        pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
-       pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_events_fixed);
-       pr_info("... event mask:             %016Lx\n", perf_event_mask);
+       pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_counters_fixed);
+       pr_info("... event mask:             %016Lx\n", x86_pmu.intel_ctrl);
 
        perf_cpu_notifier(x86_pmu_notifier);
 }
@@ -1453,6 +1369,59 @@ static inline void x86_pmu_read(struct perf_event *event)
        x86_perf_event_update(event);
 }
 
+/*
+ * Start group events scheduling transaction
+ * Set the flag to make pmu::enable() not perform the
+ * schedulability test, it will be performed at commit time
+ */
+static void x86_pmu_start_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       cpuc->group_flag |= PERF_EVENT_TXN_STARTED;
+}
+
+/*
+ * Stop group events scheduling transaction
+ * Clear the flag and pmu::enable() will perform the
+ * schedulability test.
+ */
+static void x86_pmu_cancel_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       cpuc->group_flag &= ~PERF_EVENT_TXN_STARTED;
+}
+
+/*
+ * Commit group events scheduling transaction
+ * Perform the group schedulability test as a whole
+ * Return 0 if success
+ */
+static int x86_pmu_commit_txn(const struct pmu *pmu)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int assign[X86_PMC_IDX_MAX];
+       int n, ret;
+
+       n = cpuc->n_events;
+
+       if (!x86_pmu_initialized())
+               return -EAGAIN;
+
+       ret = x86_pmu.schedule_events(cpuc, n, assign);
+       if (ret)
+               return ret;
+
+       /*
+        * copy new assignment, now we know it is possible
+        * will be used by hw_perf_enable()
+        */
+       memcpy(cpuc->assign, assign, n*sizeof(int));
+
+       return 0;
+}
+
 static const struct pmu pmu = {
        .enable         = x86_pmu_enable,
        .disable        = x86_pmu_disable,
@@ -1460,8 +1429,37 @@ static const struct pmu pmu = {
        .stop           = x86_pmu_stop,
        .read           = x86_pmu_read,
        .unthrottle     = x86_pmu_unthrottle,
+       .start_txn      = x86_pmu_start_txn,
+       .cancel_txn     = x86_pmu_cancel_txn,
+       .commit_txn     = x86_pmu_commit_txn,
 };
 
+/*
+ * validate that we can schedule this event
+ */
+static int validate_event(struct perf_event *event)
+{
+       struct cpu_hw_events *fake_cpuc;
+       struct event_constraint *c;
+       int ret = 0;
+
+       fake_cpuc = kmalloc(sizeof(*fake_cpuc), GFP_KERNEL | __GFP_ZERO);
+       if (!fake_cpuc)
+               return -ENOMEM;
+
+       c = x86_pmu.get_event_constraints(fake_cpuc, event);
+
+       if (!c || !c->weight)
+               ret = -ENOSPC;
+
+       if (x86_pmu.put_event_constraints)
+               x86_pmu.put_event_constraints(fake_cpuc, event);
+
+       kfree(fake_cpuc);
+
+       return ret;
+}
+
 /*
  * validate a single event group
  *
@@ -1502,7 +1500,7 @@ static int validate_group(struct perf_event *event)
 
        fake_cpuc->n_events = n;
 
-       ret = x86_schedule_events(fake_cpuc, n, NULL);
+       ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
 
 out_free:
        kfree(fake_cpuc);
@@ -1527,6 +1525,8 @@ const struct pmu *hw_perf_event_init(struct perf_event *event)
 
                if (event->group_leader != event)
                        err = validate_group(event);
+               else
+                       err = validate_event(event);
 
                event->pmu = tmp;
        }
@@ -1574,8 +1574,7 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
 {
        struct perf_callchain_entry *entry = data;
 
-       if (reliable)
-               callchain_store(entry, addr);
+       callchain_store(entry, addr);
 }
 
 static const struct stacktrace_ops backtrace_ops = {
@@ -1597,41 +1596,6 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
        dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
 }
 
-/*
- * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
- */
-static unsigned long
-copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
-{
-       unsigned long offset, addr = (unsigned long)from;
-       int type = in_nmi() ? KM_NMI : KM_IRQ0;
-       unsigned long size, len = 0;
-       struct page *page;
-       void *map;
-       int ret;
-
-       do {
-               ret = __get_user_pages_fast(addr, 1, 0, &page);
-               if (!ret)
-                       break;
-
-               offset = addr & (PAGE_SIZE - 1);
-               size = min(PAGE_SIZE - offset, n - len);
-
-               map = kmap_atomic(page, type);
-               memcpy(to, map+offset, size);
-               kunmap_atomic(map, type);
-               put_page(page);
-
-               len  += size;
-               to   += size;
-               addr += size;
-
-       } while (len < n);
-
-       return len;
-}
-
 #ifdef CONFIG_COMPAT
 static inline int
 perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry)
@@ -1727,6 +1691,11 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
 {
        struct perf_callchain_entry *entry;
 
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+               /* TODO: We don't support guest os callchain now */
+               return NULL;
+       }
+
        if (in_nmi())
                entry = &__get_cpu_var(pmc_nmi_entry);
        else
@@ -1750,3 +1719,37 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski
        regs->cs = __KERNEL_CS;
        local_save_flags(regs->flags);
 }
+
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+       unsigned long ip;
+
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+               ip = perf_guest_cbs->get_guest_ip();
+       else
+               ip = instruction_pointer(regs);
+
+       return ip;
+}
+
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+       int misc = 0;
+
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+               if (perf_guest_cbs->is_user_mode())
+                       misc |= PERF_RECORD_MISC_GUEST_USER;
+               else
+                       misc |= PERF_RECORD_MISC_GUEST_KERNEL;
+       } else {
+               if (user_mode(regs))
+                       misc |= PERF_RECORD_MISC_USER;
+               else
+                       misc |= PERF_RECORD_MISC_KERNEL;
+       }
+
+       if (regs->flags & PERF_EFLAGS_EXACT)
+               misc |= PERF_RECORD_MISC_EXACT_IP;
+
+       return misc;
+}
index db6f7d4..611df11 100644 (file)
@@ -2,7 +2,7 @@
 
 static DEFINE_RAW_SPINLOCK(amd_nb_lock);
 
-static __initconst u64 amd_hw_cache_event_ids
+static __initconst const u64 amd_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -111,22 +111,19 @@ static u64 amd_pmu_event_map(int hw_event)
        return amd_perfmon_event_map[hw_event];
 }
 
-static u64 amd_pmu_raw_event(u64 hw_event)
+static int amd_pmu_hw_config(struct perf_event *event)
 {
-#define K7_EVNTSEL_EVENT_MASK  0xF000000FFULL
-#define K7_EVNTSEL_UNIT_MASK   0x00000FF00ULL
-#define K7_EVNTSEL_EDGE_MASK   0x000040000ULL
-#define K7_EVNTSEL_INV_MASK    0x000800000ULL
-#define K7_EVNTSEL_REG_MASK    0x0FF000000ULL
-
-#define K7_EVNTSEL_MASK                        \
-       (K7_EVNTSEL_EVENT_MASK |        \
-        K7_EVNTSEL_UNIT_MASK  |        \
-        K7_EVNTSEL_EDGE_MASK  |        \
-        K7_EVNTSEL_INV_MASK   |        \
-        K7_EVNTSEL_REG_MASK)
-
-       return hw_event & K7_EVNTSEL_MASK;
+       int ret = x86_pmu_hw_config(event);
+
+       if (ret)
+               return ret;
+
+       if (event->attr.type != PERF_TYPE_RAW)
+               return 0;
+
+       event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK;
+
+       return 0;
 }
 
 /*
@@ -165,7 +162,7 @@ static void amd_put_event_constraints(struct cpu_hw_events *cpuc,
         * be removed on one CPU at a time AND PMU is disabled
         * when we come here
         */
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                if (nb->owners[i] == event) {
                        cmpxchg(nb->owners+i, event, NULL);
                        break;
@@ -215,7 +212,7 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
        struct hw_perf_event *hwc = &event->hw;
        struct amd_nb *nb = cpuc->amd_nb;
        struct perf_event *old = NULL;
-       int max = x86_pmu.num_events;
+       int max = x86_pmu.num_counters;
        int i, j, k = -1;
 
        /*
@@ -293,7 +290,7 @@ static struct amd_nb *amd_alloc_nb(int cpu, int nb_id)
        /*
         * initialize all possible NB constraints
         */
-       for (i = 0; i < x86_pmu.num_events; i++) {
+       for (i = 0; i < x86_pmu.num_counters; i++) {
                __set_bit(i, nb->event_constraints[i].idxmsk);
                nb->event_constraints[i].weight = 1;
        }
@@ -371,21 +368,22 @@ static void amd_pmu_cpu_dead(int cpu)
        raw_spin_unlock(&amd_nb_lock);
 }
 
-static __initconst struct x86_pmu amd_pmu = {
+static __initconst const struct x86_pmu amd_pmu = {
        .name                   = "AMD",
        .handle_irq             = x86_pmu_handle_irq,
        .disable_all            = x86_pmu_disable_all,
        .enable_all             = x86_pmu_enable_all,
        .enable                 = x86_pmu_enable_event,
        .disable                = x86_pmu_disable_event,
+       .hw_config              = amd_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_K7_EVNTSEL0,
        .perfctr                = MSR_K7_PERFCTR0,
        .event_map              = amd_pmu_event_map,
-       .raw_event              = amd_pmu_raw_event,
        .max_events             = ARRAY_SIZE(amd_perfmon_event_map),
-       .num_events             = 4,
-       .event_bits             = 48,
-       .event_mask             = (1ULL << 48) - 1,
+       .num_counters           = 4,
+       .cntval_bits            = 48,
+       .cntval_mask            = (1ULL << 48) - 1,
        .apic                   = 1,
        /* use highest bit to detect overflow */
        .max_period             = (1ULL << 47) - 1,
index 9c794ac..fdbc652 100644 (file)
@@ -88,7 +88,7 @@ static u64 intel_pmu_event_map(int hw_event)
        return intel_perfmon_event_map[hw_event];
 }
 
-static __initconst u64 westmere_hw_cache_event_ids
+static __initconst const u64 westmere_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -179,7 +179,7 @@ static __initconst u64 westmere_hw_cache_event_ids
  },
 };
 
-static __initconst u64 nehalem_hw_cache_event_ids
+static __initconst const u64 nehalem_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -270,7 +270,7 @@ static __initconst u64 nehalem_hw_cache_event_ids
  },
 };
 
-static __initconst u64 core2_hw_cache_event_ids
+static __initconst const u64 core2_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -361,7 +361,7 @@ static __initconst u64 core2_hw_cache_event_ids
  },
 };
 
-static __initconst u64 atom_hw_cache_event_ids
+static __initconst const u64 atom_hw_cache_event_ids
                                [PERF_COUNT_HW_CACHE_MAX]
                                [PERF_COUNT_HW_CACHE_OP_MAX]
                                [PERF_COUNT_HW_CACHE_RESULT_MAX] =
@@ -452,60 +452,6 @@ static __initconst u64 atom_hw_cache_event_ids
  },
 };
 
-static u64 intel_pmu_raw_event(u64 hw_event)
-{
-#define CORE_EVNTSEL_EVENT_MASK                0x000000FFULL
-#define CORE_EVNTSEL_UNIT_MASK         0x0000FF00ULL
-#define CORE_EVNTSEL_EDGE_MASK         0x00040000ULL
-#define CORE_EVNTSEL_INV_MASK          0x00800000ULL
-#define CORE_EVNTSEL_REG_MASK          0xFF000000ULL
-
-#define CORE_EVNTSEL_MASK              \
-       (INTEL_ARCH_EVTSEL_MASK |       \
-        INTEL_ARCH_UNIT_MASK   |       \
-        INTEL_ARCH_EDGE_MASK   |       \
-        INTEL_ARCH_INV_MASK    |       \
-        INTEL_ARCH_CNT_MASK)
-
-       return hw_event & CORE_EVNTSEL_MASK;
-}
-
-static void intel_pmu_enable_bts(u64 config)
-{
-       unsigned long debugctlmsr;
-
-       debugctlmsr = get_debugctlmsr();
-
-       debugctlmsr |= X86_DEBUGCTL_TR;
-       debugctlmsr |= X86_DEBUGCTL_BTS;
-       debugctlmsr |= X86_DEBUGCTL_BTINT;
-
-       if (!(config & ARCH_PERFMON_EVENTSEL_OS))
-               debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
-
-       if (!(config & ARCH_PERFMON_EVENTSEL_USR))
-               debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
-
-       update_debugctlmsr(debugctlmsr);
-}
-
-static void intel_pmu_disable_bts(void)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       unsigned long debugctlmsr;
-
-       if (!cpuc->ds)
-               return;
-
-       debugctlmsr = get_debugctlmsr();
-
-       debugctlmsr &=
-               ~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
-                 X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
-
-       update_debugctlmsr(debugctlmsr);
-}
-
 static void intel_pmu_disable_all(void)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
@@ -514,12 +460,17 @@ static void intel_pmu_disable_all(void)
 
        if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
                intel_pmu_disable_bts();
+
+       intel_pmu_pebs_disable_all();
+       intel_pmu_lbr_disable_all();
 }
 
-static void intel_pmu_enable_all(void)
+static void intel_pmu_enable_all(int added)
 {
        struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
+       intel_pmu_pebs_enable_all();
+       intel_pmu_lbr_enable_all();
        wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
 
        if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
@@ -533,6 +484,42 @@ static void intel_pmu_enable_all(void)
        }
 }
 
+/*
+ * Workaround for:
+ *   Intel Errata AAK100 (model 26)
+ *   Intel Errata AAP53  (model 30)
+ *   Intel Errata BD53   (model 44)
+ *
+ * These chips need to be 'reset' when adding counters by programming
+ * the magic three (non counting) events 0x4300D2, 0x4300B1 and 0x4300B5
+ * either in sequence on the same PMC or on different PMCs.
+ */
+static void intel_pmu_nhm_enable_all(int added)
+{
+       if (added) {
+               struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+               int i;
+
+               wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 0, 0x4300D2);
+               wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 1, 0x4300B1);
+               wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + 2, 0x4300B5);
+
+               wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x3);
+               wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
+
+               for (i = 0; i < 3; i++) {
+                       struct perf_event *event = cpuc->events[i];
+
+                       if (!event)
+                               continue;
+
+                       __x86_pmu_enable_event(&event->hw,
+                                              ARCH_PERFMON_EVENTSEL_ENABLE);
+               }
+       }
+       intel_pmu_enable_all(added);
+}
+
 static inline u64 intel_pmu_get_status(void)
 {
        u64 status;
@@ -547,8 +534,7 @@ static inline void intel_pmu_ack_status(u64 ack)
        wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
 }
 
-static inline void
-intel_pmu_disable_fixed(struct hw_perf_event *hwc)
+static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
 {
        int idx = hwc->idx - X86_PMC_IDX_FIXED;
        u64 ctrl_val, mask;
@@ -557,71 +543,10 @@ intel_pmu_disable_fixed(struct hw_perf_event *hwc)
 
        rdmsrl(hwc->config_base, ctrl_val);
        ctrl_val &= ~mask;
-       (void)checking_wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static void intel_pmu_drain_bts_buffer(void)
-{
-       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
-       struct debug_store *ds = cpuc->ds;
-       struct bts_record {
-               u64     from;
-               u64     to;
-               u64     flags;
-       };
-       struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
-       struct bts_record *at, *top;
-       struct perf_output_handle handle;
-       struct perf_event_header header;
-       struct perf_sample_data data;
-       struct pt_regs regs;
-
-       if (!event)
-               return;
-
-       if (!ds)
-               return;
-
-       at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
-       top = (struct bts_record *)(unsigned long)ds->bts_index;
-
-       if (top <= at)
-               return;
-
-       ds->bts_index = ds->bts_buffer_base;
-
-       perf_sample_data_init(&data, 0);
-
-       data.period     = event->hw.last_period;
-       regs.ip         = 0;
-
-       /*
-        * Prepare a generic sample, i.e. fill in the invariant fields.
-        * We will overwrite the from and to address before we output
-        * the sample.
-        */
-       perf_prepare_sample(&header, &data, event, &regs);
-
-       if (perf_output_begin(&handle, event,
-                             header.size * (top - at), 1, 1))
-               return;
-
-       for (; at < top; at++) {
-               data.ip         = at->from;
-               data.addr       = at->to;
-
-               perf_output_sample(&handle, &header, &data, event);
-       }
-
-       perf_output_end(&handle);
-
-       /* There's new data available. */
-       event->hw.interrupts++;
-       event->pending_kill = POLL_IN;
+       wrmsrl(hwc->config_base, ctrl_val);
 }
 
-static inline void
-intel_pmu_disable_event(struct perf_event *event)
+static void intel_pmu_disable_event(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
 
@@ -637,14 +562,15 @@ intel_pmu_disable_event(struct perf_event *event)
        }
 
        x86_pmu_disable_event(event);
+
+       if (unlikely(event->attr.precise_ip))
+               intel_pmu_pebs_disable(event);
 }
 
-static inline void
-intel_pmu_enable_fixed(struct hw_perf_event *hwc)
+static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
 {
        int idx = hwc->idx - X86_PMC_IDX_FIXED;
        u64 ctrl_val, bits, mask;
-       int err;
 
        /*
         * Enable IRQ generation (0x8),
@@ -669,7 +595,7 @@ intel_pmu_enable_fixed(struct hw_perf_event *hwc)
        rdmsrl(hwc->config_base, ctrl_val);
        ctrl_val &= ~mask;
        ctrl_val |= bits;
-       err = checking_wrmsrl(hwc->config_base, ctrl_val);
+       wrmsrl(hwc->config_base, ctrl_val);
 }
 
 static void intel_pmu_enable_event(struct perf_event *event)
@@ -689,7 +615,10 @@ static void intel_pmu_enable_event(struct perf_event *event)
                return;
        }
 
-       __x86_pmu_enable_event(hwc);
+       if (unlikely(event->attr.precise_ip))
+               intel_pmu_pebs_enable(event);
+
+       __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
 }
 
 /*
@@ -708,20 +637,20 @@ static void intel_pmu_reset(void)
        unsigned long flags;
        int idx;
 
-       if (!x86_pmu.num_events)
+       if (!x86_pmu.num_counters)
                return;
 
        local_irq_save(flags);
 
        printk("clearing PMU state on CPU#%d\n", smp_processor_id());
 
-       for (idx = 0; idx < x86_pmu.num_events; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
                checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
                checking_wrmsrl(x86_pmu.perfctr  + idx, 0ull);
        }
-       for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+       for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
                checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-       }
+
        if (ds)
                ds->bts_index = ds->bts_buffer_base;
 
@@ -747,7 +676,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
        intel_pmu_drain_bts_buffer();
        status = intel_pmu_get_status();
        if (!status) {
-               intel_pmu_enable_all();
+               intel_pmu_enable_all(0);
                return 0;
        }
 
@@ -762,6 +691,15 @@ again:
 
        inc_irq_stat(apic_perf_irqs);
        ack = status;
+
+       intel_pmu_lbr_read();
+
+       /*
+        * PEBS overflow sets bit 62 in the global status register
+        */
+       if (__test_and_clear_bit(62, (unsigned long *)&status))
+               x86_pmu.drain_pebs(regs);
+
        for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
                struct perf_event *event = cpuc->events[bit];
 
@@ -787,26 +725,22 @@ again:
                goto again;
 
 done:
-       intel_pmu_enable_all();
+       intel_pmu_enable_all(0);
        return 1;
 }
 
-static struct event_constraint bts_constraint =
-       EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
-
 static struct event_constraint *
-intel_special_constraints(struct perf_event *event)
+intel_bts_constraints(struct perf_event *event)
 {
-       unsigned int hw_event;
-
-       hw_event = event->hw.config & INTEL_ARCH_EVENT_MASK;
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned int hw_event, bts_event;
 
-       if (unlikely((hw_event ==
-                     x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
-                    (event->hw.sample_period == 1))) {
+       hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
+       bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
 
+       if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
                return &bts_constraint;
-       }
+
        return NULL;
 }
 
@@ -815,24 +749,53 @@ intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event
 {
        struct event_constraint *c;
 
-       c = intel_special_constraints(event);
+       c = intel_bts_constraints(event);
+       if (c)
+               return c;
+
+       c = intel_pebs_constraints(event);
        if (c)
                return c;
 
        return x86_get_event_constraints(cpuc, event);
 }
 
-static __initconst struct x86_pmu core_pmu = {
+static int intel_pmu_hw_config(struct perf_event *event)
+{
+       int ret = x86_pmu_hw_config(event);
+
+       if (ret)
+               return ret;
+
+       if (event->attr.type != PERF_TYPE_RAW)
+               return 0;
+
+       if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
+               return 0;
+
+       if (x86_pmu.version < 3)
+               return -EINVAL;
+
+       if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+               return -EACCES;
+
+       event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
+
+       return 0;
+}
+
+static __initconst const struct x86_pmu core_pmu = {
        .name                   = "core",
        .handle_irq             = x86_pmu_handle_irq,
        .disable_all            = x86_pmu_disable_all,
        .enable_all             = x86_pmu_enable_all,
        .enable                 = x86_pmu_enable_event,
        .disable                = x86_pmu_disable_event,
+       .hw_config              = x86_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_ARCH_PERFMON_EVENTSEL0,
        .perfctr                = MSR_ARCH_PERFMON_PERFCTR0,
        .event_map              = intel_pmu_event_map,
-       .raw_event              = intel_pmu_raw_event,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
        /*
@@ -845,17 +808,32 @@ static __initconst struct x86_pmu core_pmu = {
        .event_constraints      = intel_core_event_constraints,
 };
 
-static __initconst struct x86_pmu intel_pmu = {
+static void intel_pmu_cpu_starting(int cpu)
+{
+       init_debug_store_on_cpu(cpu);
+       /*
+        * Deal with CPUs that don't clear their LBRs on power-up.
+        */
+       intel_pmu_lbr_reset();
+}
+
+static void intel_pmu_cpu_dying(int cpu)
+{
+       fini_debug_store_on_cpu(cpu);
+}
+
+static __initconst const struct x86_pmu intel_pmu = {
        .name                   = "Intel",
        .handle_irq             = intel_pmu_handle_irq,
        .disable_all            = intel_pmu_disable_all,
        .enable_all             = intel_pmu_enable_all,
        .enable                 = intel_pmu_enable_event,
        .disable                = intel_pmu_disable_event,
+       .hw_config              = intel_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_ARCH_PERFMON_EVENTSEL0,
        .perfctr                = MSR_ARCH_PERFMON_PERFCTR0,
        .event_map              = intel_pmu_event_map,
-       .raw_event              = intel_pmu_raw_event,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
        .apic                   = 1,
        /*
@@ -864,14 +842,38 @@ static __initconst struct x86_pmu intel_pmu = {
         * the generic event period:
         */
        .max_period             = (1ULL << 31) - 1,
-       .enable_bts             = intel_pmu_enable_bts,
-       .disable_bts            = intel_pmu_disable_bts,
        .get_event_constraints  = intel_get_event_constraints,
 
-       .cpu_starting           = init_debug_store_on_cpu,
-       .cpu_dying              = fini_debug_store_on_cpu,
+       .cpu_starting           = intel_pmu_cpu_starting,
+       .cpu_dying              = intel_pmu_cpu_dying,
 };
 
+static void intel_clovertown_quirks(void)
+{
+       /*
+        * PEBS is unreliable due to:
+        *
+        *   AJ67  - PEBS may experience CPL leaks
+        *   AJ68  - PEBS PMI may be delayed by one event
+        *   AJ69  - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
+        *   AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
+        *
+        * AJ67 could be worked around by restricting the OS/USR flags.
+        * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
+        *
+        * AJ106 could possibly be worked around by not allowing LBR
+        *       usage from PEBS, including the fixup.
+        * AJ68  could possibly be worked around by always programming
+        *       a pebs_event_reset[0] value and coping with the lost events.
+        *
+        * But taken together it might just make sense to not enable PEBS on
+        * these chips.
+        */
+       printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
+       x86_pmu.pebs = 0;
+       x86_pmu.pebs_constraints = NULL;
+}
+
 static __init int intel_pmu_init(void)
 {
        union cpuid10_edx edx;
@@ -881,12 +883,13 @@ static __init int intel_pmu_init(void)
        int version;
 
        if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-               /* check for P6 processor family */
-          if (boot_cpu_data.x86 == 6) {
-               return p6_pmu_init();
-          } else {
+               switch (boot_cpu_data.x86) {
+               case 0x6:
+                       return p6_pmu_init();
+               case 0xf:
+                       return p4_pmu_init();
+               }
                return -ENODEV;
-          }
        }
 
        /*
@@ -904,16 +907,28 @@ static __init int intel_pmu_init(void)
                x86_pmu = intel_pmu;
 
        x86_pmu.version                 = version;
-       x86_pmu.num_events              = eax.split.num_events;
-       x86_pmu.event_bits              = eax.split.bit_width;
-       x86_pmu.event_mask              = (1ULL << eax.split.bit_width) - 1;
+       x86_pmu.num_counters            = eax.split.num_counters;
+       x86_pmu.cntval_bits             = eax.split.bit_width;
+       x86_pmu.cntval_mask             = (1ULL << eax.split.bit_width) - 1;
 
        /*
         * Quirk: v2 perfmon does not report fixed-purpose events, so
         * assume at least 3 events:
         */
        if (version > 1)
-               x86_pmu.num_events_fixed = max((int)edx.split.num_events_fixed, 3);
+               x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
+
+       /*
+        * v2 and above have a perf capabilities MSR
+        */
+       if (version > 1) {
+               u64 capabilities;
+
+               rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
+               x86_pmu.intel_cap.capabilities = capabilities;
+       }
+
+       intel_ds_init();
 
        /*
         * Install the hw-cache-events table:
@@ -924,12 +939,15 @@ static __init int intel_pmu_init(void)
                break;
 
        case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+               x86_pmu.quirks = intel_clovertown_quirks;
        case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
        case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
        case 29: /* six-core 45 nm xeon "Dunnington" */
                memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_core();
+
                x86_pmu.event_constraints = intel_core2_event_constraints;
                pr_cont("Core2 events, ");
                break;
@@ -940,13 +958,19 @@ static __init int intel_pmu_init(void)
                memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_nhm();
+
                x86_pmu.event_constraints = intel_nehalem_event_constraints;
-               pr_cont("Nehalem/Corei7 events, ");
+               x86_pmu.enable_all = intel_pmu_nhm_enable_all;
+               pr_cont("Nehalem events, ");
                break;
+
        case 28: /* Atom */
                memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_atom();
+
                x86_pmu.event_constraints = intel_gen_event_constraints;
                pr_cont("Atom events, ");
                break;
@@ -956,7 +980,10 @@ static __init int intel_pmu_init(void)
                memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
 
+               intel_pmu_lbr_init_nhm();
+
                x86_pmu.event_constraints = intel_westmere_event_constraints;
+               x86_pmu.enable_all = intel_pmu_nhm_enable_all;
                pr_cont("Westmere events, ");
                break;
 
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
new file mode 100644 (file)
index 0000000..18018d1
--- /dev/null
@@ -0,0 +1,641 @@
+#ifdef CONFIG_CPU_SUP_INTEL
+
+/* The maximal number of PEBS events: */
+#define MAX_PEBS_EVENTS                4
+
+/* The size of a BTS record in bytes: */
+#define BTS_RECORD_SIZE                24
+
+#define BTS_BUFFER_SIZE                (PAGE_SIZE << 4)
+#define PEBS_BUFFER_SIZE       PAGE_SIZE
+
+/*
+ * pebs_record_32 for p4 and core not supported
+
+struct pebs_record_32 {
+       u32 flags, ip;
+       u32 ax, bc, cx, dx;
+       u32 si, di, bp, sp;
+};
+
+ */
+
+struct pebs_record_core {
+       u64 flags, ip;
+       u64 ax, bx, cx, dx;
+       u64 si, di, bp, sp;
+       u64 r8,  r9,  r10, r11;
+       u64 r12, r13, r14, r15;
+};
+
+struct pebs_record_nhm {
+       u64 flags, ip;
+       u64 ax, bx, cx, dx;
+       u64 si, di, bp, sp;
+       u64 r8,  r9,  r10, r11;
+       u64 r12, r13, r14, r15;
+       u64 status, dla, dse, lat;
+};
+
+/*
+ * A debug store configuration.
+ *
+ * We only support architectures that use 64bit fields.
+ */
+struct debug_store {
+       u64     bts_buffer_base;
+       u64     bts_index;
+       u64     bts_absolute_maximum;
+       u64     bts_interrupt_threshold;
+       u64     pebs_buffer_base;
+       u64     pebs_index;
+       u64     pebs_absolute_maximum;
+       u64     pebs_interrupt_threshold;
+       u64     pebs_event_reset[MAX_PEBS_EVENTS];
+};
+
+static void init_debug_store_on_cpu(int cpu)
+{
+       struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+       if (!ds)
+               return;
+
+       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
+                    (u32)((u64)(unsigned long)ds),
+                    (u32)((u64)(unsigned long)ds >> 32));
+}
+
+static void fini_debug_store_on_cpu(int cpu)
+{
+       if (!per_cpu(cpu_hw_events, cpu).ds)
+               return;
+
+       wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+}
+
+static void release_ds_buffers(void)
+{
+       int cpu;
+
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return;
+
+       get_online_cpus();
+
+       for_each_online_cpu(cpu)
+               fini_debug_store_on_cpu(cpu);
+
+       for_each_possible_cpu(cpu) {
+               struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+               if (!ds)
+                       continue;
+
+               per_cpu(cpu_hw_events, cpu).ds = NULL;
+
+               kfree((void *)(unsigned long)ds->pebs_buffer_base);
+               kfree((void *)(unsigned long)ds->bts_buffer_base);
+               kfree(ds);
+       }
+
+       put_online_cpus();
+}
+
+static int reserve_ds_buffers(void)
+{
+       int cpu, err = 0;
+
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return 0;
+
+       get_online_cpus();
+
+       for_each_possible_cpu(cpu) {
+               struct debug_store *ds;
+               void *buffer;
+               int max, thresh;
+
+               err = -ENOMEM;
+               ds = kzalloc(sizeof(*ds), GFP_KERNEL);
+               if (unlikely(!ds))
+                       break;
+               per_cpu(cpu_hw_events, cpu).ds = ds;
+
+               if (x86_pmu.bts) {
+                       buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
+                       if (unlikely(!buffer))
+                               break;
+
+                       max = BTS_BUFFER_SIZE / BTS_RECORD_SIZE;
+                       thresh = max / 16;
+
+                       ds->bts_buffer_base = (u64)(unsigned long)buffer;
+                       ds->bts_index = ds->bts_buffer_base;
+                       ds->bts_absolute_maximum = ds->bts_buffer_base +
+                               max * BTS_RECORD_SIZE;
+                       ds->bts_interrupt_threshold = ds->bts_absolute_maximum -
+                               thresh * BTS_RECORD_SIZE;
+               }
+
+               if (x86_pmu.pebs) {
+                       buffer = kzalloc(PEBS_BUFFER_SIZE, GFP_KERNEL);
+                       if (unlikely(!buffer))
+                               break;
+
+                       max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
+
+                       ds->pebs_buffer_base = (u64)(unsigned long)buffer;
+                       ds->pebs_index = ds->pebs_buffer_base;
+                       ds->pebs_absolute_maximum = ds->pebs_buffer_base +
+                               max * x86_pmu.pebs_record_size;
+                       /*
+                        * Always use single record PEBS
+                        */
+                       ds->pebs_interrupt_threshold = ds->pebs_buffer_base +
+                               x86_pmu.pebs_record_size;
+               }
+
+               err = 0;
+       }
+
+       if (err)
+               release_ds_buffers();
+       else {
+               for_each_online_cpu(cpu)
+                       init_debug_store_on_cpu(cpu);
+       }
+
+       put_online_cpus();
+
+       return err;
+}
+
+/*
+ * BTS
+ */
+
+static struct event_constraint bts_constraint =
+       EVENT_CONSTRAINT(0, 1ULL << X86_PMC_IDX_FIXED_BTS, 0);
+
+static void intel_pmu_enable_bts(u64 config)
+{
+       unsigned long debugctlmsr;
+
+       debugctlmsr = get_debugctlmsr();
+
+       debugctlmsr |= DEBUGCTLMSR_TR;
+       debugctlmsr |= DEBUGCTLMSR_BTS;
+       debugctlmsr |= DEBUGCTLMSR_BTINT;
+
+       if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+               debugctlmsr |= DEBUGCTLMSR_BTS_OFF_OS;
+
+       if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+               debugctlmsr |= DEBUGCTLMSR_BTS_OFF_USR;
+
+       update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_disable_bts(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long debugctlmsr;
+
+       if (!cpuc->ds)
+               return;
+
+       debugctlmsr = get_debugctlmsr();
+
+       debugctlmsr &=
+               ~(DEBUGCTLMSR_TR | DEBUGCTLMSR_BTS | DEBUGCTLMSR_BTINT |
+                 DEBUGCTLMSR_BTS_OFF_OS | DEBUGCTLMSR_BTS_OFF_USR);
+
+       update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_drain_bts_buffer(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct debug_store *ds = cpuc->ds;
+       struct bts_record {
+               u64     from;
+               u64     to;
+               u64     flags;
+       };
+       struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
+       struct bts_record *at, *top;
+       struct perf_output_handle handle;
+       struct perf_event_header header;
+       struct perf_sample_data data;
+       struct pt_regs regs;
+
+       if (!event)
+               return;
+
+       if (!ds)
+               return;
+
+       at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+       top = (struct bts_record *)(unsigned long)ds->bts_index;
+
+       if (top <= at)
+               return;
+
+       ds->bts_index = ds->bts_buffer_base;
+
+       perf_sample_data_init(&data, 0);
+       data.period = event->hw.last_period;
+       regs.ip     = 0;
+
+       /*
+        * Prepare a generic sample, i.e. fill in the invariant fields.
+        * We will overwrite the from and to address before we output
+        * the sample.
+        */
+       perf_prepare_sample(&header, &data, event, &regs);
+
+       if (perf_output_begin(&handle, event, header.size * (top - at), 1, 1))
+               return;
+
+       for (; at < top; at++) {
+               data.ip         = at->from;
+               data.addr       = at->to;
+
+               perf_output_sample(&handle, &header, &data, event);
+       }
+
+       perf_output_end(&handle);
+
+       /* There's new data available. */
+       event->hw.interrupts++;
+       event->pending_kill = POLL_IN;
+}
+
+/*
+ * PEBS
+ */
+
+static struct event_constraint intel_core_pebs_events[] = {
+       PEBS_EVENT_CONSTRAINT(0x00c0, 0x1), /* INSTR_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0xfec1, 0x1), /* X87_OPS_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_RETIRED.MISPRED */
+       PEBS_EVENT_CONSTRAINT(0x1fc7, 0x1), /* SIMD_INST_RETURED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x01cb, 0x1), /* MEM_LOAD_RETIRED.L1D_MISS */
+       PEBS_EVENT_CONSTRAINT(0x02cb, 0x1), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x04cb, 0x1), /* MEM_LOAD_RETIRED.L2_MISS */
+       PEBS_EVENT_CONSTRAINT(0x08cb, 0x1), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x10cb, 0x1), /* MEM_LOAD_RETIRED.DTLB_MISS */
+       EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint intel_nehalem_pebs_events[] = {
+       PEBS_EVENT_CONSTRAINT(0x00c0, 0xf), /* INSTR_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0xfec1, 0xf), /* X87_OPS_RETIRED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x00c5, 0xf), /* BR_INST_RETIRED.MISPRED */
+       PEBS_EVENT_CONSTRAINT(0x1fc7, 0xf), /* SIMD_INST_RETURED.ANY */
+       PEBS_EVENT_CONSTRAINT(0x01cb, 0xf), /* MEM_LOAD_RETIRED.L1D_MISS */
+       PEBS_EVENT_CONSTRAINT(0x02cb, 0xf), /* MEM_LOAD_RETIRED.L1D_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x04cb, 0xf), /* MEM_LOAD_RETIRED.L2_MISS */
+       PEBS_EVENT_CONSTRAINT(0x08cb, 0xf), /* MEM_LOAD_RETIRED.L2_LINE_MISS */
+       PEBS_EVENT_CONSTRAINT(0x10cb, 0xf), /* MEM_LOAD_RETIRED.DTLB_MISS */
+       EVENT_CONSTRAINT_END
+};
+
+static struct event_constraint *
+intel_pebs_constraints(struct perf_event *event)
+{
+       struct event_constraint *c;
+
+       if (!event->attr.precise_ip)
+               return NULL;
+
+       if (x86_pmu.pebs_constraints) {
+               for_each_event_constraint(c, x86_pmu.pebs_constraints) {
+                       if ((event->hw.config & c->cmask) == c->code)
+                               return c;
+               }
+       }
+
+       return &emptyconstraint;
+}
+
+static void intel_pmu_pebs_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+
+       hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT;
+
+       cpuc->pebs_enabled |= 1ULL << hwc->idx;
+       WARN_ON_ONCE(cpuc->enabled);
+
+       if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
+               intel_pmu_lbr_enable(event);
+}
+
+static void intel_pmu_pebs_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+
+       cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
+       if (cpuc->enabled)
+               wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+
+       hwc->config |= ARCH_PERFMON_EVENTSEL_INT;
+
+       if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1)
+               intel_pmu_lbr_disable(event);
+}
+
+static void intel_pmu_pebs_enable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->pebs_enabled)
+               wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
+}
+
+static void intel_pmu_pebs_disable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->pebs_enabled)
+               wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
+}
+
+#include <asm/insn.h>
+
+static inline bool kernel_ip(unsigned long ip)
+{
+#ifdef CONFIG_X86_32
+       return ip > PAGE_OFFSET;
+#else
+       return (long)ip < 0;
+#endif
+}
+
+static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       unsigned long from = cpuc->lbr_entries[0].from;
+       unsigned long old_to, to = cpuc->lbr_entries[0].to;
+       unsigned long ip = regs->ip;
+
+       /*
+        * We don't need to fixup if the PEBS assist is fault like
+        */
+       if (!x86_pmu.intel_cap.pebs_trap)
+               return 1;
+
+       /*
+        * No LBR entry, no basic block, no rewinding
+        */
+       if (!cpuc->lbr_stack.nr || !from || !to)
+               return 0;
+
+       /*
+        * Basic blocks should never cross user/kernel boundaries
+        */
+       if (kernel_ip(ip) != kernel_ip(to))
+               return 0;
+
+       /*
+        * unsigned math, either ip is before the start (impossible) or
+        * the basic block is larger than 1 page (sanity)
+        */
+       if ((ip - to) > PAGE_SIZE)
+               return 0;
+
+       /*
+        * We sampled a branch insn, rewind using the LBR stack
+        */
+       if (ip == to) {
+               regs->ip = from;
+               return 1;
+       }
+
+       do {
+               struct insn insn;
+               u8 buf[MAX_INSN_SIZE];
+               void *kaddr;
+
+               old_to = to;
+               if (!kernel_ip(ip)) {
+                       int bytes, size = MAX_INSN_SIZE;
+
+                       bytes = copy_from_user_nmi(buf, (void __user *)to, size);
+                       if (bytes != size)
+                               return 0;
+
+                       kaddr = buf;
+               } else
+                       kaddr = (void *)to;
+
+               kernel_insn_init(&insn, kaddr);
+               insn_get_length(&insn);
+               to += insn.length;
+       } while (to < ip);
+
+       if (to == ip) {
+               regs->ip = old_to;
+               return 1;
+       }
+
+       /*
+        * Even though we decoded the basic block, the instruction stream
+        * never matched the given IP, either the TO or the IP got corrupted.
+        */
+       return 0;
+}
+
+static int intel_pmu_save_and_restart(struct perf_event *event);
+
+static void __intel_pmu_pebs_event(struct perf_event *event,
+                                  struct pt_regs *iregs, void *__pebs)
+{
+       /*
+        * We cast to pebs_record_core since that is a subset of
+        * both formats and we don't use the other fields in this
+        * routine.
+        */
+       struct pebs_record_core *pebs = __pebs;
+       struct perf_sample_data data;
+       struct pt_regs regs;
+
+       if (!intel_pmu_save_and_restart(event))
+               return;
+
+       perf_sample_data_init(&data, 0);
+       data.period = event->hw.last_period;
+
+       /*
+        * We use the interrupt regs as a base because the PEBS record
+        * does not contain a full regs set, specifically it seems to
+        * lack segment descriptors, which get used by things like
+        * user_mode().
+        *
+        * In the simple case fix up only the IP and BP,SP regs, for
+        * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
+        * A possible PERF_SAMPLE_REGS will have to transfer all regs.
+        */
+       regs = *iregs;
+       regs.ip = pebs->ip;
+       regs.bp = pebs->bp;
+       regs.sp = pebs->sp;
+
+       if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(&regs))
+               regs.flags |= PERF_EFLAGS_EXACT;
+       else
+               regs.flags &= ~PERF_EFLAGS_EXACT;
+
+       if (perf_event_overflow(event, 1, &data, &regs))
+               x86_pmu_stop(event);
+}
+
+static void intel_pmu_drain_pebs_core(struct pt_regs *iregs)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct debug_store *ds = cpuc->ds;
+       struct perf_event *event = cpuc->events[0]; /* PMC0 only */
+       struct pebs_record_core *at, *top;
+       int n;
+
+       if (!ds || !x86_pmu.pebs)
+               return;
+
+       at  = (struct pebs_record_core *)(unsigned long)ds->pebs_buffer_base;
+       top = (struct pebs_record_core *)(unsigned long)ds->pebs_index;
+
+       /*
+        * Whatever else happens, drain the thing
+        */
+       ds->pebs_index = ds->pebs_buffer_base;
+
+       if (!test_bit(0, cpuc->active_mask))
+               return;
+
+       WARN_ON_ONCE(!event);
+
+       if (!event->attr.precise_ip)
+               return;
+
+       n = top - at;
+       if (n <= 0)
+               return;
+
+       /*
+        * Should not happen, we program the threshold at 1 and do not
+        * set a reset value.
+        */
+       WARN_ON_ONCE(n > 1);
+       at += n - 1;
+
+       __intel_pmu_pebs_event(event, iregs, at);
+}
+
+static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       struct debug_store *ds = cpuc->ds;
+       struct pebs_record_nhm *at, *top;
+       struct perf_event *event = NULL;
+       u64 status = 0;
+       int bit, n;
+
+       if (!ds || !x86_pmu.pebs)
+               return;
+
+       at  = (struct pebs_record_nhm *)(unsigned long)ds->pebs_buffer_base;
+       top = (struct pebs_record_nhm *)(unsigned long)ds->pebs_index;
+
+       ds->pebs_index = ds->pebs_buffer_base;
+
+       n = top - at;
+       if (n <= 0)
+               return;
+
+       /*
+        * Should not happen, we program the threshold at 1 and do not
+        * set a reset value.
+        */
+       WARN_ON_ONCE(n > MAX_PEBS_EVENTS);
+
+       for ( ; at < top; at++) {
+               for_each_set_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) {
+                       event = cpuc->events[bit];
+                       if (!test_bit(bit, cpuc->active_mask))
+                               continue;
+
+                       WARN_ON_ONCE(!event);
+
+                       if (!event->attr.precise_ip)
+                               continue;
+
+                       if (__test_and_set_bit(bit, (unsigned long *)&status))
+                               continue;
+
+                       break;
+               }
+
+               if (!event || bit >= MAX_PEBS_EVENTS)
+                       continue;
+
+               __intel_pmu_pebs_event(event, iregs, at);
+       }
+}
+
+/*
+ * BTS, PEBS probe and setup
+ */
+
+static void intel_ds_init(void)
+{
+       /*
+        * No support for 32bit formats
+        */
+       if (!boot_cpu_has(X86_FEATURE_DTES64))
+               return;
+
+       x86_pmu.bts  = boot_cpu_has(X86_FEATURE_BTS);
+       x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
+       if (x86_pmu.pebs) {
+               char pebs_type = x86_pmu.intel_cap.pebs_trap ?  '+' : '-';
+               int format = x86_pmu.intel_cap.pebs_format;
+
+               switch (format) {
+               case 0:
+                       printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
+                       x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
+                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
+                       x86_pmu.pebs_constraints = intel_core_pebs_events;
+                       break;
+
+               case 1:
+                       printk(KERN_CONT "PEBS fmt1%c, ", pebs_type);
+                       x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm);
+                       x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm;
+                       x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
+                       break;
+
+               default:
+                       printk(KERN_CONT "no PEBS fmt%d%c, ", format, pebs_type);
+                       x86_pmu.pebs = 0;
+                       break;
+               }
+       }
+}
+
+#else /* CONFIG_CPU_SUP_INTEL */
+
+static int reserve_ds_buffers(void)
+{
+       return 0;
+}
+
+static void release_ds_buffers(void)
+{
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
new file mode 100644 (file)
index 0000000..d202c1b
--- /dev/null
@@ -0,0 +1,218 @@
+#ifdef CONFIG_CPU_SUP_INTEL
+
+enum {
+       LBR_FORMAT_32           = 0x00,
+       LBR_FORMAT_LIP          = 0x01,
+       LBR_FORMAT_EIP          = 0x02,
+       LBR_FORMAT_EIP_FLAGS    = 0x03,
+};
+
+/*
+ * We only support LBR implementations that have FREEZE_LBRS_ON_PMI
+ * otherwise it becomes near impossible to get a reliable stack.
+ */
+
+static void __intel_pmu_lbr_enable(void)
+{
+       u64 debugctl;
+
+       rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+       debugctl |= (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+       wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void __intel_pmu_lbr_disable(void)
+{
+       u64 debugctl;
+
+       rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+       debugctl &= ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI);
+       wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl);
+}
+
+static void intel_pmu_lbr_reset_32(void)
+{
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++)
+               wrmsrl(x86_pmu.lbr_from + i, 0);
+}
+
+static void intel_pmu_lbr_reset_64(void)
+{
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               wrmsrl(x86_pmu.lbr_from + i, 0);
+               wrmsrl(x86_pmu.lbr_to   + i, 0);
+       }
+}
+
+static void intel_pmu_lbr_reset(void)
+{
+       if (!x86_pmu.lbr_nr)
+               return;
+
+       if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+               intel_pmu_lbr_reset_32();
+       else
+               intel_pmu_lbr_reset_64();
+}
+
+static void intel_pmu_lbr_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!x86_pmu.lbr_nr)
+               return;
+
+       WARN_ON_ONCE(cpuc->enabled);
+
+       /*
+        * Reset the LBR stack if we changed task context to
+        * avoid data leaks.
+        */
+
+       if (event->ctx->task && cpuc->lbr_context != event->ctx) {
+               intel_pmu_lbr_reset();
+               cpuc->lbr_context = event->ctx;
+       }
+
+       cpuc->lbr_users++;
+}
+
+static void intel_pmu_lbr_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!x86_pmu.lbr_nr)
+               return;
+
+       cpuc->lbr_users--;
+       WARN_ON_ONCE(cpuc->lbr_users < 0);
+
+       if (cpuc->enabled && !cpuc->lbr_users)
+               __intel_pmu_lbr_disable();
+}
+
+static void intel_pmu_lbr_enable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->lbr_users)
+               __intel_pmu_lbr_enable();
+}
+
+static void intel_pmu_lbr_disable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (cpuc->lbr_users)
+               __intel_pmu_lbr_disable();
+}
+
+static inline u64 intel_pmu_lbr_tos(void)
+{
+       u64 tos;
+
+       rdmsrl(x86_pmu.lbr_tos, tos);
+
+       return tos;
+}
+
+static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
+{
+       unsigned long mask = x86_pmu.lbr_nr - 1;
+       u64 tos = intel_pmu_lbr_tos();
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               unsigned long lbr_idx = (tos - i) & mask;
+               union {
+                       struct {
+                               u32 from;
+                               u32 to;
+                       };
+                       u64     lbr;
+               } msr_lastbranch;
+
+               rdmsrl(x86_pmu.lbr_from + lbr_idx, msr_lastbranch.lbr);
+
+               cpuc->lbr_entries[i].from  = msr_lastbranch.from;
+               cpuc->lbr_entries[i].to    = msr_lastbranch.to;
+               cpuc->lbr_entries[i].flags = 0;
+       }
+       cpuc->lbr_stack.nr = i;
+}
+
+#define LBR_FROM_FLAG_MISPRED  (1ULL << 63)
+
+/*
+ * Due to lack of segmentation in Linux the effective address (offset)
+ * is the same as the linear address, allowing us to merge the LIP and EIP
+ * LBR formats.
+ */
+static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
+{
+       unsigned long mask = x86_pmu.lbr_nr - 1;
+       int lbr_format = x86_pmu.intel_cap.lbr_format;
+       u64 tos = intel_pmu_lbr_tos();
+       int i;
+
+       for (i = 0; i < x86_pmu.lbr_nr; i++) {
+               unsigned long lbr_idx = (tos - i) & mask;
+               u64 from, to, flags = 0;
+
+               rdmsrl(x86_pmu.lbr_from + lbr_idx, from);
+               rdmsrl(x86_pmu.lbr_to   + lbr_idx, to);
+
+               if (lbr_format == LBR_FORMAT_EIP_FLAGS) {
+                       flags = !!(from & LBR_FROM_FLAG_MISPRED);
+                       from = (u64)((((s64)from) << 1) >> 1);
+               }
+
+               cpuc->lbr_entries[i].from  = from;
+               cpuc->lbr_entries[i].to    = to;
+               cpuc->lbr_entries[i].flags = flags;
+       }
+       cpuc->lbr_stack.nr = i;
+}
+
+static void intel_pmu_lbr_read(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+       if (!cpuc->lbr_users)
+               return;
+
+       if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+               intel_pmu_lbr_read_32(cpuc);
+       else
+               intel_pmu_lbr_read_64(cpuc);
+}
+
+static void intel_pmu_lbr_init_core(void)
+{
+       x86_pmu.lbr_nr     = 4;
+       x86_pmu.lbr_tos    = 0x01c9;
+       x86_pmu.lbr_from   = 0x40;
+       x86_pmu.lbr_to     = 0x60;
+}
+
+static void intel_pmu_lbr_init_nhm(void)
+{
+       x86_pmu.lbr_nr     = 16;
+       x86_pmu.lbr_tos    = 0x01c9;
+       x86_pmu.lbr_from   = 0x680;
+       x86_pmu.lbr_to     = 0x6c0;
+}
+
+static void intel_pmu_lbr_init_atom(void)
+{
+       x86_pmu.lbr_nr     = 8;
+       x86_pmu.lbr_tos    = 0x01c9;
+       x86_pmu.lbr_from   = 0x40;
+       x86_pmu.lbr_to     = 0x60;
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c
new file mode 100644 (file)
index 0000000..424fc8d
--- /dev/null
@@ -0,0 +1,857 @@
+/*
+ * Netburst Perfomance Events (P4, old Xeon)
+ *
+ *  Copyright (C) 2010 Parallels, Inc., Cyrill Gorcunov <gorcunov@openvz.org>
+ *  Copyright (C) 2010 Intel Corporation, Lin Ming <ming.m.lin@intel.com>
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#ifdef CONFIG_CPU_SUP_INTEL
+
+#include <asm/perf_event_p4.h>
+
+#define P4_CNTR_LIMIT 3
+/*
+ * array indices: 0,1 - HT threads, used with HT enabled cpu
+ */
+struct p4_event_bind {
+       unsigned int opcode;                    /* Event code and ESCR selector */
+       unsigned int escr_msr[2];               /* ESCR MSR for this event */
+       char cntr[2][P4_CNTR_LIMIT];            /* counter index (offset), -1 on abscence */
+};
+
+struct p4_cache_event_bind {
+       unsigned int metric_pebs;
+       unsigned int metric_vert;
+};
+
+#define P4_GEN_CACHE_EVENT_BIND(name)          \
+       [P4_CACHE__##name] = {                  \
+               .metric_pebs = P4_PEBS__##name, \
+               .metric_vert = P4_VERT__##name, \
+       }
+
+static struct p4_cache_event_bind p4_cache_event_bind_map[] = {
+       P4_GEN_CACHE_EVENT_BIND(1stl_cache_load_miss_retired),
+       P4_GEN_CACHE_EVENT_BIND(2ndl_cache_load_miss_retired),
+       P4_GEN_CACHE_EVENT_BIND(dtlb_load_miss_retired),
+       P4_GEN_CACHE_EVENT_BIND(dtlb_store_miss_retired),
+};
+
+/*
+ * Note that we don't use CCCR1 here, there is an
+ * exception for P4_BSQ_ALLOCATION but we just have
+ * no workaround
+ *
+ * consider this binding as resources which particular
+ * event may borrow, it doesn't contain EventMask,
+ * Tags and friends -- they are left to a caller
+ */
+static struct p4_event_bind p4_event_bind_map[] = {
+       [P4_EVENT_TC_DELIVER_MODE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_TC_DELIVER_MODE),
+               .escr_msr       = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_BPU_FETCH_REQUEST] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BPU_FETCH_REQUEST),
+               .escr_msr       = { MSR_P4_BPU_ESCR0, MSR_P4_BPU_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_ITLB_REFERENCE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_ITLB_REFERENCE),
+               .escr_msr       = { MSR_P4_ITLB_ESCR0, MSR_P4_ITLB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_MEMORY_CANCEL] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MEMORY_CANCEL),
+               .escr_msr       = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_MEMORY_COMPLETE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MEMORY_COMPLETE),
+               .escr_msr       = { MSR_P4_SAAT_ESCR0 , MSR_P4_SAAT_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_LOAD_PORT_REPLAY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_LOAD_PORT_REPLAY),
+               .escr_msr       = { MSR_P4_SAAT_ESCR0, MSR_P4_SAAT_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_STORE_PORT_REPLAY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_STORE_PORT_REPLAY),
+               .escr_msr       = { MSR_P4_SAAT_ESCR0 ,  MSR_P4_SAAT_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_MOB_LOAD_REPLAY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MOB_LOAD_REPLAY),
+               .escr_msr       = { MSR_P4_MOB_ESCR0, MSR_P4_MOB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_PAGE_WALK_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_PAGE_WALK_TYPE),
+               .escr_msr       = { MSR_P4_PMH_ESCR0, MSR_P4_PMH_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_BSQ_CACHE_REFERENCE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BSQ_CACHE_REFERENCE),
+               .escr_msr       = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_IOQ_ALLOCATION] = {
+               .opcode         = P4_OPCODE(P4_EVENT_IOQ_ALLOCATION),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_IOQ_ACTIVE_ENTRIES] = {       /* shared ESCR */
+               .opcode         = P4_OPCODE(P4_EVENT_IOQ_ACTIVE_ENTRIES),
+               .escr_msr       = { MSR_P4_FSB_ESCR1,  MSR_P4_FSB_ESCR1 },
+               .cntr           = { {2, -1, -1}, {3, -1, -1} },
+       },
+       [P4_EVENT_FSB_DATA_ACTIVITY] = {
+               .opcode         = P4_OPCODE(P4_EVENT_FSB_DATA_ACTIVITY),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_BSQ_ALLOCATION] = {           /* shared ESCR, broken CCCR1 */
+               .opcode         = P4_OPCODE(P4_EVENT_BSQ_ALLOCATION),
+               .escr_msr       = { MSR_P4_BSU_ESCR0, MSR_P4_BSU_ESCR0 },
+               .cntr           = { {0, -1, -1}, {1, -1, -1} },
+       },
+       [P4_EVENT_BSQ_ACTIVE_ENTRIES] = {       /* shared ESCR */
+               .opcode         = P4_OPCODE(P4_EVENT_BSQ_ACTIVE_ENTRIES),
+               .escr_msr       = { MSR_P4_BSU_ESCR1 , MSR_P4_BSU_ESCR1 },
+               .cntr           = { {2, -1, -1}, {3, -1, -1} },
+       },
+       [P4_EVENT_SSE_INPUT_ASSIST] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SSE_INPUT_ASSIST),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_PACKED_SP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_PACKED_SP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_PACKED_DP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_PACKED_DP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_SCALAR_SP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SCALAR_SP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_SCALAR_DP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SCALAR_DP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_64BIT_MMX_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_64BIT_MMX_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_128BIT_MMX_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_128BIT_MMX_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_X87_FP_UOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_X87_FP_UOP),
+               .escr_msr       = { MSR_P4_FIRM_ESCR0, MSR_P4_FIRM_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_TC_MISC] = {
+               .opcode         = P4_OPCODE(P4_EVENT_TC_MISC),
+               .escr_msr       = { MSR_P4_TC_ESCR0, MSR_P4_TC_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_GLOBAL_POWER_EVENTS] = {
+               .opcode         = P4_OPCODE(P4_EVENT_GLOBAL_POWER_EVENTS),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_TC_MS_XFER] = {
+               .opcode         = P4_OPCODE(P4_EVENT_TC_MS_XFER),
+               .escr_msr       = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_UOP_QUEUE_WRITES] = {
+               .opcode         = P4_OPCODE(P4_EVENT_UOP_QUEUE_WRITES),
+               .escr_msr       = { MSR_P4_MS_ESCR0, MSR_P4_MS_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RETIRED_MISPRED_BRANCH_TYPE),
+               .escr_msr       = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR0 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_RETIRED_BRANCH_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RETIRED_BRANCH_TYPE),
+               .escr_msr       = { MSR_P4_TBPU_ESCR0 , MSR_P4_TBPU_ESCR1 },
+               .cntr           = { {4, 5, -1}, {6, 7, -1} },
+       },
+       [P4_EVENT_RESOURCE_STALL] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RESOURCE_STALL),
+               .escr_msr       = { MSR_P4_ALF_ESCR0, MSR_P4_ALF_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_WC_BUFFER] = {
+               .opcode         = P4_OPCODE(P4_EVENT_WC_BUFFER),
+               .escr_msr       = { MSR_P4_DAC_ESCR0, MSR_P4_DAC_ESCR1 },
+               .cntr           = { {8, 9, -1}, {10, 11, -1} },
+       },
+       [P4_EVENT_B2B_CYCLES] = {
+               .opcode         = P4_OPCODE(P4_EVENT_B2B_CYCLES),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_BNR] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BNR),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_SNOOP] = {
+               .opcode         = P4_OPCODE(P4_EVENT_SNOOP),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_RESPONSE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_RESPONSE),
+               .escr_msr       = { MSR_P4_FSB_ESCR0, MSR_P4_FSB_ESCR1 },
+               .cntr           = { {0, -1, -1}, {2, -1, -1} },
+       },
+       [P4_EVENT_FRONT_END_EVENT] = {
+               .opcode         = P4_OPCODE(P4_EVENT_FRONT_END_EVENT),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_EXECUTION_EVENT] = {
+               .opcode         = P4_OPCODE(P4_EVENT_EXECUTION_EVENT),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_REPLAY_EVENT] = {
+               .opcode         = P4_OPCODE(P4_EVENT_REPLAY_EVENT),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_INSTR_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_INSTR_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_UOPS_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_UOPS_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_UOP_TYPE] = {
+               .opcode         = P4_OPCODE(P4_EVENT_UOP_TYPE),
+               .escr_msr       = { MSR_P4_RAT_ESCR0, MSR_P4_RAT_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_BRANCH_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_BRANCH_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_MISPRED_BRANCH_RETIRED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_X87_ASSIST] = {
+               .opcode         = P4_OPCODE(P4_EVENT_X87_ASSIST),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_MACHINE_CLEAR] = {
+               .opcode         = P4_OPCODE(P4_EVENT_MACHINE_CLEAR),
+               .escr_msr       = { MSR_P4_CRU_ESCR2, MSR_P4_CRU_ESCR3 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+       [P4_EVENT_INSTR_COMPLETED] = {
+               .opcode         = P4_OPCODE(P4_EVENT_INSTR_COMPLETED),
+               .escr_msr       = { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
+               .cntr           = { {12, 13, 16}, {14, 15, 17} },
+       },
+};
+
+#define P4_GEN_CACHE_EVENT(event, bit, cache_event)                      \
+       p4_config_pack_escr(P4_ESCR_EVENT(event)                        | \
+                           P4_ESCR_EMASK_BIT(event, bit))              | \
+       p4_config_pack_cccr(cache_event                                 | \
+                           P4_CCCR_ESEL(P4_OPCODE_ESEL(P4_OPCODE(event))))
+
+static __initconst const u64 p4_hw_cache_event_ids
+                               [PERF_COUNT_HW_CACHE_MAX]
+                               [PERF_COUNT_HW_CACHE_OP_MAX]
+                               [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D ) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__1stl_cache_load_miss_retired),
+       },
+ },
+ [ C(LL  ) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__2ndl_cache_load_miss_retired),
+       },
+},
+ [ C(DTLB) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__dtlb_load_miss_retired),
+       },
+       [ C(OP_WRITE) ] = {
+               [ C(RESULT_ACCESS) ] = 0x0,
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_REPLAY_EVENT, NBOGUS,
+                                               P4_CACHE__dtlb_store_miss_retired),
+       },
+ },
+ [ C(ITLB) ] = {
+       [ C(OP_READ) ] = {
+               [ C(RESULT_ACCESS) ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, HIT,
+                                               P4_CACHE__itlb_reference_hit),
+               [ C(RESULT_MISS)   ] = P4_GEN_CACHE_EVENT(P4_EVENT_ITLB_REFERENCE, MISS,
+                                               P4_CACHE__itlb_reference_miss),
+       },
+       [ C(OP_WRITE) ] = {
+               [ C(RESULT_ACCESS) ] = -1,
+               [ C(RESULT_MISS)   ] = -1,
+       },
+       [ C(OP_PREFETCH) ] = {
+               [ C(RESULT_ACCESS) ] = -1,
+               [ C(RESULT_MISS)   ] = -1,
+       },
+ },
+};
+
+static u64 p4_general_events[PERF_COUNT_HW_MAX] = {
+  /* non-halted CPU clocks */
+  [PERF_COUNT_HW_CPU_CYCLES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_GLOBAL_POWER_EVENTS)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_GLOBAL_POWER_EVENTS, RUNNING)),
+
+  /*
+   * retired instructions
+   * in a sake of simplicity we don't use the FSB tagging
+   */
+  [PERF_COUNT_HW_INSTRUCTIONS] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_INSTR_RETIRED)               |
+               P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, NBOGUSNTAG)           |
+               P4_ESCR_EMASK_BIT(P4_EVENT_INSTR_RETIRED, BOGUSNTAG)),
+
+  /* cache hits */
+  [PERF_COUNT_HW_CACHE_REFERENCES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITE)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_HITM)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITE)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_HITM)),
+
+  /* cache misses */
+  [PERF_COUNT_HW_CACHE_MISSES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_BSQ_CACHE_REFERENCE)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_2ndL_MISS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, RD_3rdL_MISS)   |
+               P4_ESCR_EMASK_BIT(P4_EVENT_BSQ_CACHE_REFERENCE, WR_2ndL_MISS)),
+
+  /* branch instructions retired */
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_RETIRED_BRANCH_TYPE)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CONDITIONAL)    |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, CALL)           |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, RETURN)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_RETIRED_BRANCH_TYPE, INDIRECT)),
+
+  /* mispredicted branches retired */
+  [PERF_COUNT_HW_BRANCH_MISSES]        =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_MISPRED_BRANCH_RETIRED)      |
+               P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS)),
+
+  /* bus ready clocks (cpu is driving #DRDY_DRV\#DRDY_OWN):  */
+  [PERF_COUNT_HW_BUS_CYCLES] =
+       p4_config_pack_escr(P4_ESCR_EVENT(P4_EVENT_FSB_DATA_ACTIVITY)           |
+               P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_DRV)         |
+               P4_ESCR_EMASK_BIT(P4_EVENT_FSB_DATA_ACTIVITY, DRDY_OWN))        |
+       p4_config_pack_cccr(P4_CCCR_EDGE | P4_CCCR_COMPARE),
+};
+
+static struct p4_event_bind *p4_config_get_bind(u64 config)
+{
+       unsigned int evnt = p4_config_unpack_event(config);
+       struct p4_event_bind *bind = NULL;
+
+       if (evnt < ARRAY_SIZE(p4_event_bind_map))
+               bind = &p4_event_bind_map[evnt];
+
+       return bind;
+}
+
+static u64 p4_pmu_event_map(int hw_event)
+{
+       struct p4_event_bind *bind;
+       unsigned int esel;
+       u64 config;
+
+       config = p4_general_events[hw_event];
+       bind = p4_config_get_bind(config);
+       esel = P4_OPCODE_ESEL(bind->opcode);
+       config |= p4_config_pack_cccr(P4_CCCR_ESEL(esel));
+
+       return config;
+}
+
+static int p4_hw_config(struct perf_event *event)
+{
+       int cpu = get_cpu();
+       int rc = 0;
+       unsigned int evnt;
+       u32 escr, cccr;
+
+       /*
+        * the reason we use cpu that early is that: if we get scheduled
+        * first time on the same cpu -- we will not need swap thread
+        * specific flags in config (and will save some cpu cycles)
+        */
+
+       cccr = p4_default_cccr_conf(cpu);
+       escr = p4_default_escr_conf(cpu, event->attr.exclude_kernel,
+                                        event->attr.exclude_user);
+       event->hw.config = p4_config_pack_escr(escr) |
+                          p4_config_pack_cccr(cccr);
+
+       if (p4_ht_active() && p4_ht_thread(cpu))
+               event->hw.config = p4_set_ht_bit(event->hw.config);
+
+       if (event->attr.type == PERF_TYPE_RAW) {
+
+               /* user data may have out-of-bound event index */
+               evnt = p4_config_unpack_event(event->attr.config);
+               if (evnt >= ARRAY_SIZE(p4_event_bind_map)) {
+                       rc = -EINVAL;
+                       goto out;
+               }
+
+               /*
+                * We don't control raw events so it's up to the caller
+                * to pass sane values (and we don't count the thread number
+                * on HT machine but allow HT-compatible specifics to be
+                * passed on)
+                *
+                * XXX: HT wide things should check perf_paranoid_cpu() &&
+                *      CAP_SYS_ADMIN
+                */
+               event->hw.config |= event->attr.config &
+                       (p4_config_pack_escr(P4_ESCR_MASK_HT) |
+                        p4_config_pack_cccr(P4_CCCR_MASK_HT));
+       }
+
+       rc = x86_setup_perfctr(event);
+out:
+       put_cpu();
+       return rc;
+}
+
+static inline void p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
+{
+       unsigned long dummy;
+
+       rdmsrl(hwc->config_base + hwc->idx, dummy);
+       if (dummy & P4_CCCR_OVF) {
+               (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+                       ((u64)dummy) & ~P4_CCCR_OVF);
+       }
+}
+
+static inline void p4_pmu_disable_event(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+
+       /*
+        * If event gets disabled while counter is in overflowed
+        * state we need to clear P4_CCCR_OVF, otherwise interrupt get
+        * asserted again and again
+        */
+       (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+               (u64)(p4_config_unpack_cccr(hwc->config)) &
+                       ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED);
+}
+
+static void p4_pmu_disable_all(void)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int idx;
+
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+               struct perf_event *event = cpuc->events[idx];
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+               p4_pmu_disable_event(event);
+       }
+}
+
+static void p4_pmu_enable_event(struct perf_event *event)
+{
+       struct hw_perf_event *hwc = &event->hw;
+       int thread = p4_ht_config_thread(hwc->config);
+       u64 escr_conf = p4_config_unpack_escr(p4_clear_ht_bit(hwc->config));
+       unsigned int idx = p4_config_unpack_event(hwc->config);
+       unsigned int idx_cache = p4_config_unpack_cache_event(hwc->config);
+       struct p4_event_bind *bind;
+       struct p4_cache_event_bind *bind_cache;
+       u64 escr_addr, cccr;
+
+       bind = &p4_event_bind_map[idx];
+       escr_addr = (u64)bind->escr_msr[thread];
+
+       /*
+        * - we dont support cascaded counters yet
+        * - and counter 1 is broken (erratum)
+        */
+       WARN_ON_ONCE(p4_is_event_cascaded(hwc->config));
+       WARN_ON_ONCE(hwc->idx == 1);
+
+       /* we need a real Event value */
+       escr_conf &= ~P4_ESCR_EVENT_MASK;
+       escr_conf |= P4_ESCR_EVENT(P4_OPCODE_EVNT(bind->opcode));
+
+       cccr = p4_config_unpack_cccr(hwc->config);
+
+       /*
+        * it could be Cache event so that we need to
+        * set metrics into additional MSRs
+        */
+       BUILD_BUG_ON(P4_CACHE__MAX > P4_CCCR_CACHE_OPS_MASK);
+       if (idx_cache > P4_CACHE__NONE &&
+               idx_cache < ARRAY_SIZE(p4_cache_event_bind_map)) {
+               bind_cache = &p4_cache_event_bind_map[idx_cache];
+               (void)checking_wrmsrl(MSR_IA32_PEBS_ENABLE, (u64)bind_cache->metric_pebs);
+               (void)checking_wrmsrl(MSR_P4_PEBS_MATRIX_VERT, (u64)bind_cache->metric_vert);
+       }
+
+       (void)checking_wrmsrl(escr_addr, escr_conf);
+       (void)checking_wrmsrl(hwc->config_base + hwc->idx,
+                               (cccr & ~P4_CCCR_RESERVED) | P4_CCCR_ENABLE);
+}
+
+static void p4_pmu_enable_all(int added)
+{
+       struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+       int idx;
+
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+               struct perf_event *event = cpuc->events[idx];
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+               p4_pmu_enable_event(event);
+       }
+}
+
+static int p4_pmu_handle_irq(struct pt_regs *regs)
+{
+       struct perf_sample_data data;
+       struct cpu_hw_events *cpuc;
+       struct perf_event *event;
+       struct hw_perf_event *hwc;
+       int idx, handled = 0;
+       u64 val;
+
+       data.addr = 0;
+       data.raw = NULL;
+
+       cpuc = &__get_cpu_var(cpu_hw_events);
+
+       for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+
+               if (!test_bit(idx, cpuc->active_mask))
+                       continue;
+
+               event = cpuc->events[idx];
+               hwc = &event->hw;
+
+               WARN_ON_ONCE(hwc->idx != idx);
+
+               /*
+                * FIXME: Redundant call, actually not needed
+                * but just to check if we're screwed
+                */
+               p4_pmu_clear_cccr_ovf(hwc);
+
+               val = x86_perf_event_update(event);
+               if (val & (1ULL << (x86_pmu.cntval_bits - 1)))
+                       continue;
+
+               /*
+                * event overflow
+                */
+               handled         = 1;
+               data.period     = event->hw.last_period;
+
+               if (!x86_perf_event_set_period(event))
+                       continue;
+               if (perf_event_overflow(event, 1, &data, regs))
+                       p4_pmu_disable_event(event);
+       }
+
+       if (handled) {
+               /* p4 quirk: unmask it again */
+               apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
+               inc_irq_stat(apic_perf_irqs);
+       }
+
+       return handled;
+}
+
+/*
+ * swap thread specific fields according to a thread
+ * we are going to run on
+ */
+static void p4_pmu_swap_config_ts(struct hw_perf_event *hwc, int cpu)
+{
+       u32 escr, cccr;
+
+       /*
+        * we either lucky and continue on same cpu or no HT support
+        */
+       if (!p4_should_swap_ts(hwc->config, cpu))
+               return;
+
+       /*
+        * the event is migrated from an another logical
+        * cpu, so we need to swap thread specific flags
+        */
+
+       escr = p4_config_unpack_escr(hwc->config);
+       cccr = p4_config_unpack_cccr(hwc->config);
+
+       if (p4_ht_thread(cpu)) {
+               cccr &= ~P4_CCCR_OVF_PMI_T0;
+               cccr |= P4_CCCR_OVF_PMI_T1;
+               if (escr & P4_ESCR_T0_OS) {
+                       escr &= ~P4_ESCR_T0_OS;
+                       escr |= P4_ESCR_T1_OS;
+               }
+               if (escr & P4_ESCR_T0_USR) {
+                       escr &= ~P4_ESCR_T0_USR;
+                       escr |= P4_ESCR_T1_USR;
+               }
+               hwc->config  = p4_config_pack_escr(escr);
+               hwc->config |= p4_config_pack_cccr(cccr);
+               hwc->config |= P4_CONFIG_HT;
+       } else {
+               cccr &= ~P4_CCCR_OVF_PMI_T1;
+               cccr |= P4_CCCR_OVF_PMI_T0;
+               if (escr & P4_ESCR_T1_OS) {
+                       escr &= ~P4_ESCR_T1_OS;
+                       escr |= P4_ESCR_T0_OS;
+               }
+               if (escr & P4_ESCR_T1_USR) {
+                       escr &= ~P4_ESCR_T1_USR;
+                       escr |= P4_ESCR_T0_USR;
+               }
+               hwc->config  = p4_config_pack_escr(escr);
+               hwc->config |= p4_config_pack_cccr(cccr);
+               hwc->config &= ~P4_CONFIG_HT;
+       }
+}
+
+/*
+ * ESCR address hashing is tricky, ESCRs are not sequential
+ * in memory but all starts from MSR_P4_BSU_ESCR0 (0x03e0) and
+ * the metric between any ESCRs is laid in range [0xa0,0xe1]
+ *
+ * so we make ~70% filled hashtable
+ */
+
+#define P4_ESCR_MSR_BASE               0x000003a0
+#define P4_ESCR_MSR_MAX                        0x000003e1
+#define P4_ESCR_MSR_TABLE_SIZE         (P4_ESCR_MSR_MAX - P4_ESCR_MSR_BASE + 1)
+#define P4_ESCR_MSR_IDX(msr)           (msr - P4_ESCR_MSR_BASE)
+#define P4_ESCR_MSR_TABLE_ENTRY(msr)   [P4_ESCR_MSR_IDX(msr)] = msr
+
+static const unsigned int p4_escr_table[P4_ESCR_MSR_TABLE_SIZE] = {
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ALF_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BPU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_BSU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR2),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR3),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR4),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_CRU_ESCR5),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_DAC_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FIRM_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FLAME_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_FSB_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IQ_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IS_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_ITLB_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_IX_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MOB_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_MS_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_PMH_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_RAT_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SAAT_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_SSU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TBPU_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_TC_ESCR1),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR0),
+       P4_ESCR_MSR_TABLE_ENTRY(MSR_P4_U2L_ESCR1),
+};
+
+static int p4_get_escr_idx(unsigned int addr)
+{
+       unsigned int idx = P4_ESCR_MSR_IDX(addr);
+
+       if (unlikely(idx >= P4_ESCR_MSR_TABLE_SIZE ||
+                       !p4_escr_table[idx])) {
+               WARN_ONCE(1, "P4 PMU: Wrong address passed: %x\n", addr);
+               return -1;
+       }
+
+       return idx;
+}
+
+static int p4_next_cntr(int thread, unsigned long *used_mask,
+                       struct p4_event_bind *bind)
+{
+       int i, j;
+
+       for (i = 0; i < P4_CNTR_LIMIT; i++) {
+               j = bind->cntr[thread][i];
+               if (j != -1 && !test_bit(j, used_mask))
+                       return j;
+       }
+
+       return -1;
+}
+
+static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
+{
+       unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+       unsigned long escr_mask[BITS_TO_LONGS(P4_ESCR_MSR_TABLE_SIZE)];
+       int cpu = raw_smp_processor_id();
+       struct hw_perf_event *hwc;
+       struct p4_event_bind *bind;
+       unsigned int i, thread, num;
+       int cntr_idx, escr_idx;
+
+       bitmap_zero(used_mask, X86_PMC_IDX_MAX);
+       bitmap_zero(escr_mask, P4_ESCR_MSR_TABLE_SIZE);
+
+       for (i = 0, num = n; i < n; i++, num--) {
+
+               hwc = &cpuc->event_list[i]->hw;
+               thread = p4_ht_thread(cpu);
+               bind = p4_config_get_bind(hwc->config);
+               escr_idx = p4_get_escr_idx(bind->escr_msr[thread]);
+               if (unlikely(escr_idx == -1))
+                       goto done;
+
+               if (hwc->idx != -1 && !p4_should_swap_ts(hwc->config, cpu)) {
+                       cntr_idx = hwc->idx;
+                       if (assign)
+                               assign[i] = hwc->idx;
+                       goto reserve;
+               }
+
+               cntr_idx = p4_next_cntr(thread, used_mask, bind);
+               if (cntr_idx == -1 || test_bit(escr_idx, escr_mask))
+                       goto done;
+
+               p4_pmu_swap_config_ts(hwc, cpu);
+               if (assign)
+                       assign[i] = cntr_idx;
+reserve:
+               set_bit(cntr_idx, used_mask);
+               set_bit(escr_idx, escr_mask);
+       }
+
+done:
+       return num ? -ENOSPC : 0;
+}
+
+static __initconst const struct x86_pmu p4_pmu = {
+       .name                   = "Netburst P4/Xeon",
+       .handle_irq             = p4_pmu_handle_irq,
+       .disable_all            = p4_pmu_disable_all,
+       .enable_all             = p4_pmu_enable_all,
+       .enable                 = p4_pmu_enable_event,
+       .disable                = p4_pmu_disable_event,
+       .eventsel               = MSR_P4_BPU_CCCR0,
+       .perfctr                = MSR_P4_BPU_PERFCTR0,
+       .event_map              = p4_pmu_event_map,
+       .max_events             = ARRAY_SIZE(p4_general_events),
+       .get_event_constraints  = x86_get_event_constraints,
+       /*
+        * IF HT disabled we may need to use all
+        * ARCH_P4_MAX_CCCR counters simulaneously
+        * though leave it restricted at moment assuming
+        * HT is on
+        */
+       .num_counters           = ARCH_P4_MAX_CCCR,
+       .apic                   = 1,
+       .cntval_bits            = 40,
+       .cntval_mask            = (1ULL << 40) - 1,
+       .max_period             = (1ULL << 39) - 1,
+       .hw_config              = p4_hw_config,
+       .schedule_events        = p4_pmu_schedule_events,
+};
+
+static __init int p4_pmu_init(void)
+{
+       unsigned int low, high;
+
+       /* If we get stripped -- indexig fails */
+       BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC);
+
+       rdmsr(MSR_IA32_MISC_ENABLE, low, high);
+       if (!(low & (1 << 7))) {
+               pr_cont("unsupported Netburst CPU model %d ",
+                       boot_cpu_data.x86_model);
+               return -ENODEV;
+       }
+
+       memcpy(hw_cache_event_ids, p4_hw_cache_event_ids,
+               sizeof(hw_cache_event_ids));
+
+       pr_cont("Netburst events, ");
+
+       x86_pmu = p4_pmu;
+
+       return 0;
+}
+
+#endif /* CONFIG_CPU_SUP_INTEL */
index a330485..34ba07b 100644 (file)
@@ -27,24 +27,6 @@ static u64 p6_pmu_event_map(int hw_event)
  */
 #define P6_NOP_EVENT                   0x0000002EULL
 
-static u64 p6_pmu_raw_event(u64 hw_event)
-{
-#define P6_EVNTSEL_EVENT_MASK          0x000000FFULL
-#define P6_EVNTSEL_UNIT_MASK           0x0000FF00ULL
-#define P6_EVNTSEL_EDGE_MASK           0x00040000ULL
-#define P6_EVNTSEL_INV_MASK            0x00800000ULL
-#define P6_EVNTSEL_REG_MASK            0xFF000000ULL
-
-#define P6_EVNTSEL_MASK                        \
-       (P6_EVNTSEL_EVENT_MASK |        \
-        P6_EVNTSEL_UNIT_MASK  |        \
-        P6_EVNTSEL_EDGE_MASK  |        \
-        P6_EVNTSEL_INV_MASK   |        \
-        P6_EVNTSEL_REG_MASK)
-
-       return hw_event & P6_EVNTSEL_MASK;
-}
-
 static struct event_constraint p6_event_constraints[] =
 {
        INTEL_EVENT_CONSTRAINT(0xc1, 0x1),      /* FLOPS */
@@ -66,7 +48,7 @@ static void p6_pmu_disable_all(void)
        wrmsrl(MSR_P6_EVNTSEL0, val);
 }
 
-static void p6_pmu_enable_all(void)
+static void p6_pmu_enable_all(int added)
 {
        unsigned long val;
 
@@ -102,22 +84,23 @@ static void p6_pmu_enable_event(struct perf_event *event)
        (void)checking_wrmsrl(hwc->config_base + hwc->idx, val);
 }
 
-static __initconst struct x86_pmu p6_pmu = {
+static __initconst const struct x86_pmu p6_pmu = {
        .name                   = "p6",
        .handle_irq             = x86_pmu_handle_irq,
        .disable_all            = p6_pmu_disable_all,
        .enable_all             = p6_pmu_enable_all,
        .enable                 = p6_pmu_enable_event,
        .disable                = p6_pmu_disable_event,
+       .hw_config              = x86_pmu_hw_config,
+       .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_P6_EVNTSEL0,
        .perfctr                = MSR_P6_PERFCTR0,
        .event_map              = p6_pmu_event_map,
-       .raw_event              = p6_pmu_raw_event,
        .max_events             = ARRAY_SIZE(p6_perfmon_event_map),
        .apic                   = 1,
        .max_period             = (1ULL << 31) - 1,
        .version                = 0,
-       .num_events             = 2,
+       .num_counters           = 2,
        /*
         * Events have 40 bits implemented. However they are designed such
         * that bits [32-39] are sign extensions of bit 31. As such the
@@ -125,8 +108,8 @@ static __initconst struct x86_pmu p6_pmu = {
         *
         * See IA-32 Intel Architecture Software developer manual Vol 3B
         */
-       .event_bits             = 32,
-       .event_mask             = (1ULL << 32) - 1,
+       .cntval_bits            = 32,
+       .cntval_mask            = (1ULL << 32) - 1,
        .get_event_constraints  = x86_get_event_constraints,
        .event_constraints      = p6_event_constraints,
 };
index 1cbed97..b9d1ff5 100644 (file)
  */
 
 #include <linux/dmi.h>
+#include <linux/module.h>
 #include <asm/div64.h>
-#include <asm/vmware.h>
 #include <asm/x86_init.h>
+#include <asm/hypervisor.h>
 
 #define CPUID_VMWARE_INFO_LEAF 0x40000000
 #define VMWARE_HYPERVISOR_MAGIC        0x564D5868
@@ -64,7 +65,7 @@ static unsigned long vmware_get_tsc_khz(void)
        return tsc_hz;
 }
 
-void __init vmware_platform_setup(void)
+static void __init vmware_platform_setup(void)
 {
        uint32_t eax, ebx, ecx, edx;
 
@@ -82,24 +83,21 @@ void __init vmware_platform_setup(void)
  * serial key should be enough, as this will always have a VMware
  * specific string when running under VMware hypervisor.
  */
-int vmware_platform(void)
+static bool __init vmware_platform(void)
 {
        if (cpu_has_hypervisor) {
-               unsigned int eax, ebx, ecx, edx;
-               char hyper_vendor_id[13];
-
-               cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &ebx, &ecx, &edx);
-               memcpy(hyper_vendor_id + 0, &ebx, 4);
-               memcpy(hyper_vendor_id + 4, &ecx, 4);
-               memcpy(hyper_vendor_id + 8, &edx, 4);
-               hyper_vendor_id[12] = '\0';
-               if (!strcmp(hyper_vendor_id, "VMwareVMware"))
-                       return 1;
+               unsigned int eax;
+               unsigned int hyper_vendor_id[3];
+
+               cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &hyper_vendor_id[0],
+                     &hyper_vendor_id[1], &hyper_vendor_id[2]);
+               if (!memcmp(hyper_vendor_id, "VMwareVMware", 12))
+                       return true;
        } else if (dmi_available && dmi_name_in_serial("VMware") &&
                   __vmware_platform())
-               return 1;
+               return true;
 
-       return 0;
+       return false;
 }
 
 /*
@@ -114,8 +112,16 @@ int vmware_platform(void)
  * so that the kernel could just trust the hypervisor with providing a
  * reliable virtual TSC that is suitable for timekeeping.
  */
-void __cpuinit vmware_set_feature_bits(struct cpuinfo_x86 *c)
+static void __cpuinit vmware_set_cpu_features(struct cpuinfo_x86 *c)
 {
        set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
        set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
 }
+
+const __refconst struct hypervisor_x86 x86_hyper_vmware = {
+       .name                   = "VMware",
+       .detect                 = vmware_platform,
+       .set_cpu_features       = vmware_set_cpu_features,
+       .init_platform          = vmware_platform_setup,
+};
+EXPORT_SYMBOL(x86_hyper_vmware);
index a4849c1..ebd4c51 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
-#include <asm/x86_init.h>
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 #ifdef CONFIG_HPET_TIMER
        hpet_disable();
 #endif
-
-#ifdef CONFIG_X86_64
-       x86_platform.iommu_shutdown();
-#endif
-
        crash_save_cpu(regs, safe_smp_processor_id());
 }
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
deleted file mode 100644 (file)
index 1c47390..0000000
+++ /dev/null
@@ -1,1437 +0,0 @@
-/*
- * Debug Store support
- *
- * This provides a low-level interface to the hardware's Debug Store
- * feature that is used for branch trace store (BTS) and
- * precise-event based sampling (PEBS).
- *
- * It manages:
- * - DS and BTS hardware configuration
- * - buffer overflow handling (to be done)
- * - buffer access
- *
- * It does not do:
- * - security checking (is the caller allowed to trace the task)
- * - buffer allocation (memory accounting)
- *
- *
- * Copyright (C) 2007-2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2007-2009
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/trace_clock.h>
-
-#include <asm/ds.h>
-
-#include "ds_selftest.h"
-
-/*
- * The configuration for a particular DS hardware implementation:
- */
-struct ds_configuration {
-       /* The name of the configuration: */
-       const char              *name;
-
-       /* The size of pointer-typed fields in DS, BTS, and PEBS: */
-       unsigned char           sizeof_ptr_field;
-
-       /* The size of a BTS/PEBS record in bytes: */
-       unsigned char           sizeof_rec[2];
-
-       /* The number of pebs counter reset values in the DS structure. */
-       unsigned char           nr_counter_reset;
-
-       /* Control bit-masks indexed by enum ds_feature: */
-       unsigned long           ctl[dsf_ctl_max];
-};
-static struct ds_configuration ds_cfg __read_mostly;
-
-
-/* Maximal size of a DS configuration: */
-#define MAX_SIZEOF_DS          0x80
-
-/* Maximal size of a BTS record: */
-#define MAX_SIZEOF_BTS         (3 * 8)
-
-/* BTS and PEBS buffer alignment: */
-#define DS_ALIGNMENT           (1 << 3)
-
-/* Number of buffer pointers in DS: */
-#define NUM_DS_PTR_FIELDS      8
-
-/* Size of a pebs reset value in DS: */
-#define PEBS_RESET_FIELD_SIZE  8
-
-/* Mask of control bits in the DS MSR register: */
-#define BTS_CONTROL                              \
-       ( ds_cfg.ctl[dsf_bts]                   | \
-         ds_cfg.ctl[dsf_bts_kernel]            | \
-         ds_cfg.ctl[dsf_bts_user]              | \
-         ds_cfg.ctl[dsf_bts_overflow] )
-
-/*
- * A BTS or PEBS tracer.
- *
- * This holds the configuration of the tracer and serves as a handle
- * to identify tracers.
- */
-struct ds_tracer {
-       /* The DS context (partially) owned by this tracer. */
-       struct ds_context       *context;
-       /* The buffer provided on ds_request() and its size in bytes. */
-       void                    *buffer;
-       size_t                  size;
-};
-
-struct bts_tracer {
-       /* The common DS part: */
-       struct ds_tracer        ds;
-
-       /* The trace including the DS configuration: */
-       struct bts_trace        trace;
-
-       /* Buffer overflow notification function: */
-       bts_ovfl_callback_t     ovfl;
-
-       /* Active flags affecting trace collection. */
-       unsigned int            flags;
-};
-
-struct pebs_tracer {
-       /* The common DS part: */
-       struct ds_tracer        ds;
-
-       /* The trace including the DS configuration: */
-       struct pebs_trace       trace;
-
-       /* Buffer overflow notification function: */
-       pebs_ovfl_callback_t    ovfl;
-};
-
-/*
- * Debug Store (DS) save area configuration (see Intel64 and IA32
- * Architectures Software Developer's Manual, section 18.5)
- *
- * The DS configuration consists of the following fields; different
- * architetures vary in the size of those fields.
- *
- * - double-word aligned base linear address of the BTS buffer
- * - write pointer into the BTS buffer
- * - end linear address of the BTS buffer (one byte beyond the end of
- *   the buffer)
- * - interrupt pointer into BTS buffer
- *   (interrupt occurs when write pointer passes interrupt pointer)
- * - double-word aligned base linear address of the PEBS buffer
- * - write pointer into the PEBS buffer
- * - end linear address of the PEBS buffer (one byte beyond the end of
- *   the buffer)
- * - interrupt pointer into PEBS buffer
- *   (interrupt occurs when write pointer passes interrupt pointer)
- * - value to which counter is reset following counter overflow
- *
- * Later architectures use 64bit pointers throughout, whereas earlier
- * architectures use 32bit pointers in 32bit mode.
- *
- *
- * We compute the base address for the first 8 fields based on:
- * - the field size stored in the DS configuration
- * - the relative field position
- * - an offset giving the start of the respective region
- *
- * This offset is further used to index various arrays holding
- * information for BTS and PEBS at the respective index.
- *
- * On later 32bit processors, we only access the lower 32bit of the
- * 64bit pointer fields. The upper halves will be zeroed out.
- */
-
-enum ds_field {
-       ds_buffer_base = 0,
-       ds_index,
-       ds_absolute_maximum,
-       ds_interrupt_threshold,
-};
-
-enum ds_qualifier {
-       ds_bts = 0,
-       ds_pebs
-};
-
-static inline unsigned long
-ds_get(const unsigned char *base, enum ds_qualifier qual, enum ds_field field)
-{
-       base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
-       return *(unsigned long *)base;
-}
-
-static inline void
-ds_set(unsigned char *base, enum ds_qualifier qual, enum ds_field field,
-       unsigned long value)
-{
-       base += (ds_cfg.sizeof_ptr_field * (field + (4 * qual)));
-       (*(unsigned long *)base) = value;
-}
-
-
-/*
- * Locking is done only for allocating BTS or PEBS resources.
- */
-static DEFINE_SPINLOCK(ds_lock);
-
-/*
- * We either support (system-wide) per-cpu or per-thread allocation.
- * We distinguish the two based on the task_struct pointer, where a
- * NULL pointer indicates per-cpu allocation for the current cpu.
- *
- * Allocations are use-counted. As soon as resources are allocated,
- * further allocations must be of the same type (per-cpu or
- * per-thread). We model this by counting allocations (i.e. the number
- * of tracers of a certain type) for one type negatively:
- *   =0  no tracers
- *   >0  number of per-thread tracers
- *   <0  number of per-cpu tracers
- *
- * Tracers essentially gives the number of ds contexts for a certain
- * type of allocation.
- */
-static atomic_t tracers = ATOMIC_INIT(0);
-
-static inline int get_tracer(struct task_struct *task)
-{
-       int error;
-
-       spin_lock_irq(&ds_lock);
-
-       if (task) {
-               error = -EPERM;
-               if (atomic_read(&tracers) < 0)
-                       goto out;
-               atomic_inc(&tracers);
-       } else {
-               error = -EPERM;
-               if (atomic_read(&tracers) > 0)
-                       goto out;
-               atomic_dec(&tracers);
-       }
-
-       error = 0;
-out:
-       spin_unlock_irq(&ds_lock);
-       return error;
-}
-
-static inline void put_tracer(struct task_struct *task)
-{
-       if (task)
-               atomic_dec(&tracers);
-       else
-               atomic_inc(&tracers);
-}
-
-/*
- * The DS context is either attached to a thread or to a cpu:
- * - in the former case, the thread_struct contains a pointer to the
- *   attached context.
- * - in the latter case, we use a static array of per-cpu context
- *   pointers.
- *
- * Contexts are use-counted. They are allocated on first access and
- * deallocated when the last user puts the context.
- */
-struct ds_context {
-       /* The DS configuration; goes into MSR_IA32_DS_AREA: */
-       unsigned char           ds[MAX_SIZEOF_DS];
-
-       /* The owner of the BTS and PEBS configuration, respectively: */
-       struct bts_tracer       *bts_master;
-       struct pebs_tracer      *pebs_master;
-
-       /* Use count: */
-       unsigned long           count;
-
-       /* Pointer to the context pointer field: */
-       struct ds_context       **this;
-
-       /* The traced task; NULL for cpu tracing: */
-       struct task_struct      *task;
-
-       /* The traced cpu; only valid if task is NULL: */
-       int                     cpu;
-};
-
-static DEFINE_PER_CPU(struct ds_context *, cpu_ds_context);
-
-
-static struct ds_context *ds_get_context(struct task_struct *task, int cpu)
-{
-       struct ds_context **p_context =
-               (task ? &task->thread.ds_ctx : &per_cpu(cpu_ds_context, cpu));
-       struct ds_context *context = NULL;
-       struct ds_context *new_context = NULL;
-
-       /* Chances are small that we already have a context. */
-       new_context = kzalloc(sizeof(*new_context), GFP_KERNEL);
-       if (!new_context)
-               return NULL;
-
-       spin_lock_irq(&ds_lock);
-
-       context = *p_context;
-       if (likely(!context)) {
-               context = new_context;
-
-               context->this = p_context;
-               context->task = task;
-               context->cpu = cpu;
-               context->count = 0;
-
-               *p_context = context;
-       }
-
-       context->count++;
-
-       spin_unlock_irq(&ds_lock);
-
-       if (context != new_context)
-               kfree(new_context);
-
-       return context;
-}
-
-static void ds_put_context(struct ds_context *context)
-{
-       struct task_struct *task;
-       unsigned long irq;
-
-       if (!context)
-               return;
-
-       spin_lock_irqsave(&ds_lock, irq);
-
-       if (--context->count) {
-               spin_unlock_irqrestore(&ds_lock, irq);
-               return;
-       }
-
-       *(context->this) = NULL;
-
-       task = context->task;
-
-       if (task)
-               clear_tsk_thread_flag(task, TIF_DS_AREA_MSR);
-
-       /*
-        * We leave the (now dangling) pointer to the DS configuration in
-        * the DS_AREA msr. This is as good or as bad as replacing it with
-        * NULL - the hardware would crash if we enabled tracing.
-        *
-        * This saves us some problems with having to write an msr on a
-        * different cpu while preventing others from doing the same for the
-        * next context for that same cpu.
-        */
-
-       spin_unlock_irqrestore(&ds_lock, irq);
-
-       /* The context might still be in use for context switching. */
-       if (task && (task != current))
-               wait_task_context_switch(task);
-
-       kfree(context);
-}
-
-static void ds_install_ds_area(struct ds_context *context)
-{
-       unsigned long ds;
-
-       ds = (unsigned long)context->ds;
-
-       /*
-        * There is a race between the bts master and the pebs master.
-        *
-        * The thread/cpu access is synchronized via get/put_cpu() for
-        * task tracing and via wrmsr_on_cpu for cpu tracing.
-        *
-        * If bts and pebs are collected for the same task or same cpu,
-        * the same confiuration is written twice.
-        */
-       if (context->task) {
-               get_cpu();
-               if (context->task == current)
-                       wrmsrl(MSR_IA32_DS_AREA, ds);
-               set_tsk_thread_flag(context->task, TIF_DS_AREA_MSR);
-               put_cpu();
-       } else
-               wrmsr_on_cpu(context->cpu, MSR_IA32_DS_AREA,
-                            (u32)((u64)ds), (u32)((u64)ds >> 32));
-}
-
-/*
- * Call the tracer's callback on a buffer overflow.
- *
- * context: the ds context
- * qual: the buffer type
- */
-static void ds_overflow(struct ds_context *context, enum ds_qualifier qual)
-{
-       switch (qual) {
-       case ds_bts:
-               if (context->bts_master &&
-                   context->bts_master->ovfl)
-                       context->bts_master->ovfl(context->bts_master);
-               break;
-       case ds_pebs:
-               if (context->pebs_master &&
-                   context->pebs_master->ovfl)
-                       context->pebs_master->ovfl(context->pebs_master);
-               break;
-       }
-}
-
-
-/*
- * Write raw data into the BTS or PEBS buffer.
- *
- * The remainder of any partially written record is zeroed out.
- *
- * context: the DS context
- * qual:    the buffer type
- * record:  the data to write
- * size:    the size of the data
- */
-static int ds_write(struct ds_context *context, enum ds_qualifier qual,
-                   const void *record, size_t size)
-{
-       int bytes_written = 0;
-
-       if (!record)
-               return -EINVAL;
-
-       while (size) {
-               unsigned long base, index, end, write_end, int_th;
-               unsigned long write_size, adj_write_size;
-
-               /*
-                * Write as much as possible without producing an
-                * overflow interrupt.
-                *
-                * Interrupt_threshold must either be
-                * - bigger than absolute_maximum or
-                * - point to a record between buffer_base and absolute_maximum
-                *
-                * Index points to a valid record.
-                */
-               base   = ds_get(context->ds, qual, ds_buffer_base);
-               index  = ds_get(context->ds, qual, ds_index);
-               end    = ds_get(context->ds, qual, ds_absolute_maximum);
-               int_th = ds_get(context->ds, qual, ds_interrupt_threshold);
-
-               write_end = min(end, int_th);
-
-               /*
-                * If we are already beyond the interrupt threshold,
-                * we fill the entire buffer.
-                */
-               if (write_end <= index)
-                       write_end = end;
-
-               if (write_end <= index)
-                       break;
-
-               write_size = min((unsigned long) size, write_end - index);
-               memcpy((void *)index, record, write_size);
-
-               record = (const char *)record + write_size;
-               size -= write_size;
-               bytes_written += write_size;
-
-               adj_write_size = write_size / ds_cfg.sizeof_rec[qual];
-               adj_write_size *= ds_cfg.sizeof_rec[qual];
-
-               /* Zero out trailing bytes. */
-               memset((char *)index + write_size, 0,
-                      adj_write_size - write_size);
-               index += adj_write_size;
-
-               if (index >= end)
-                       index = base;
-               ds_set(context->ds, qual, ds_index, index);
-
-               if (index >= int_th)
-                       ds_overflow(context, qual);
-       }
-
-       return bytes_written;
-}
-
-
-/*
- * Branch Trace Store (BTS) uses the following format. Different
- * architectures vary in the size of those fields.
- * - source linear address
- * - destination linear address
- * - flags
- *
- * Later architectures use 64bit pointers throughout, whereas earlier
- * architectures use 32bit pointers in 32bit mode.
- *
- * We compute the base address for the fields based on:
- * - the field size stored in the DS configuration
- * - the relative field position
- *
- * In order to store additional information in the BTS buffer, we use
- * a special source address to indicate that the record requires
- * special interpretation.
- *
- * Netburst indicated via a bit in the flags field whether the branch
- * was predicted; this is ignored.
- *
- * We use two levels of abstraction:
- * - the raw data level defined here
- * - an arch-independent level defined in ds.h
- */
-
-enum bts_field {
-       bts_from,
-       bts_to,
-       bts_flags,
-
-       bts_qual                = bts_from,
-       bts_clock               = bts_to,
-       bts_pid                 = bts_flags,
-
-       bts_qual_mask           = (bts_qual_max - 1),
-       bts_escape              = ((unsigned long)-1 & ~bts_qual_mask)
-};
-
-static inline unsigned long bts_get(const char *base, unsigned long field)
-{
-       base += (ds_cfg.sizeof_ptr_field * field);
-       return *(unsigned long *)base;
-}
-
-static inline void bts_set(char *base, unsigned long field, unsigned long val)
-{
-       base += (ds_cfg.sizeof_ptr_field * field);
-       (*(unsigned long *)base) = val;
-}
-
-
-/*
- * The raw BTS data is architecture dependent.
- *
- * For higher-level users, we give an arch-independent view.
- * - ds.h defines struct bts_struct
- * - bts_read translates one raw bts record into a bts_struct
- * - bts_write translates one bts_struct into the raw format and
- *   writes it into the top of the parameter tracer's buffer.
- *
- * return: bytes read/written on success; -Eerrno, otherwise
- */
-static int
-bts_read(struct bts_tracer *tracer, const void *at, struct bts_struct *out)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       if (at < tracer->trace.ds.begin)
-               return -EINVAL;
-
-       if (tracer->trace.ds.end < (at + tracer->trace.ds.size))
-               return -EINVAL;
-
-       memset(out, 0, sizeof(*out));
-       if ((bts_get(at, bts_qual) & ~bts_qual_mask) == bts_escape) {
-               out->qualifier = (bts_get(at, bts_qual) & bts_qual_mask);
-               out->variant.event.clock = bts_get(at, bts_clock);
-               out->variant.event.pid = bts_get(at, bts_pid);
-       } else {
-               out->qualifier = bts_branch;
-               out->variant.lbr.from = bts_get(at, bts_from);
-               out->variant.lbr.to   = bts_get(at, bts_to);
-
-               if (!out->variant.lbr.from && !out->variant.lbr.to)
-                       out->qualifier = bts_invalid;
-       }
-
-       return ds_cfg.sizeof_rec[ds_bts];
-}
-
-static int bts_write(struct bts_tracer *tracer, const struct bts_struct *in)
-{
-       unsigned char raw[MAX_SIZEOF_BTS];
-
-       if (!tracer)
-               return -EINVAL;
-
-       if (MAX_SIZEOF_BTS < ds_cfg.sizeof_rec[ds_bts])
-               return -EOVERFLOW;
-
-       switch (in->qualifier) {
-       case bts_invalid:
-               bts_set(raw, bts_from, 0);
-               bts_set(raw, bts_to, 0);
-               bts_set(raw, bts_flags, 0);
-               break;
-       case bts_branch:
-               bts_set(raw, bts_from, in->variant.lbr.from);
-               bts_set(raw, bts_to,   in->variant.lbr.to);
-               bts_set(raw, bts_flags, 0);
-               break;
-       case bts_task_arrives:
-       case bts_task_departs:
-               bts_set(raw, bts_qual, (bts_escape | in->qualifier));
-               bts_set(raw, bts_clock, in->variant.event.clock);
-               bts_set(raw, bts_pid, in->variant.event.pid);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return ds_write(tracer->ds.context, ds_bts, raw,
-                       ds_cfg.sizeof_rec[ds_bts]);
-}
-
-
-static void ds_write_config(struct ds_context *context,
-                           struct ds_trace *cfg, enum ds_qualifier qual)
-{
-       unsigned char *ds = context->ds;
-
-       ds_set(ds, qual, ds_buffer_base, (unsigned long)cfg->begin);
-       ds_set(ds, qual, ds_index, (unsigned long)cfg->top);
-       ds_set(ds, qual, ds_absolute_maximum, (unsigned long)cfg->end);
-       ds_set(ds, qual, ds_interrupt_threshold, (unsigned long)cfg->ith);
-}
-
-static void ds_read_config(struct ds_context *context,
-                          struct ds_trace *cfg, enum ds_qualifier qual)
-{
-       unsigned char *ds = context->ds;
-
-       cfg->begin = (void *)ds_get(ds, qual, ds_buffer_base);
-       cfg->top = (void *)ds_get(ds, qual, ds_index);
-       cfg->end = (void *)ds_get(ds, qual, ds_absolute_maximum);
-       cfg->ith = (void *)ds_get(ds, qual, ds_interrupt_threshold);
-}
-
-static void ds_init_ds_trace(struct ds_trace *trace, enum ds_qualifier qual,
-                            void *base, size_t size, size_t ith,
-                            unsigned int flags) {
-       unsigned long buffer, adj;
-
-       /*
-        * Adjust the buffer address and size to meet alignment
-        * constraints:
-        * - buffer is double-word aligned
-        * - size is multiple of record size
-        *
-        * We checked the size at the very beginning; we have enough
-        * space to do the adjustment.
-        */
-       buffer = (unsigned long)base;
-
-       adj = ALIGN(buffer, DS_ALIGNMENT) - buffer;
-       buffer += adj;
-       size   -= adj;
-
-       trace->n = size / ds_cfg.sizeof_rec[qual];
-       trace->size = ds_cfg.sizeof_rec[qual];
-
-       size = (trace->n * trace->size);
-
-       trace->begin = (void *)buffer;
-       trace->top = trace->begin;
-       trace->end = (void *)(buffer + size);
-       /*
-        * The value for 'no threshold' is -1, which will set the
-        * threshold outside of the buffer, just like we want it.
-        */
-       ith *= ds_cfg.sizeof_rec[qual];
-       trace->ith = (void *)(buffer + size - ith);
-
-       trace->flags = flags;
-}
-
-
-static int ds_request(struct ds_tracer *tracer, struct ds_trace *trace,
-                     enum ds_qualifier qual, struct task_struct *task,
-                     int cpu, void *base, size_t size, size_t th)
-{
-       struct ds_context *context;
-       int error;
-       size_t req_size;
-
-       error = -EOPNOTSUPP;
-       if (!ds_cfg.sizeof_rec[qual])
-               goto out;
-
-       error = -EINVAL;
-       if (!base)
-               goto out;
-
-       req_size = ds_cfg.sizeof_rec[qual];
-       /* We might need space for alignment adjustments. */
-       if (!IS_ALIGNED((unsigned long)base, DS_ALIGNMENT))
-               req_size += DS_ALIGNMENT;
-
-       error = -EINVAL;
-       if (size < req_size)
-               goto out;
-
-       if (th != (size_t)-1) {
-               th *= ds_cfg.sizeof_rec[qual];
-
-               error = -EINVAL;
-               if (size <= th)
-                       goto out;
-       }
-
-       tracer->buffer = base;
-       tracer->size = size;
-
-       error = -ENOMEM;
-       context = ds_get_context(task, cpu);
-       if (!context)
-               goto out;
-       tracer->context = context;
-
-       /*
-        * Defer any tracer-specific initialization work for the context until
-        * context ownership has been clarified.
-        */
-
-       error = 0;
- out:
-       return error;
-}
-
-static struct bts_tracer *ds_request_bts(struct task_struct *task, int cpu,
-                                        void *base, size_t size,
-                                        bts_ovfl_callback_t ovfl, size_t th,
-                                        unsigned int flags)
-{
-       struct bts_tracer *tracer;
-       int error;
-
-       /* Buffer overflow notification is not yet implemented. */
-       error = -EOPNOTSUPP;
-       if (ovfl)
-               goto out;
-
-       error = get_tracer(task);
-       if (error < 0)
-               goto out;
-
-       error = -ENOMEM;
-       tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
-       if (!tracer)
-               goto out_put_tracer;
-       tracer->ovfl = ovfl;
-
-       /* Do some more error checking and acquire a tracing context. */
-       error = ds_request(&tracer->ds, &tracer->trace.ds,
-                          ds_bts, task, cpu, base, size, th);
-       if (error < 0)
-               goto out_tracer;
-
-       /* Claim the bts part of the tracing context we acquired above. */
-       spin_lock_irq(&ds_lock);
-
-       error = -EPERM;
-       if (tracer->ds.context->bts_master)
-               goto out_unlock;
-       tracer->ds.context->bts_master = tracer;
-
-       spin_unlock_irq(&ds_lock);
-
-       /*
-        * Now that we own the bts part of the context, let's complete the
-        * initialization for that part.
-        */
-       ds_init_ds_trace(&tracer->trace.ds, ds_bts, base, size, th, flags);
-       ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
-       ds_install_ds_area(tracer->ds.context);
-
-       tracer->trace.read  = bts_read;
-       tracer->trace.write = bts_write;
-
-       /* Start tracing. */
-       ds_resume_bts(tracer);
-
-       return tracer;
-
- out_unlock:
-       spin_unlock_irq(&ds_lock);
-       ds_put_context(tracer->ds.context);
- out_tracer:
-       kfree(tracer);
- out_put_tracer:
-       put_tracer(task);
- out:
-       return ERR_PTR(error);
-}
-
-struct bts_tracer *ds_request_bts_task(struct task_struct *task,
-                                      void *base, size_t size,
-                                      bts_ovfl_callback_t ovfl,
-                                      size_t th, unsigned int flags)
-{
-       return ds_request_bts(task, 0, base, size, ovfl, th, flags);
-}
-
-struct bts_tracer *ds_request_bts_cpu(int cpu, void *base, size_t size,
-                                     bts_ovfl_callback_t ovfl,
-                                     size_t th, unsigned int flags)
-{
-       return ds_request_bts(NULL, cpu, base, size, ovfl, th, flags);
-}
-
-static struct pebs_tracer *ds_request_pebs(struct task_struct *task, int cpu,
-                                          void *base, size_t size,
-                                          pebs_ovfl_callback_t ovfl, size_t th,
-                                          unsigned int flags)
-{
-       struct pebs_tracer *tracer;
-       int error;
-
-       /* Buffer overflow notification is not yet implemented. */
-       error = -EOPNOTSUPP;
-       if (ovfl)
-               goto out;
-
-       error = get_tracer(task);
-       if (error < 0)
-               goto out;
-
-       error = -ENOMEM;
-       tracer = kzalloc(sizeof(*tracer), GFP_KERNEL);
-       if (!tracer)
-               goto out_put_tracer;
-       tracer->ovfl = ovfl;
-
-       /* Do some more error checking and acquire a tracing context. */
-       error = ds_request(&tracer->ds, &tracer->trace.ds,
-                          ds_pebs, task, cpu, base, size, th);
-       if (error < 0)
-               goto out_tracer;
-
-       /* Claim the pebs part of the tracing context we acquired above. */
-       spin_lock_irq(&ds_lock);
-
-       error = -EPERM;
-       if (tracer->ds.context->pebs_master)
-               goto out_unlock;
-       tracer->ds.context->pebs_master = tracer;
-
-       spin_unlock_irq(&ds_lock);
-
-       /*
-        * Now that we own the pebs part of the context, let's complete the
-        * initialization for that part.
-        */
-       ds_init_ds_trace(&tracer->trace.ds, ds_pebs, base, size, th, flags);
-       ds_write_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
-       ds_install_ds_area(tracer->ds.context);
-
-       /* Start tracing. */
-       ds_resume_pebs(tracer);
-
-       return tracer;
-
- out_unlock:
-       spin_unlock_irq(&ds_lock);
-       ds_put_context(tracer->ds.context);
- out_tracer:
-       kfree(tracer);
- out_put_tracer:
-       put_tracer(task);
- out:
-       return ERR_PTR(error);
-}
-
-struct pebs_tracer *ds_request_pebs_task(struct task_struct *task,
-                                        void *base, size_t size,
-                                        pebs_ovfl_callback_t ovfl,
-                                        size_t th, unsigned int flags)
-{
-       return ds_request_pebs(task, 0, base, size, ovfl, th, flags);
-}
-
-struct pebs_tracer *ds_request_pebs_cpu(int cpu, void *base, size_t size,
-                                       pebs_ovfl_callback_t ovfl,
-                                       size_t th, unsigned int flags)
-{
-       return ds_request_pebs(NULL, cpu, base, size, ovfl, th, flags);
-}
-
-static void ds_free_bts(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-
-       task = tracer->ds.context->task;
-
-       WARN_ON_ONCE(tracer->ds.context->bts_master != tracer);
-       tracer->ds.context->bts_master = NULL;
-
-       /* Make sure tracing stopped and the tracer is not in use. */
-       if (task && (task != current))
-               wait_task_context_switch(task);
-
-       ds_put_context(tracer->ds.context);
-       put_tracer(task);
-
-       kfree(tracer);
-}
-
-void ds_release_bts(struct bts_tracer *tracer)
-{
-       might_sleep();
-
-       if (!tracer)
-               return;
-
-       ds_suspend_bts(tracer);
-       ds_free_bts(tracer);
-}
-
-int ds_release_bts_noirq(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long irq;
-       int error;
-
-       if (!tracer)
-               return 0;
-
-       task = tracer->ds.context->task;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task &&
-           (tracer->ds.context->cpu != smp_processor_id()))
-               goto out;
-
-       error = -EPERM;
-       if (task && (task != current))
-               goto out;
-
-       ds_suspend_bts_noirq(tracer);
-       ds_free_bts(tracer);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-static void update_task_debugctlmsr(struct task_struct *task,
-                                   unsigned long debugctlmsr)
-{
-       task->thread.debugctlmsr = debugctlmsr;
-
-       get_cpu();
-       if (task == current)
-               update_debugctlmsr(debugctlmsr);
-       put_cpu();
-}
-
-void ds_suspend_bts(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr;
-       int cpu;
-
-       if (!tracer)
-               return;
-
-       tracer->flags = 0;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       WARN_ON(!task && irqs_disabled());
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr_on_cpu(cpu));
-       debugctlmsr &= ~BTS_CONTROL;
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr_on_cpu(cpu, debugctlmsr);
-}
-
-int ds_suspend_bts_noirq(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr, irq;
-       int cpu, error = 0;
-
-       if (!tracer)
-               return 0;
-
-       tracer->flags = 0;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task && (cpu != smp_processor_id()))
-               goto out;
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr());
-       debugctlmsr &= ~BTS_CONTROL;
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr(debugctlmsr);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-static unsigned long ds_bts_control(struct bts_tracer *tracer)
-{
-       unsigned long control;
-
-       control = ds_cfg.ctl[dsf_bts];
-       if (!(tracer->trace.ds.flags & BTS_KERNEL))
-               control |= ds_cfg.ctl[dsf_bts_kernel];
-       if (!(tracer->trace.ds.flags & BTS_USER))
-               control |= ds_cfg.ctl[dsf_bts_user];
-
-       return control;
-}
-
-void ds_resume_bts(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr;
-       int cpu;
-
-       if (!tracer)
-               return;
-
-       tracer->flags = tracer->trace.ds.flags;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       WARN_ON(!task && irqs_disabled());
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr_on_cpu(cpu));
-       debugctlmsr |= ds_bts_control(tracer);
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr_on_cpu(cpu, debugctlmsr);
-}
-
-int ds_resume_bts_noirq(struct bts_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long debugctlmsr, irq;
-       int cpu, error = 0;
-
-       if (!tracer)
-               return 0;
-
-       tracer->flags = tracer->trace.ds.flags;
-
-       task = tracer->ds.context->task;
-       cpu  = tracer->ds.context->cpu;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task && (cpu != smp_processor_id()))
-               goto out;
-
-       debugctlmsr = (task ?
-                      task->thread.debugctlmsr :
-                      get_debugctlmsr());
-       debugctlmsr |= ds_bts_control(tracer);
-
-       if (task)
-               update_task_debugctlmsr(task, debugctlmsr);
-       else
-               update_debugctlmsr(debugctlmsr);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-static void ds_free_pebs(struct pebs_tracer *tracer)
-{
-       struct task_struct *task;
-
-       task = tracer->ds.context->task;
-
-       WARN_ON_ONCE(tracer->ds.context->pebs_master != tracer);
-       tracer->ds.context->pebs_master = NULL;
-
-       ds_put_context(tracer->ds.context);
-       put_tracer(task);
-
-       kfree(tracer);
-}
-
-void ds_release_pebs(struct pebs_tracer *tracer)
-{
-       might_sleep();
-
-       if (!tracer)
-               return;
-
-       ds_suspend_pebs(tracer);
-       ds_free_pebs(tracer);
-}
-
-int ds_release_pebs_noirq(struct pebs_tracer *tracer)
-{
-       struct task_struct *task;
-       unsigned long irq;
-       int error;
-
-       if (!tracer)
-               return 0;
-
-       task = tracer->ds.context->task;
-
-       local_irq_save(irq);
-
-       error = -EPERM;
-       if (!task &&
-           (tracer->ds.context->cpu != smp_processor_id()))
-               goto out;
-
-       error = -EPERM;
-       if (task && (task != current))
-               goto out;
-
-       ds_suspend_pebs_noirq(tracer);
-       ds_free_pebs(tracer);
-
-       error = 0;
- out:
-       local_irq_restore(irq);
-       return error;
-}
-
-void ds_suspend_pebs(struct pebs_tracer *tracer)
-{
-
-}
-
-int ds_suspend_pebs_noirq(struct pebs_tracer *tracer)
-{
-       return 0;
-}
-
-void ds_resume_pebs(struct pebs_tracer *tracer)
-{
-
-}
-
-int ds_resume_pebs_noirq(struct pebs_tracer *tracer)
-{
-       return 0;
-}
-
-const struct bts_trace *ds_read_bts(struct bts_tracer *tracer)
-{
-       if (!tracer)
-               return NULL;
-
-       ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_bts);
-       return &tracer->trace;
-}
-
-const struct pebs_trace *ds_read_pebs(struct pebs_tracer *tracer)
-{
-       if (!tracer)
-               return NULL;
-
-       ds_read_config(tracer->ds.context, &tracer->trace.ds, ds_pebs);
-
-       tracer->trace.counters = ds_cfg.nr_counter_reset;
-       memcpy(tracer->trace.counter_reset,
-              tracer->ds.context->ds +
-              (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field),
-              ds_cfg.nr_counter_reset * PEBS_RESET_FIELD_SIZE);
-
-       return &tracer->trace;
-}
-
-int ds_reset_bts(struct bts_tracer *tracer)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       tracer->trace.ds.top = tracer->trace.ds.begin;
-
-       ds_set(tracer->ds.context->ds, ds_bts, ds_index,
-              (unsigned long)tracer->trace.ds.top);
-
-       return 0;
-}
-
-int ds_reset_pebs(struct pebs_tracer *tracer)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       tracer->trace.ds.top = tracer->trace.ds.begin;
-
-       ds_set(tracer->ds.context->ds, ds_pebs, ds_index,
-              (unsigned long)tracer->trace.ds.top);
-
-       return 0;
-}
-
-int ds_set_pebs_reset(struct pebs_tracer *tracer,
-                     unsigned int counter, u64 value)
-{
-       if (!tracer)
-               return -EINVAL;
-
-       if (ds_cfg.nr_counter_reset < counter)
-               return -EINVAL;
-
-       *(u64 *)(tracer->ds.context->ds +
-                (NUM_DS_PTR_FIELDS * ds_cfg.sizeof_ptr_field) +
-                (counter * PEBS_RESET_FIELD_SIZE)) = value;
-
-       return 0;
-}
-
-static const struct ds_configuration ds_cfg_netburst = {
-       .name = "Netburst",
-       .ctl[dsf_bts]           = (1 << 2) | (1 << 3),
-       .ctl[dsf_bts_kernel]    = (1 << 5),
-       .ctl[dsf_bts_user]      = (1 << 6),
-       .nr_counter_reset       = 1,
-};
-static const struct ds_configuration ds_cfg_pentium_m = {
-       .name = "Pentium M",
-       .ctl[dsf_bts]           = (1 << 6) | (1 << 7),
-       .nr_counter_reset       = 1,
-};
-static const struct ds_configuration ds_cfg_core2_atom = {
-       .name = "Core 2/Atom",
-       .ctl[dsf_bts]           = (1 << 6) | (1 << 7),
-       .ctl[dsf_bts_kernel]    = (1 << 9),
-       .ctl[dsf_bts_user]      = (1 << 10),
-       .nr_counter_reset       = 1,
-};
-static const struct ds_configuration ds_cfg_core_i7 = {
-       .name = "Core i7",
-       .ctl[dsf_bts]           = (1 << 6) | (1 << 7),
-       .ctl[dsf_bts_kernel]    = (1 << 9),
-       .ctl[dsf_bts_user]      = (1 << 10),
-       .nr_counter_reset       = 4,
-};
-
-static void
-ds_configure(const struct ds_configuration *cfg,
-            struct cpuinfo_x86 *cpu)
-{
-       unsigned long nr_pebs_fields = 0;
-
-       printk(KERN_INFO "[ds] using %s configuration\n", cfg->name);
-
-#ifdef __i386__
-       nr_pebs_fields = 10;
-#else
-       nr_pebs_fields = 18;
-#endif
-
-       /*
-        * Starting with version 2, architectural performance
-        * monitoring supports a format specifier.
-        */
-       if ((cpuid_eax(0xa) & 0xff) > 1) {
-               unsigned long perf_capabilities, format;
-
-               rdmsrl(MSR_IA32_PERF_CAPABILITIES, perf_capabilities);
-
-               format = (perf_capabilities >> 8) & 0xf;
-
-               switch (format) {
-               case 0:
-                       nr_pebs_fields = 18;
-                       break;
-               case 1:
-                       nr_pebs_fields = 22;
-                       break;
-               default:
-                       printk(KERN_INFO
-                              "[ds] unknown PEBS format: %lu\n", format);
-                       nr_pebs_fields = 0;
-                       break;
-               }
-       }
-
-       memset(&ds_cfg, 0, sizeof(ds_cfg));
-       ds_cfg = *cfg;
-
-       ds_cfg.sizeof_ptr_field =
-               (cpu_has(cpu, X86_FEATURE_DTES64) ? 8 : 4);
-
-       ds_cfg.sizeof_rec[ds_bts]  = ds_cfg.sizeof_ptr_field * 3;
-       ds_cfg.sizeof_rec[ds_pebs] = ds_cfg.sizeof_ptr_field * nr_pebs_fields;
-
-       if (!cpu_has(cpu, X86_FEATURE_BTS)) {
-               ds_cfg.sizeof_rec[ds_bts] = 0;
-               printk(KERN_INFO "[ds] bts not available\n");
-       }
-       if (!cpu_has(cpu, X86_FEATURE_PEBS)) {
-               ds_cfg.sizeof_rec[ds_pebs] = 0;
-               printk(KERN_INFO "[ds] pebs not available\n");
-       }
-
-       printk(KERN_INFO "[ds] sizes: address: %u bit, ",
-              8 * ds_cfg.sizeof_ptr_field);
-       printk("bts/pebs record: %u/%u bytes\n",
-              ds_cfg.sizeof_rec[ds_bts], ds_cfg.sizeof_rec[ds_pebs]);
-
-       WARN_ON_ONCE(MAX_PEBS_COUNTERS < ds_cfg.nr_counter_reset);
-}
-
-void __cpuinit ds_init_intel(struct cpuinfo_x86 *c)
-{
-       /* Only configure the first cpu. Others are identical. */
-       if (ds_cfg.name)
-               return;
-
-       switch (c->x86) {
-       case 0x6:
-               switch (c->x86_model) {
-               case 0x9:
-               case 0xd: /* Pentium M */
-                       ds_configure(&ds_cfg_pentium_m, c);
-                       break;
-               case 0xf:
-               case 0x17: /* Core2 */
-               case 0x1c: /* Atom */
-                       ds_configure(&ds_cfg_core2_atom, c);
-                       break;
-               case 0x1a: /* Core i7 */
-                       ds_configure(&ds_cfg_core_i7, c);
-                       break;
-               default:
-                       /* Sorry, don't know about them. */
-                       break;
-               }
-               break;
-       case 0xf:
-               switch (c->x86_model) {
-               case 0x0:
-               case 0x1:
-               case 0x2: /* Netburst */
-                       ds_configure(&ds_cfg_netburst, c);
-                       break;
-               default:
-                       /* Sorry, don't know about them. */
-                       break;
-               }
-               break;
-       default:
-               /* Sorry, don't know about them. */
-               break;
-       }
-}
-
-static inline void ds_take_timestamp(struct ds_context *context,
-                                    enum bts_qualifier qualifier,
-                                    struct task_struct *task)
-{
-       struct bts_tracer *tracer = context->bts_master;
-       struct bts_struct ts;
-
-       /* Prevent compilers from reading the tracer pointer twice. */
-       barrier();
-
-       if (!tracer || !(tracer->flags & BTS_TIMESTAMPS))
-               return;
-
-       memset(&ts, 0, sizeof(ts));
-       ts.qualifier            = qualifier;
-       ts.variant.event.clock  = trace_clock_global();
-       ts.variant.event.pid    = task->pid;
-
-       bts_write(tracer, &ts);
-}
-
-/*
- * Change the DS configuration from tracing prev to tracing next.
- */
-void ds_switch_to(struct task_struct *prev, struct task_struct *next)
-{
-       struct ds_context *prev_ctx     = prev->thread.ds_ctx;
-       struct ds_context *next_ctx     = next->thread.ds_ctx;
-       unsigned long debugctlmsr       = next->thread.debugctlmsr;
-
-       /* Make sure all data is read before we start. */
-       barrier();
-
-       if (prev_ctx) {
-               update_debugctlmsr(0);
-
-               ds_take_timestamp(prev_ctx, bts_task_departs, prev);
-       }
-
-       if (next_ctx) {
-               ds_take_timestamp(next_ctx, bts_task_arrives, next);
-
-               wrmsrl(MSR_IA32_DS_AREA, (unsigned long)next_ctx->ds);
-       }
-
-       update_debugctlmsr(debugctlmsr);
-}
-
-static __init int ds_selftest(void)
-{
-       if (ds_cfg.sizeof_rec[ds_bts]) {
-               int error;
-
-               error = ds_selftest_bts();
-               if (error) {
-                       WARN(1, "[ds] selftest failed. disabling bts.\n");
-                       ds_cfg.sizeof_rec[ds_bts] = 0;
-               }
-       }
-
-       if (ds_cfg.sizeof_rec[ds_pebs]) {
-               int error;
-
-               error = ds_selftest_pebs();
-               if (error) {
-                       WARN(1, "[ds] selftest failed. disabling pebs.\n");
-                       ds_cfg.sizeof_rec[ds_pebs] = 0;
-               }
-       }
-
-       return 0;
-}
-device_initcall(ds_selftest);
diff --git a/arch/x86/kernel/ds_selftest.c b/arch/x86/kernel/ds_selftest.c
deleted file mode 100644 (file)
index 6bc7c19..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Debug Store support - selftest
- *
- *
- * Copyright (C) 2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2009
- */
-
-#include "ds_selftest.h"
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-
-#include <asm/ds.h>
-
-
-#define BUFFER_SIZE            521     /* Intentionally chose an odd size. */
-#define SMALL_BUFFER_SIZE      24      /* A single bts entry. */
-
-struct ds_selftest_bts_conf {
-       struct bts_tracer *tracer;
-       int error;
-       int (*suspend)(struct bts_tracer *);
-       int (*resume)(struct bts_tracer *);
-};
-
-static int ds_selftest_bts_consistency(const struct bts_trace *trace)
-{
-       int error = 0;
-
-       if (!trace) {
-               printk(KERN_CONT "failed to access trace...");
-               /* Bail out. Other tests are pointless. */
-               return -1;
-       }
-
-       if (!trace->read) {
-               printk(KERN_CONT "bts read not available...");
-               error = -1;
-       }
-
-       /* Do some sanity checks on the trace configuration. */
-       if (!trace->ds.n) {
-               printk(KERN_CONT "empty bts buffer...");
-               error = -1;
-       }
-       if (!trace->ds.size) {
-               printk(KERN_CONT "bad bts trace setup...");
-               error = -1;
-       }
-       if (trace->ds.end !=
-           (char *)trace->ds.begin + (trace->ds.n * trace->ds.size)) {
-               printk(KERN_CONT "bad bts buffer setup...");
-               error = -1;
-       }
-       /*
-        * We allow top in [begin; end], since its not clear when the
-        * overflow adjustment happens: after the increment or before the
-        * write.
-        */
-       if ((trace->ds.top < trace->ds.begin) ||
-           (trace->ds.end < trace->ds.top)) {
-               printk(KERN_CONT "bts top out of bounds...");
-               error = -1;
-       }
-
-       return error;
-}
-
-static int ds_selftest_bts_read(struct bts_tracer *tracer,
-                               const struct bts_trace *trace,
-                               const void *from, const void *to)
-{
-       const unsigned char *at;
-
-       /*
-        * Check a few things which do not belong to this test.
-        * They should be covered by other tests.
-        */
-       if (!trace)
-               return -1;
-
-       if (!trace->read)
-               return -1;
-
-       if (to < from)
-               return -1;
-
-       if (from < trace->ds.begin)
-               return -1;
-
-       if (trace->ds.end < to)
-               return -1;
-
-       if (!trace->ds.size)
-               return -1;
-
-       /* Now to the test itself. */
-       for (at = from; (void *)at < to; at += trace->ds.size) {
-               struct bts_struct bts;
-               unsigned long index;
-               int error;
-
-               if (((void *)at - trace->ds.begin) % trace->ds.size) {
-                       printk(KERN_CONT
-                              "read from non-integer index...");
-                       return -1;
-               }
-               index = ((void *)at - trace->ds.begin) / trace->ds.size;
-
-               memset(&bts, 0, sizeof(bts));
-               error = trace->read(tracer, at, &bts);
-               if (error < 0) {
-                       printk(KERN_CONT
-                              "error reading bts trace at [%lu] (0x%p)...",
-                              index, at);
-                       return error;
-               }
-
-               switch (bts.qualifier) {
-               case BTS_BRANCH:
-                       break;
-               default:
-                       printk(KERN_CONT
-                              "unexpected bts entry %llu at [%lu] (0x%p)...",
-                              bts.qualifier, index, at);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-static void ds_selftest_bts_cpu(void *arg)
-{
-       struct ds_selftest_bts_conf *conf = arg;
-       const struct bts_trace *trace;
-       void *top;
-
-       if (IS_ERR(conf->tracer)) {
-               conf->error = PTR_ERR(conf->tracer);
-               conf->tracer = NULL;
-
-               printk(KERN_CONT
-                      "initialization failed (err: %d)...", conf->error);
-               return;
-       }
-
-       /* We should meanwhile have enough trace. */
-       conf->error = conf->suspend(conf->tracer);
-       if (conf->error < 0)
-               return;
-
-       /* Let's see if we can access the trace. */
-       trace = ds_read_bts(conf->tracer);
-
-       conf->error = ds_selftest_bts_consistency(trace);
-       if (conf->error < 0)
-               return;
-
-       /* If everything went well, we should have a few trace entries. */
-       if (trace->ds.top == trace->ds.begin) {
-               /*
-                * It is possible but highly unlikely that we got a
-                * buffer overflow and end up at exactly the same
-                * position we started from.
-                * Let's issue a warning, but continue.
-                */
-               printk(KERN_CONT "no trace/overflow...");
-       }
-
-       /* Let's try to read the trace we collected. */
-       conf->error =
-               ds_selftest_bts_read(conf->tracer, trace,
-                                    trace->ds.begin, trace->ds.top);
-       if (conf->error < 0)
-               return;
-
-       /*
-        * Let's read the trace again.
-        * Since we suspended tracing, we should get the same result.
-        */
-       top = trace->ds.top;
-
-       trace = ds_read_bts(conf->tracer);
-       conf->error = ds_selftest_bts_consistency(trace);
-       if (conf->error < 0)
-               return;
-
-       if (top != trace->ds.top) {
-               printk(KERN_CONT "suspend not working...");
-               conf->error = -1;
-               return;
-       }
-
-       /* Let's collect some more trace - see if resume is working. */
-       conf->error = conf->resume(conf->tracer);
-       if (conf->error < 0)
-               return;
-
-       conf->error = conf->suspend(conf->tracer);
-       if (conf->error < 0)
-               return;
-
-       trace = ds_read_bts(conf->tracer);
-
-       conf->error = ds_selftest_bts_consistency(trace);
-       if (conf->error < 0)
-               return;
-
-       if (trace->ds.top == top) {
-               /*
-                * It is possible but highly unlikely that we got a
-                * buffer overflow and end up at exactly the same
-                * position we started from.
-                * Let's issue a warning and check the full trace.
-                */
-               printk(KERN_CONT
-                      "no resume progress/overflow...");
-
-               conf->error =
-                       ds_selftest_bts_read(conf->tracer, trace,
-                                            trace->ds.begin, trace->ds.end);
-       } else if (trace->ds.top < top) {
-               /*
-                * We had a buffer overflow - the entire buffer should
-                * contain trace records.
-                */
-               conf->error =
-                       ds_selftest_bts_read(conf->tracer, trace,
-                                            trace->ds.begin, trace->ds.end);
-       } else {
-               /*
-                * It is quite likely that the buffer did not overflow.
-                * Let's just check the delta trace.
-                */
-               conf->error =
-                       ds_selftest_bts_read(conf->tracer, trace, top,
-                                            trace->ds.top);
-       }
-       if (conf->error < 0)
-               return;
-
-       conf->error = 0;
-}
-
-static int ds_suspend_bts_wrap(struct bts_tracer *tracer)
-{
-       ds_suspend_bts(tracer);
-       return 0;
-}
-
-static int ds_resume_bts_wrap(struct bts_tracer *tracer)
-{
-       ds_resume_bts(tracer);
-       return 0;
-}
-
-static void ds_release_bts_noirq_wrap(void *tracer)
-{
-       (void)ds_release_bts_noirq(tracer);
-}
-
-static int ds_selftest_bts_bad_release_noirq(int cpu,
-                                            struct bts_tracer *tracer)
-{
-       int error = -EPERM;
-
-       /* Try to release the tracer on the wrong cpu. */
-       get_cpu();
-       if (cpu != smp_processor_id()) {
-               error = ds_release_bts_noirq(tracer);
-               if (error != -EPERM)
-                       printk(KERN_CONT "release on wrong cpu...");
-       }
-       put_cpu();
-
-       return error ? 0 : -1;
-}
-
-static int ds_selftest_bts_bad_request_cpu(int cpu, void *buffer)
-{
-       struct bts_tracer *tracer;
-       int error;
-
-       /* Try to request cpu tracing while task tracing is active. */
-       tracer = ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE, NULL,
-                                   (size_t)-1, BTS_KERNEL);
-       error = PTR_ERR(tracer);
-       if (!IS_ERR(tracer)) {
-               ds_release_bts(tracer);
-               error = 0;
-       }
-
-       if (error != -EPERM)
-               printk(KERN_CONT "cpu/task tracing overlap...");
-
-       return error ? 0 : -1;
-}
-
-static int ds_selftest_bts_bad_request_task(void *buffer)
-{
-       struct bts_tracer *tracer;
-       int error;
-
-       /* Try to request cpu tracing while task tracing is active. */
-       tracer = ds_request_bts_task(current, buffer, BUFFER_SIZE, NULL,
-                                   (size_t)-1, BTS_KERNEL);
-       error = PTR_ERR(tracer);
-       if (!IS_ERR(tracer)) {
-               error = 0;
-               ds_release_bts(tracer);
-       }
-
-       if (error != -EPERM)
-               printk(KERN_CONT "task/cpu tracing overlap...");
-
-       return error ? 0 : -1;
-}
-
-int ds_selftest_bts(void)
-{
-       struct ds_selftest_bts_conf conf;
-       unsigned char buffer[BUFFER_SIZE], *small_buffer;
-       unsigned long irq;
-       int cpu;
-
-       printk(KERN_INFO "[ds] bts selftest...");
-       conf.error = 0;
-
-       small_buffer = (unsigned char *)ALIGN((unsigned long)buffer, 8) + 8;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               conf.suspend = ds_suspend_bts_wrap;
-               conf.resume = ds_resume_bts_wrap;
-               conf.tracer =
-                       ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
-                                          NULL, (size_t)-1, BTS_KERNEL);
-               ds_selftest_bts_cpu(&conf);
-               if (conf.error >= 0)
-                       conf.error = ds_selftest_bts_bad_request_task(buffer);
-               ds_release_bts(conf.tracer);
-               if (conf.error < 0)
-                       goto out;
-
-               conf.suspend = ds_suspend_bts_noirq;
-               conf.resume = ds_resume_bts_noirq;
-               conf.tracer =
-                       ds_request_bts_cpu(cpu, buffer, BUFFER_SIZE,
-                                          NULL, (size_t)-1, BTS_KERNEL);
-               smp_call_function_single(cpu, ds_selftest_bts_cpu, &conf, 1);
-               if (conf.error >= 0) {
-                       conf.error =
-                               ds_selftest_bts_bad_release_noirq(cpu,
-                                                                 conf.tracer);
-                       /* We must not release the tracer twice. */
-                       if (conf.error < 0)
-                               conf.tracer = NULL;
-               }
-               if (conf.error >= 0)
-                       conf.error = ds_selftest_bts_bad_request_task(buffer);
-               smp_call_function_single(cpu, ds_release_bts_noirq_wrap,
-                                        conf.tracer, 1);
-               if (conf.error < 0)
-                       goto out;
-       }
-
-       conf.suspend = ds_suspend_bts_wrap;
-       conf.resume = ds_resume_bts_wrap;
-       conf.tracer =
-               ds_request_bts_task(current, buffer, BUFFER_SIZE,
-                                   NULL, (size_t)-1, BTS_KERNEL);
-       ds_selftest_bts_cpu(&conf);
-       if (conf.error >= 0)
-               conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
-       ds_release_bts(conf.tracer);
-       if (conf.error < 0)
-               goto out;
-
-       conf.suspend = ds_suspend_bts_noirq;
-       conf.resume = ds_resume_bts_noirq;
-       conf.tracer =
-               ds_request_bts_task(current, small_buffer, SMALL_BUFFER_SIZE,
-                                  NULL, (size_t)-1, BTS_KERNEL);
-       local_irq_save(irq);
-       ds_selftest_bts_cpu(&conf);
-       if (conf.error >= 0)
-               conf.error = ds_selftest_bts_bad_request_cpu(0, buffer);
-       ds_release_bts_noirq(conf.tracer);
-       local_irq_restore(irq);
-       if (conf.error < 0)
-               goto out;
-
-       conf.error = 0;
- out:
-       put_online_cpus();
-       printk(KERN_CONT "%s.\n", (conf.error ? "failed" : "passed"));
-
-       return conf.error;
-}
-
-int ds_selftest_pebs(void)
-{
-       return 0;
-}
diff --git a/arch/x86/kernel/ds_selftest.h b/arch/x86/kernel/ds_selftest.h
deleted file mode 100644 (file)
index 2ba8745..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Debug Store support - selftest
- *
- *
- * Copyright (C) 2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@intel.com>, 2009
- */
-
-#ifdef CONFIG_X86_DS_SELFTEST
-extern int ds_selftest_bts(void);
-extern int ds_selftest_pebs(void);
-#else
-static inline int ds_selftest_bts(void) { return 0; }
-static inline int ds_selftest_pebs(void) { return 0; }
-#endif
index 6d81755..c89a386 100644 (file)
@@ -224,11 +224,6 @@ unsigned __kprobes long oops_begin(void)
        int cpu;
        unsigned long flags;
 
-       /* notify the hw-branch tracer so it may disable tracing and
-          add the last trace to the trace buffer -
-          the earlier this happens, the more useful the trace. */
-       trace_hw_branch_oops();
-
        oops_enter();
 
        /* racy, but better than risking deadlock. */
index e39e771..e1a93be 100644 (file)
@@ -14,6 +14,8 @@
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
+#include <linux/uaccess.h>
+
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp, char *log_lvl);
@@ -42,8 +44,10 @@ static inline unsigned long rewind_frame_pointer(int n)
        get_bp(frame);
 
 #ifdef CONFIG_FRAME_POINTER
-       while (n--)
-               frame = frame->next_frame;
+       while (n--) {
+               if (probe_kernel_address(&frame->next_frame, frame))
+                       break;
+       }
 #endif
 
        return (unsigned long)frame;
index 44a8e0d..cd49141 100644 (file)
@@ -53,6 +53,7 @@
 #include <asm/processor-flags.h>
 #include <asm/ftrace.h>
 #include <asm/irq_vectors.h>
+#include <asm/cpufeature.h>
 
 /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
 #include <linux/elf-em.h>
@@ -905,7 +906,25 @@ ENTRY(simd_coprocessor_error)
        RING0_INT_FRAME
        pushl $0
        CFI_ADJUST_CFA_OFFSET 4
+#ifdef CONFIG_X86_INVD_BUG
+       /* AMD 486 bug: invd from userspace calls exception 19 instead of #GP */
+661:   pushl $do_general_protection
+662:
+.section .altinstructions,"a"
+       .balign 4
+       .long 661b
+       .long 663f
+       .byte X86_FEATURE_XMM
+       .byte 662b-661b
+       .byte 664f-663f
+.previous
+.section .altinstr_replacement,"ax"
+663:   pushl $do_simd_coprocessor_error
+664:
+.previous
+#else
        pushl $do_simd_coprocessor_error
+#endif
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
index 23b4ecd..a198b7c 100644 (file)
@@ -36,6 +36,7 @@
 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,19 +396,23 @@ 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. 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.
-        * 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.
+        * the counter register below.
+        *
+        * 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.
+        *
+        * We restrict the read back to the affected ATI chipsets (set
+        * by quirks) and also run it with hpet=verbose for debugging
+        * purposes.
         */
-       if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) {
-               WARN_ONCE(hpet_readl(HPET_Tn_CMP(timer)) != cnt,
-                 KERN_WARNING "hpet: compare register read back failed.\n");
+       if (hpet_readback_cmp || hpet_verbose) {
+               u32 cmp = hpet_readl(HPET_Tn_CMP(timer));
+
+               if (cmp != cnt)
+                       printk_once(KERN_WARNING
+                           "hpet: compare register read back failed.\n");
        }
 
        return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
index d6cc065..a8f1b80 100644 (file)
@@ -188,26 +188,17 @@ static int get_hbp_len(u8 hbp_len)
        return len_in_bytes;
 }
 
-/*
- * Check for virtual address in user space.
- */
-int arch_check_va_in_userspace(unsigned long va, u8 hbp_len)
-{
-       unsigned int len;
-
-       len = get_hbp_len(hbp_len);
-
-       return (va <= TASK_SIZE - len);
-}
-
 /*
  * Check for virtual address in kernel space.
  */
-static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
 {
        unsigned int len;
+       unsigned long va;
+       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       len = get_hbp_len(hbp_len);
+       va = info->address;
+       len = get_hbp_len(info->len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
@@ -300,8 +291,7 @@ static int arch_build_bp_info(struct perf_event *bp)
 /*
  * Validate the arch-specific HW Breakpoint register settings
  */
-int arch_validate_hwbkpt_settings(struct perf_event *bp,
-                                 struct task_struct *tsk)
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
 {
        struct arch_hw_breakpoint *info = counter_arch_bp(bp);
        unsigned int align;
@@ -314,16 +304,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
 
        ret = -EINVAL;
 
-       if (info->type == X86_BREAKPOINT_EXECUTE)
-               /*
-                * Ptrace-refactoring code
-                * For now, we'll allow instruction breakpoint only for user-space
-                * addresses
-                */
-               if ((!arch_check_va_in_userspace(info->address, info->len)) &&
-                       info->len != X86_BREAKPOINT_EXECUTE)
-                       return ret;
-
        switch (info->len) {
        case X86_BREAKPOINT_LEN_1:
                align = 0;
@@ -350,15 +330,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
        if (info->address & align)
                return -EINVAL;
 
-       /* Check that the virtual address is in the proper range */
-       if (tsk) {
-               if (!arch_check_va_in_userspace(info->address, info->len))
-                       return -EFAULT;
-       } else {
-               if (!arch_check_va_in_kernelspace(info->address, info->len))
-                       return -EFAULT;
-       }
-
        return 0;
 }
 
index 54c31c2..86cef6b 100644 (file)
@@ -102,65 +102,62 @@ void __cpuinit fpu_init(void)
 
        mxcsr_feature_mask_init();
        /* clean state in init */
-       if (cpu_has_xsave)
-               current_thread_info()->status = TS_XSAVE;
-       else
-               current_thread_info()->status = 0;
+       current_thread_info()->status = 0;
        clear_used_math();
 }
 #endif /* CONFIG_X86_64 */
 
-/*
- * The _current_ task is using the FPU for the first time
- * so initialize it and set the mxcsr to its default
- * value at reset if we support XMM instructions and then
- * remeber the current task has used the FPU.
- */
-int init_fpu(struct task_struct *tsk)
+static void fpu_finit(struct fpu *fpu)
 {
-       if (tsk_used_math(tsk)) {
-               if (HAVE_HWFP && tsk == current)
-                       unlazy_fpu(tsk);
-               return 0;
-       }
-
-       /*
-        * Memory allocation at the first usage of the FPU and other state.
-        */
-       if (!tsk->thread.xstate) {
-               tsk->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
-                                                     GFP_KERNEL);
-               if (!tsk->thread.xstate)
-                       return -ENOMEM;
-       }
-
 #ifdef CONFIG_X86_32
        if (!HAVE_HWFP) {
-               memset(tsk->thread.xstate, 0, xstate_size);
-               finit_task(tsk);
-               set_stopped_child_used_math(tsk);
-               return 0;
+               finit_soft_fpu(&fpu->state->soft);
+               return;
        }
 #endif
 
        if (cpu_has_fxsr) {
-               struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+               struct i387_fxsave_struct *fx = &fpu->state->fxsave;
 
                memset(fx, 0, xstate_size);
                fx->cwd = 0x37f;
                if (cpu_has_xmm)
                        fx->mxcsr = MXCSR_DEFAULT;
        } else {
-               struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;
+               struct i387_fsave_struct *fp = &fpu->state->fsave;
                memset(fp, 0, xstate_size);
                fp->cwd = 0xffff037fu;
                fp->swd = 0xffff0000u;
                fp->twd = 0xffffffffu;
                fp->fos = 0xffff0000u;
        }
+}
+
+/*
+ * The _current_ task is using the FPU for the first time
+ * so initialize it and set the mxcsr to its default
+ * value at reset if we support XMM instructions and then
+ * remeber the current task has used the FPU.
+ */
+int init_fpu(struct task_struct *tsk)
+{
+       int ret;
+
+       if (tsk_used_math(tsk)) {
+               if (HAVE_HWFP && tsk == current)
+                       unlazy_fpu(tsk);
+               return 0;
+       }
+
        /*
-        * Only the device not available exception or ptrace can call init_fpu.
+        * Memory allocation at the first usage of the FPU and other state.
         */
+       ret = fpu_alloc(&tsk->thread.fpu);
+       if (ret)
+               return ret;
+
+       fpu_finit(&tsk->thread.fpu);
+
        set_stopped_child_used_math(tsk);
        return 0;
 }
@@ -194,7 +191,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
                return ret;
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                  &target->thread.xstate->fxsave, 0, -1);
+                                  &target->thread.fpu.state->fxsave, 0, -1);
 }
 
 int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
@@ -211,19 +208,19 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
                return ret;
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &target->thread.xstate->fxsave, 0, -1);
+                                &target->thread.fpu.state->fxsave, 0, -1);
 
        /*
         * mxcsr reserved bits must be masked to zero for security reasons.
         */
-       target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+       target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
 
        /*
         * update the header bits in the xsave header, indicating the
         * presence of FP and SSE state.
         */
        if (cpu_has_xsave)
-               target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
+               target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
 
        return ret;
 }
@@ -246,14 +243,14 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
         * memory layout in the thread struct, so that we can copy the entire
         * xstateregs to the user using one user_regset_copyout().
         */
-       memcpy(&target->thread.xstate->fxsave.sw_reserved,
+       memcpy(&target->thread.fpu.state->fxsave.sw_reserved,
               xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes));
 
        /*
         * Copy the xstate memory layout.
         */
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 &target->thread.xstate->xsave, 0, -1);
+                                 &target->thread.fpu.state->xsave, 0, -1);
        return ret;
 }
 
@@ -272,14 +269,14 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
                return ret;
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &target->thread.xstate->xsave, 0, -1);
+                                &target->thread.fpu.state->xsave, 0, -1);
 
        /*
         * mxcsr reserved bits must be masked to zero for security reasons.
         */
-       target->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+       target->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
 
-       xsave_hdr = &target->thread.xstate->xsave.xsave_hdr;
+       xsave_hdr = &target->thread.fpu.state->xsave.xsave_hdr;
 
        xsave_hdr->xstate_bv &= pcntxt_mask;
        /*
@@ -365,7 +362,7 @@ static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
 static void
 convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
 {
-       struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave;
+       struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
        struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
        struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
        int i;
@@ -405,7 +402,7 @@ static void convert_to_fxsr(struct task_struct *tsk,
                            const struct user_i387_ia32_struct *env)
 
 {
-       struct i387_fxsave_struct *fxsave = &tsk->thread.xstate->fxsave;
+       struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state->fxsave;
        struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
        struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
        int i;
@@ -445,7 +442,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset,
 
        if (!cpu_has_fxsr) {
                return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                          &target->thread.xstate->fsave, 0,
+                                          &target->thread.fpu.state->fsave, 0,
                                           -1);
        }
 
@@ -475,7 +472,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
 
        if (!cpu_has_fxsr) {
                return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                         &target->thread.xstate->fsave, 0, -1);
+                                         &target->thread.fpu.state->fsave, 0, -1);
        }
 
        if (pos > 0 || count < sizeof(env))
@@ -490,7 +487,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
         * presence of FP.
         */
        if (cpu_has_xsave)
-               target->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FP;
+               target->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FP;
        return ret;
 }
 
@@ -501,7 +498,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
 static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
-       struct i387_fsave_struct *fp = &tsk->thread.xstate->fsave;
+       struct i387_fsave_struct *fp = &tsk->thread.fpu.state->fsave;
 
        fp->status = fp->swd;
        if (__copy_to_user(buf, fp, sizeof(struct i387_fsave_struct)))
@@ -512,7 +509,7 @@ static inline int save_i387_fsave(struct _fpstate_ia32 __user *buf)
 static int save_i387_fxsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
-       struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave;
+       struct i387_fxsave_struct *fx = &tsk->thread.fpu.state->fxsave;
        struct user_i387_ia32_struct env;
        int err = 0;
 
@@ -547,7 +544,7 @@ static int save_i387_xsave(void __user *buf)
         * header as well as change any contents in the memory layout.
         * xrestore as part of sigreturn will capture all the changes.
         */
-       tsk->thread.xstate->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
+       tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv |= XSTATE_FPSSE;
 
        if (save_i387_fxsave(fx) < 0)
                return -1;
@@ -599,7 +596,7 @@ static inline int restore_i387_fsave(struct _fpstate_ia32 __user *buf)
 {
        struct task_struct *tsk = current;
 
-       return __copy_from_user(&tsk->thread.xstate->fsave, buf,
+       return __copy_from_user(&tsk->thread.fpu.state->fsave, buf,
                                sizeof(struct i387_fsave_struct));
 }
 
@@ -610,10 +607,10 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf,
        struct user_i387_ia32_struct env;
        int err;
 
-       err = __copy_from_user(&tsk->thread.xstate->fxsave, &buf->_fxsr_env[0],
+       err = __copy_from_user(&tsk->thread.fpu.state->fxsave, &buf->_fxsr_env[0],
                               size);
        /* mxcsr reserved bits must be masked to zero for security reasons */
-       tsk->thread.xstate->fxsave.mxcsr &= mxcsr_feature_mask;
+       tsk->thread.fpu.state->fxsave.mxcsr &= mxcsr_feature_mask;
        if (err || __copy_from_user(&env, buf, sizeof(env)))
                return 1;
        convert_to_fxsr(tsk, &env);
@@ -629,7 +626,7 @@ static int restore_i387_xsave(void __user *buf)
        struct i387_fxsave_struct __user *fx =
                (struct i387_fxsave_struct __user *) &fx_user->_fxsr_env[0];
        struct xsave_hdr_struct *xsave_hdr =
-                               &current->thread.xstate->xsave.xsave_hdr;
+                               &current->thread.fpu.state->xsave.xsave_hdr;
        u64 mask;
        int err;
 
index 23c1679..2dfd315 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/hpet.h>
 #include <asm/smp.h>
 
-DEFINE_SPINLOCK(i8253_lock);
+DEFINE_RAW_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
 /*
@@ -33,7 +33,7 @@ struct clock_event_device *global_clock_event;
 static void init_pit_timer(enum clock_event_mode mode,
                           struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
@@ -62,7 +62,7 @@ static void init_pit_timer(enum clock_event_mode mode,
                /* Nothing to do here */
                break;
        }
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 }
 
 /*
@@ -72,10 +72,10 @@ static void init_pit_timer(enum clock_event_mode mode,
  */
 static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
 {
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        outb_pit(delta & 0xff , PIT_CH0);       /* LSB */
        outb_pit(delta >> 8 , PIT_CH0);         /* MSB */
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 
        return 0;
 }
@@ -130,7 +130,7 @@ static cycle_t pit_read(struct clocksource *cs)
        int count;
        u32 jifs;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        /*
         * Although our caller may have the read side of xtime_lock,
         * this is now a seqlock, and we are cheating in this routine
@@ -176,7 +176,7 @@ static cycle_t pit_read(struct clocksource *cs)
        old_count = count;
        old_jifs = jifs;
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        count = (LATCH - 1) - count;
 
index 0ed2d30..990ae7c 100644 (file)
@@ -60,7 +60,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
        outb(0, 0xF0);
        if (ignore_fpu_irq || !boot_cpu_data.hard_math)
                return IRQ_NONE;
-       math_error((void __user *)get_irq_regs()->ip);
+       math_error(get_irq_regs(), 0, 16);
        return IRQ_HANDLED;
 }
 
index b43bbae..345a4b1 100644 (file)
@@ -422,14 +422,22 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
 
 static void __kprobes clear_btf(void)
 {
-       if (test_thread_flag(TIF_DEBUGCTLMSR))
-               update_debugctlmsr(0);
+       if (test_thread_flag(TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+       }
 }
 
 static void __kprobes restore_btf(void)
 {
-       if (test_thread_flag(TIF_DEBUGCTLMSR))
-               update_debugctlmsr(current->thread.debugctlmsr);
+       if (test_thread_flag(TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl |= DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+       }
 }
 
 void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
@@ -534,20 +542,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
        struct kprobe_ctlblk *kcb;
 
        addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
-       if (*addr != BREAKPOINT_INSTRUCTION) {
-               /*
-                * The breakpoint instruction was removed right
-                * after we hit it.  Another cpu has removed
-                * either a probepoint or a debugger breakpoint
-                * at this address.  In either case, no further
-                * handling of this interrupt is appropriate.
-                * Back up over the (now missing) int3 and run
-                * the original instruction.
-                */
-               regs->ip = (unsigned long)addr;
-               return 1;
-       }
-
        /*
         * We don't want to be preempted for the entire
         * duration of kprobe processing. We conditionally
@@ -579,6 +573,19 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                                setup_singlestep(p, regs, kcb, 0);
                        return 1;
                }
+       } else if (*addr != BREAKPOINT_INSTRUCTION) {
+               /*
+                * The breakpoint instruction was removed right
+                * after we hit it.  Another cpu has removed
+                * either a probepoint or a debugger breakpoint
+                * at this address.  In either case, no further
+                * handling of this interrupt is appropriate.
+                * Back up over the (now missing) int3 and run
+                * the original instruction.
+                */
+               regs->ip = (unsigned long)addr;
+               preempt_enable_no_resched();
+               return 1;
        } else if (kprobe_running()) {
                p = __get_cpu_var(current_kprobe);
                if (p->break_handler && p->break_handler(p, regs)) {
index cceb5bc..2cd8c54 100644 (file)
@@ -201,9 +201,9 @@ static int do_microcode_update(const void __user *buf, size_t size)
        return error;
 }
 
-static int microcode_open(struct inode *unused1, struct file *unused2)
+static int microcode_open(struct inode *inode, struct file *file)
 {
-       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+       return capable(CAP_SYS_RAWIO) ? nonseekable_open(inode, file) : -EPERM;
 }
 
 static ssize_t microcode_write(struct file *file, const char __user *buf,
index 85a343e..3561702 100644 (file)
@@ -343,10 +343,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                                int (*get_ucode_data)(void *, const void *, size_t))
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-       u8 *ucode_ptr = data, *new_mc = NULL, *mc;
+       u8 *ucode_ptr = data, *new_mc = NULL, *mc = NULL;
        int new_rev = uci->cpu_sig.rev;
        unsigned int leftover = size;
        enum ucode_state state = UCODE_OK;
+       unsigned int curr_mc_size = 0;
 
        while (leftover) {
                struct microcode_header_intel mc_header;
@@ -361,9 +362,15 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                        break;
                }
 
-               mc = vmalloc(mc_size);
-               if (!mc)
-                       break;
+               /* For performance reasons, reuse mc area when possible */
+               if (!mc || mc_size > curr_mc_size) {
+                       if (mc)
+                               vfree(mc);
+                       mc = vmalloc(mc_size);
+                       if (!mc)
+                               break;
+                       curr_mc_size = mc_size;
+               }
 
                if (get_ucode_data(mc, ucode_ptr, mc_size) ||
                    microcode_sanity_check(mc) < 0) {
@@ -376,13 +383,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
                                vfree(new_mc);
                        new_rev = mc_header.rev;
                        new_mc  = mc;
-               } else
-                       vfree(mc);
+                       mc = NULL;      /* trigger new vmalloc */
+               }
 
                ucode_ptr += mc_size;
                leftover  -= mc_size;
        }
 
+       if (mc)
+               vfree(mc);
+
        if (leftover) {
                if (new_mc)
                        vfree(new_mc);
index e81030f..5ae5d24 100644 (file)
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
                printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
 }
 
-static int bad_ioapic(unsigned long address)
-{
-       if (nr_ioapics >= MAX_IO_APICS) {
-               printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-                      "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-               panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-       }
-       if (!address) {
-               printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-                      " found in table, skipping!\n");
-               return 1;
-       }
-       return 0;
-}
-
 static void __init MP_ioapic_info(struct mpc_ioapic *m)
 {
        if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
        printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
               m->apicid, m->apicver, m->apicaddr);
 
-       if (bad_ioapic(m->apicaddr))
-               return;
-
-       mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
-       mp_ioapics[nr_ioapics].apicid = m->apicid;
-       mp_ioapics[nr_ioapics].type = m->type;
-       mp_ioapics[nr_ioapics].apicver = m->apicver;
-       mp_ioapics[nr_ioapics].flags = m->flags;
-       nr_ioapics++;
+       mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1);
 }
 
 static void print_MP_intsrc_info(struct mpc_intsrc *m)
index 0aad867..e796448 100644 (file)
@@ -237,4 +237,9 @@ void __init x86_mrst_early_setup(void)
        x86_init.pci.fixup_irqs = x86_init_noop;
 
        legacy_pic = &null_legacy_pic;
+
+       /* Avoid searching for BIOS MP tables */
+       x86_init.mpparse.find_smp_config = x86_init_noop;
+       x86_init.mpparse.get_smp_config = x86_init_uint_noop;
+
 }
index 68cd24f..0f7f130 100644 (file)
@@ -565,6 +565,9 @@ static void enable_gart_translations(void)
 
                enable_gart_translation(dev, __pa(agp_gatt_table));
        }
+
+       /* Flush the GART-TLB to remove stale entries */
+       k8_flush_garts();
 }
 
 /*
index 28ad9f4..e7e3521 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/idle.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
-#include <asm/ds.h>
 #include <asm/debugreg.h>
 
 unsigned long idle_halt;
@@ -32,26 +31,22 @@ struct kmem_cache *task_xstate_cachep;
 
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
+       int ret;
+
        *dst = *src;
-       if (src->thread.xstate) {
-               dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep,
-                                                     GFP_KERNEL);
-               if (!dst->thread.xstate)
-                       return -ENOMEM;
-               WARN_ON((unsigned long)dst->thread.xstate & 15);
-               memcpy(dst->thread.xstate, src->thread.xstate, xstate_size);
+       if (fpu_allocated(&src->thread.fpu)) {
+               memset(&dst->thread.fpu, 0, sizeof(dst->thread.fpu));
+               ret = fpu_alloc(&dst->thread.fpu);
+               if (ret)
+                       return ret;
+               fpu_copy(&dst->thread.fpu, &src->thread.fpu);
        }
        return 0;
 }
 
 void free_thread_xstate(struct task_struct *tsk)
 {
-       if (tsk->thread.xstate) {
-               kmem_cache_free(task_xstate_cachep, tsk->thread.xstate);
-               tsk->thread.xstate = NULL;
-       }
-
-       WARN(tsk->thread.ds_ctx, "leaking DS context\n");
+       fpu_free(&tsk->thread.fpu);
 }
 
 void free_thread_info(struct thread_info *ti)
@@ -198,11 +193,16 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
        prev = &prev_p->thread;
        next = &next_p->thread;
 
-       if (test_tsk_thread_flag(next_p, TIF_DS_AREA_MSR) ||
-           test_tsk_thread_flag(prev_p, TIF_DS_AREA_MSR))
-               ds_switch_to(prev_p, next_p);
-       else if (next->debugctlmsr != prev->debugctlmsr)
-               update_debugctlmsr(next->debugctlmsr);
+       if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^
+           test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP))
+                       debugctl |= DEBUGCTLMSR_BTF;
+
+               update_debugctlmsr(debugctl);
+       }
 
        if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^
            test_tsk_thread_flag(next_p, TIF_NOTSC)) {
@@ -546,11 +546,13 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
                 * check OSVW bit for CPUs that are not affected
                 * by erratum #400
                 */
-               rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
-               if (val >= 2) {
-                       rdmsrl(MSR_AMD64_OSVW_STATUS, val);
-                       if (!(val & BIT(1)))
-                               goto no_c1e_idle;
+               if (cpu_has(c, X86_FEATURE_OSVW)) {
+                       rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, val);
+                       if (val >= 2) {
+                               rdmsrl(MSR_AMD64_OSVW_STATUS, val);
+                               if (!(val & BIT(1)))
+                                       goto no_c1e_idle;
+                       }
                }
                return 1;
        }
index f6c6266..8d12878 100644 (file)
@@ -55,7 +55,6 @@
 #include <asm/cpu.h>
 #include <asm/idle.h>
 #include <asm/syscalls.h>
-#include <asm/ds.h>
 #include <asm/debugreg.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
@@ -238,13 +237,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                kfree(p->thread.io_bitmap_ptr);
                p->thread.io_bitmap_max = 0;
        }
-
-       clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
-       p->thread.ds_ctx = NULL;
-
-       clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
-       p->thread.debugctlmsr = 0;
-
        return err;
 }
 
@@ -317,7 +309,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        /* we're going to use this soon, after a few expensive things */
        if (preload_fpu)
-               prefetch(next->xstate);
+               prefetch(next->fpu.state);
 
        /*
         * Reload esp0.
index dc9690b..3c2422a 100644 (file)
@@ -49,7 +49,6 @@
 #include <asm/ia32.h>
 #include <asm/idle.h>
 #include <asm/syscalls.h>
-#include <asm/ds.h>
 #include <asm/debugreg.h>
 
 asmlinkage extern void ret_from_fork(void);
@@ -276,12 +275,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
        set_tsk_thread_flag(p, TIF_FORK);
 
-       p->thread.fs = me->thread.fs;
-       p->thread.gs = me->thread.gs;
        p->thread.io_bitmap_ptr = NULL;
 
        savesegment(gs, p->thread.gsindex);
+       p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs;
        savesegment(fs, p->thread.fsindex);
+       p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
        savesegment(es, p->thread.es);
        savesegment(ds, p->thread.ds);
 
@@ -313,13 +312,6 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                if (err)
                        goto out;
        }
-
-       clear_tsk_thread_flag(p, TIF_DS_AREA_MSR);
-       p->thread.ds_ctx = NULL;
-
-       clear_tsk_thread_flag(p, TIF_DEBUGCTLMSR);
-       p->thread.debugctlmsr = 0;
-
        err = 0;
 out:
        if (err && p->thread.io_bitmap_ptr) {
@@ -396,7 +388,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
        /* we're going to use this soon, after a few expensive things */
        if (preload_fpu)
-               prefetch(next->xstate);
+               prefetch(next->fpu.state);
 
        /*
         * Reload esp0, LDT and the page table pointer:
index 2e9b550..70c4872 100644 (file)
@@ -2,9 +2,6 @@
 /*
  * Pentium III FXSR, SSE support
  *     Gareth Hughes <gareth@valinux.com>, May 2000
- *
- * BTS tracing
- *     Markus Metzger <markus.t.metzger@intel.com>, Dec 2007
  */
 
 #include <linux/kernel.h>
@@ -22,7 +19,6 @@
 #include <linux/audit.h>
 #include <linux/seccomp.h>
 #include <linux/signal.h>
-#include <linux/workqueue.h>
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
 
@@ -36,7 +32,6 @@
 #include <asm/desc.h>
 #include <asm/prctl.h>
 #include <asm/proto.h>
-#include <asm/ds.h>
 #include <asm/hw_breakpoint.h>
 
 #include "tls.h"
@@ -693,7 +688,7 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
        struct perf_event_attr attr;
 
        if (!t->ptrace_bps[nr]) {
-               hw_breakpoint_init(&attr);
+               ptrace_breakpoint_init(&attr);
                /*
                 * Put stub len and type to register (reserve) an inactive but
                 * correct bp
@@ -789,342 +784,6 @@ static int ioperm_get(struct task_struct *target,
                                   0, IO_BITMAP_BYTES);
 }
 
-#ifdef CONFIG_X86_PTRACE_BTS
-/*
- * A branch trace store context.
- *
- * Contexts may only be installed by ptrace_bts_config() and only for
- * ptraced tasks.
- *
- * Contexts are destroyed when the tracee is detached from the tracer.
- * The actual destruction work requires interrupts enabled, so the
- * work is deferred and will be scheduled during __ptrace_unlink().
- *
- * Contexts hold an additional task_struct reference on the traced
- * task, as well as a reference on the tracer's mm.
- *
- * Ptrace already holds a task_struct for the duration of ptrace operations,
- * but since destruction is deferred, it may be executed after both
- * tracer and tracee exited.
- */
-struct bts_context {
-       /* The branch trace handle. */
-       struct bts_tracer       *tracer;
-
-       /* The buffer used to store the branch trace and its size. */
-       void                    *buffer;
-       unsigned int            size;
-
-       /* The mm that paid for the above buffer. */
-       struct mm_struct        *mm;
-
-       /* The task this context belongs to. */
-       struct task_struct      *task;
-
-       /* The signal to send on a bts buffer overflow. */
-       unsigned int            bts_ovfl_signal;
-
-       /* The work struct to destroy a context. */
-       struct work_struct      work;
-};
-
-static int alloc_bts_buffer(struct bts_context *context, unsigned int size)
-{
-       void *buffer = NULL;
-       int err = -ENOMEM;
-
-       err = account_locked_memory(current->mm, current->signal->rlim, size);
-       if (err < 0)
-               return err;
-
-       buffer = kzalloc(size, GFP_KERNEL);
-       if (!buffer)
-               goto out_refund;
-
-       context->buffer = buffer;
-       context->size = size;
-       context->mm = get_task_mm(current);
-
-       return 0;
-
- out_refund:
-       refund_locked_memory(current->mm, size);
-       return err;
-}
-
-static inline void free_bts_buffer(struct bts_context *context)
-{
-       if (!context->buffer)
-               return;
-
-       kfree(context->buffer);
-       context->buffer = NULL;
-
-       refund_locked_memory(context->mm, context->size);
-       context->size = 0;
-
-       mmput(context->mm);
-       context->mm = NULL;
-}
-
-static void free_bts_context_work(struct work_struct *w)
-{
-       struct bts_context *context;
-
-       context = container_of(w, struct bts_context, work);
-
-       ds_release_bts(context->tracer);
-       put_task_struct(context->task);
-       free_bts_buffer(context);
-       kfree(context);
-}
-
-static inline void free_bts_context(struct bts_context *context)
-{
-       INIT_WORK(&context->work, free_bts_context_work);
-       schedule_work(&context->work);
-}
-
-static inline struct bts_context *alloc_bts_context(struct task_struct *task)
-{
-       struct bts_context *context = kzalloc(sizeof(*context), GFP_KERNEL);
-       if (context) {
-               context->task = task;
-               task->bts = context;
-
-               get_task_struct(task);
-       }
-
-       return context;
-}
-
-static int ptrace_bts_read_record(struct task_struct *child, size_t index,
-                                 struct bts_struct __user *out)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-       struct bts_struct bts;
-       const unsigned char *at;
-       int error;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       at = trace->ds.top - ((index + 1) * trace->ds.size);
-       if ((void *)at < trace->ds.begin)
-               at += (trace->ds.n * trace->ds.size);
-
-       if (!trace->read)
-               return -EOPNOTSUPP;
-
-       error = trace->read(context->tracer, at, &bts);
-       if (error < 0)
-               return error;
-
-       if (copy_to_user(out, &bts, sizeof(bts)))
-               return -EFAULT;
-
-       return sizeof(bts);
-}
-
-static int ptrace_bts_drain(struct task_struct *child,
-                           long size,
-                           struct bts_struct __user *out)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-       const unsigned char *at;
-       int error, drained = 0;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       if (!trace->read)
-               return -EOPNOTSUPP;
-
-       if (size < (trace->ds.top - trace->ds.begin))
-               return -EIO;
-
-       for (at = trace->ds.begin; (void *)at < trace->ds.top;
-            out++, drained++, at += trace->ds.size) {
-               struct bts_struct bts;
-
-               error = trace->read(context->tracer, at, &bts);
-               if (error < 0)
-                       return error;
-
-               if (copy_to_user(out, &bts, sizeof(bts)))
-                       return -EFAULT;
-       }
-
-       memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
-
-       error = ds_reset_bts(context->tracer);
-       if (error < 0)
-               return error;
-
-       return drained;
-}
-
-static int ptrace_bts_config(struct task_struct *child,
-                            long cfg_size,
-                            const struct ptrace_bts_config __user *ucfg)
-{
-       struct bts_context *context;
-       struct ptrace_bts_config cfg;
-       unsigned int flags = 0;
-
-       if (cfg_size < sizeof(cfg))
-               return -EIO;
-
-       if (copy_from_user(&cfg, ucfg, sizeof(cfg)))
-               return -EFAULT;
-
-       context = child->bts;
-       if (!context)
-               context = alloc_bts_context(child);
-       if (!context)
-               return -ENOMEM;
-
-       if (cfg.flags & PTRACE_BTS_O_SIGNAL) {
-               if (!cfg.signal)
-                       return -EINVAL;
-
-               return -EOPNOTSUPP;
-               context->bts_ovfl_signal = cfg.signal;
-       }
-
-       ds_release_bts(context->tracer);
-       context->tracer = NULL;
-
-       if ((cfg.flags & PTRACE_BTS_O_ALLOC) && (cfg.size != context->size)) {
-               int err;
-
-               free_bts_buffer(context);
-               if (!cfg.size)
-                       return 0;
-
-               err = alloc_bts_buffer(context, cfg.size);
-               if (err < 0)
-                       return err;
-       }
-
-       if (cfg.flags & PTRACE_BTS_O_TRACE)
-               flags |= BTS_USER;
-
-       if (cfg.flags & PTRACE_BTS_O_SCHED)
-               flags |= BTS_TIMESTAMPS;
-
-       context->tracer =
-               ds_request_bts_task(child, context->buffer, context->size,
-                                   NULL, (size_t)-1, flags);
-       if (unlikely(IS_ERR(context->tracer))) {
-               int error = PTR_ERR(context->tracer);
-
-               free_bts_buffer(context);
-               context->tracer = NULL;
-               return error;
-       }
-
-       return sizeof(cfg);
-}
-
-static int ptrace_bts_status(struct task_struct *child,
-                            long cfg_size,
-                            struct ptrace_bts_config __user *ucfg)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-       struct ptrace_bts_config cfg;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       if (cfg_size < sizeof(cfg))
-               return -EIO;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       memset(&cfg, 0, sizeof(cfg));
-       cfg.size        = trace->ds.end - trace->ds.begin;
-       cfg.signal      = context->bts_ovfl_signal;
-       cfg.bts_size    = sizeof(struct bts_struct);
-
-       if (cfg.signal)
-               cfg.flags |= PTRACE_BTS_O_SIGNAL;
-
-       if (trace->ds.flags & BTS_USER)
-               cfg.flags |= PTRACE_BTS_O_TRACE;
-
-       if (trace->ds.flags & BTS_TIMESTAMPS)
-               cfg.flags |= PTRACE_BTS_O_SCHED;
-
-       if (copy_to_user(ucfg, &cfg, sizeof(cfg)))
-               return -EFAULT;
-
-       return sizeof(cfg);
-}
-
-static int ptrace_bts_clear(struct task_struct *child)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       memset(trace->ds.begin, 0, trace->ds.n * trace->ds.size);
-
-       return ds_reset_bts(context->tracer);
-}
-
-static int ptrace_bts_size(struct task_struct *child)
-{
-       struct bts_context *context;
-       const struct bts_trace *trace;
-
-       context = child->bts;
-       if (!context)
-               return -ESRCH;
-
-       trace = ds_read_bts(context->tracer);
-       if (!trace)
-               return -ESRCH;
-
-       return (trace->ds.top - trace->ds.begin) / trace->ds.size;
-}
-
-/*
- * Called from __ptrace_unlink() after the child has been moved back
- * to its original parent.
- */
-void ptrace_bts_untrace(struct task_struct *child)
-{
-       if (unlikely(child->bts)) {
-               free_bts_context(child->bts);
-               child->bts = NULL;
-       }
-}
-#endif /* CONFIG_X86_PTRACE_BTS */
-
 /*
  * Called by kernel/ptrace.c when detaching..
  *
@@ -1252,39 +911,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                break;
 #endif
 
-       /*
-        * These bits need more cooking - not enabled yet:
-        */
-#ifdef CONFIG_X86_PTRACE_BTS
-       case PTRACE_BTS_CONFIG:
-               ret = ptrace_bts_config
-                       (child, data, (struct ptrace_bts_config __user *)addr);
-               break;
-
-       case PTRACE_BTS_STATUS:
-               ret = ptrace_bts_status
-                       (child, data, (struct ptrace_bts_config __user *)addr);
-               break;
-
-       case PTRACE_BTS_SIZE:
-               ret = ptrace_bts_size(child);
-               break;
-
-       case PTRACE_BTS_GET:
-               ret = ptrace_bts_read_record
-                       (child, data, (struct bts_struct __user *) addr);
-               break;
-
-       case PTRACE_BTS_CLEAR:
-               ret = ptrace_bts_clear(child);
-               break;
-
-       case PTRACE_BTS_DRAIN:
-               ret = ptrace_bts_drain
-                       (child, data, (struct bts_struct __user *) addr);
-               break;
-#endif /* CONFIG_X86_PTRACE_BTS */
-
        default:
                ret = ptrace_request(child, request, addr, data);
                break;
@@ -1544,14 +1170,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
        case PTRACE_GET_THREAD_AREA:
        case PTRACE_SET_THREAD_AREA:
-#ifdef CONFIG_X86_PTRACE_BTS
-       case PTRACE_BTS_CONFIG:
-       case PTRACE_BTS_STATUS:
-       case PTRACE_BTS_SIZE:
-       case PTRACE_BTS_GET:
-       case PTRACE_BTS_CLEAR:
-       case PTRACE_BTS_DRAIN:
-#endif /* CONFIG_X86_PTRACE_BTS */
                return arch_ptrace(child, request, addr, data);
 
        default:
index 12e9fea..e72d3fc 100644 (file)
@@ -495,10 +495,18 @@ void force_hpet_resume(void)
 /*
  * HPET MSI on some boards (ATI SB700/SB800) has side effect on
  * floppy DMA. Disable HPET MSI on such platforms.
+ * See erratum #27 (Misinterpreted MSI Requests May Result in
+ * Corrupted LPC DMA Data) in AMD Publication #46837,
+ * "SB700 Family Product Errata", Rev. 1.0, March 2010.
+ *
+ * Also 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.
  */
 static void force_disable_hpet_msi(struct pci_dev *unused)
 {
        hpet_msi_disable = 1;
+       hpet_readback_cmp = 1;
 }
 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS,
index 34e0993..7ded578 100644 (file)
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
 
 static int __init sfi_parse_ioapic(struct sfi_table_header *table)
 {
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
        pentry = (struct sfi_apic_table_entry *)sb->pentry;
 
        for (i = 0; i < num; i++) {
-               mp_register_ioapic(i, pentry->phys_addr, gsi_base);
-               gsi_base += io_apic_get_redir_entries(i);
+               mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1);
                pentry++;
        }
 
index 3149032..58de45e 100644 (file)
@@ -157,22 +157,6 @@ static int enable_single_step(struct task_struct *child)
        return 1;
 }
 
-/*
- * Install this value in MSR_IA32_DEBUGCTLMSR whenever child is running.
- */
-static void write_debugctlmsr(struct task_struct *child, unsigned long val)
-{
-       if (child->thread.debugctlmsr == val)
-               return;
-
-       child->thread.debugctlmsr = val;
-
-       if (child != current)
-               return;
-
-       update_debugctlmsr(val);
-}
-
 /*
  * Enable single or block step.
  */
@@ -186,15 +170,17 @@ static void enable_step(struct task_struct *child, bool block)
         * that uses user-mode single stepping itself.
         */
        if (enable_single_step(child) && block) {
-               set_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
-               write_debugctlmsr(child,
-                                 child->thread.debugctlmsr | DEBUGCTLMSR_BTF);
-       } else {
-               write_debugctlmsr(child,
-                                 child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
-
-               if (!child->thread.debugctlmsr)
-                       clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl |= DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+               set_tsk_thread_flag(child, TIF_BLOCKSTEP);
+       } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
+
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+               clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
        }
 }
 
@@ -213,11 +199,13 @@ void user_disable_single_step(struct task_struct *child)
        /*
         * Make sure block stepping (BTF) is disabled.
         */
-       write_debugctlmsr(child,
-                         child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF);
+       if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
+               unsigned long debugctl = get_debugctlmsr();
 
-       if (!child->thread.debugctlmsr)
-               clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR);
+               debugctl &= ~DEBUGCTLMSR_BTF;
+               update_debugctlmsr(debugctl);
+               clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
+       }
 
        /* Always clear TIF_SINGLESTEP... */
        clear_tsk_thread_flag(child, TIF_SINGLESTEP);
index 86c9f91..cc2c604 100644 (file)
@@ -175,6 +175,9 @@ static void add_mac_region(phys_addr_t start, unsigned long size)
        struct tboot_mac_region *mr;
        phys_addr_t end = start + size;
 
+       if (tboot->num_mac_regions >= MAX_TB_MAC_REGIONS)
+               panic("tboot: Too many MAC regions\n");
+
        if (start && size) {
                mr = &tboot->mac_regions[tboot->num_mac_regions++];
                mr->start = round_down(start, PAGE_SIZE);
@@ -184,18 +187,17 @@ static void add_mac_region(phys_addr_t start, unsigned long size)
 
 static int tboot_setup_sleep(void)
 {
+       int i;
+
        tboot->num_mac_regions = 0;
 
-       /* S3 resume code */
-       add_mac_region(acpi_wakeup_address, WAKEUP_SIZE);
+       for (i = 0; i < e820.nr_map; i++) {
+               if ((e820.map[i].type != E820_RAM)
+                && (e820.map[i].type != E820_RESERVED_KERN))
+                       continue;
 
-#ifdef CONFIG_X86_TRAMPOLINE
-       /* AP trampoline code */
-       add_mac_region(virt_to_phys(trampoline_base), TRAMPOLINE_SIZE);
-#endif
-
-       /* kernel code + data + bss */
-       add_mac_region(virt_to_phys(_text), _end - _text);
+               add_mac_region(e820.map[i].addr, e820.map[i].size);
+       }
 
        tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address;
 
index 17b03dd..7fea555 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     SGI UltraViolet TLB flush routines.
  *
- *     (c) 2008 Cliff Wickman <cpw@sgi.com>, SGI.
+ *     (c) 2008-2010 Cliff Wickman <cpw@sgi.com>, SGI.
  *
  *     This code is released under the GNU General Public License version 2 or
  *     later.
 #include <asm/idle.h>
 #include <asm/tsc.h>
 #include <asm/irq_vectors.h>
+#include <asm/timer.h>
 
-static struct bau_control      **uv_bau_table_bases __read_mostly;
-static int                     uv_bau_retry_limit __read_mostly;
+struct msg_desc {
+       struct bau_payload_queue_entry *msg;
+       int msg_slot;
+       int sw_ack_slot;
+       struct bau_payload_queue_entry *va_queue_first;
+       struct bau_payload_queue_entry *va_queue_last;
+};
 
-/* base pnode in this partition */
-static int                     uv_partition_base_pnode __read_mostly;
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD        0x000000000bUL
+
+static int uv_bau_max_concurrent __read_mostly;
+
+static int nobau;
+static int __init setup_nobau(char *arg)
+{
+       nobau = 1;
+       return 0;
+}
+early_param("nobau", setup_nobau);
 
-static unsigned long           uv_mmask __read_mostly;
+/* base pnode in this partition */
+static int uv_partition_base_pnode __read_mostly;
+/* position of pnode (which is nasid>>1): */
+static int uv_nshift __read_mostly;
+static unsigned long uv_mmask __read_mostly;
 
 static DEFINE_PER_CPU(struct ptc_stats, ptcstats);
 static DEFINE_PER_CPU(struct bau_control, bau_control);
+static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
+
+struct reset_args {
+       int sender;
+};
 
 /*
- * Determine the first node on a blade.
+ * Determine the first node on a uvhub. 'Nodes' are used for kernel
+ * memory allocation.
  */
-static int __init blade_to_first_node(int blade)
+static int __init uvhub_to_first_node(int uvhub)
 {
        int node, b;
 
        for_each_online_node(node) {
                b = uv_node_to_blade_id(node);
-               if (blade == b)
+               if (uvhub == b)
                        return node;
        }
-       return -1; /* shouldn't happen */
+       return -1;
 }
 
 /*
- * Determine the apicid of the first cpu on a blade.
+ * Determine the apicid of the first cpu on a uvhub.
  */
-static int __init blade_to_first_apicid(int blade)
+static int __init uvhub_to_first_apicid(int uvhub)
 {
        int cpu;
 
        for_each_present_cpu(cpu)
-               if (blade == uv_cpu_to_blade_id(cpu))
+               if (uvhub == uv_cpu_to_blade_id(cpu))
                        return per_cpu(x86_cpu_to_apicid, cpu);
        return -1;
 }
@@ -68,195 +93,459 @@ static int __init blade_to_first_apicid(int blade)
  * clear of the Timeout bit (as well) will free the resource. No reply will
  * be sent (the hardware will only do one reply per message).
  */
-static void uv_reply_to_message(int resource,
-                               struct bau_payload_queue_entry *msg,
-                               struct bau_msg_status *msp)
+static inline void uv_reply_to_message(struct msg_desc *mdp,
+                                      struct bau_control *bcp)
 {
        unsigned long dw;
+       struct bau_payload_queue_entry *msg;
 
-       dw = (1 << (resource + UV_SW_ACK_NPENDING)) | (1 << resource);
+       msg = mdp->msg;
+       if (!msg->canceled) {
+               dw = (msg->sw_ack_vector << UV_SW_ACK_NPENDING) |
+                                               msg->sw_ack_vector;
+               uv_write_local_mmr(
+                               UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw);
+       }
        msg->replied_to = 1;
        msg->sw_ack_vector = 0;
-       if (msp)
-               msp->seen_by.bits = 0;
-       uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw);
 }
 
 /*
- * Do all the things a cpu should do for a TLB shootdown message.
- * Other cpu's may come here at the same time for this message.
+ * Process the receipt of a RETRY message
  */
-static void uv_bau_process_message(struct bau_payload_queue_entry *msg,
-                                  int msg_slot, int sw_ack_slot)
+static inline void uv_bau_process_retry_msg(struct msg_desc *mdp,
+                                           struct bau_control *bcp)
 {
-       unsigned long this_cpu_mask;
-       struct bau_msg_status *msp;
-       int cpu;
+       int i;
+       int cancel_count = 0;
+       int slot2;
+       unsigned long msg_res;
+       unsigned long mmr = 0;
+       struct bau_payload_queue_entry *msg;
+       struct bau_payload_queue_entry *msg2;
+       struct ptc_stats *stat;
 
-       msp = __get_cpu_var(bau_control).msg_statuses + msg_slot;
-       cpu = uv_blade_processor_id();
-       msg->number_of_cpus =
-               uv_blade_nr_online_cpus(uv_node_to_blade_id(numa_node_id()));
-       this_cpu_mask = 1UL << cpu;
-       if (msp->seen_by.bits & this_cpu_mask)
-               return;
-       atomic_or_long(&msp->seen_by.bits, this_cpu_mask);
+       msg = mdp->msg;
+       stat = &per_cpu(ptcstats, bcp->cpu);
+       stat->d_retries++;
+       /*
+        * cancel any message from msg+1 to the retry itself
+        */
+       for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) {
+               if (msg2 > mdp->va_queue_last)
+                       msg2 = mdp->va_queue_first;
+               if (msg2 == msg)
+                       break;
+
+               /* same conditions for cancellation as uv_do_reset */
+               if ((msg2->replied_to == 0) && (msg2->canceled == 0) &&
+                   (msg2->sw_ack_vector) && ((msg2->sw_ack_vector &
+                       msg->sw_ack_vector) == 0) &&
+                   (msg2->sending_cpu == msg->sending_cpu) &&
+                   (msg2->msg_type != MSG_NOOP)) {
+                       slot2 = msg2 - mdp->va_queue_first;
+                       mmr = uv_read_local_mmr
+                               (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
+                       msg_res = ((msg2->sw_ack_vector << 8) |
+                                  msg2->sw_ack_vector);
+                       /*
+                        * This is a message retry; clear the resources held
+                        * by the previous message only if they timed out.
+                        * If it has not timed out we have an unexpected
+                        * situation to report.
+                        */
+                       if (mmr & (msg_res << 8)) {
+                               /*
+                                * is the resource timed out?
+                                * make everyone ignore the cancelled message.
+                                */
+                               msg2->canceled = 1;
+                               stat->d_canceled++;
+                               cancel_count++;
+                               uv_write_local_mmr(
+                                   UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
+                                       (msg_res << 8) | msg_res);
+                       } else
+                               printk(KERN_INFO "note bau retry: no effect\n");
+               }
+       }
+       if (!cancel_count)
+               stat->d_nocanceled++;
+}
 
-       if (msg->replied_to == 1)
-               return;
+/*
+ * Do all the things a cpu should do for a TLB shootdown message.
+ * Other cpu's may come here at the same time for this message.
+ */
+static void uv_bau_process_message(struct msg_desc *mdp,
+                                  struct bau_control *bcp)
+{
+       int msg_ack_count;
+       short socket_ack_count = 0;
+       struct ptc_stats *stat;
+       struct bau_payload_queue_entry *msg;
+       struct bau_control *smaster = bcp->socket_master;
 
+       /*
+        * This must be a normal message, or retry of a normal message
+        */
+       msg = mdp->msg;
+       stat = &per_cpu(ptcstats, bcp->cpu);
        if (msg->address == TLB_FLUSH_ALL) {
                local_flush_tlb();
-               __get_cpu_var(ptcstats).alltlb++;
+               stat->d_alltlb++;
        } else {
                __flush_tlb_one(msg->address);
-               __get_cpu_var(ptcstats).onetlb++;
+               stat->d_onetlb++;
        }
+       stat->d_requestee++;
+
+       /*
+        * One cpu on each uvhub has the additional job on a RETRY
+        * of releasing the resource held by the message that is
+        * being retried.  That message is identified by sending
+        * cpu number.
+        */
+       if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master)
+               uv_bau_process_retry_msg(mdp, bcp);
 
-       __get_cpu_var(ptcstats).requestee++;
+       /*
+        * This is a sw_ack message, so we have to reply to it.
+        * Count each responding cpu on the socket. This avoids
+        * pinging the count's cache line back and forth between
+        * the sockets.
+        */
+       socket_ack_count = atomic_add_short_return(1, (struct atomic_short *)
+                       &smaster->socket_acknowledge_count[mdp->msg_slot]);
+       if (socket_ack_count == bcp->cpus_in_socket) {
+               /*
+                * Both sockets dump their completed count total into
+                * the message's count.
+                */
+               smaster->socket_acknowledge_count[mdp->msg_slot] = 0;
+               msg_ack_count = atomic_add_short_return(socket_ack_count,
+                               (struct atomic_short *)&msg->acknowledge_count);
+
+               if (msg_ack_count == bcp->cpus_in_uvhub) {
+                       /*
+                        * All cpus in uvhub saw it; reply
+                        */
+                       uv_reply_to_message(mdp, bcp);
+               }
+       }
 
-       atomic_inc_short(&msg->acknowledge_count);
-       if (msg->number_of_cpus == msg->acknowledge_count)
-               uv_reply_to_message(sw_ack_slot, msg, msp);
+       return;
 }
 
 /*
- * Examine the payload queue on one distribution node to see
- * which messages have not been seen, and which cpu(s) have not seen them.
+ * Determine the first cpu on a uvhub.
+ */
+static int uvhub_to_first_cpu(int uvhub)
+{
+       int cpu;
+       for_each_present_cpu(cpu)
+               if (uvhub == uv_cpu_to_blade_id(cpu))
+                       return cpu;
+       return -1;
+}
+
+/*
+ * Last resort when we get a large number of destination timeouts is
+ * to clear resources held by a given cpu.
+ * Do this with IPI so that all messages in the BAU message queue
+ * can be identified by their nonzero sw_ack_vector field.
  *
- * Returns the number of cpu's that have not responded.
+ * This is entered for a single cpu on the uvhub.
+ * The sender want's this uvhub to free a specific message's
+ * sw_ack resources.
  */
-static int uv_examine_destination(struct bau_control *bau_tablesp, int sender)
+static void
+uv_do_reset(void *ptr)
 {
-       struct bau_payload_queue_entry *msg;
-       struct bau_msg_status *msp;
-       int count = 0;
        int i;
-       int j;
+       int slot;
+       int count = 0;
+       unsigned long mmr;
+       unsigned long msg_res;
+       struct bau_control *bcp;
+       struct reset_args *rap;
+       struct bau_payload_queue_entry *msg;
+       struct ptc_stats *stat;
 
-       for (msg = bau_tablesp->va_queue_first, i = 0; i < DEST_Q_SIZE;
-            msg++, i++) {
-               if ((msg->sending_cpu == sender) && (!msg->replied_to)) {
-                       msp = bau_tablesp->msg_statuses + i;
-                       printk(KERN_DEBUG
-                              "blade %d: address:%#lx %d of %d, not cpu(s): ",
-                              i, msg->address, msg->acknowledge_count,
-                              msg->number_of_cpus);
-                       for (j = 0; j < msg->number_of_cpus; j++) {
-                               if (!((1L << j) & msp->seen_by.bits)) {
-                                       count++;
-                                       printk("%d ", j);
-                               }
+       bcp = &per_cpu(bau_control, smp_processor_id());
+       rap = (struct reset_args *)ptr;
+       stat = &per_cpu(ptcstats, bcp->cpu);
+       stat->d_resets++;
+
+       /*
+        * We're looking for the given sender, and
+        * will free its sw_ack resource.
+        * If all cpu's finally responded after the timeout, its
+        * message 'replied_to' was set.
+        */
+       for (msg = bcp->va_queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) {
+               /* uv_do_reset: same conditions for cancellation as
+                  uv_bau_process_retry_msg() */
+               if ((msg->replied_to == 0) &&
+                   (msg->canceled == 0) &&
+                   (msg->sending_cpu == rap->sender) &&
+                   (msg->sw_ack_vector) &&
+                   (msg->msg_type != MSG_NOOP)) {
+                       /*
+                        * make everyone else ignore this message
+                        */
+                       msg->canceled = 1;
+                       slot = msg - bcp->va_queue_first;
+                       count++;
+                       /*
+                        * only reset the resource if it is still pending
+                        */
+                       mmr = uv_read_local_mmr
+                                       (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
+                       msg_res = ((msg->sw_ack_vector << 8) |
+                                                  msg->sw_ack_vector);
+                       if (mmr & msg_res) {
+                               stat->d_rcanceled++;
+                               uv_write_local_mmr(
+                                   UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
+                                                       msg_res);
                        }
-                       printk("\n");
                }
        }
-       return count;
+       return;
 }
 
 /*
- * Examine the payload queue on all the distribution nodes to see
- * which messages have not been seen, and which cpu(s) have not seen them.
- *
- * Returns the number of cpu's that have not responded.
+ * Use IPI to get all target uvhubs to release resources held by
+ * a given sending cpu number.
  */
-static int uv_examine_destinations(struct bau_target_nodemask *distribution)
+static void uv_reset_with_ipi(struct bau_target_uvhubmask *distribution,
+                             int sender)
 {
-       int sender;
-       int i;
-       int count = 0;
+       int uvhub;
+       int cpu;
+       cpumask_t mask;
+       struct reset_args reset_args;
+
+       reset_args.sender = sender;
 
-       sender = smp_processor_id();
-       for (i = 0; i < sizeof(struct bau_target_nodemask) * BITSPERBYTE; i++) {
-               if (!bau_node_isset(i, distribution))
+       cpus_clear(mask);
+       /* find a single cpu for each uvhub in this distribution mask */
+       for (uvhub = 0;
+                   uvhub < sizeof(struct bau_target_uvhubmask) * BITSPERBYTE;
+                   uvhub++) {
+               if (!bau_uvhub_isset(uvhub, distribution))
                        continue;
-               count += uv_examine_destination(uv_bau_table_bases[i], sender);
+               /* find a cpu for this uvhub */
+               cpu = uvhub_to_first_cpu(uvhub);
+               cpu_set(cpu, mask);
        }
-       return count;
+       /* IPI all cpus; Preemption is already disabled */
+       smp_call_function_many(&mask, uv_do_reset, (void *)&reset_args, 1);
+       return;
+}
+
+static inline unsigned long
+cycles_2_us(unsigned long long cyc)
+{
+       unsigned long long ns;
+       unsigned long us;
+       ns =  (cyc * per_cpu(cyc2ns, smp_processor_id()))
+                                               >> CYC2NS_SCALE_FACTOR;
+       us = ns / 1000;
+       return us;
 }
 
 /*
- * wait for completion of a broadcast message
- *
- * return COMPLETE, RETRY or GIVEUP
+ * wait for all cpus on this hub to finish their sends and go quiet
+ * leaves uvhub_quiesce set so that no new broadcasts are started by
+ * bau_flush_send_and_wait()
+ */
+static inline void
+quiesce_local_uvhub(struct bau_control *hmaster)
+{
+       atomic_add_short_return(1, (struct atomic_short *)
+                &hmaster->uvhub_quiesce);
+}
+
+/*
+ * mark this quiet-requestor as done
+ */
+static inline void
+end_uvhub_quiesce(struct bau_control *hmaster)
+{
+       atomic_add_short_return(-1, (struct atomic_short *)
+               &hmaster->uvhub_quiesce);
+}
+
+/*
+ * Wait for completion of a broadcast software ack message
+ * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP
  */
 static int uv_wait_completion(struct bau_desc *bau_desc,
-                             unsigned long mmr_offset, int right_shift)
+       unsigned long mmr_offset, int right_shift, int this_cpu,
+       struct bau_control *bcp, struct bau_control *smaster, long try)
 {
-       int exams = 0;
-       long destination_timeouts = 0;
-       long source_timeouts = 0;
+       int relaxes = 0;
        unsigned long descriptor_status;
+       unsigned long mmr;
+       unsigned long mask;
+       cycles_t ttime;
+       cycles_t timeout_time;
+       struct ptc_stats *stat = &per_cpu(ptcstats, this_cpu);
+       struct bau_control *hmaster;
+
+       hmaster = bcp->uvhub_master;
+       timeout_time = get_cycles() + bcp->timeout_interval;
 
+       /* spin on the status MMR, waiting for it to go idle */
        while ((descriptor_status = (((unsigned long)
                uv_read_local_mmr(mmr_offset) >>
                        right_shift) & UV_ACT_STATUS_MASK)) !=
                        DESC_STATUS_IDLE) {
-               if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) {
-                       source_timeouts++;
-                       if (source_timeouts > SOURCE_TIMEOUT_LIMIT)
-                               source_timeouts = 0;
-                       __get_cpu_var(ptcstats).s_retry++;
-                       return FLUSH_RETRY;
-               }
                /*
-                * spin here looking for progress at the destinations
+                * Our software ack messages may be blocked because there are
+                * no swack resources available.  As long as none of them
+                * has timed out hardware will NACK our message and its
+                * state will stay IDLE.
                 */
-               if (descriptor_status == DESC_STATUS_DESTINATION_TIMEOUT) {
-                       destination_timeouts++;
-                       if (destination_timeouts > DESTINATION_TIMEOUT_LIMIT) {
-                               /*
-                                * returns number of cpus not responding
-                                */
-                               if (uv_examine_destinations
-                                   (&bau_desc->distribution) == 0) {
-                                       __get_cpu_var(ptcstats).d_retry++;
-                                       return FLUSH_RETRY;
-                               }
-                               exams++;
-                               if (exams >= uv_bau_retry_limit) {
-                                       printk(KERN_DEBUG
-                                              "uv_flush_tlb_others");
-                                       printk("giving up on cpu %d\n",
-                                              smp_processor_id());
+               if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) {
+                       stat->s_stimeout++;
+                       return FLUSH_GIVEUP;
+               } else if (descriptor_status ==
+                                       DESC_STATUS_DESTINATION_TIMEOUT) {
+                       stat->s_dtimeout++;
+                       ttime = get_cycles();
+
+                       /*
+                        * Our retries may be blocked by all destination
+                        * swack resources being consumed, and a timeout
+                        * pending.  In that case hardware returns the
+                        * ERROR that looks like a destination timeout.
+                        */
+                       if (cycles_2_us(ttime - bcp->send_message) < BIOS_TO) {
+                               bcp->conseccompletes = 0;
+                               return FLUSH_RETRY_PLUGGED;
+                       }
+
+                       bcp->conseccompletes = 0;
+                       return FLUSH_RETRY_TIMEOUT;
+               } else {
+                       /*
+                        * descriptor_status is still BUSY
+                        */
+                       cpu_relax();
+                       relaxes++;
+                       if (relaxes >= 10000) {
+                               relaxes = 0;
+                               if (get_cycles() > timeout_time) {
+                                       quiesce_local_uvhub(hmaster);
+
+                                       /* single-thread the register change */
+                                       spin_lock(&hmaster->masks_lock);
+                                       mmr = uv_read_local_mmr(mmr_offset);
+                                       mask = 0UL;
+                                       mask |= (3UL < right_shift);
+                                       mask = ~mask;
+                                       mmr &= mask;
+                                       uv_write_local_mmr(mmr_offset, mmr);
+                                       spin_unlock(&hmaster->masks_lock);
+                                       end_uvhub_quiesce(hmaster);
+                                       stat->s_busy++;
                                        return FLUSH_GIVEUP;
                                }
-                               /*
-                                * delays can hang the simulator
-                                  udelay(1000);
-                                */
-                               destination_timeouts = 0;
                        }
                }
-               cpu_relax();
        }
+       bcp->conseccompletes++;
        return FLUSH_COMPLETE;
 }
 
+static inline cycles_t
+sec_2_cycles(unsigned long sec)
+{
+       unsigned long ns;
+       cycles_t cyc;
+
+       ns = sec * 1000000000;
+       cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id()));
+       return cyc;
+}
+
+/*
+ * conditionally add 1 to *v, unless *v is >= u
+ * return 0 if we cannot add 1 to *v because it is >= u
+ * return 1 if we can add 1 to *v because it is < u
+ * the add is atomic
+ *
+ * This is close to atomic_add_unless(), but this allows the 'u' value
+ * to be lowered below the current 'v'.  atomic_add_unless can only stop
+ * on equal.
+ */
+static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u)
+{
+       spin_lock(lock);
+       if (atomic_read(v) >= u) {
+               spin_unlock(lock);
+               return 0;
+       }
+       atomic_inc(v);
+       spin_unlock(lock);
+       return 1;
+}
+
 /**
  * uv_flush_send_and_wait
  *
- * Send a broadcast and wait for a broadcast message to complete.
+ * Send a broadcast and wait for it to complete.
  *
- * The flush_mask contains the cpus the broadcast was sent to.
+ * The flush_mask contains the cpus the broadcast is to be sent to, plus
+ * cpus that are on the local uvhub.
  *
- * Returns NULL if all remote flushing was done. The mask is zeroed.
+ * Returns NULL if all flushing represented in the mask was done. The mask
+ * is zeroed.
  * Returns @flush_mask if some remote flushing remains to be done. The
- * mask will have some bits still set.
+ * mask will have some bits still set, representing any cpus on the local
+ * uvhub (not current cpu) and any on remote uvhubs if the broadcast failed.
  */
-const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode,
-                                            struct bau_desc *bau_desc,
-                                            struct cpumask *flush_mask)
+const struct cpumask *uv_flush_send_and_wait(struct bau_desc *bau_desc,
+                                            struct cpumask *flush_mask,
+                                            struct bau_control *bcp)
 {
-       int completion_status = 0;
        int right_shift;
-       int tries = 0;
-       int pnode;
+       int uvhub;
        int bit;
+       int completion_status = 0;
+       int seq_number = 0;
+       long try = 0;
+       int cpu = bcp->uvhub_cpu;
+       int this_cpu = bcp->cpu;
+       int this_uvhub = bcp->uvhub;
        unsigned long mmr_offset;
        unsigned long index;
        cycles_t time1;
        cycles_t time2;
+       struct ptc_stats *stat = &per_cpu(ptcstats, bcp->cpu);
+       struct bau_control *smaster = bcp->socket_master;
+       struct bau_control *hmaster = bcp->uvhub_master;
+
+       /*
+        * Spin here while there are hmaster->max_concurrent or more active
+        * descriptors. This is the per-uvhub 'throttle'.
+        */
+       if (!atomic_inc_unless_ge(&hmaster->uvhub_lock,
+                       &hmaster->active_descriptor_count,
+                       hmaster->max_concurrent)) {
+               stat->s_throttles++;
+               do {
+                       cpu_relax();
+               } while (!atomic_inc_unless_ge(&hmaster->uvhub_lock,
+                       &hmaster->active_descriptor_count,
+                       hmaster->max_concurrent));
+       }
+
+       while (hmaster->uvhub_quiesce)
+               cpu_relax();
 
        if (cpu < UV_CPUS_PER_ACT_STATUS) {
                mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
@@ -268,24 +557,108 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode,
        }
        time1 = get_cycles();
        do {
-               tries++;
+               /*
+                * Every message from any given cpu gets a unique message
+                * sequence number. But retries use that same number.
+                * Our message may have timed out at the destination because
+                * all sw-ack resources are in use and there is a timeout
+                * pending there.  In that case, our last send never got
+                * placed into the queue and we need to persist until it
+                * does.
+                *
+                * Make any retry a type MSG_RETRY so that the destination will
+                * free any resource held by a previous message from this cpu.
+                */
+               if (try == 0) {
+                       /* use message type set by the caller the first time */
+                       seq_number = bcp->message_number++;
+               } else {
+                       /* use RETRY type on all the rest; same sequence */
+                       bau_desc->header.msg_type = MSG_RETRY;
+                       stat->s_retry_messages++;
+               }
+               bau_desc->header.sequence = seq_number;
                index = (1UL << UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT) |
-                       cpu;
+                       bcp->uvhub_cpu;
+               bcp->send_message = get_cycles();
+
                uv_write_local_mmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index);
+
+               try++;
                completion_status = uv_wait_completion(bau_desc, mmr_offset,
-                                       right_shift);
-       } while (completion_status == FLUSH_RETRY);
+                       right_shift, this_cpu, bcp, smaster, try);
+
+               if (completion_status == FLUSH_RETRY_PLUGGED) {
+                       /*
+                        * Our retries may be blocked by all destination swack
+                        * resources being consumed, and a timeout pending. In
+                        * that case hardware immediately returns the ERROR
+                        * that looks like a destination timeout.
+                        */
+                       udelay(TIMEOUT_DELAY);
+                       bcp->plugged_tries++;
+                       if (bcp->plugged_tries >= PLUGSB4RESET) {
+                               bcp->plugged_tries = 0;
+                               quiesce_local_uvhub(hmaster);
+                               spin_lock(&hmaster->queue_lock);
+                               uv_reset_with_ipi(&bau_desc->distribution,
+                                                       this_cpu);
+                               spin_unlock(&hmaster->queue_lock);
+                               end_uvhub_quiesce(hmaster);
+                               bcp->ipi_attempts++;
+                               stat->s_resets_plug++;
+                       }
+               } else if (completion_status == FLUSH_RETRY_TIMEOUT) {
+                       hmaster->max_concurrent = 1;
+                       bcp->timeout_tries++;
+                       udelay(TIMEOUT_DELAY);
+                       if (bcp->timeout_tries >= TIMEOUTSB4RESET) {
+                               bcp->timeout_tries = 0;
+                               quiesce_local_uvhub(hmaster);
+                               spin_lock(&hmaster->queue_lock);
+                               uv_reset_with_ipi(&bau_desc->distribution,
+                                                               this_cpu);
+                               spin_unlock(&hmaster->queue_lock);
+                               end_uvhub_quiesce(hmaster);
+                               bcp->ipi_attempts++;
+                               stat->s_resets_timeout++;
+                       }
+               }
+               if (bcp->ipi_attempts >= 3) {
+                       bcp->ipi_attempts = 0;
+                       completion_status = FLUSH_GIVEUP;
+                       break;
+               }
+               cpu_relax();
+       } while ((completion_status == FLUSH_RETRY_PLUGGED) ||
+                (completion_status == FLUSH_RETRY_TIMEOUT));
        time2 = get_cycles();
-       __get_cpu_var(ptcstats).sflush += (time2 - time1);
-       if (tries > 1)
-               __get_cpu_var(ptcstats).retriesok++;
 
-       if (completion_status == FLUSH_GIVEUP) {
+       if ((completion_status == FLUSH_COMPLETE) && (bcp->conseccompletes > 5)
+           && (hmaster->max_concurrent < hmaster->max_concurrent_constant))
+                       hmaster->max_concurrent++;
+
+       /*
+        * hold any cpu not timing out here; no other cpu currently held by
+        * the 'throttle' should enter the activation code
+        */
+       while (hmaster->uvhub_quiesce)
+               cpu_relax();
+       atomic_dec(&hmaster->active_descriptor_count);
+
+       /* guard against cycles wrap */
+       if (time2 > time1)
+               stat->s_time += (time2 - time1);
+       else
+               stat->s_requestor--; /* don't count this one */
+       if (completion_status == FLUSH_COMPLETE && try > 1)
+               stat->s_retriesok++;
+       else if (completion_status == FLUSH_GIVEUP) {
                /*
                 * Cause the caller to do an IPI-style TLB shootdown on
-                * the cpu's, all of which are still in the mask.
+                * the target cpu's, all of which are still in the mask.
                 */
-               __get_cpu_var(ptcstats).ptc_i++;
+               stat->s_giveup++;
                return flush_mask;
        }
 
@@ -294,18 +667,17 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_pnode,
         * use the IPI method of shootdown on them.
         */
        for_each_cpu(bit, flush_mask) {
-               pnode = uv_cpu_to_pnode(bit);
-               if (pnode == this_pnode)
+               uvhub = uv_cpu_to_blade_id(bit);
+               if (uvhub == this_uvhub)
                        continue;
                cpumask_clear_cpu(bit, flush_mask);
        }
        if (!cpumask_empty(flush_mask))
                return flush_mask;
+
        return NULL;
 }
 
-static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
-
 /**
  * uv_flush_tlb_others - globally purge translation cache of a virtual
  * address or all TLB's
@@ -322,8 +694,8 @@ static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
  * The caller has derived the cpumask from the mm_struct.  This function
  * is called only if there are bits set in the mask. (e.g. flush_tlb_page())
  *
- * The cpumask is converted into a nodemask of the nodes containing
- * the cpus.
+ * The cpumask is converted into a uvhubmask of the uvhubs containing
+ * those cpus.
  *
  * Note that this function should be called with preemption disabled.
  *
@@ -335,52 +707,82 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
                                          struct mm_struct *mm,
                                          unsigned long va, unsigned int cpu)
 {
-       struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask);
-       int i;
-       int bit;
-       int pnode;
-       int uv_cpu;
-       int this_pnode;
+       int remotes;
+       int tcpu;
+       int uvhub;
        int locals = 0;
        struct bau_desc *bau_desc;
+       struct cpumask *flush_mask;
+       struct ptc_stats *stat;
+       struct bau_control *bcp;
 
-       cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu));
+       if (nobau)
+               return cpumask;
 
-       uv_cpu = uv_blade_processor_id();
-       this_pnode = uv_hub_info->pnode;
-       bau_desc = __get_cpu_var(bau_control).descriptor_base;
-       bau_desc += UV_ITEMS_PER_DESCRIPTOR * uv_cpu;
+       bcp = &per_cpu(bau_control, cpu);
+       /*
+        * Each sending cpu has a per-cpu mask which it fills from the caller's
+        * cpu mask.  Only remote cpus are converted to uvhubs and copied.
+        */
+       flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu);
+       /*
+        * copy cpumask to flush_mask, removing current cpu
+        * (current cpu should already have been flushed by the caller and
+        *  should never be returned if we return flush_mask)
+        */
+       cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu));
+       if (cpu_isset(cpu, *cpumask))
+               locals++;  /* current cpu was targeted */
 
-       bau_nodes_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
+       bau_desc = bcp->descriptor_base;
+       bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu;
 
-       i = 0;
-       for_each_cpu(bit, flush_mask) {
-               pnode = uv_cpu_to_pnode(bit);
-               BUG_ON(pnode > (UV_DISTRIBUTION_SIZE - 1));
-               if (pnode == this_pnode) {
+       bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
+       remotes = 0;
+       for_each_cpu(tcpu, flush_mask) {
+               uvhub = uv_cpu_to_blade_id(tcpu);
+               if (uvhub == bcp->uvhub) {
                        locals++;
                        continue;
                }
-               bau_node_set(pnode - uv_partition_base_pnode,
-                               &bau_desc->distribution);
-               i++;
+               bau_uvhub_set(uvhub, &bau_desc->distribution);
+               remotes++;
        }
-       if (i == 0) {
+       if (remotes == 0) {
                /*
-                * no off_node flushing; return status for local node
+                * No off_hub flushing; return status for local hub.
+                * Return the caller's mask if all were local (the current
+                * cpu may be in that mask).
                 */
                if (locals)
-                       return flush_mask;
+                       return cpumask;
                else
                        return NULL;
        }
-       __get_cpu_var(ptcstats).requestor++;
-       __get_cpu_var(ptcstats).ntargeted += i;
+       stat = &per_cpu(ptcstats, cpu);
+       stat->s_requestor++;
+       stat->s_ntargcpu += remotes;
+       remotes = bau_uvhub_weight(&bau_desc->distribution);
+       stat->s_ntarguvhub += remotes;
+       if (remotes >= 16)
+               stat->s_ntarguvhub16++;
+       else if (remotes >= 8)
+               stat->s_ntarguvhub8++;
+       else if (remotes >= 4)
+               stat->s_ntarguvhub4++;
+       else if (remotes >= 2)
+               stat->s_ntarguvhub2++;
+       else
+               stat->s_ntarguvhub1++;
 
        bau_desc->payload.address = va;
        bau_desc->payload.sending_cpu = cpu;
 
-       return uv_flush_send_and_wait(uv_cpu, this_pnode, bau_desc, flush_mask);
+       /*
+        * uv_flush_send_and_wait returns null if all cpu's were messaged, or
+        * the adjusted flush_mask if any cpu's were not messaged.
+        */
+       return uv_flush_send_and_wait(bau_desc, flush_mask, bcp);
 }
 
 /*
@@ -389,87 +791,70 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
  *
  * We received a broadcast assist message.
  *
- * Interrupts may have been disabled; this interrupt could represent
+ * Interrupts are disabled; this interrupt could represent
  * the receipt of several messages.
  *
- * All cores/threads on this node get this interrupt.
- * The last one to see it does the s/w ack.
+ * All cores/threads on this hub get this interrupt.
+ * The last one to see it does the software ack.
  * (the resource will not be freed until noninterruptable cpus see this
- *  interrupt; hardware will timeout the s/w ack and reply ERROR)
+ *  interrupt; hardware may timeout the s/w ack and reply ERROR)
  */
 void uv_bau_message_interrupt(struct pt_regs *regs)
 {
-       struct bau_payload_queue_entry *va_queue_first;
-       struct bau_payload_queue_entry *va_queue_last;
-       struct bau_payload_queue_entry *msg;
-       struct pt_regs *old_regs = set_irq_regs(regs);
-       cycles_t time1;
-       cycles_t time2;
-       int msg_slot;
-       int sw_ack_slot;
-       int fw;
        int count = 0;
-       unsigned long local_pnode;
-
-       ack_APIC_irq();
-       exit_idle();
-       irq_enter();
-
-       time1 = get_cycles();
-
-       local_pnode = uv_blade_to_pnode(uv_numa_blade_id());
-
-       va_queue_first = __get_cpu_var(bau_control).va_queue_first;
-       va_queue_last = __get_cpu_var(bau_control).va_queue_last;
-
-       msg = __get_cpu_var(bau_control).bau_msg_head;
+       cycles_t time_start;
+       struct bau_payload_queue_entry *msg;
+       struct bau_control *bcp;
+       struct ptc_stats *stat;
+       struct msg_desc msgdesc;
+
+       time_start = get_cycles();
+       bcp = &per_cpu(bau_control, smp_processor_id());
+       stat = &per_cpu(ptcstats, smp_processor_id());
+       msgdesc.va_queue_first = bcp->va_queue_first;
+       msgdesc.va_queue_last = bcp->va_queue_last;
+       msg = bcp->bau_msg_head;
        while (msg->sw_ack_vector) {
                count++;
-               fw = msg->sw_ack_vector;
-               msg_slot = msg - va_queue_first;
-               sw_ack_slot = ffs(fw) - 1;
-
-               uv_bau_process_message(msg, msg_slot, sw_ack_slot);
-
+               msgdesc.msg_slot = msg - msgdesc.va_queue_first;
+               msgdesc.sw_ack_slot = ffs(msg->sw_ack_vector) - 1;
+               msgdesc.msg = msg;
+               uv_bau_process_message(&msgdesc, bcp);
                msg++;
-               if (msg > va_queue_last)
-                       msg = va_queue_first;
-               __get_cpu_var(bau_control).bau_msg_head = msg;
+               if (msg > msgdesc.va_queue_last)
+                       msg = msgdesc.va_queue_first;
+               bcp->bau_msg_head = msg;
        }
+       stat->d_time += (get_cycles() - time_start);
        if (!count)
-               __get_cpu_var(ptcstats).nomsg++;
+               stat->d_nomsg++;
        else if (count > 1)
-               __get_cpu_var(ptcstats).multmsg++;
-
-       time2 = get_cycles();
-       __get_cpu_var(ptcstats).dflush += (time2 - time1);
-
-       irq_exit();
-       set_irq_regs(old_regs);
+               stat->d_multmsg++;
+       ack_APIC_irq();
 }
 
 /*
  * uv_enable_timeouts
  *
- * Each target blade (i.e. blades that have cpu's) needs to have
+ * Each target uvhub (i.e. a uvhub that has no cpu's) needs to have
  * shootdown message timeouts enabled.  The timeout does not cause
  * an interrupt, but causes an error message to be returned to
  * the sender.
  */
 static void uv_enable_timeouts(void)
 {
-       int blade;
-       int nblades;
+       int uvhub;
+       int nuvhubs;
        int pnode;
        unsigned long mmr_image;
 
-       nblades = uv_num_possible_blades();
+       nuvhubs = uv_num_possible_blades();
 
-       for (blade = 0; blade < nblades; blade++) {
-               if (!uv_blade_nr_possible_cpus(blade))
+       for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
+               if (!uv_blade_nr_possible_cpus(uvhub))
                        continue;
 
-               pnode = uv_blade_to_pnode(blade);
+               pnode = uv_blade_to_pnode(uvhub);
                mmr_image =
                    uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL);
                /*
@@ -479,16 +864,16 @@ static void uv_enable_timeouts(void)
                 * To program the period, the SOFT_ACK_MODE must be off.
                 */
                mmr_image &= ~((unsigned long)1 <<
-                              UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT);
+                   UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT);
                uv_write_global_mmr64
                    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
                /*
                 * Set the 4-bit period.
                 */
                mmr_image &= ~((unsigned long)0xf <<
-                       UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT);
+                    UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT);
                mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD <<
-                            UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT);
+                    UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT);
                uv_write_global_mmr64
                    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
                /*
@@ -497,7 +882,7 @@ static void uv_enable_timeouts(void)
                 * indicated in bits 2:0 (7 causes all of them to timeout).
                 */
                mmr_image |= ((unsigned long)1 <<
-                             UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT);
+                   UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT);
                uv_write_global_mmr64
                    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
        }
@@ -522,9 +907,20 @@ static void uv_ptc_seq_stop(struct seq_file *file, void *data)
 {
 }
 
+static inline unsigned long long
+millisec_2_cycles(unsigned long millisec)
+{
+       unsigned long ns;
+       unsigned long long cyc;
+
+       ns = millisec * 1000;
+       cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id()));
+       return cyc;
+}
+
 /*
- * Display the statistics thru /proc
- * data points to the cpu number
+ * Display the statistics thru /proc.
+ * 'data' points to the cpu number
  */
 static int uv_ptc_seq_show(struct seq_file *file, void *data)
 {
@@ -535,78 +931,155 @@ static int uv_ptc_seq_show(struct seq_file *file, void *data)
 
        if (!cpu) {
                seq_printf(file,
-               "# cpu requestor requestee one all sretry dretry ptc_i ");
+                       "# cpu sent stime numuvhubs numuvhubs16 numuvhubs8 ");
                seq_printf(file,
-               "sw_ack sflush dflush sok dnomsg dmult starget\n");
+                       "numuvhubs4 numuvhubs2 numuvhubs1 numcpus dto ");
+               seq_printf(file,
+                       "retries rok resetp resett giveup sto bz throt ");
+               seq_printf(file,
+                       "sw_ack recv rtime all ");
+               seq_printf(file,
+                       "one mult none retry canc nocan reset rcan\n");
        }
        if (cpu < num_possible_cpus() && cpu_online(cpu)) {
                stat = &per_cpu(ptcstats, cpu);
-               seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld ",
-                          cpu, stat->requestor,
-                          stat->requestee, stat->onetlb, stat->alltlb,
-                          stat->s_retry, stat->d_retry, stat->ptc_i);
-               seq_printf(file, "%lx %ld %ld %ld %ld %ld %ld\n",
+               /* source side statistics */
+               seq_printf(file,
+                       "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ",
+                          cpu, stat->s_requestor, cycles_2_us(stat->s_time),
+                          stat->s_ntarguvhub, stat->s_ntarguvhub16,
+                          stat->s_ntarguvhub8, stat->s_ntarguvhub4,
+                          stat->s_ntarguvhub2, stat->s_ntarguvhub1,
+                          stat->s_ntargcpu, stat->s_dtimeout);
+               seq_printf(file, "%ld %ld %ld %ld %ld %ld %ld %ld ",
+                          stat->s_retry_messages, stat->s_retriesok,
+                          stat->s_resets_plug, stat->s_resets_timeout,
+                          stat->s_giveup, stat->s_stimeout,
+                          stat->s_busy, stat->s_throttles);
+               /* destination side statistics */
+               seq_printf(file,
+                          "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n",
                           uv_read_global_mmr64(uv_cpu_to_pnode(cpu),
                                        UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE),
-                          stat->sflush, stat->dflush,
-                          stat->retriesok, stat->nomsg,
-                          stat->multmsg, stat->ntargeted);
+                          stat->d_requestee, cycles_2_us(stat->d_time),
+                          stat->d_alltlb, stat->d_onetlb, stat->d_multmsg,
+                          stat->d_nomsg, stat->d_retries, stat->d_canceled,
+                          stat->d_nocanceled, stat->d_resets,
+                          stat->d_rcanceled);
        }
 
        return 0;
 }
 
 /*
+ * -1: resetf the statistics
  *  0: display meaning of the statistics
- * >0: retry limit
+ * >0: maximum concurrent active descriptors per uvhub (throttle)
  */
 static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user,
                                 size_t count, loff_t *data)
 {
-       long newmode;
+       int cpu;
+       long input_arg;
        char optstr[64];
+       struct ptc_stats *stat;
+       struct bau_control *bcp;
 
        if (count == 0 || count > sizeof(optstr))
                return -EINVAL;
        if (copy_from_user(optstr, user, count))
                return -EFAULT;
        optstr[count - 1] = '\0';
-       if (strict_strtoul(optstr, 10, &newmode) < 0) {
+       if (strict_strtol(optstr, 10, &input_arg) < 0) {
                printk(KERN_DEBUG "%s is invalid\n", optstr);
                return -EINVAL;
        }
 
-       if (newmode == 0) {
+       if (input_arg == 0) {
                printk(KERN_DEBUG "# cpu:      cpu number\n");
+               printk(KERN_DEBUG "Sender statistics:\n");
+               printk(KERN_DEBUG
+               "sent:     number of shootdown messages sent\n");
+               printk(KERN_DEBUG
+               "stime:    time spent sending messages\n");
+               printk(KERN_DEBUG
+               "numuvhubs: number of hubs targeted with shootdown\n");
+               printk(KERN_DEBUG
+               "numuvhubs16: number times 16 or more hubs targeted\n");
+               printk(KERN_DEBUG
+               "numuvhubs8: number times 8 or more hubs targeted\n");
+               printk(KERN_DEBUG
+               "numuvhubs4: number times 4 or more hubs targeted\n");
+               printk(KERN_DEBUG
+               "numuvhubs2: number times 2 or more hubs targeted\n");
+               printk(KERN_DEBUG
+               "numuvhubs1: number times 1 hub targeted\n");
+               printk(KERN_DEBUG
+               "numcpus:  number of cpus targeted with shootdown\n");
+               printk(KERN_DEBUG
+               "dto:      number of destination timeouts\n");
+               printk(KERN_DEBUG
+               "retries:  destination timeout retries sent\n");
+               printk(KERN_DEBUG
+               "rok:   :  destination timeouts successfully retried\n");
+               printk(KERN_DEBUG
+               "resetp:   ipi-style resource resets for plugs\n");
+               printk(KERN_DEBUG
+               "resett:   ipi-style resource resets for timeouts\n");
+               printk(KERN_DEBUG
+               "giveup:   fall-backs to ipi-style shootdowns\n");
+               printk(KERN_DEBUG
+               "sto:      number of source timeouts\n");
+               printk(KERN_DEBUG
+               "bz:       number of stay-busy's\n");
+               printk(KERN_DEBUG
+               "throt:    number times spun in throttle\n");
+               printk(KERN_DEBUG "Destination side statistics:\n");
                printk(KERN_DEBUG
-               "requestor:  times this cpu was the flush requestor\n");
+               "sw_ack:   image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n");
                printk(KERN_DEBUG
-               "requestee:  times this cpu was requested to flush its TLBs\n");
+               "recv:     shootdown messages received\n");
                printk(KERN_DEBUG
-               "one:        times requested to flush a single address\n");
+               "rtime:    time spent processing messages\n");
                printk(KERN_DEBUG
-               "all:        times requested to flush all TLB's\n");
+               "all:      shootdown all-tlb messages\n");
                printk(KERN_DEBUG
-               "sretry:     number of retries of source-side timeouts\n");
+               "one:      shootdown one-tlb messages\n");
                printk(KERN_DEBUG
-               "dretry:     number of retries of destination-side timeouts\n");
+               "mult:     interrupts that found multiple messages\n");
                printk(KERN_DEBUG
-               "ptc_i:      times UV fell through to IPI-style flushes\n");
+               "none:     interrupts that found no messages\n");
                printk(KERN_DEBUG
-               "sw_ack:     image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n");
+               "retry:    number of retry messages processed\n");
                printk(KERN_DEBUG
-               "sflush_us:  cycles spent in uv_flush_tlb_others()\n");
+               "canc:     number messages canceled by retries\n");
                printk(KERN_DEBUG
-               "dflush_us:  cycles spent in handling flush requests\n");
-               printk(KERN_DEBUG "sok:        successes on retry\n");
-               printk(KERN_DEBUG "dnomsg:     interrupts with no message\n");
+               "nocan:    number retries that found nothing to cancel\n");
                printk(KERN_DEBUG
-               "dmult:      interrupts with multiple messages\n");
-               printk(KERN_DEBUG "starget:    nodes targeted\n");
+               "reset:    number of ipi-style reset requests processed\n");
+               printk(KERN_DEBUG
+               "rcan:     number messages canceled by reset requests\n");
+       } else if (input_arg == -1) {
+               for_each_present_cpu(cpu) {
+                       stat = &per_cpu(ptcstats, cpu);
+                       memset(stat, 0, sizeof(struct ptc_stats));
+               }
        } else {
-               uv_bau_retry_limit = newmode;
-               printk(KERN_DEBUG "timeout retry limit:%d\n",
-                      uv_bau_retry_limit);
+               uv_bau_max_concurrent = input_arg;
+               bcp = &per_cpu(bau_control, smp_processor_id());
+               if (uv_bau_max_concurrent < 1 ||
+                   uv_bau_max_concurrent > bcp->cpus_in_uvhub) {
+                       printk(KERN_DEBUG
+                               "Error: BAU max concurrent %d; %d is invalid\n",
+                               bcp->max_concurrent, uv_bau_max_concurrent);
+                       return -EINVAL;
+               }
+               printk(KERN_DEBUG "Set BAU max concurrent:%d\n",
+                      uv_bau_max_concurrent);
+               for_each_present_cpu(cpu) {
+                       bcp = &per_cpu(bau_control, cpu);
+                       bcp->max_concurrent = uv_bau_max_concurrent;
+               }
        }
 
        return count;
@@ -649,80 +1122,31 @@ static int __init uv_ptc_init(void)
        return 0;
 }
 
-/*
- * begin the initialization of the per-blade control structures
- */
-static struct bau_control * __init uv_table_bases_init(int blade, int node)
-{
-       int i;
-       struct bau_msg_status *msp;
-       struct bau_control *bau_tabp;
-
-       bau_tabp =
-           kmalloc_node(sizeof(struct bau_control), GFP_KERNEL, node);
-       BUG_ON(!bau_tabp);
-
-       bau_tabp->msg_statuses =
-           kmalloc_node(sizeof(struct bau_msg_status) *
-                        DEST_Q_SIZE, GFP_KERNEL, node);
-       BUG_ON(!bau_tabp->msg_statuses);
-
-       for (i = 0, msp = bau_tabp->msg_statuses; i < DEST_Q_SIZE; i++, msp++)
-               bau_cpubits_clear(&msp->seen_by, (int)
-                                 uv_blade_nr_possible_cpus(blade));
-
-       uv_bau_table_bases[blade] = bau_tabp;
-
-       return bau_tabp;
-}
-
-/*
- * finish the initialization of the per-blade control structures
- */
-static void __init
-uv_table_bases_finish(int blade,
-                     struct bau_control *bau_tablesp,
-                     struct bau_desc *adp)
-{
-       struct bau_control *bcp;
-       int cpu;
-
-       for_each_present_cpu(cpu) {
-               if (blade != uv_cpu_to_blade_id(cpu))
-                       continue;
-
-               bcp = (struct bau_control *)&per_cpu(bau_control, cpu);
-               bcp->bau_msg_head       = bau_tablesp->va_queue_first;
-               bcp->va_queue_first     = bau_tablesp->va_queue_first;
-               bcp->va_queue_last      = bau_tablesp->va_queue_last;
-               bcp->msg_statuses       = bau_tablesp->msg_statuses;
-               bcp->descriptor_base    = adp;
-       }
-}
-
 /*
  * initialize the sending side's sending buffers
  */
-static struct bau_desc * __init
+static void
 uv_activation_descriptor_init(int node, int pnode)
 {
        int i;
+       int cpu;
        unsigned long pa;
        unsigned long m;
        unsigned long n;
-       struct bau_desc *adp;
-       struct bau_desc *ad2;
+       struct bau_desc *bau_desc;
+       struct bau_desc *bd2;
+       struct bau_control *bcp;
 
        /*
         * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
-        * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per blade
+        * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub
         */
-       adp = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
+       bau_desc = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
                UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
-       BUG_ON(!adp);
+       BUG_ON(!bau_desc);
 
-       pa = uv_gpa(adp); /* need the real nasid*/
-       n = uv_gpa_to_pnode(pa);
+       pa = uv_gpa(bau_desc); /* need the real nasid*/
+       n = pa >> uv_nshift;
        m = pa & uv_mmask;
 
        uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
@@ -731,96 +1155,188 @@ uv_activation_descriptor_init(int node, int pnode)
        /*
         * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each
         * cpu even though we only use the first one; one descriptor can
-        * describe a broadcast to 256 nodes.
+        * describe a broadcast to 256 uv hubs.
         */
-       for (i = 0, ad2 = adp; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
-               i++, ad2++) {
-               memset(ad2, 0, sizeof(struct bau_desc));
-               ad2->header.sw_ack_flag = 1;
+       for (i = 0, bd2 = bau_desc; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
+               i++, bd2++) {
+               memset(bd2, 0, sizeof(struct bau_desc));
+               bd2->header.sw_ack_flag = 1;
                /*
-                * base_dest_nodeid is the first node in the partition, so
-                * the bit map will indicate partition-relative node numbers.
-                * note that base_dest_nodeid is actually a nasid.
+                * base_dest_nodeid is the nasid (pnode<<1) of the first uvhub
+                * in the partition. The bit map will indicate uvhub numbers,
+                * which are 0-N in a partition. Pnodes are unique system-wide.
                 */
-               ad2->header.base_dest_nodeid = uv_partition_base_pnode << 1;
-               ad2->header.dest_subnodeid = 0x10; /* the LB */
-               ad2->header.command = UV_NET_ENDPOINT_INTD;
-               ad2->header.int_both = 1;
+               bd2->header.base_dest_nodeid = uv_partition_base_pnode << 1;
+               bd2->header.dest_subnodeid = 0x10; /* the LB */
+               bd2->header.command = UV_NET_ENDPOINT_INTD;
+               bd2->header.int_both = 1;
                /*
                 * all others need to be set to zero:
                 *   fairness chaining multilevel count replied_to
                 */
        }
-       return adp;
+       for_each_present_cpu(cpu) {
+               if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu)))
+                       continue;
+               bcp = &per_cpu(bau_control, cpu);
+               bcp->descriptor_base = bau_desc;
+       }
 }
 
 /*
  * initialize the destination side's receiving buffers
+ * entered for each uvhub in the partition
+ * - node is first node (kernel memory notion) on the uvhub
+ * - pnode is the uvhub's physical identifier
  */
-static struct bau_payload_queue_entry * __init
-uv_payload_queue_init(int node, int pnode, struct bau_control *bau_tablesp)
+static void
+uv_payload_queue_init(int node, int pnode)
 {
-       struct bau_payload_queue_entry *pqp;
-       unsigned long pa;
        int pn;
+       int cpu;
        char *cp;
+       unsigned long pa;
+       struct bau_payload_queue_entry *pqp;
+       struct bau_payload_queue_entry *pqp_malloc;
+       struct bau_control *bcp;
 
        pqp = (struct bau_payload_queue_entry *) kmalloc_node(
                (DEST_Q_SIZE + 1) * sizeof(struct bau_payload_queue_entry),
                GFP_KERNEL, node);
        BUG_ON(!pqp);
+       pqp_malloc = pqp;
 
        cp = (char *)pqp + 31;
        pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5);
-       bau_tablesp->va_queue_first = pqp;
+
+       for_each_present_cpu(cpu) {
+               if (pnode != uv_cpu_to_pnode(cpu))
+                       continue;
+               /* for every cpu on this pnode: */
+               bcp = &per_cpu(bau_control, cpu);
+               bcp->va_queue_first = pqp;
+               bcp->bau_msg_head = pqp;
+               bcp->va_queue_last = pqp + (DEST_Q_SIZE - 1);
+       }
        /*
         * need the pnode of where the memory was really allocated
         */
        pa = uv_gpa(pqp);
-       pn = uv_gpa_to_pnode(pa);
+       pn = pa >> uv_nshift;
        uv_write_global_mmr64(pnode,
                              UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
                              ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
                              uv_physnodeaddr(pqp));
        uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL,
                              uv_physnodeaddr(pqp));
-       bau_tablesp->va_queue_last = pqp + (DEST_Q_SIZE - 1);
        uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST,
                              (unsigned long)
-                             uv_physnodeaddr(bau_tablesp->va_queue_last));
+                             uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)));
+       /* in effect, all msg_type's are set to MSG_NOOP */
        memset(pqp, 0, sizeof(struct bau_payload_queue_entry) * DEST_Q_SIZE);
-
-       return pqp;
 }
 
 /*
- * Initialization of each UV blade's structures
+ * Initialization of each UV hub's structures
  */
-static int __init uv_init_blade(int blade)
+static void __init uv_init_uvhub(int uvhub, int vector)
 {
        int node;
        int pnode;
-       unsigned long pa;
        unsigned long apicid;
-       struct bau_desc *adp;
-       struct bau_payload_queue_entry *pqp;
-       struct bau_control *bau_tablesp;
-
-       node = blade_to_first_node(blade);
-       bau_tablesp = uv_table_bases_init(blade, node);
-       pnode = uv_blade_to_pnode(blade);
-       adp = uv_activation_descriptor_init(node, pnode);
-       pqp = uv_payload_queue_init(node, pnode, bau_tablesp);
-       uv_table_bases_finish(blade, bau_tablesp, adp);
+
+       node = uvhub_to_first_node(uvhub);
+       pnode = uv_blade_to_pnode(uvhub);
+       uv_activation_descriptor_init(node, pnode);
+       uv_payload_queue_init(node, pnode);
        /*
         * the below initialization can't be in firmware because the
         * messaging IRQ will be determined by the OS
         */
-       apicid = blade_to_first_apicid(blade);
-       pa = uv_read_global_mmr64(pnode, UVH_BAU_DATA_CONFIG);
+       apicid = uvhub_to_first_apicid(uvhub);
        uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
-                                     ((apicid << 32) | UV_BAU_MESSAGE));
-       return 0;
+                                     ((apicid << 32) | vector));
+}
+
+/*
+ * initialize the bau_control structure for each cpu
+ */
+static void uv_init_per_cpu(int nuvhubs)
+{
+       int i, j, k;
+       int cpu;
+       int pnode;
+       int uvhub;
+       short socket = 0;
+       struct bau_control *bcp;
+       struct uvhub_desc *bdp;
+       struct socket_desc *sdp;
+       struct bau_control *hmaster = NULL;
+       struct bau_control *smaster = NULL;
+       struct socket_desc {
+               short num_cpus;
+               short cpu_number[16];
+       };
+       struct uvhub_desc {
+               short num_sockets;
+               short num_cpus;
+               short uvhub;
+               short pnode;
+               struct socket_desc socket[2];
+       };
+       struct uvhub_desc *uvhub_descs;
+
+       uvhub_descs = (struct uvhub_desc *)
+               kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
+       memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
+       for_each_present_cpu(cpu) {
+               bcp = &per_cpu(bau_control, cpu);
+               memset(bcp, 0, sizeof(struct bau_control));
+               spin_lock_init(&bcp->masks_lock);
+               bcp->max_concurrent = uv_bau_max_concurrent;
+               pnode = uv_cpu_hub_info(cpu)->pnode;
+               uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
+               bdp = &uvhub_descs[uvhub];
+               bdp->num_cpus++;
+               bdp->uvhub = uvhub;
+               bdp->pnode = pnode;
+               /* time interval to catch a hardware stay-busy bug */
+               bcp->timeout_interval = millisec_2_cycles(3);
+               /* kludge: assume uv_hub.h is constant */
+               socket = (cpu_physical_id(cpu)>>5)&1;
+               if (socket >= bdp->num_sockets)
+                       bdp->num_sockets = socket+1;
+               sdp = &bdp->socket[socket];
+               sdp->cpu_number[sdp->num_cpus] = cpu;
+               sdp->num_cpus++;
+       }
+       socket = 0;
+       for_each_possible_blade(uvhub) {
+               bdp = &uvhub_descs[uvhub];
+               for (i = 0; i < bdp->num_sockets; i++) {
+                       sdp = &bdp->socket[i];
+                       for (j = 0; j < sdp->num_cpus; j++) {
+                               cpu = sdp->cpu_number[j];
+                               bcp = &per_cpu(bau_control, cpu);
+                               bcp->cpu = cpu;
+                               if (j == 0) {
+                                       smaster = bcp;
+                                       if (i == 0)
+                                               hmaster = bcp;
+                               }
+                               bcp->cpus_in_uvhub = bdp->num_cpus;
+                               bcp->cpus_in_socket = sdp->num_cpus;
+                               bcp->socket_master = smaster;
+                               bcp->uvhub_master = hmaster;
+                               for (k = 0; k < DEST_Q_SIZE; k++)
+                                       bcp->socket_acknowledge_count[k] = 0;
+                               bcp->uvhub_cpu =
+                                 uv_cpu_hub_info(cpu)->blade_processor_id;
+                       }
+                       socket++;
+               }
+       }
+       kfree(uvhub_descs);
 }
 
 /*
@@ -828,38 +1344,54 @@ static int __init uv_init_blade(int blade)
  */
 static int __init uv_bau_init(void)
 {
-       int blade;
-       int nblades;
+       int uvhub;
+       int pnode;
+       int nuvhubs;
        int cur_cpu;
+       int vector;
+       unsigned long mmr;
 
        if (!is_uv_system())
                return 0;
 
+       if (nobau)
+               return 0;
+
        for_each_possible_cpu(cur_cpu)
                zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
                                       GFP_KERNEL, cpu_to_node(cur_cpu));
 
-       uv_bau_retry_limit = 1;
+       uv_bau_max_concurrent = MAX_BAU_CONCURRENT;
+       uv_nshift = uv_hub_info->m_val;
        uv_mmask = (1UL << uv_hub_info->m_val) - 1;
-       nblades = uv_num_possible_blades();
+       nuvhubs = uv_num_possible_blades();
 
-       uv_bau_table_bases = (struct bau_control **)
-           kmalloc(nblades * sizeof(struct bau_control *), GFP_KERNEL);
-       BUG_ON(!uv_bau_table_bases);
+       uv_init_per_cpu(nuvhubs);
 
        uv_partition_base_pnode = 0x7fffffff;
-       for (blade = 0; blade < nblades; blade++)
-               if (uv_blade_nr_possible_cpus(blade) &&
-                       (uv_blade_to_pnode(blade) < uv_partition_base_pnode))
-                       uv_partition_base_pnode = uv_blade_to_pnode(blade);
-       for (blade = 0; blade < nblades; blade++)
-               if (uv_blade_nr_possible_cpus(blade))
-                       uv_init_blade(blade);
-
-       alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
+       for (uvhub = 0; uvhub < nuvhubs; uvhub++)
+               if (uv_blade_nr_possible_cpus(uvhub) &&
+                       (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode))
+                       uv_partition_base_pnode = uv_blade_to_pnode(uvhub);
+
+       vector = UV_BAU_MESSAGE;
+       for_each_possible_blade(uvhub)
+               if (uv_blade_nr_possible_cpus(uvhub))
+                       uv_init_uvhub(uvhub, vector);
+
        uv_enable_timeouts();
+       alloc_intr_gate(vector, uv_bau_message_intr1);
+
+       for_each_possible_blade(uvhub) {
+               pnode = uv_blade_to_pnode(uvhub);
+               /* INIT the bau */
+               uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL,
+                                     ((unsigned long)1 << 63));
+               mmr = 1; /* should be 1 to broadcast to both sockets */
+               uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST, mmr);
+       }
 
        return 0;
 }
-__initcall(uv_bau_init);
-__initcall(uv_ptc_init);
+core_initcall(uv_bau_init);
+core_initcall(uv_ptc_init);
index 1168e44..02cfb9b 100644 (file)
@@ -108,15 +108,6 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
        dec_preempt_count();
 }
 
-#ifdef CONFIG_X86_32
-static inline void
-die_if_kernel(const char *str, struct pt_regs *regs, long err)
-{
-       if (!user_mode_vm(regs))
-               die(str, regs, err);
-}
-#endif
-
 static void __kprobes
 do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
        long error_code, siginfo_t *info)
@@ -543,11 +534,11 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 
        /* DR6 may or may not be cleared by the CPU */
        set_debugreg(0, 6);
+
        /*
         * The processor cleared BTF, so don't mark that we need it set.
         */
-       clear_tsk_thread_flag(tsk, TIF_DEBUGCTLMSR);
-       tsk->thread.debugctlmsr = 0;
+       clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
 
        /* Store the virtualized DR6 value */
        tsk->thread.debugreg6 = dr6;
@@ -585,55 +576,67 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
        return;
 }
 
-#ifdef CONFIG_X86_64
-static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
-{
-       if (fixup_exception(regs))
-               return 1;
-
-       notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
-       /* Illegal floating point operation in the kernel */
-       current->thread.trap_no = trapnr;
-       die(str, regs, 0);
-       return 0;
-}
-#endif
-
 /*
  * Note that we play around with the 'TS' bit in an attempt to get
  * the correct behaviour even in the presence of the asynchronous
  * IRQ13 behaviour
  */
-void math_error(void __user *ip)
+void math_error(struct pt_regs *regs, int error_code, int trapnr)
 {
-       struct task_struct *task;
+       struct task_struct *task = current;
        siginfo_t info;
-       unsigned short cwd, swd, err;
+       unsigned short err;
+       char *str = (trapnr == 16) ? "fpu exception" : "simd exception";
+
+       if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
+               return;
+       conditional_sti(regs);
+
+       if (!user_mode_vm(regs))
+       {
+               if (!fixup_exception(regs)) {
+                       task->thread.error_code = error_code;
+                       task->thread.trap_no = trapnr;
+                       die(str, regs, error_code);
+               }
+               return;
+       }
 
        /*
         * Save the info for the exception handler and clear the error.
         */
-       task = current;
        save_init_fpu(task);
-       task->thread.trap_no = 16;
-       task->thread.error_code = 0;
+       task->thread.trap_no = trapnr;
+       task->thread.error_code = error_code;
        info.si_signo = SIGFPE;
        info.si_errno = 0;
-       info.si_addr = ip;
-       /*
-        * (~cwd & swd) will mask out exceptions that are not set to unmasked
-        * status.  0x3f is the exception bits in these regs, 0x200 is the
-        * C1 reg you need in case of a stack fault, 0x040 is the stack
-        * fault bit.  We should only be taking one exception at a time,
-        * so if this combination doesn't produce any single exception,
-        * then we have a bad program that isn't synchronizing its FPU usage
-        * and it will suffer the consequences since we won't be able to
-        * fully reproduce the context of the exception
-        */
-       cwd = get_fpu_cwd(task);
-       swd = get_fpu_swd(task);
+       info.si_addr = (void __user *)regs->ip;
+       if (trapnr == 16) {
+               unsigned short cwd, swd;
+               /*
+                * (~cwd & swd) will mask out exceptions that are not set to unmasked
+                * status.  0x3f is the exception bits in these regs, 0x200 is the
+                * C1 reg you need in case of a stack fault, 0x040 is the stack
+                * fault bit.  We should only be taking one exception at a time,
+                * so if this combination doesn't produce any single exception,
+                * then we have a bad program that isn't synchronizing its FPU usage
+                * and it will suffer the consequences since we won't be able to
+                * fully reproduce the context of the exception
+                */
+               cwd = get_fpu_cwd(task);
+               swd = get_fpu_swd(task);
 
-       err = swd & ~cwd;
+               err = swd & ~cwd;
+       } else {
+               /*
+                * The SIMD FPU exceptions are handled a little differently, as there
+                * is only a single status/control register.  Thus, to determine which
+                * unmasked exception was caught we must mask the exception mask bits
+                * at 0x1f80, and then use these to mask the exception bits at 0x3f.
+                */
+               unsigned short mxcsr = get_fpu_mxcsr(task);
+               err = ~(mxcsr >> 7) & mxcsr;
+       }
 
        if (err & 0x001) {      /* Invalid op */
                /*
@@ -662,97 +665,17 @@ void math_error(void __user *ip)
 
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-       conditional_sti(regs);
-
 #ifdef CONFIG_X86_32
        ignore_fpu_irq = 1;
-#else
-       if (!user_mode(regs) &&
-           kernel_math_error(regs, "kernel x87 math error", 16))
-               return;
 #endif
 
-       math_error((void __user *)regs->ip);
-}
-
-static void simd_math_error(void __user *ip)
-{
-       struct task_struct *task;
-       siginfo_t info;
-       unsigned short mxcsr;
-
-       /*
-        * Save the info for the exception handler and clear the error.
-        */
-       task = current;
-       save_init_fpu(task);
-       task->thread.trap_no = 19;
-       task->thread.error_code = 0;
-       info.si_signo = SIGFPE;
-       info.si_errno = 0;
-       info.si_code = __SI_FAULT;
-       info.si_addr = ip;
-       /*
-        * The SIMD FPU exceptions are handled a little differently, as there
-        * is only a single status/control register.  Thus, to determine which
-        * unmasked exception was caught we must mask the exception mask bits
-        * at 0x1f80, and then use these to mask the exception bits at 0x3f.
-        */
-       mxcsr = get_fpu_mxcsr(task);
-       switch (~((mxcsr & 0x1f80) >> 7) & (mxcsr & 0x3f)) {
-       case 0x000:
-       default:
-               break;
-       case 0x001: /* Invalid Op */
-               info.si_code = FPE_FLTINV;
-               break;
-       case 0x002: /* Denormalize */
-       case 0x010: /* Underflow */
-               info.si_code = FPE_FLTUND;
-               break;
-       case 0x004: /* Zero Divide */
-               info.si_code = FPE_FLTDIV;
-               break;
-       case 0x008: /* Overflow */
-               info.si_code = FPE_FLTOVF;
-               break;
-       case 0x020: /* Precision */
-               info.si_code = FPE_FLTRES;
-               break;
-       }
-       force_sig_info(SIGFPE, &info, task);
+       math_error(regs, error_code, 16);
 }
 
 dotraplinkage void
 do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
 {
-       conditional_sti(regs);
-
-#ifdef CONFIG_X86_32
-       if (cpu_has_xmm) {
-               /* Handle SIMD FPU exceptions on PIII+ processors. */
-               ignore_fpu_irq = 1;
-               simd_math_error((void __user *)regs->ip);
-               return;
-       }
-       /*
-        * Handle strange cache flush from user space exception
-        * in all other cases.  This is undocumented behaviour.
-        */
-       if (regs->flags & X86_VM_MASK) {
-               handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
-               return;
-       }
-       current->thread.trap_no = 19;
-       current->thread.error_code = error_code;
-       die_if_kernel("cache flush denied", regs, error_code);
-       force_sig(SIGSEGV, current);
-#else
-       if (!user_mode(regs) &&
-                       kernel_math_error(regs, "kernel simd math error", 19))
-               return;
-       simd_math_error((void __user *)regs->ip);
-#endif
+       math_error(regs, error_code, 19);
 }
 
 dotraplinkage void
index 1d40336..1132129 100644 (file)
@@ -44,7 +44,7 @@ static void uv_ack_apic(unsigned int irq)
        ack_APIC_irq();
 }
 
-struct irq_chip uv_irq_chip = {
+static struct irq_chip uv_irq_chip = {
        .name           = "UV-CORE",
        .startup        = uv_noop_ret,
        .shutdown       = uv_noop,
@@ -141,7 +141,7 @@ int uv_irq_2_mmr_info(int irq, unsigned long *offset, int *pnode)
  */
 static int
 arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
-                      unsigned long mmr_offset, int restrict)
+                      unsigned long mmr_offset, int limit)
 {
        const struct cpumask *eligible_cpu = cpumask_of(cpu);
        struct irq_desc *desc = irq_to_desc(irq);
@@ -160,7 +160,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
        if (err != 0)
                return err;
 
-       if (restrict == UV_AFFINITY_CPU)
+       if (limit == UV_AFFINITY_CPU)
                desc->status |= IRQ_NO_BALANCING;
        else
                desc->status |= IRQ_MOVE_PCNTXT;
@@ -214,7 +214,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
        unsigned long mmr_value;
        struct uv_IO_APIC_route_entry *entry;
        unsigned long mmr_offset;
-       unsigned mmr_pnode;
+       int mmr_pnode;
 
        if (set_desc_affinity(desc, mask, &dest))
                return -1;
@@ -248,7 +248,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
  * interrupt is raised.
  */
 int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
-                unsigned long mmr_offset, int restrict)
+                unsigned long mmr_offset, int limit)
 {
        int irq, ret;
 
@@ -258,7 +258,7 @@ int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
                return -EBUSY;
 
        ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset,
-               restrict);
+               limit);
        if (ret == irq)
                uv_set_irq_2_mmr_info(irq, mmr_offset, mmr_blade);
        else
index 693920b..1b950d1 100644 (file)
@@ -54,7 +54,6 @@ EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__memcpy);
 
 EXPORT_SYMBOL(empty_zero_page);
-EXPORT_SYMBOL(init_level4_pgt);
 #ifndef CONFIG_PARAVIRT
 EXPORT_SYMBOL(native_load_gs_index);
 #endif
index 782c3a3..37e68fc 100644 (file)
@@ -99,7 +99,7 @@ int save_i387_xstate(void __user *buf)
                if (err)
                        return err;
 
-               if (task_thread_info(tsk)->status & TS_XSAVE)
+               if (use_xsave())
                        err = xsave_user(buf);
                else
                        err = fxsave_user(buf);
@@ -109,14 +109,14 @@ int save_i387_xstate(void __user *buf)
                task_thread_info(tsk)->status &= ~TS_USEDFPU;
                stts();
        } else {
-               if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
+               if (__copy_to_user(buf, &tsk->thread.fpu.state->fxsave,
                                   xstate_size))
                        return -1;
        }
 
        clear_used_math(); /* trigger finit */
 
-       if (task_thread_info(tsk)->status & TS_XSAVE) {
+       if (use_xsave()) {
                struct _fpstate __user *fx = buf;
                struct _xstate __user *x = buf;
                u64 xstate_bv;
@@ -225,7 +225,7 @@ int restore_i387_xstate(void __user *buf)
                clts();
                task_thread_info(current)->status |= TS_USEDFPU;
        }
-       if (task_thread_info(tsk)->status & TS_XSAVE)
+       if (use_xsave())
                err = restore_user_xstate(buf);
        else
                err = fxrstor_checking((__force struct i387_fxsave_struct *)
index 48aeee8..19a8906 100644 (file)
@@ -1490,8 +1490,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
                for_each_sp(pages, sp, parents, i) {
                        kvm_mmu_zap_page(kvm, sp);
                        mmu_pages_clear_parents(&parents);
+                       zapped++;
                }
-               zapped += pages.nr;
                kvm_mmu_pages_init(parent, &parents, &pages);
        }
 
@@ -1542,14 +1542,16 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
         */
 
        if (used_pages > kvm_nr_mmu_pages) {
-               while (used_pages > kvm_nr_mmu_pages) {
+               while (used_pages > kvm_nr_mmu_pages &&
+                       !list_empty(&kvm->arch.active_mmu_pages)) {
                        struct kvm_mmu_page *page;
 
                        page = container_of(kvm->arch.active_mmu_pages.prev,
                                            struct kvm_mmu_page, link);
-                       kvm_mmu_zap_page(kvm, page);
+                       used_pages -= kvm_mmu_zap_page(kvm, page);
                        used_pages--;
                }
+               kvm_nr_mmu_pages = used_pages;
                kvm->arch.n_free_mmu_pages = 0;
        }
        else
@@ -1596,7 +1598,8 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
                    && !sp->role.invalid) {
                        pgprintk("%s: zap %lx %x\n",
                                 __func__, gfn, sp->role.word);
-                       kvm_mmu_zap_page(kvm, sp);
+                       if (kvm_mmu_zap_page(kvm, sp))
+                               nn = bucket->first;
                }
        }
 }
index 445c594..737361f 100644 (file)
@@ -706,29 +706,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
        if (err)
                goto free_svm;
 
+       err = -ENOMEM;
        page = alloc_page(GFP_KERNEL);
-       if (!page) {
-               err = -ENOMEM;
+       if (!page)
                goto uninit;
-       }
 
-       err = -ENOMEM;
        msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
        if (!msrpm_pages)
-               goto uninit;
+               goto free_page1;
 
        nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
        if (!nested_msrpm_pages)
-               goto uninit;
-
-       svm->msrpm = page_address(msrpm_pages);
-       svm_vcpu_init_msrpm(svm->msrpm);
+               goto free_page2;
 
        hsave_page = alloc_page(GFP_KERNEL);
        if (!hsave_page)
-               goto uninit;
+               goto free_page3;
+
        svm->nested.hsave = page_address(hsave_page);
 
+       svm->msrpm = page_address(msrpm_pages);
+       svm_vcpu_init_msrpm(svm->msrpm);
+
        svm->nested.msrpm = page_address(nested_msrpm_pages);
 
        svm->vmcb = page_address(page);
@@ -744,6 +743,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
 
        return &svm->vcpu;
 
+free_page3:
+       __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page2:
+       __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page1:
+       __free_page(page);
 uninit:
        kvm_vcpu_uninit(&svm->vcpu);
 free_svm:
@@ -2062,7 +2067,7 @@ static int cpuid_interception(struct vcpu_svm *svm)
 static int iret_interception(struct vcpu_svm *svm)
 {
        ++svm->vcpu.stat.nmi_window_exits;
-       svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+       svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
        svm->vcpu.arch.hflags |= HF_IRET_MASK;
        return 1;
 }
@@ -2474,7 +2479,7 @@ static void svm_inject_nmi(struct kvm_vcpu *vcpu)
 
        svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_NMI;
        vcpu->arch.hflags |= HF_NMI_MASK;
-       svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+       svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
        ++vcpu->stat.nmi_injections;
 }
 
@@ -2534,10 +2539,10 @@ static void svm_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked)
 
        if (masked) {
                svm->vcpu.arch.hflags |= HF_NMI_MASK;
-               svm->vmcb->control.intercept |= (1UL << INTERCEPT_IRET);
+               svm->vmcb->control.intercept |= (1ULL << INTERCEPT_IRET);
        } else {
                svm->vcpu.arch.hflags &= ~HF_NMI_MASK;
-               svm->vmcb->control.intercept &= ~(1UL << INTERCEPT_IRET);
+               svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_IRET);
        }
 }
 
index 686492e..edca080 100644 (file)
@@ -77,6 +77,8 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
 #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
 
+#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM))
+
 /*
  * These 2 parameters are used to config the controls for Pause-Loop Exiting:
  * ple_gap:    upper bound on the amount of time between two successive
@@ -131,7 +133,7 @@ struct vcpu_vmx {
        } host_state;
        struct {
                int vm86_active;
-               u8 save_iopl;
+               ulong save_rflags;
                struct kvm_save_segment {
                        u16 selector;
                        unsigned long base;
@@ -818,18 +820,23 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
 
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
-       unsigned long rflags;
+       unsigned long rflags, save_rflags;
 
        rflags = vmcs_readl(GUEST_RFLAGS);
-       if (to_vmx(vcpu)->rmode.vm86_active)
-               rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
+       if (to_vmx(vcpu)->rmode.vm86_active) {
+               rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+               save_rflags = to_vmx(vcpu)->rmode.save_rflags;
+               rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+       }
        return rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
-       if (to_vmx(vcpu)->rmode.vm86_active)
+       if (to_vmx(vcpu)->rmode.vm86_active) {
+               to_vmx(vcpu)->rmode.save_rflags = rflags;
                rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
+       }
        vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
@@ -1483,8 +1490,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
        vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
 
        flags = vmcs_readl(GUEST_RFLAGS);
-       flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
-       flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
+       flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+       flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
        vmcs_writel(GUEST_RFLAGS, flags);
 
        vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1557,8 +1564,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
        vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
 
        flags = vmcs_readl(GUEST_RFLAGS);
-       vmx->rmode.save_iopl
-               = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+       vmx->rmode.save_rflags = flags;
 
        flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
 
@@ -2697,8 +2703,7 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu)
                return 0;
 
        return  !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
-                       (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS |
-                               GUEST_INTR_STATE_NMI));
+                       (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI));
 }
 
 static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu)
@@ -3654,8 +3659,11 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
 
        /* We need to handle NMIs before interrupts are enabled */
        if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
-           (exit_intr_info & INTR_INFO_VALID_MASK))
+           (exit_intr_info & INTR_INFO_VALID_MASK)) {
+               kvm_before_handle_nmi(&vmx->vcpu);
                asm("int $2");
+               kvm_after_handle_nmi(&vmx->vcpu);
+       }
 
        idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
 
index 24cd0ee..dd9bc8f 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/user-return-notifier.h>
 #include <linux/srcu.h>
 #include <linux/slab.h>
+#include <linux/perf_event.h>
 #include <trace/events/kvm.h>
 #undef TRACE_INCLUDE_FILE
 #define CREATE_TRACE_POINTS
@@ -433,8 +434,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 
 #ifdef CONFIG_X86_64
        if (cr0 & 0xffffffff00000000UL) {
-               printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
-                      cr0, kvm_read_cr0(vcpu));
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -443,14 +442,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        cr0 &= ~CR0_RESERVED_BITS;
 
        if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
-               printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) {
-               printk(KERN_DEBUG "set_cr0: #GP, set PG flag "
-                      "and a clear PE flag\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -461,15 +457,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                        int cs_db, cs_l;
 
                        if (!is_pae(vcpu)) {
-                               printk(KERN_DEBUG "set_cr0: #GP, start paging "
-                                      "in long mode while PAE is disabled\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
                        kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
                        if (cs_l) {
-                               printk(KERN_DEBUG "set_cr0: #GP, start paging "
-                                      "in long mode while CS.L == 1\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
 
@@ -477,8 +469,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                } else
 #endif
                if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-                       printk(KERN_DEBUG "set_cr0: #GP, pdptrs "
-                              "reserved bits\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -505,28 +495,23 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
        unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
 
        if (cr4 & CR4_RESERVED_BITS) {
-               printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (is_long_mode(vcpu)) {
                if (!(cr4 & X86_CR4_PAE)) {
-                       printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
-                              "in long mode\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
        } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
                   && ((cr4 ^ old_cr4) & pdptr_bits)
                   && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-               printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (cr4 & X86_CR4_VMXE) {
-               printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -547,21 +532,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 
        if (is_long_mode(vcpu)) {
                if (cr3 & CR3_L_MODE_RESERVED_BITS) {
-                       printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
        } else {
                if (is_pae(vcpu)) {
                        if (cr3 & CR3_PAE_RESERVED_BITS) {
-                               printk(KERN_DEBUG
-                                      "set_cr3: #GP, reserved bits\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
                        if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
-                               printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
-                                      "reserved bits\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
@@ -593,7 +573,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3);
 void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
 {
        if (cr8 & CR8_RESERVED_BITS) {
-               printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -649,15 +628,12 @@ static u32 emulated_msrs[] = {
 static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
        if (efer & efer_reserved_bits) {
-               printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
-                      efer);
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (is_paging(vcpu)
            && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) {
-               printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -667,7 +643,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 
                feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
                if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) {
-                       printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -678,7 +653,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 
                feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
                if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
-                       printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -967,9 +941,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                if (msr >= MSR_IA32_MC0_CTL &&
                    msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
                        u32 offset = msr - MSR_IA32_MC0_CTL;
-                       /* only 0 or all 1s can be written to IA32_MCi_CTL */
+                       /* only 0 or all 1s can be written to IA32_MCi_CTL
+                        * some Linux kernels though clear bit 10 in bank 4 to
+                        * workaround a BIOS/GART TBL issue on AMD K8s, ignore
+                        * this to avoid an uncatched #GP in the guest
+                        */
                        if ((offset & 0x3) == 0 &&
-                           data != 0 && data != ~(u64)0)
+                           data != 0 && (data | (1 << 10)) != ~(u64)0)
                                return -1;
                        vcpu->arch.mce_banks[offset] = data;
                        break;
@@ -1735,6 +1713,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
        if (copy_from_user(cpuid_entries, entries,
                           cpuid->nent * sizeof(struct kvm_cpuid_entry)))
                goto out_free;
+       vcpu_load(vcpu);
        for (i = 0; i < cpuid->nent; i++) {
                vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
                vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
@@ -1752,6 +1731,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
        r = 0;
        kvm_apic_set_version(vcpu);
        kvm_x86_ops->cpuid_update(vcpu);
+       vcpu_put(vcpu);
 
 out_free:
        vfree(cpuid_entries);
@@ -1772,9 +1752,11 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
        if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
                           cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
                goto out;
+       vcpu_load(vcpu);
        vcpu->arch.cpuid_nent = cpuid->nent;
        kvm_apic_set_version(vcpu);
        kvm_x86_ops->cpuid_update(vcpu);
+       vcpu_put(vcpu);
        return 0;
 
 out:
@@ -2635,8 +2617,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                                      struct kvm_dirty_log *log)
 {
-       int r, n, i;
+       int r, i;
        struct kvm_memory_slot *memslot;
+       unsigned long n;
        unsigned long is_dirty = 0;
        unsigned long *dirty_bitmap = NULL;
 
@@ -2651,7 +2634,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
 
        r = -ENOMEM;
        dirty_bitmap = vmalloc(n);
@@ -3765,6 +3748,51 @@ static void kvm_timer_init(void)
        }
 }
 
+static DEFINE_PER_CPU(struct kvm_vcpu *, current_vcpu);
+
+static int kvm_is_in_guest(void)
+{
+       return percpu_read(current_vcpu) != NULL;
+}
+
+static int kvm_is_user_mode(void)
+{
+       int user_mode = 3;
+
+       if (percpu_read(current_vcpu))
+               user_mode = kvm_x86_ops->get_cpl(percpu_read(current_vcpu));
+
+       return user_mode != 0;
+}
+
+static unsigned long kvm_get_guest_ip(void)
+{
+       unsigned long ip = 0;
+
+       if (percpu_read(current_vcpu))
+               ip = kvm_rip_read(percpu_read(current_vcpu));
+
+       return ip;
+}
+
+static struct perf_guest_info_callbacks kvm_guest_cbs = {
+       .is_in_guest            = kvm_is_in_guest,
+       .is_user_mode           = kvm_is_user_mode,
+       .get_guest_ip           = kvm_get_guest_ip,
+};
+
+void kvm_before_handle_nmi(struct kvm_vcpu *vcpu)
+{
+       percpu_write(current_vcpu, vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_before_handle_nmi);
+
+void kvm_after_handle_nmi(struct kvm_vcpu *vcpu)
+{
+       percpu_write(current_vcpu, NULL);
+}
+EXPORT_SYMBOL_GPL(kvm_after_handle_nmi);
+
 int kvm_arch_init(void *opaque)
 {
        int r;
@@ -3801,6 +3829,8 @@ int kvm_arch_init(void *opaque)
 
        kvm_timer_init();
 
+       perf_register_guest_info_callbacks(&kvm_guest_cbs);
+
        return 0;
 
 out:
@@ -3809,6 +3839,8 @@ out:
 
 void kvm_arch_exit(void)
 {
+       perf_unregister_guest_info_callbacks(&kvm_guest_cbs);
+
        if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
                cpufreq_unregister_notifier(&kvmclock_cpufreq_notifier_block,
                                            CPUFREQ_TRANSITION_NOTIFIER);
@@ -4483,7 +4515,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                kvm_set_cr8(vcpu, kvm_run->cr8);
 
        if (vcpu->arch.pio.cur_count) {
+               vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
                r = complete_pio(vcpu);
+               srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
                if (r)
                        goto out;
        }
@@ -5146,6 +5180,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
        int ret = 0;
        u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
        u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
+       u32 desc_limit;
 
        old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL);
 
@@ -5168,7 +5203,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
                }
        }
 
-       if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
+       desc_limit = get_desc_limit(&nseg_desc);
+       if (!nseg_desc.p ||
+           ((desc_limit < 0x67 && (nseg_desc.type & 8)) ||
+            desc_limit < 0x2b)) {
                kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
                return 1;
        }
index 2d10163..b7a4047 100644 (file)
@@ -65,4 +65,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
        return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
 }
 
+void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
+void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
+
 #endif
index 7e59dc1..2bdf628 100644 (file)
@@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1,
        local_irq_save(flags);
        if (lguest_data.hcall_status[next_call] != 0xFF) {
                /* Table full, so do normal hcall which will flush table. */
-               kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+               hcall(call, arg1, arg2, arg3, arg4);
        } else {
                lguest_data.hcalls[next_call].arg0 = call;
                lguest_data.hcalls[next_call].arg1 = arg1;
@@ -145,46 +145,45 @@ static void async_hcall(unsigned long call, unsigned long arg1,
  * So, when we're in lazy mode, we call async_hcall() to store the call for
  * future processing:
  */
-static void lazy_hcall1(unsigned long call,
-                      unsigned long arg1)
+static void lazy_hcall1(unsigned long call, unsigned long arg1)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall1(call, arg1);
+               hcall(call, arg1, 0, 0, 0);
        else
                async_hcall(call, arg1, 0, 0, 0);
 }
 
 /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/
 static void lazy_hcall2(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2)
+                       unsigned long arg1,
+                       unsigned long arg2)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall2(call, arg1, arg2);
+               hcall(call, arg1, arg2, 0, 0);
        else
                async_hcall(call, arg1, arg2, 0, 0);
 }
 
 static void lazy_hcall3(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3)
+                       unsigned long arg1,
+                       unsigned long arg2,
+                       unsigned long arg3)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall3(call, arg1, arg2, arg3);
+               hcall(call, arg1, arg2, arg3, 0);
        else
                async_hcall(call, arg1, arg2, arg3, 0);
 }
 
 #ifdef CONFIG_X86_PAE
 static void lazy_hcall4(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3,
-                      unsigned long arg4)
+                       unsigned long arg1,
+                       unsigned long arg2,
+                       unsigned long arg3,
+                       unsigned long arg4)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+               hcall(call, arg1, arg2, arg3, arg4);
        else
                async_hcall(call, arg1, arg2, arg3, arg4);
 }
@@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long call,
 :*/
 static void lguest_leave_lazy_mmu_mode(void)
 {
-       kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
        paravirt_leave_lazy_mmu();
 }
 
 static void lguest_end_context_switch(struct task_struct *next)
 {
-       kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
        paravirt_end_context_switch(next);
 }
 
@@ -286,7 +285,7 @@ static void lguest_write_idt_entry(gate_desc *dt,
        /* Keep the local copy up to date. */
        native_write_idt_entry(dt, entrynum, g);
        /* Tell Host about this new entry. */
-       kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+       hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0);
 }
 
 /*
@@ -300,7 +299,7 @@ static void lguest_load_idt(const struct desc_ptr *desc)
        struct desc_struct *idt = (void *)desc->address;
 
        for (i = 0; i < (desc->size+1)/8; i++)
-               kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+               hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0);
 }
 
 /*
@@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc)
        struct desc_struct *gdt = (void *)desc->address;
 
        for (i = 0; i < (desc->size+1)/8; i++)
-               kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b);
+               hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0);
 }
 
 /*
@@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
 {
        native_write_gdt_entry(dt, entrynum, desc, type);
        /* Tell Host about this new entry. */
-       kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum,
-                      dt[entrynum].a, dt[entrynum].b);
+       hcall(LHCALL_LOAD_GDT_ENTRY, entrynum,
+             dt[entrynum].a, dt[entrynum].b, 0);
 }
 
 /*
@@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta,
        }
 
        /* Please wake us this far in the future. */
-       kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
+       hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0);
        return 0;
 }
 
@@ -942,7 +941,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
                /* A 0 argument shuts the clock down. */
-               kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
+               hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                /* This is what we expect. */
@@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(void)
 /* STOP!  Until an interrupt comes in. */
 static void lguest_safe_halt(void)
 {
-       kvm_hypercall0(LHCALL_HALT);
+       hcall(LHCALL_HALT, 0, 0, 0, 0);
 }
 
 /*
@@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void)
  */
 static void lguest_power_off(void)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
-                                       LGUEST_SHUTDOWN_POWEROFF);
+       hcall(LHCALL_SHUTDOWN, __pa("Power down"),
+             LGUEST_SHUTDOWN_POWEROFF, 0, 0);
 }
 
 /*
@@ -1123,7 +1122,7 @@ static void lguest_power_off(void)
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
+       hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0);
        /* The hcall won't return, but to keep gcc happy, we're "done". */
        return NOTIFY_DONE;
 }
@@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
                len = sizeof(scratch) - 1;
        scratch[len] = '\0';
        memcpy(scratch, buf, len);
-       kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
+       hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
 
        /* This routine returns the number of bytes actually written. */
        return len;
@@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
  */
 static void lguest_restart(char *reason)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
+       hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0);
 }
 
 /*G:050
index 27eac0f..4f420c2 100644 (file)
@@ -32,7 +32,7 @@ ENTRY(lguest_entry)
         */
        movl $LHCALL_LGUEST_INIT, %eax
        movl $lguest_data - __PAGE_OFFSET, %ebx
-       .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
+       int $LGUEST_TRAP_ENTRY
 
        /* Set up the initial stack so we can run C code. */
        movl $(init_thread_union+THREAD_SIZE),%esp
index 419386c..f871e04 100644 (file)
@@ -20,17 +20,18 @@ lib-y := delay.o
 lib-y += thunk_$(BITS).o
 lib-y += usercopy_$(BITS).o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
-lib-$(CONFIG_KPROBES) += insn.o inat.o
+lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
 
 obj-y += msr.o msr-reg.o msr-reg-export.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
+        lib-y += atomic64_cx8_32.o
         lib-y += checksum_32.o
         lib-y += strstr_32.o
         lib-y += semaphore_32.o string_32.o
 ifneq ($(CONFIG_X86_CMPXCHG64),y)
-        lib-y += cmpxchg8b_emu.o
+        lib-y += cmpxchg8b_emu.o atomic64_386_32.o
 endif
         lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
 else
index 824fa0b..540179e 100644 (file)
 #include <asm/cmpxchg.h>
 #include <asm/atomic.h>
 
-static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new)
-{
-       u32 low = new;
-       u32 high = new >> 32;
-
-       asm volatile(
-               LOCK_PREFIX "cmpxchg8b %1\n"
-                    : "+A" (old), "+m" (*ptr)
-                    :  "b" (low),  "c" (high)
-                    );
-       return old;
-}
-
-u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val)
-{
-       return cmpxchg8b(&ptr->counter, old_val, new_val);
-}
-EXPORT_SYMBOL(atomic64_cmpxchg);
-
-/**
- * atomic64_xchg - xchg atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
- *
- * Atomically xchgs the value of @ptr to @new_val and returns
- * the old value.
- */
-u64 atomic64_xchg(atomic64_t *ptr, u64 new_val)
-{
-       /*
-        * Try first with a (possibly incorrect) assumption about
-        * what we have there. We'll do two loops most likely,
-        * but we'll get an ownership MESI transaction straight away
-        * instead of a read transaction followed by a
-        * flush-for-ownership transaction:
-        */
-       u64 old_val, real_val = 0;
-
-       do {
-               old_val = real_val;
-
-               real_val = atomic64_cmpxchg(ptr, old_val, new_val);
-
-       } while (real_val != old_val);
-
-       return old_val;
-}
-EXPORT_SYMBOL(atomic64_xchg);
-
-/**
- * atomic64_set - set atomic64 variable
- * @ptr:      pointer to type atomic64_t
- * @new_val:  value to assign
- *
- * Atomically sets the value of @ptr to @new_val.
- */
-void atomic64_set(atomic64_t *ptr, u64 new_val)
-{
-       atomic64_xchg(ptr, new_val);
-}
-EXPORT_SYMBOL(atomic64_set);
-
-/**
-EXPORT_SYMBOL(atomic64_read);
- * atomic64_add_return - add and return
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr and returns @delta + *@ptr
- */
-noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr)
-{
-       /*
-        * Try first with a (possibly incorrect) assumption about
-        * what we have there. We'll do two loops most likely,
-        * but we'll get an ownership MESI transaction straight away
-        * instead of a read transaction followed by a
-        * flush-for-ownership transaction:
-        */
-       u64 old_val, new_val, real_val = 0;
-
-       do {
-               old_val = real_val;
-               new_val = old_val + delta;
-
-               real_val = atomic64_cmpxchg(ptr, old_val, new_val);
-
-       } while (real_val != old_val);
-
-       return new_val;
-}
-EXPORT_SYMBOL(atomic64_add_return);
-
-u64 atomic64_sub_return(u64 delta, atomic64_t *ptr)
-{
-       return atomic64_add_return(-delta, ptr);
-}
-EXPORT_SYMBOL(atomic64_sub_return);
-
-u64 atomic64_inc_return(atomic64_t *ptr)
-{
-       return atomic64_add_return(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_inc_return);
-
-u64 atomic64_dec_return(atomic64_t *ptr)
-{
-       return atomic64_sub_return(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_dec_return);
-
-/**
- * atomic64_add - add integer to atomic64 variable
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr.
- */
-void atomic64_add(u64 delta, atomic64_t *ptr)
-{
-       atomic64_add_return(delta, ptr);
-}
-EXPORT_SYMBOL(atomic64_add);
-
-/**
- * atomic64_sub - subtract the atomic64 variable
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr.
- */
-void atomic64_sub(u64 delta, atomic64_t *ptr)
-{
-       atomic64_add(-delta, ptr);
-}
-EXPORT_SYMBOL(atomic64_sub);
-
-/**
- * atomic64_sub_and_test - subtract value from variable and test result
- * @delta: integer value to subtract
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically subtracts @delta from @ptr and returns
- * true if the result is zero, or false for all
- * other cases.
- */
-int atomic64_sub_and_test(u64 delta, atomic64_t *ptr)
-{
-       u64 new_val = atomic64_sub_return(delta, ptr);
-
-       return new_val == 0;
-}
-EXPORT_SYMBOL(atomic64_sub_and_test);
-
-/**
- * atomic64_inc - increment atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically increments @ptr by 1.
- */
-void atomic64_inc(atomic64_t *ptr)
-{
-       atomic64_add(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_inc);
-
-/**
- * atomic64_dec - decrement atomic64 variable
- * @ptr: pointer to type atomic64_t
- *
- * Atomically decrements @ptr by 1.
- */
-void atomic64_dec(atomic64_t *ptr)
-{
-       atomic64_sub(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_dec);
-
-/**
- * atomic64_dec_and_test - decrement and test
- * @ptr: pointer to type atomic64_t
- *
- * Atomically decrements @ptr by 1 and
- * returns true if the result is 0, or false for all other
- * cases.
- */
-int atomic64_dec_and_test(atomic64_t *ptr)
-{
-       return atomic64_sub_and_test(1, ptr);
-}
-EXPORT_SYMBOL(atomic64_dec_and_test);
-
-/**
- * atomic64_inc_and_test - increment and test
- * @ptr: pointer to type atomic64_t
- *
- * Atomically increments @ptr by 1
- * and returns true if the result is zero, or false for all
- * other cases.
- */
-int atomic64_inc_and_test(atomic64_t *ptr)
-{
-       return atomic64_sub_and_test(-1, ptr);
-}
-EXPORT_SYMBOL(atomic64_inc_and_test);
-
-/**
- * atomic64_add_negative - add and test if negative
- * @delta: integer value to add
- * @ptr:   pointer to type atomic64_t
- *
- * Atomically adds @delta to @ptr and returns true
- * if the result is negative, or false when
- * result is greater than or equal to zero.
- */
-int atomic64_add_negative(u64 delta, atomic64_t *ptr)
-{
-       s64 new_val = atomic64_add_return(delta, ptr);
-
-       return new_val < 0;
-}
-EXPORT_SYMBOL(atomic64_add_negative);
+long long atomic64_read_cx8(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_read_cx8);
+long long atomic64_set_cx8(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_set_cx8);
+long long atomic64_xchg_cx8(long long, unsigned high);
+EXPORT_SYMBOL(atomic64_xchg_cx8);
+long long atomic64_add_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_add_return_cx8);
+long long atomic64_sub_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_sub_return_cx8);
+long long atomic64_inc_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_return_cx8);
+long long atomic64_dec_return_cx8(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_return_cx8);
+long long atomic64_dec_if_positive_cx8(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_if_positive_cx8);
+int atomic64_inc_not_zero_cx8(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_not_zero_cx8);
+int atomic64_add_unless_cx8(atomic64_t *v, long long a, long long u);
+EXPORT_SYMBOL(atomic64_add_unless_cx8);
+
+#ifndef CONFIG_X86_CMPXCHG64
+long long atomic64_read_386(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_read_386);
+long long atomic64_set_386(long long, const atomic64_t *v);
+EXPORT_SYMBOL(atomic64_set_386);
+long long atomic64_xchg_386(long long, unsigned high);
+EXPORT_SYMBOL(atomic64_xchg_386);
+long long atomic64_add_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_add_return_386);
+long long atomic64_sub_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_sub_return_386);
+long long atomic64_inc_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_return_386);
+long long atomic64_dec_return_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_return_386);
+long long atomic64_add_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_add_386);
+long long atomic64_sub_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_sub_386);
+long long atomic64_inc_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_386);
+long long atomic64_dec_386(long long a, atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_386);
+long long atomic64_dec_if_positive_386(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_dec_if_positive_386);
+int atomic64_inc_not_zero_386(atomic64_t *v);
+EXPORT_SYMBOL(atomic64_inc_not_zero_386);
+int atomic64_add_unless_386(atomic64_t *v, long long a, long long u);
+EXPORT_SYMBOL(atomic64_add_unless_386);
+#endif
diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S
new file mode 100644 (file)
index 0000000..4a5979a
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * atomic64_t for 386/486
+ *
+ * Copyright Â© 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/alternative-asm.h>
+#include <asm/dwarf2.h>
+
+/* if you want SMP support, implement these with real spinlocks */
+.macro LOCK reg
+       pushfl
+       CFI_ADJUST_CFA_OFFSET 4
+       cli
+.endm
+
+.macro UNLOCK reg
+       popfl
+       CFI_ADJUST_CFA_OFFSET -4
+.endm
+
+.macro BEGIN func reg
+$v = \reg
+
+ENTRY(atomic64_\func\()_386)
+       CFI_STARTPROC
+       LOCK $v
+
+.macro RETURN
+       UNLOCK $v
+       ret
+.endm
+
+.macro END_
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_386)
+.purgem RETURN
+.purgem END_
+.purgem END
+.endm
+
+.macro END
+RETURN
+END_
+.endm
+.endm
+
+BEGIN read %ecx
+       movl  ($v), %eax
+       movl 4($v), %edx
+END
+
+BEGIN set %esi
+       movl %ebx,  ($v)
+       movl %ecx, 4($v)
+END
+
+BEGIN xchg %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       movl %ebx,  ($v)
+       movl %ecx, 4($v)
+END
+
+BEGIN add %ecx
+       addl %eax,  ($v)
+       adcl %edx, 4($v)
+END
+
+BEGIN add_return %ecx
+       addl  ($v), %eax
+       adcl 4($v), %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN sub %ecx
+       subl %eax,  ($v)
+       sbbl %edx, 4($v)
+END
+
+BEGIN sub_return %ecx
+       negl %edx
+       negl %eax
+       sbbl $0, %edx
+       addl  ($v), %eax
+       adcl 4($v), %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN inc %esi
+       addl $1,  ($v)
+       adcl $0, 4($v)
+END
+
+BEGIN inc_return %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       addl $1, %eax
+       adcl $0, %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN dec %esi
+       subl $1,  ($v)
+       sbbl $0, 4($v)
+END
+
+BEGIN dec_return %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       subl $1, %eax
+       sbbl $0, %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+END
+
+BEGIN add_unless %ecx
+       addl %eax, %esi
+       adcl %edx, %edi
+       addl  ($v), %eax
+       adcl 4($v), %edx
+       cmpl %eax, %esi
+       je 3f
+1:
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+       movl $1, %eax
+2:
+RETURN
+3:
+       cmpl %edx, %edi
+       jne 1b
+       xorl %eax, %eax
+       jmp 2b
+END_
+
+BEGIN inc_not_zero %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       testl %eax, %eax
+       je 3f
+1:
+       addl $1, %eax
+       adcl $0, %edx
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+       movl $1, %eax
+2:
+RETURN
+3:
+       testl %edx, %edx
+       jne 1b
+       jmp 2b
+END_
+
+BEGIN dec_if_positive %esi
+       movl  ($v), %eax
+       movl 4($v), %edx
+       subl $1, %eax
+       sbbl $0, %edx
+       js 1f
+       movl %eax,  ($v)
+       movl %edx, 4($v)
+1:
+END
diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S
new file mode 100644 (file)
index 0000000..71e080d
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * atomic64_t for 586+
+ *
+ * Copyright Â© 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/alternative-asm.h>
+#include <asm/dwarf2.h>
+
+.macro SAVE reg
+       pushl %\reg
+       CFI_ADJUST_CFA_OFFSET 4
+       CFI_REL_OFFSET \reg, 0
+.endm
+
+.macro RESTORE reg
+       popl %\reg
+       CFI_ADJUST_CFA_OFFSET -4
+       CFI_RESTORE \reg
+.endm
+
+.macro read64 reg
+       movl %ebx, %eax
+       movl %ecx, %edx
+/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */
+       LOCK_PREFIX
+       cmpxchg8b (\reg)
+.endm
+
+ENTRY(atomic64_read_cx8)
+       CFI_STARTPROC
+
+       read64 %ecx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_read_cx8)
+
+ENTRY(atomic64_set_cx8)
+       CFI_STARTPROC
+
+1:
+/* we don't need LOCK_PREFIX since aligned 64-bit writes
+ * are atomic on 586 and newer */
+       cmpxchg8b (%esi)
+       jne 1b
+
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_set_cx8)
+
+ENTRY(atomic64_xchg_cx8)
+       CFI_STARTPROC
+
+       movl %ebx, %eax
+       movl %ecx, %edx
+1:
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_xchg_cx8)
+
+.macro addsub_return func ins insc
+ENTRY(atomic64_\func\()_return_cx8)
+       CFI_STARTPROC
+       SAVE ebp
+       SAVE ebx
+       SAVE esi
+       SAVE edi
+
+       movl %eax, %esi
+       movl %edx, %edi
+       movl %ecx, %ebp
+
+       read64 %ebp
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       \ins\()l %esi, %ebx
+       \insc\()l %edi, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%ebp)
+       jne 1b
+
+10:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE edi
+       RESTORE esi
+       RESTORE ebx
+       RESTORE ebp
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_return_cx8)
+.endm
+
+addsub_return add add adc
+addsub_return sub sub sbb
+
+.macro incdec_return func ins insc
+ENTRY(atomic64_\func\()_return_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       \ins\()l $1, %ebx
+       \insc\()l $0, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+10:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE ebx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_\func\()_return_cx8)
+.endm
+
+incdec_return inc add adc
+incdec_return dec sub sbb
+
+ENTRY(atomic64_dec_if_positive_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       subl $1, %ebx
+       sbb $0, %ecx
+       js 2f
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+2:
+       movl %ebx, %eax
+       movl %ecx, %edx
+       RESTORE ebx
+       ret
+       CFI_ENDPROC
+ENDPROC(atomic64_dec_if_positive_cx8)
+
+ENTRY(atomic64_add_unless_cx8)
+       CFI_STARTPROC
+       SAVE ebp
+       SAVE ebx
+/* these just push these two parameters on the stack */
+       SAVE edi
+       SAVE esi
+
+       movl %ecx, %ebp
+       movl %eax, %esi
+       movl %edx, %edi
+
+       read64 %ebp
+1:
+       cmpl %eax, 0(%esp)
+       je 4f
+2:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       addl %esi, %ebx
+       adcl %edi, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%ebp)
+       jne 1b
+
+       movl $1, %eax
+3:
+       addl $8, %esp
+       CFI_ADJUST_CFA_OFFSET -8
+       RESTORE ebx
+       RESTORE ebp
+       ret
+4:
+       cmpl %edx, 4(%esp)
+       jne 2b
+       xorl %eax, %eax
+       jmp 3b
+       CFI_ENDPROC
+ENDPROC(atomic64_add_unless_cx8)
+
+ENTRY(atomic64_inc_not_zero_cx8)
+       CFI_STARTPROC
+       SAVE ebx
+
+       read64 %esi
+1:
+       testl %eax, %eax
+       je 4f
+2:
+       movl %eax, %ebx
+       movl %edx, %ecx
+       addl $1, %ebx
+       adcl $0, %ecx
+       LOCK_PREFIX
+       cmpxchg8b (%esi)
+       jne 1b
+
+       movl $1, %eax
+3:
+       RESTORE ebx
+       ret
+4:
+       testl %edx, %edx
+       jne 2b
+       jmp 3b
+       CFI_ENDPROC
+ENDPROC(atomic64_inc_not_zero_cx8)
index 15acecf..41fcf00 100644 (file)
@@ -60,7 +60,7 @@ ENTRY(call_rwsem_down_write_failed)
        ENDPROC(call_rwsem_down_write_failed)
 
 ENTRY(call_rwsem_wake)
-       decw %dx    /* do nothing if still outstanding active readers */
+       decl %edx       /* do nothing if still outstanding active readers */
        jnz 1f
        save_common_regs
        movq %rax,%rdi
index aa09870..dc8adad 100644 (file)
@@ -30,10 +30,10 @@ static void fclex(void)
 }
 
 /* Needs to be externally visible */
-void finit_task(struct task_struct *tsk)
+void finit_soft_fpu(struct i387_soft_struct *soft)
 {
-       struct i387_soft_struct *soft = &tsk->thread.xstate->soft;
        struct address *oaddr, *iaddr;
+       memset(soft, 0, sizeof(*soft));
        soft->cwd = 0x037f;
        soft->swd = 0;
        soft->ftop = 0; /* We don't keep top in the status word internally. */
@@ -52,7 +52,7 @@ void finit_task(struct task_struct *tsk)
 
 void finit(void)
 {
-       finit_task(current);
+       finit_soft_fpu(&current->thread.fpu.state->soft);
 }
 
 /*
index 5d87f58..7718541 100644 (file)
@@ -681,7 +681,7 @@ int fpregs_soft_set(struct task_struct *target,
                    unsigned int pos, unsigned int count,
                    const void *kbuf, const void __user *ubuf)
 {
-       struct i387_soft_struct *s387 = &target->thread.xstate->soft;
+       struct i387_soft_struct *s387 = &target->thread.fpu.state->soft;
        void *space = s387->st_space;
        int ret;
        int offset, other, i, tags, regnr, tag, newtop;
@@ -733,7 +733,7 @@ int fpregs_soft_get(struct task_struct *target,
                    unsigned int pos, unsigned int count,
                    void *kbuf, void __user *ubuf)
 {
-       struct i387_soft_struct *s387 = &target->thread.xstate->soft;
+       struct i387_soft_struct *s387 = &target->thread.fpu.state->soft;
        const void *space = s387->st_space;
        int ret;
        int offset = (S387->ftop & 7) * 10, other = 80 - offset;
index 50fa0ec..2c61441 100644 (file)
@@ -31,7 +31,7 @@
 #define SEG_EXPAND_DOWN(s)     (((s).b & ((1 << 11) | (1 << 10))) \
                                 == (1 << 10))
 
-#define I387                   (current->thread.xstate)
+#define I387                   (current->thread.fpu.state)
 #define FPU_info               (I387->soft.info)
 
 #define FPU_CS                 (*(unsigned short *) &(FPU_info->regs->cs))
index 06630d2..a4c7683 100644 (file)
@@ -6,6 +6,7 @@ nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_physaddr.o              := $(nostackp)
 CFLAGS_setup_nx.o              := $(nostackp)
 
+obj-$(CONFIG_X86_PAT)          += pat_rbtree.o
 obj-$(CONFIG_SMP)              += tlb.o
 
 obj-$(CONFIG_X86_32)           += pgtable_32.o iomap_32.o
index 5eb1ba7..12e4d2d 100644 (file)
@@ -448,6 +448,20 @@ static inline void __init early_clear_fixmap(enum fixed_addresses idx)
 static void __iomem *prev_map[FIX_BTMAPS_SLOTS] __initdata;
 static unsigned long prev_size[FIX_BTMAPS_SLOTS] __initdata;
 
+void __init fixup_early_ioremap(void)
+{
+       int i;
+
+       for (i = 0; i < FIX_BTMAPS_SLOTS; i++) {
+               if (prev_map[i]) {
+                       WARN_ON(1);
+                       break;
+               }
+       }
+
+       early_ioremap_init();
+}
+
 static int __init check_early_ioremap_leak(void)
 {
        int count = 0;
index edc8b95..bbe5502 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/pat.h>
 #include <asm/io.h>
 
+#include "pat_internal.h"
+
 #ifdef CONFIG_X86_PAT
 int __read_mostly pat_enabled = 1;
 
@@ -53,19 +55,15 @@ static inline void pat_disable(const char *reason)
 #endif
 
 
-static int debug_enable;
+int pat_debug_enable;
 
 static int __init pat_debug_setup(char *str)
 {
-       debug_enable = 1;
+       pat_debug_enable = 1;
        return 0;
 }
 __setup("debugpat", pat_debug_setup);
 
-#define dprintk(fmt, arg...) \
-       do { if (debug_enable) printk(KERN_INFO fmt, ##arg); } while (0)
-
-
 static u64 __read_mostly boot_pat_state;
 
 enum {
@@ -132,84 +130,7 @@ void pat_init(void)
 
 #undef PAT
 
-static char *cattr_name(unsigned long flags)
-{
-       switch (flags & _PAGE_CACHE_MASK) {
-       case _PAGE_CACHE_UC:            return "uncached";
-       case _PAGE_CACHE_UC_MINUS:      return "uncached-minus";
-       case _PAGE_CACHE_WB:            return "write-back";
-       case _PAGE_CACHE_WC:            return "write-combining";
-       default:                        return "broken";
-       }
-}
-
-/*
- * The global memtype list keeps track of memory type for specific
- * physical memory areas. Conflicting memory types in different
- * mappings can cause CPU cache corruption. To avoid this we keep track.
- *
- * The list is sorted based on starting address and can contain multiple
- * entries for each address (this allows reference counting for overlapping
- * areas). All the aliases have the same cache attributes of course.
- * Zero attributes are represented as holes.
- *
- * The data structure is a list that is also organized as an rbtree
- * sorted on the start address of memtype range.
- *
- * memtype_lock protects both the linear list and rbtree.
- */
-
-struct memtype {
-       u64                     start;
-       u64                     end;
-       unsigned long           type;
-       struct list_head        nd;
-       struct rb_node          rb;
-};
-
-static struct rb_root memtype_rbroot = RB_ROOT;
-static LIST_HEAD(memtype_list);
-static DEFINE_SPINLOCK(memtype_lock);  /* protects memtype list */
-
-static struct memtype *memtype_rb_search(struct rb_root *root, u64 start)
-{
-       struct rb_node *node = root->rb_node;
-       struct memtype *last_lower = NULL;
-
-       while (node) {
-               struct memtype *data = container_of(node, struct memtype, rb);
-
-               if (data->start < start) {
-                       last_lower = data;
-                       node = node->rb_right;
-               } else if (data->start > start) {
-                       node = node->rb_left;
-               } else
-                       return data;
-       }
-
-       /* Will return NULL if there is no entry with its start <= start */
-       return last_lower;
-}
-
-static void memtype_rb_insert(struct rb_root *root, struct memtype *data)
-{
-       struct rb_node **new = &(root->rb_node);
-       struct rb_node *parent = NULL;
-
-       while (*new) {
-               struct memtype *this = container_of(*new, struct memtype, rb);
-
-               parent = *new;
-               if (data->start <= this->start)
-                       new = &((*new)->rb_left);
-               else if (data->start > this->start)
-                       new = &((*new)->rb_right);
-       }
-
-       rb_link_node(&data->rb, parent, new);
-       rb_insert_color(&data->rb, root);
-}
+static DEFINE_SPINLOCK(memtype_lock);  /* protects memtype accesses */
 
 /*
  * Does intersection of PAT memory type and MTRR memory type and returns
@@ -237,33 +158,6 @@ static unsigned long pat_x_mtrr_type(u64 start, u64 end, unsigned long req_type)
        return req_type;
 }
 
-static int
-chk_conflict(struct memtype *new, struct memtype *entry, unsigned long *type)
-{
-       if (new->type != entry->type) {
-               if (type) {
-                       new->type = entry->type;
-                       *type = entry->type;
-               } else
-                       goto conflict;
-       }
-
-        /* check overlaps with more than one entry in the list */
-       list_for_each_entry_continue(entry, &memtype_list, nd) {
-               if (new->end <= entry->start)
-                       break;
-               else if (new->type != entry->type)
-                       goto conflict;
-       }
-       return 0;
-
- conflict:
-       printk(KERN_INFO "%s:%d conflicting memory types "
-              "%Lx-%Lx %s<->%s\n", current->comm, current->pid, new->start,
-              new->end, cattr_name(new->type), cattr_name(entry->type));
-       return -EBUSY;
-}
-
 static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
 {
        int ram_page = 0, not_rampage = 0;
@@ -296,8 +190,6 @@ static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
  * Here we do two pass:
  * - Find the memtype of all the pages in the range, look for any conflicts
  * - In case of no conflicts, set the new memtype for pages in the range
- *
- * Caller must hold memtype_lock for atomicity.
  */
 static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type,
                                  unsigned long *new_type)
@@ -364,9 +256,8 @@ static int free_ram_pages_type(u64 start, u64 end)
 int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                    unsigned long *new_type)
 {
-       struct memtype *new, *entry;
+       struct memtype *new;
        unsigned long actual_type;
-       struct list_head *where;
        int is_range_ram;
        int err = 0;
 
@@ -404,9 +295,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
        is_range_ram = pat_pagerange_is_ram(start, end);
        if (is_range_ram == 1) {
 
-               spin_lock(&memtype_lock);
                err = reserve_ram_pages_type(start, end, req_type, new_type);
-               spin_unlock(&memtype_lock);
 
                return err;
        } else if (is_range_ram < 0) {
@@ -423,42 +312,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
        spin_lock(&memtype_lock);
 
-       /* Search for existing mapping that overlaps the current range */
-       where = NULL;
-       list_for_each_entry(entry, &memtype_list, nd) {
-               if (end <= entry->start) {
-                       where = entry->nd.prev;
-                       break;
-               } else if (start <= entry->start) { /* end > entry->start */
-                       err = chk_conflict(new, entry, new_type);
-                       if (!err) {
-                               dprintk("Overlap at 0x%Lx-0x%Lx\n",
-                                       entry->start, entry->end);
-                               where = entry->nd.prev;
-                       }
-                       break;
-               } else if (start < entry->end) { /* start > entry->start */
-                       err = chk_conflict(new, entry, new_type);
-                       if (!err) {
-                               dprintk("Overlap at 0x%Lx-0x%Lx\n",
-                                       entry->start, entry->end);
-
-                               /*
-                                * Move to right position in the linked
-                                * list to add this new entry
-                                */
-                               list_for_each_entry_continue(entry,
-                                                       &memtype_list, nd) {
-                                       if (start <= entry->start) {
-                                               where = entry->nd.prev;
-                                               break;
-                                       }
-                               }
-                       }
-                       break;
-               }
-       }
-
+       err = rbt_memtype_check_insert(new, new_type);
        if (err) {
                printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, "
                       "track %s, req %s\n",
@@ -469,13 +323,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                return err;
        }
 
-       if (where)
-               list_add(&new->nd, where);
-       else
-               list_add_tail(&new->nd, &memtype_list);
-
-       memtype_rb_insert(&memtype_rbroot, new);
-
        spin_unlock(&memtype_lock);
 
        dprintk("reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n",
@@ -487,7 +334,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
 int free_memtype(u64 start, u64 end)
 {
-       struct memtype *entry, *saved_entry;
        int err = -EINVAL;
        int is_range_ram;
 
@@ -501,9 +347,7 @@ int free_memtype(u64 start, u64 end)
        is_range_ram = pat_pagerange_is_ram(start, end);
        if (is_range_ram == 1) {
 
-               spin_lock(&memtype_lock);
                err = free_ram_pages_type(start, end);
-               spin_unlock(&memtype_lock);
 
                return err;
        } else if (is_range_ram < 0) {
@@ -511,46 +355,7 @@ int free_memtype(u64 start, u64 end)
        }
 
        spin_lock(&memtype_lock);
-
-       entry = memtype_rb_search(&memtype_rbroot, start);
-       if (unlikely(entry == NULL))
-               goto unlock_ret;
-
-       /*
-        * Saved entry points to an entry with start same or less than what
-        * we searched for. Now go through the list in both directions to look
-        * for the entry that matches with both start and end, with list stored
-        * in sorted start address
-        */
-       saved_entry = entry;
-       list_for_each_entry_from(entry, &memtype_list, nd) {
-               if (entry->start == start && entry->end == end) {
-                       rb_erase(&entry->rb, &memtype_rbroot);
-                       list_del(&entry->nd);
-                       kfree(entry);
-                       err = 0;
-                       break;
-               } else if (entry->start > start) {
-                       break;
-               }
-       }
-
-       if (!err)
-               goto unlock_ret;
-
-       entry = saved_entry;
-       list_for_each_entry_reverse(entry, &memtype_list, nd) {
-               if (entry->start == start && entry->end == end) {
-                       rb_erase(&entry->rb, &memtype_rbroot);
-                       list_del(&entry->nd);
-                       kfree(entry);
-                       err = 0;
-                       break;
-               } else if (entry->start < start) {
-                       break;
-               }
-       }
-unlock_ret:
+       err = rbt_memtype_erase(start, end);
        spin_unlock(&memtype_lock);
 
        if (err) {
@@ -583,10 +388,8 @@ static unsigned long lookup_memtype(u64 paddr)
 
        if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) {
                struct page *page;
-               spin_lock(&memtype_lock);
                page = pfn_to_page(paddr >> PAGE_SHIFT);
                rettype = get_page_memtype(page);
-               spin_unlock(&memtype_lock);
                /*
                 * -1 from get_page_memtype() implies RAM page is in its
                 * default state and not reserved, and hence of type WB
@@ -599,7 +402,7 @@ static unsigned long lookup_memtype(u64 paddr)
 
        spin_lock(&memtype_lock);
 
-       entry = memtype_rb_search(&memtype_rbroot, paddr);
+       entry = rbt_memtype_lookup(paddr);
        if (entry != NULL)
                rettype = entry->type;
        else
@@ -936,29 +739,25 @@ EXPORT_SYMBOL_GPL(pgprot_writecombine);
 
 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_X86_PAT)
 
-/* get Nth element of the linked list */
 static struct memtype *memtype_get_idx(loff_t pos)
 {
-       struct memtype *list_node, *print_entry;
-       int i = 1;
+       struct memtype *print_entry;
+       int ret;
 
-       print_entry  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
+       print_entry  = kzalloc(sizeof(struct memtype), GFP_KERNEL);
        if (!print_entry)
                return NULL;
 
        spin_lock(&memtype_lock);
-       list_for_each_entry(list_node, &memtype_list, nd) {
-               if (pos == i) {
-                       *print_entry = *list_node;
-                       spin_unlock(&memtype_lock);
-                       return print_entry;
-               }
-               ++i;
-       }
+       ret = rbt_memtype_copy_nth_element(print_entry, pos);
        spin_unlock(&memtype_lock);
-       kfree(print_entry);
 
-       return NULL;
+       if (!ret) {
+               return print_entry;
+       } else {
+               kfree(print_entry);
+               return NULL;
+       }
 }
 
 static void *memtype_seq_start(struct seq_file *seq, loff_t *pos)
diff --git a/arch/x86/mm/pat_internal.h b/arch/x86/mm/pat_internal.h
new file mode 100644 (file)
index 0000000..4f39eef
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __PAT_INTERNAL_H_
+#define __PAT_INTERNAL_H_
+
+extern int pat_debug_enable;
+
+#define dprintk(fmt, arg...) \
+       do { if (pat_debug_enable) printk(KERN_INFO fmt, ##arg); } while (0)
+
+struct memtype {
+       u64                     start;
+       u64                     end;
+       u64                     subtree_max_end;
+       unsigned long           type;
+       struct rb_node          rb;
+};
+
+static inline char *cattr_name(unsigned long flags)
+{
+       switch (flags & _PAGE_CACHE_MASK) {
+       case _PAGE_CACHE_UC:            return "uncached";
+       case _PAGE_CACHE_UC_MINUS:      return "uncached-minus";
+       case _PAGE_CACHE_WB:            return "write-back";
+       case _PAGE_CACHE_WC:            return "write-combining";
+       default:                        return "broken";
+       }
+}
+
+#ifdef CONFIG_X86_PAT
+extern int rbt_memtype_check_insert(struct memtype *new,
+                                       unsigned long *new_type);
+extern int rbt_memtype_erase(u64 start, u64 end);
+extern struct memtype *rbt_memtype_lookup(u64 addr);
+extern int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos);
+#else
+static inline int rbt_memtype_check_insert(struct memtype *new,
+                                       unsigned long *new_type)
+{ return 0; }
+static inline int rbt_memtype_erase(u64 start, u64 end)
+{ return 0; }
+static inline struct memtype *rbt_memtype_lookup(u64 addr)
+{ return NULL; }
+static inline int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos)
+{ return 0; }
+#endif
+
+#endif /* __PAT_INTERNAL_H_ */
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
new file mode 100644 (file)
index 0000000..07de4cb
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Handle caching attributes in page tables (PAT)
+ *
+ * Authors: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *          Suresh B Siddha <suresh.b.siddha@intel.com>
+ *
+ * Interval tree (augmented rbtree) used to store the PAT memory type
+ * reservations.
+ */
+
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rbtree.h>
+#include <linux/sched.h>
+#include <linux/gfp.h>
+
+#include <asm/pgtable.h>
+#include <asm/pat.h>
+
+#include "pat_internal.h"
+
+/*
+ * The memtype tree keeps track of memory type for specific
+ * physical memory areas. Without proper tracking, conflicting memory
+ * types in different mappings can cause CPU cache corruption.
+ *
+ * The tree is an interval tree (augmented rbtree) with tree ordered
+ * on starting address. Tree can contain multiple entries for
+ * different regions which overlap. All the aliases have the same
+ * cache attributes of course.
+ *
+ * memtype_lock protects the rbtree.
+ */
+
+static void memtype_rb_augment_cb(struct rb_node *node);
+static struct rb_root memtype_rbroot = RB_AUGMENT_ROOT(&memtype_rb_augment_cb);
+
+static int is_node_overlap(struct memtype *node, u64 start, u64 end)
+{
+       if (node->start >= end || node->end <= start)
+               return 0;
+
+       return 1;
+}
+
+static u64 get_subtree_max_end(struct rb_node *node)
+{
+       u64 ret = 0;
+       if (node) {
+               struct memtype *data = container_of(node, struct memtype, rb);
+               ret = data->subtree_max_end;
+       }
+       return ret;
+}
+
+/* Update 'subtree_max_end' for a node, based on node and its children */
+static void update_node_max_end(struct rb_node *node)
+{
+       struct memtype *data;
+       u64 max_end, child_max_end;
+
+       if (!node)
+               return;
+
+       data = container_of(node, struct memtype, rb);
+       max_end = data->end;
+
+       child_max_end = get_subtree_max_end(node->rb_right);
+       if (child_max_end > max_end)
+               max_end = child_max_end;
+
+       child_max_end = get_subtree_max_end(node->rb_left);
+       if (child_max_end > max_end)
+               max_end = child_max_end;
+
+       data->subtree_max_end = max_end;
+}
+
+/* Update 'subtree_max_end' for a node and all its ancestors */
+static void update_path_max_end(struct rb_node *node)
+{
+       u64 old_max_end, new_max_end;
+
+       while (node) {
+               struct memtype *data = container_of(node, struct memtype, rb);
+
+               old_max_end = data->subtree_max_end;
+               update_node_max_end(node);
+               new_max_end = data->subtree_max_end;
+
+               if (new_max_end == old_max_end)
+                       break;
+
+               node = rb_parent(node);
+       }
+}
+
+/* Find the first (lowest start addr) overlapping range from rb tree */
+static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
+                               u64 start, u64 end)
+{
+       struct rb_node *node = root->rb_node;
+       struct memtype *last_lower = NULL;
+
+       while (node) {
+               struct memtype *data = container_of(node, struct memtype, rb);
+
+               if (get_subtree_max_end(node->rb_left) > start) {
+                       /* Lowest overlap if any must be on left side */
+                       node = node->rb_left;
+               } else if (is_node_overlap(data, start, end)) {
+                       last_lower = data;
+                       break;
+               } else if (start >= data->start) {
+                       /* Lowest overlap if any must be on right side */
+                       node = node->rb_right;
+               } else {
+                       break;
+               }
+       }
+       return last_lower; /* Returns NULL if there is no overlap */
+}
+
+static struct memtype *memtype_rb_exact_match(struct rb_root *root,
+                               u64 start, u64 end)
+{
+       struct memtype *match;
+
+       match = memtype_rb_lowest_match(root, start, end);
+       while (match != NULL && match->start < end) {
+               struct rb_node *node;
+
+               if (match->start == start && match->end == end)
+                       return match;
+
+               node = rb_next(&match->rb);
+               if (node)
+                       match = container_of(node, struct memtype, rb);
+               else
+                       match = NULL;
+       }
+
+       return NULL; /* Returns NULL if there is no exact match */
+}
+
+static int memtype_rb_check_conflict(struct rb_root *root,
+                               u64 start, u64 end,
+                               unsigned long reqtype, unsigned long *newtype)
+{
+       struct rb_node *node;
+       struct memtype *match;
+       int found_type = reqtype;
+
+       match = memtype_rb_lowest_match(&memtype_rbroot, start, end);
+       if (match == NULL)
+               goto success;
+
+       if (match->type != found_type && newtype == NULL)
+               goto failure;
+
+       dprintk("Overlap at 0x%Lx-0x%Lx\n", match->start, match->end);
+       found_type = match->type;
+
+       node = rb_next(&match->rb);
+       while (node) {
+               match = container_of(node, struct memtype, rb);
+
+               if (match->start >= end) /* Checked all possible matches */
+                       goto success;
+
+               if (is_node_overlap(match, start, end) &&
+                   match->type != found_type) {
+                       goto failure;
+               }
+
+               node = rb_next(&match->rb);
+       }
+success:
+       if (newtype)
+               *newtype = found_type;
+
+       return 0;
+
+failure:
+       printk(KERN_INFO "%s:%d conflicting memory types "
+               "%Lx-%Lx %s<->%s\n", current->comm, current->pid, start,
+               end, cattr_name(found_type), cattr_name(match->type));
+       return -EBUSY;
+}
+
+static void memtype_rb_augment_cb(struct rb_node *node)
+{
+       if (node)
+               update_path_max_end(node);
+}
+
+static void memtype_rb_insert(struct rb_root *root, struct memtype *newdata)
+{
+       struct rb_node **node = &(root->rb_node);
+       struct rb_node *parent = NULL;
+
+       while (*node) {
+               struct memtype *data = container_of(*node, struct memtype, rb);
+
+               parent = *node;
+               if (newdata->start <= data->start)
+                       node = &((*node)->rb_left);
+               else if (newdata->start > data->start)
+                       node = &((*node)->rb_right);
+       }
+
+       rb_link_node(&newdata->rb, parent, node);
+       rb_insert_color(&newdata->rb, root);
+}
+
+int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
+{
+       int err = 0;
+
+       err = memtype_rb_check_conflict(&memtype_rbroot, new->start, new->end,
+                                               new->type, ret_type);
+
+       if (!err) {
+               if (ret_type)
+                       new->type = *ret_type;
+
+               memtype_rb_insert(&memtype_rbroot, new);
+       }
+       return err;
+}
+
+int rbt_memtype_erase(u64 start, u64 end)
+{
+       struct memtype *data;
+
+       data = memtype_rb_exact_match(&memtype_rbroot, start, end);
+       if (!data)
+               return -EINVAL;
+
+       rb_erase(&data->rb, &memtype_rbroot);
+       return 0;
+}
+
+struct memtype *rbt_memtype_lookup(u64 addr)
+{
+       struct memtype *data;
+       data = memtype_rb_lowest_match(&memtype_rbroot, addr, addr + PAGE_SIZE);
+       return data;
+}
+
+#if defined(CONFIG_DEBUG_FS)
+int rbt_memtype_copy_nth_element(struct memtype *out, loff_t pos)
+{
+       struct rb_node *node;
+       int i = 1;
+
+       node = rb_first(&memtype_rbroot);
+       while (node && pos != i) {
+               node = rb_next(node);
+               i++;
+       }
+
+       if (node) { /* pos == i */
+               struct memtype *this = container_of(node, struct memtype, rb);
+               *out = *this;
+               return 0;
+       } else {
+               return 1;
+       }
+}
+#endif
index 1a8faf0..7928540 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/e820.h>
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
+#include <asm/io.h>
 
 unsigned int __VMALLOC_RESERVE = 128 << 20;
 
@@ -128,6 +129,7 @@ static int __init parse_reservetop(char *arg)
 
        address = memparse(arg, &arg);
        reserve_top_address(address);
+       fixup_early_ioremap();
        return 0;
 }
 early_param("reservetop", parse_reservetop);
index 28c6876..f9897f7 100644 (file)
@@ -363,6 +363,54 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
        for (i = 0; i < MAX_NUMNODES; i++)
                cutoff_node(i, start, end);
 
+       /*
+        * Join together blocks on the same node, holes between
+        * which don't overlap with memory on other nodes.
+        */
+       for (i = 0; i < num_node_memblks; ++i) {
+               int j, k;
+
+               for (j = i + 1; j < num_node_memblks; ++j) {
+                       unsigned long start, end;
+
+                       if (memblk_nodeid[i] != memblk_nodeid[j])
+                               continue;
+                       start = min(node_memblk_range[i].end,
+                                   node_memblk_range[j].end);
+                       end = max(node_memblk_range[i].start,
+                                 node_memblk_range[j].start);
+                       for (k = 0; k < num_node_memblks; ++k) {
+                               if (memblk_nodeid[i] == memblk_nodeid[k])
+                                       continue;
+                               if (start < node_memblk_range[k].end &&
+                                   end > node_memblk_range[k].start)
+                                       break;
+                       }
+                       if (k < num_node_memblks)
+                               continue;
+                       start = min(node_memblk_range[i].start,
+                                   node_memblk_range[j].start);
+                       end = max(node_memblk_range[i].end,
+                                 node_memblk_range[j].end);
+                       printk(KERN_INFO "SRAT: Node %d "
+                              "[%Lx,%Lx) + [%Lx,%Lx) -> [%lx,%lx)\n",
+                              memblk_nodeid[i],
+                              node_memblk_range[i].start,
+                              node_memblk_range[i].end,
+                              node_memblk_range[j].start,
+                              node_memblk_range[j].end,
+                              start, end);
+                       node_memblk_range[i].start = start;
+                       node_memblk_range[i].end = end;
+                       k = --num_node_memblks - j;
+                       memmove(memblk_nodeid + j, memblk_nodeid + j+1,
+                               k * sizeof(*memblk_nodeid));
+                       memmove(node_memblk_range + j, node_memblk_range + j+1,
+                               k * sizeof(*node_memblk_range));
+                       --j;
+               }
+       }
+
        memnode_shift = compute_hash_shift(node_memblk_range, num_node_memblks,
                                           memblk_nodeid);
        if (memnode_shift < 0) {
@@ -461,7 +509,8 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
                 * node, it must now point to the fake node ID.
                 */
                for (j = 0; j < MAX_LOCAL_APIC; j++)
-                       if (apicid_to_node[j] == nid)
+                       if (apicid_to_node[j] == nid &&
+                           fake_apicid_to_node[j] == NUMA_NO_NODE)
                                fake_apicid_to_node[j] = i;
        }
        for (i = 0; i < num_nodes; i++)
index 2c505ee..b28d2f1 100644 (file)
@@ -31,8 +31,9 @@ static struct op_x86_model_spec *model;
 static DEFINE_PER_CPU(struct op_msrs, cpu_msrs);
 static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
 
-/* 0 == registered but off, 1 == registered and on */
-static int nmi_enabled = 0;
+/* must be protected with get_online_cpus()/put_online_cpus(): */
+static int nmi_enabled;
+static int ctr_running;
 
 struct op_counter_config counter_config[OP_MAX_COUNTER];
 
@@ -61,12 +62,16 @@ static int profile_exceptions_notify(struct notifier_block *self,
 {
        struct die_args *args = (struct die_args *)data;
        int ret = NOTIFY_DONE;
-       int cpu = smp_processor_id();
 
        switch (val) {
        case DIE_NMI:
        case DIE_NMI_IPI:
-               model->check_ctrs(args->regs, &per_cpu(cpu_msrs, cpu));
+               if (ctr_running)
+                       model->check_ctrs(args->regs, &__get_cpu_var(cpu_msrs));
+               else if (!nmi_enabled)
+                       break;
+               else
+                       model->stop(&__get_cpu_var(cpu_msrs));
                ret = NOTIFY_STOP;
                break;
        default:
@@ -95,24 +100,36 @@ static void nmi_cpu_save_registers(struct op_msrs *msrs)
 static void nmi_cpu_start(void *dummy)
 {
        struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
-       model->start(msrs);
+       if (!msrs->controls)
+               WARN_ON_ONCE(1);
+       else
+               model->start(msrs);
 }
 
 static int nmi_start(void)
 {
+       get_online_cpus();
        on_each_cpu(nmi_cpu_start, NULL, 1);
+       ctr_running = 1;
+       put_online_cpus();
        return 0;
 }
 
 static void nmi_cpu_stop(void *dummy)
 {
        struct op_msrs const *msrs = &__get_cpu_var(cpu_msrs);
-       model->stop(msrs);
+       if (!msrs->controls)
+               WARN_ON_ONCE(1);
+       else
+               model->stop(msrs);
 }
 
 static void nmi_stop(void)
 {
+       get_online_cpus();
        on_each_cpu(nmi_cpu_stop, NULL, 1);
+       ctr_running = 0;
+       put_online_cpus();
 }
 
 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
@@ -252,7 +269,10 @@ static int nmi_switch_event(void)
        if (nmi_multiplex_on() < 0)
                return -EINVAL;         /* not necessary */
 
-       on_each_cpu(nmi_cpu_switch, NULL, 1);
+       get_online_cpus();
+       if (ctr_running)
+               on_each_cpu(nmi_cpu_switch, NULL, 1);
+       put_online_cpus();
 
        return 0;
 }
@@ -295,6 +315,7 @@ static void free_msrs(void)
                kfree(per_cpu(cpu_msrs, i).controls);
                per_cpu(cpu_msrs, i).controls = NULL;
        }
+       nmi_shutdown_mux();
 }
 
 static int allocate_msrs(void)
@@ -307,14 +328,21 @@ static int allocate_msrs(void)
                per_cpu(cpu_msrs, i).counters = kzalloc(counters_size,
                                                        GFP_KERNEL);
                if (!per_cpu(cpu_msrs, i).counters)
-                       return 0;
+                       goto fail;
                per_cpu(cpu_msrs, i).controls = kzalloc(controls_size,
                                                        GFP_KERNEL);
                if (!per_cpu(cpu_msrs, i).controls)
-                       return 0;
+                       goto fail;
        }
 
+       if (!nmi_setup_mux())
+               goto fail;
+
        return 1;
+
+fail:
+       free_msrs();
+       return 0;
 }
 
 static void nmi_cpu_setup(void *dummy)
@@ -336,49 +364,6 @@ static struct notifier_block profile_exceptions_nb = {
        .priority = 2
 };
 
-static int nmi_setup(void)
-{
-       int err = 0;
-       int cpu;
-
-       if (!allocate_msrs())
-               err = -ENOMEM;
-       else if (!nmi_setup_mux())
-               err = -ENOMEM;
-       else
-               err = register_die_notifier(&profile_exceptions_nb);
-
-       if (err) {
-               free_msrs();
-               nmi_shutdown_mux();
-               return err;
-       }
-
-       /* We need to serialize save and setup for HT because the subset
-        * of msrs are distinct for save and setup operations
-        */
-
-       /* Assume saved/restored counters are the same on all CPUs */
-       model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
-       for_each_possible_cpu(cpu) {
-               if (!cpu)
-                       continue;
-
-               memcpy(per_cpu(cpu_msrs, cpu).counters,
-                      per_cpu(cpu_msrs, 0).counters,
-                      sizeof(struct op_msr) * model->num_counters);
-
-               memcpy(per_cpu(cpu_msrs, cpu).controls,
-                      per_cpu(cpu_msrs, 0).controls,
-                      sizeof(struct op_msr) * model->num_controls);
-
-               mux_clone(cpu);
-       }
-       on_each_cpu(nmi_cpu_setup, NULL, 1);
-       nmi_enabled = 1;
-       return 0;
-}
-
 static void nmi_cpu_restore_registers(struct op_msrs *msrs)
 {
        struct op_msr *counters = msrs->counters;
@@ -412,20 +397,24 @@ static void nmi_cpu_shutdown(void *dummy)
        apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
        apic_write(APIC_LVTERR, v);
        nmi_cpu_restore_registers(msrs);
+       if (model->cpu_down)
+               model->cpu_down();
 }
 
-static void nmi_shutdown(void)
+static void nmi_cpu_up(void *dummy)
 {
-       struct op_msrs *msrs;
+       if (nmi_enabled)
+               nmi_cpu_setup(dummy);
+       if (ctr_running)
+               nmi_cpu_start(dummy);
+}
 
-       nmi_enabled = 0;
-       on_each_cpu(nmi_cpu_shutdown, NULL, 1);
-       unregister_die_notifier(&profile_exceptions_nb);
-       nmi_shutdown_mux();
-       msrs = &get_cpu_var(cpu_msrs);
-       model->shutdown(msrs);
-       free_msrs();
-       put_cpu_var(cpu_msrs);
+static void nmi_cpu_down(void *dummy)
+{
+       if (ctr_running)
+               nmi_cpu_stop(dummy);
+       if (nmi_enabled)
+               nmi_cpu_shutdown(dummy);
 }
 
 static int nmi_create_files(struct super_block *sb, struct dentry *root)
@@ -457,7 +446,6 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root)
        return 0;
 }
 
-#ifdef CONFIG_SMP
 static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
                                 void *data)
 {
@@ -465,10 +453,10 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
        switch (action) {
        case CPU_DOWN_FAILED:
        case CPU_ONLINE:
-               smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
+               smp_call_function_single(cpu, nmi_cpu_up, NULL, 0);
                break;
        case CPU_DOWN_PREPARE:
-               smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
+               smp_call_function_single(cpu, nmi_cpu_down, NULL, 1);
                break;
        }
        return NOTIFY_DONE;
@@ -477,7 +465,75 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
 static struct notifier_block oprofile_cpu_nb = {
        .notifier_call = oprofile_cpu_notifier
 };
-#endif
+
+static int nmi_setup(void)
+{
+       int err = 0;
+       int cpu;
+
+       if (!allocate_msrs())
+               return -ENOMEM;
+
+       /* We need to serialize save and setup for HT because the subset
+        * of msrs are distinct for save and setup operations
+        */
+
+       /* Assume saved/restored counters are the same on all CPUs */
+       err = model->fill_in_addresses(&per_cpu(cpu_msrs, 0));
+       if (err)
+               goto fail;
+
+       for_each_possible_cpu(cpu) {
+               if (!cpu)
+                       continue;
+
+               memcpy(per_cpu(cpu_msrs, cpu).counters,
+                      per_cpu(cpu_msrs, 0).counters,
+                      sizeof(struct op_msr) * model->num_counters);
+
+               memcpy(per_cpu(cpu_msrs, cpu).controls,
+                      per_cpu(cpu_msrs, 0).controls,
+                      sizeof(struct op_msr) * model->num_controls);
+
+               mux_clone(cpu);
+       }
+
+       nmi_enabled = 0;
+       ctr_running = 0;
+       barrier();
+       err = register_die_notifier(&profile_exceptions_nb);
+       if (err)
+               goto fail;
+
+       get_online_cpus();
+       register_cpu_notifier(&oprofile_cpu_nb);
+       on_each_cpu(nmi_cpu_setup, NULL, 1);
+       nmi_enabled = 1;
+       put_online_cpus();
+
+       return 0;
+fail:
+       free_msrs();
+       return err;
+}
+
+static void nmi_shutdown(void)
+{
+       struct op_msrs *msrs;
+
+       get_online_cpus();
+       unregister_cpu_notifier(&oprofile_cpu_nb);
+       on_each_cpu(nmi_cpu_shutdown, NULL, 1);
+       nmi_enabled = 0;
+       ctr_running = 0;
+       put_online_cpus();
+       barrier();
+       unregister_die_notifier(&profile_exceptions_nb);
+       msrs = &get_cpu_var(cpu_msrs);
+       model->shutdown(msrs);
+       free_msrs();
+       put_cpu_var(cpu_msrs);
+}
 
 #ifdef CONFIG_PM
 
@@ -687,9 +743,6 @@ int __init op_nmi_init(struct oprofile_operations *ops)
                return -ENODEV;
        }
 
-#ifdef CONFIG_SMP
-       register_cpu_notifier(&oprofile_cpu_nb);
-#endif
        /* default values, can be overwritten by model */
        ops->create_files       = nmi_create_files;
        ops->setup              = nmi_setup;
@@ -716,12 +769,6 @@ int __init op_nmi_init(struct oprofile_operations *ops)
 
 void op_nmi_exit(void)
 {
-       if (using_nmi) {
+       if (using_nmi)
                exit_sysfs();
-#ifdef CONFIG_SMP
-               unregister_cpu_notifier(&oprofile_cpu_nb);
-#endif
-       }
-       if (model->exit)
-               model->exit();
 }
index 090cbbe..b67a6b5 100644 (file)
 #include "op_counter.h"
 
 #define NUM_COUNTERS 4
-#define NUM_CONTROLS 4
 #ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
 #define NUM_VIRT_COUNTERS 32
-#define NUM_VIRT_CONTROLS 32
 #else
 #define NUM_VIRT_COUNTERS NUM_COUNTERS
-#define NUM_VIRT_CONTROLS NUM_CONTROLS
 #endif
 
 #define OP_EVENT_MASK                  0x0FFF
@@ -105,102 +102,6 @@ static u32 get_ibs_caps(void)
        return ibs_caps;
 }
 
-#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
-
-static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
-                              struct op_msrs const * const msrs)
-{
-       u64 val;
-       int i;
-
-       /* enable active counters */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               int virt = op_x86_phys_to_virt(i);
-               if (!reset_value[virt])
-                       continue;
-               rdmsrl(msrs->controls[i].addr, val);
-               val &= model->reserved;
-               val |= op_x86_get_ctrl(model, &counter_config[virt]);
-               wrmsrl(msrs->controls[i].addr, val);
-       }
-}
-
-#endif
-
-/* functions for op_amd_spec */
-
-static void op_amd_fill_in_addresses(struct op_msrs * const msrs)
-{
-       int i;
-
-       for (i = 0; i < NUM_COUNTERS; i++) {
-               if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
-                       msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
-       }
-
-       for (i = 0; i < NUM_CONTROLS; i++) {
-               if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
-                       msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
-       }
-}
-
-static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
-                             struct op_msrs const * const msrs)
-{
-       u64 val;
-       int i;
-
-       /* setup reset_value */
-       for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
-               if (counter_config[i].enabled
-                   && msrs->counters[op_x86_virt_to_phys(i)].addr)
-                       reset_value[i] = counter_config[i].count;
-               else
-                       reset_value[i] = 0;
-       }
-
-       /* clear all counters */
-       for (i = 0; i < NUM_CONTROLS; ++i) {
-               if (unlikely(!msrs->controls[i].addr)) {
-                       if (counter_config[i].enabled && !smp_processor_id())
-                               /*
-                                * counter is reserved, this is on all
-                                * cpus, so report only for cpu #0
-                                */
-                               op_x86_warn_reserved(i);
-                       continue;
-               }
-               rdmsrl(msrs->controls[i].addr, val);
-               if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
-                       op_x86_warn_in_use(i);
-               val &= model->reserved;
-               wrmsrl(msrs->controls[i].addr, val);
-       }
-
-       /* avoid a false detection of ctr overflows in NMI handler */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               if (unlikely(!msrs->counters[i].addr))
-                       continue;
-               wrmsrl(msrs->counters[i].addr, -1LL);
-       }
-
-       /* enable active counters */
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               int virt = op_x86_phys_to_virt(i);
-               if (!reset_value[virt])
-                       continue;
-
-               /* setup counter registers */
-               wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]);
-
-               /* setup control registers */
-               rdmsrl(msrs->controls[i].addr, val);
-               val &= model->reserved;
-               val |= op_x86_get_ctrl(model, &counter_config[virt]);
-               wrmsrl(msrs->controls[i].addr, val);
-       }
-}
-
 /*
  * 16-bit Linear Feedback Shift Register (LFSR)
  *
@@ -365,6 +266,125 @@ static void op_amd_stop_ibs(void)
                wrmsrl(MSR_AMD64_IBSOPCTL, 0);
 }
 
+#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
+
+static void op_mux_switch_ctrl(struct op_x86_model_spec const *model,
+                              struct op_msrs const * const msrs)
+{
+       u64 val;
+       int i;
+
+       /* enable active counters */
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               int virt = op_x86_phys_to_virt(i);
+               if (!reset_value[virt])
+                       continue;
+               rdmsrl(msrs->controls[i].addr, val);
+               val &= model->reserved;
+               val |= op_x86_get_ctrl(model, &counter_config[virt]);
+               wrmsrl(msrs->controls[i].addr, val);
+       }
+}
+
+#endif
+
+/* functions for op_amd_spec */
+
+static void op_amd_shutdown(struct op_msrs const * const msrs)
+{
+       int i;
+
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               if (!msrs->counters[i].addr)
+                       continue;
+               release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+               release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+       }
+}
+
+static int op_amd_fill_in_addresses(struct op_msrs * const msrs)
+{
+       int i;
+
+       for (i = 0; i < NUM_COUNTERS; i++) {
+               if (!reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
+                       goto fail;
+               if (!reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) {
+                       release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+                       goto fail;
+               }
+               /* both registers must be reserved */
+               msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
+               msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
+               continue;
+       fail:
+               if (!counter_config[i].enabled)
+                       continue;
+               op_x86_warn_reserved(i);
+               op_amd_shutdown(msrs);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static void op_amd_setup_ctrs(struct op_x86_model_spec const *model,
+                             struct op_msrs const * const msrs)
+{
+       u64 val;
+       int i;
+
+       /* setup reset_value */
+       for (i = 0; i < NUM_VIRT_COUNTERS; ++i) {
+               if (counter_config[i].enabled
+                   && msrs->counters[op_x86_virt_to_phys(i)].addr)
+                       reset_value[i] = counter_config[i].count;
+               else
+                       reset_value[i] = 0;
+       }
+
+       /* clear all counters */
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               if (!msrs->controls[i].addr)
+                       continue;
+               rdmsrl(msrs->controls[i].addr, val);
+               if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
+                       op_x86_warn_in_use(i);
+               val &= model->reserved;
+               wrmsrl(msrs->controls[i].addr, val);
+               /*
+                * avoid a false detection of ctr overflows in NMI
+                * handler
+                */
+               wrmsrl(msrs->counters[i].addr, -1LL);
+       }
+
+       /* enable active counters */
+       for (i = 0; i < NUM_COUNTERS; ++i) {
+               int virt = op_x86_phys_to_virt(i);
+               if (!reset_value[virt])
+                       continue;
+
+               /* setup counter registers */
+               wrmsrl(msrs->counters[i].addr, -(u64)reset_value[virt]);
+
+               /* setup control registers */
+               rdmsrl(msrs->controls[i].addr, val);
+               val &= model->reserved;
+               val |= op_x86_get_ctrl(model, &counter_config[virt]);
+               wrmsrl(msrs->controls[i].addr, val);
+       }
+
+       if (ibs_caps)
+               setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
+}
+
+static void op_amd_cpu_shutdown(void)
+{
+       if (ibs_caps)
+               setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
+}
+
 static int op_amd_check_ctrs(struct pt_regs * const regs,
                             struct op_msrs const * const msrs)
 {
@@ -425,42 +445,16 @@ static void op_amd_stop(struct op_msrs const * const msrs)
        op_amd_stop_ibs();
 }
 
-static void op_amd_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < NUM_COUNTERS; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
-       }
-       for (i = 0; i < NUM_CONTROLS; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
-       }
-}
-
-static u8 ibs_eilvt_off;
-
-static inline void apic_init_ibs_nmi_per_cpu(void *arg)
-{
-       ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_NMI, 0);
-}
-
-static inline void apic_clear_ibs_nmi_per_cpu(void *arg)
-{
-       setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
-}
-
-static int init_ibs_nmi(void)
+static int __init_ibs_nmi(void)
 {
 #define IBSCTL_LVTOFFSETVAL            (1 << 8)
 #define IBSCTL                         0x1cc
        struct pci_dev *cpu_cfg;
        int nodes;
        u32 value = 0;
+       u8 ibs_eilvt_off;
 
-       /* per CPU setup */
-       on_each_cpu(apic_init_ibs_nmi_per_cpu, NULL, 1);
+       ibs_eilvt_off = setup_APIC_eilvt_ibs(0, APIC_EILVT_MSG_FIX, 1);
 
        nodes = 0;
        cpu_cfg = NULL;
@@ -490,22 +484,15 @@ static int init_ibs_nmi(void)
        return 0;
 }
 
-/* uninitialize the APIC for the IBS interrupts if needed */
-static void clear_ibs_nmi(void)
-{
-       if (ibs_caps)
-               on_each_cpu(apic_clear_ibs_nmi_per_cpu, NULL, 1);
-}
-
 /* initialize the APIC for the IBS interrupts if available */
-static void ibs_init(void)
+static void init_ibs(void)
 {
        ibs_caps = get_ibs_caps();
 
        if (!ibs_caps)
                return;
 
-       if (init_ibs_nmi()) {
+       if (__init_ibs_nmi()) {
                ibs_caps = 0;
                return;
        }
@@ -514,14 +501,6 @@ static void ibs_init(void)
               (unsigned)ibs_caps);
 }
 
-static void ibs_exit(void)
-{
-       if (!ibs_caps)
-               return;
-
-       clear_ibs_nmi();
-}
-
 static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
 
 static int setup_ibs_files(struct super_block *sb, struct dentry *root)
@@ -570,27 +549,22 @@ static int setup_ibs_files(struct super_block *sb, struct dentry *root)
 
 static int op_amd_init(struct oprofile_operations *ops)
 {
-       ibs_init();
+       init_ibs();
        create_arch_files = ops->create_files;
        ops->create_files = setup_ibs_files;
        return 0;
 }
 
-static void op_amd_exit(void)
-{
-       ibs_exit();
-}
-
 struct op_x86_model_spec op_amd_spec = {
        .num_counters           = NUM_COUNTERS,
-       .num_controls           = NUM_CONTROLS,
+       .num_controls           = NUM_COUNTERS,
        .num_virt_counters      = NUM_VIRT_COUNTERS,
        .reserved               = MSR_AMD_EVENTSEL_RESERVED,
        .event_mask             = OP_EVENT_MASK,
        .init                   = op_amd_init,
-       .exit                   = op_amd_exit,
        .fill_in_addresses      = &op_amd_fill_in_addresses,
        .setup_ctrs             = &op_amd_setup_ctrs,
+       .cpu_down               = &op_amd_cpu_shutdown,
        .check_ctrs             = &op_amd_check_ctrs,
        .start                  = &op_amd_start,
        .stop                   = &op_amd_stop,
index e6a160a..182558d 100644 (file)
@@ -385,8 +385,26 @@ static unsigned int get_stagger(void)
 
 static unsigned long reset_value[NUM_COUNTERS_NON_HT];
 
+static void p4_shutdown(struct op_msrs const * const msrs)
+{
+       int i;
 
-static void p4_fill_in_addresses(struct op_msrs * const msrs)
+       for (i = 0; i < num_counters; ++i) {
+               if (msrs->counters[i].addr)
+                       release_perfctr_nmi(msrs->counters[i].addr);
+       }
+       /*
+        * some of the control registers are specially reserved in
+        * conjunction with the counter registers (hence the starting offset).
+        * This saves a few bits.
+        */
+       for (i = num_counters; i < num_controls; ++i) {
+               if (msrs->controls[i].addr)
+                       release_evntsel_nmi(msrs->controls[i].addr);
+       }
+}
+
+static int p4_fill_in_addresses(struct op_msrs * const msrs)
 {
        unsigned int i;
        unsigned int addr, cccraddr, stag;
@@ -468,6 +486,18 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
                        msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
                }
        }
+
+       for (i = 0; i < num_counters; ++i) {
+               if (!counter_config[i].enabled)
+                       continue;
+               if (msrs->controls[i].addr)
+                       continue;
+               op_x86_warn_reserved(i);
+               p4_shutdown(msrs);
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
 
@@ -668,26 +698,6 @@ static void p4_stop(struct op_msrs const * const msrs)
        }
 }
 
-static void p4_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(msrs->counters[i].addr);
-       }
-       /*
-        * some of the control registers are specially reserved in
-        * conjunction with the counter registers (hence the starting offset).
-        * This saves a few bits.
-        */
-       for (i = num_counters; i < num_controls; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(msrs->controls[i].addr);
-       }
-}
-
-
 #ifdef CONFIG_SMP
 struct op_x86_model_spec op_p4_ht2_spec = {
        .num_counters           = NUM_COUNTERS_HT2,
index 2bf90fa..d769cda 100644 (file)
@@ -30,19 +30,46 @@ static int counter_width = 32;
 
 static u64 *reset_value;
 
-static void ppro_fill_in_addresses(struct op_msrs * const msrs)
+static void ppro_shutdown(struct op_msrs const * const msrs)
 {
        int i;
 
-       for (i = 0; i < num_counters; i++) {
-               if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
-                       msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
+       for (i = 0; i < num_counters; ++i) {
+               if (!msrs->counters[i].addr)
+                       continue;
+               release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
+               release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
+       }
+       if (reset_value) {
+               kfree(reset_value);
+               reset_value = NULL;
        }
+}
+
+static int ppro_fill_in_addresses(struct op_msrs * const msrs)
+{
+       int i;
 
        for (i = 0; i < num_counters; i++) {
-               if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
-                       msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
+               if (!reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
+                       goto fail;
+               if (!reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) {
+                       release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
+                       goto fail;
+               }
+               /* both registers must be reserved */
+               msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
+               msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
+               continue;
+       fail:
+               if (!counter_config[i].enabled)
+                       continue;
+               op_x86_warn_reserved(i);
+               ppro_shutdown(msrs);
+               return -EBUSY;
        }
+
+       return 0;
 }
 
 
@@ -78,26 +105,17 @@ static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
 
        /* clear all counters */
        for (i = 0; i < num_counters; ++i) {
-               if (unlikely(!msrs->controls[i].addr)) {
-                       if (counter_config[i].enabled && !smp_processor_id())
-                               /*
-                                * counter is reserved, this is on all
-                                * cpus, so report only for cpu #0
-                                */
-                               op_x86_warn_reserved(i);
+               if (!msrs->controls[i].addr)
                        continue;
-               }
                rdmsrl(msrs->controls[i].addr, val);
                if (val & ARCH_PERFMON_EVENTSEL_ENABLE)
                        op_x86_warn_in_use(i);
                val &= model->reserved;
                wrmsrl(msrs->controls[i].addr, val);
-       }
-
-       /* avoid a false detection of ctr overflows in NMI handler */
-       for (i = 0; i < num_counters; ++i) {
-               if (unlikely(!msrs->counters[i].addr))
-                       continue;
+               /*
+                * avoid a false detection of ctr overflows in NMI *
+                * handler
+                */
                wrmsrl(msrs->counters[i].addr, -1LL);
        }
 
@@ -189,25 +207,6 @@ static void ppro_stop(struct op_msrs const * const msrs)
        }
 }
 
-static void ppro_shutdown(struct op_msrs const * const msrs)
-{
-       int i;
-
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->counters[i].addr)
-                       release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
-       }
-       for (i = 0; i < num_counters; ++i) {
-               if (msrs->controls[i].addr)
-                       release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
-       }
-       if (reset_value) {
-               kfree(reset_value);
-               reset_value = NULL;
-       }
-}
-
-
 struct op_x86_model_spec op_ppro_spec = {
        .num_counters           = 2,
        .num_controls           = 2,
@@ -239,11 +238,11 @@ static void arch_perfmon_setup_counters(void)
        if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 &&
                current_cpu_data.x86_model == 15) {
                eax.split.version_id = 2;
-               eax.split.num_events = 2;
+               eax.split.num_counters = 2;
                eax.split.bit_width = 40;
        }
 
-       num_counters = eax.split.num_events;
+       num_counters = eax.split.num_counters;
 
        op_arch_perfmon_spec.num_counters = num_counters;
        op_arch_perfmon_spec.num_controls = num_counters;
index ff82a75..89017fa 100644 (file)
@@ -40,10 +40,10 @@ struct op_x86_model_spec {
        u64             reserved;
        u16             event_mask;
        int             (*init)(struct oprofile_operations *ops);
-       void            (*exit)(void);
-       void            (*fill_in_addresses)(struct op_msrs * const msrs);
+       int             (*fill_in_addresses)(struct op_msrs * const msrs);
        void            (*setup_ctrs)(struct op_x86_model_spec const *model,
                                      struct op_msrs const * const msrs);
+       void            (*cpu_down)(void);
        int             (*check_ctrs)(struct pt_regs * const regs,
                                      struct op_msrs const * const msrs);
        void            (*start)(struct op_msrs const * const msrs);
index c7b1ebf..31930fd 100644 (file)
@@ -66,14 +66,44 @@ resource_to_addr(struct acpi_resource *resource,
                        struct acpi_resource_address64 *addr)
 {
        acpi_status status;
-
-       status = acpi_resource_to_address64(resource, addr);
-       if (ACPI_SUCCESS(status) &&
-           (addr->resource_type == ACPI_MEMORY_RANGE ||
-           addr->resource_type == ACPI_IO_RANGE) &&
-           addr->address_length > 0 &&
-           addr->producer_consumer == ACPI_PRODUCER) {
+       struct acpi_resource_memory24 *memory24;
+       struct acpi_resource_memory32 *memory32;
+       struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+       memset(addr, 0, sizeof(*addr));
+       switch (resource->type) {
+       case ACPI_RESOURCE_TYPE_MEMORY24:
+               memory24 = &resource->data.memory24;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = memory24->minimum;
+               addr->address_length = memory24->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_MEMORY32:
+               memory32 = &resource->data.memory32;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = memory32->minimum;
+               addr->address_length = memory32->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
                return AE_OK;
+       case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+               fixed_memory32 = &resource->data.fixed_memory32;
+               addr->resource_type = ACPI_MEMORY_RANGE;
+               addr->minimum = fixed_memory32->address;
+               addr->address_length = fixed_memory32->address_length;
+               addr->maximum = addr->minimum + addr->address_length - 1;
+               return AE_OK;
+       case ACPI_RESOURCE_TYPE_ADDRESS16:
+       case ACPI_RESOURCE_TYPE_ADDRESS32:
+       case ACPI_RESOURCE_TYPE_ADDRESS64:
+               status = acpi_resource_to_address64(resource, addr);
+               if (ACPI_SUCCESS(status) &&
+                   (addr->resource_type == ACPI_MEMORY_RANGE ||
+                   addr->resource_type == ACPI_IO_RANGE) &&
+                   addr->address_length > 0) {
+                       return AE_OK;
+               }
+               break;
        }
        return AE_ERROR;
 }
@@ -91,30 +121,6 @@ count_resource(struct acpi_resource *acpi_res, void *data)
        return AE_OK;
 }
 
-static void
-align_resource(struct acpi_device *bridge, struct resource *res)
-{
-       int align = (res->flags & IORESOURCE_MEM) ? 16 : 4;
-
-       /*
-        * Host bridge windows are not BARs, but the decoders on the PCI side
-        * that claim this address space have starting alignment and length
-        * constraints, so fix any obvious BIOS goofs.
-        */
-       if (!IS_ALIGNED(res->start, align)) {
-               dev_printk(KERN_DEBUG, &bridge->dev,
-                          "host bridge window %pR invalid; "
-                          "aligning start to %d-byte boundary\n", res, align);
-               res->start &= ~(align - 1);
-       }
-       if (!IS_ALIGNED(res->end + 1, align)) {
-               dev_printk(KERN_DEBUG, &bridge->dev,
-                          "host bridge window %pR invalid; "
-                          "aligning end to %d-byte boundary\n", res, align);
-               res->end = ALIGN(res->end, align) - 1;
-       }
-}
-
 static acpi_status
 setup_resource(struct acpi_resource *acpi_res, void *data)
 {
@@ -124,7 +130,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        acpi_status status;
        unsigned long flags;
        struct resource *root, *conflict;
-       u64 start, end, max_len;
+       u64 start, end;
 
        status = resource_to_addr(acpi_res, &addr);
        if (!ACPI_SUCCESS(status))
@@ -141,19 +147,8 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        } else
                return AE_OK;
 
-       max_len = addr.maximum - addr.minimum + 1;
-       if (addr.address_length > max_len) {
-               dev_printk(KERN_DEBUG, &info->bridge->dev,
-                          "host bridge window length %#llx doesn't fit in "
-                          "%#llx-%#llx, trimming\n",
-                          (unsigned long long) addr.address_length,
-                          (unsigned long long) addr.minimum,
-                          (unsigned long long) addr.maximum);
-               addr.address_length = max_len;
-       }
-
        start = addr.minimum + addr.translation_offset;
-       end = start + addr.address_length - 1;
+       end = addr.maximum + addr.translation_offset;
 
        res = &info->res[info->res_num];
        res->name = info->name;
@@ -161,7 +156,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
        res->start = start;
        res->end = end;
        res->child = NULL;
-       align_resource(info->bridge, res);
 
        if (!pci_use_crs) {
                dev_printk(KERN_DEBUG, &info->bridge->dev,
index 46fd43f..97da2ba 100644 (file)
@@ -72,6 +72,9 @@ pcibios_align_resource(void *data, const struct resource *res,
                        return start;
                if (start & 0x300)
                        start = (start + 0x3ff) & ~0x3ff;
+       } else if (res->flags & IORESOURCE_MEM) {
+               if (start < BIOS_END)
+                       start = BIOS_END;
        }
        return start;
 }
index 8bf2fcb..7ef3a27 100644 (file)
@@ -109,7 +109,7 @@ static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
                        decode++;
                        decode = ~(decode - 1);
                } else {
-                       decode = ~0;
+                       decode = 0;
                }
 
                /*
@@ -247,6 +247,10 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
        u32 size;
        int i;
 
+       /* Must have extended configuration space */
+       if (dev->cfg_size < PCIE_CAP_OFFSET + 4)
+               return;
+
        /* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
        offset = fixed_bar_cap(dev->bus, dev->devfn);
        if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
index 32764b8..b3c6c59 100644 (file)
@@ -476,6 +476,7 @@ void xen_timer_resume(void)
 __init void xen_time_init(void)
 {
        int cpu = smp_processor_id();
+       struct timespec tp;
 
        clocksource_register(&xen_clocksource);
 
@@ -487,9 +488,8 @@ __init void xen_time_init(void)
        }
 
        /* Set initial system time with full resolution */
-       xen_read_wallclock(&xtime);
-       set_normalized_timespec(&wall_to_monotonic,
-                               -xtime.tv_sec, -xtime.tv_nsec);
+       xen_read_wallclock(&tp);
+       do_settimeofday(&tp);
 
        setup_force_cpu_cap(X86_FEATURE_TSC);
 
index 22d6dde..a96a061 100644 (file)
@@ -46,7 +46,7 @@
  *
  * Atomically reads the value of @v.
  */
-#define atomic_read(v)         ((v)->counter)
+#define atomic_read(v)         (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
index 19f7df3..19df764 100644 (file)
@@ -60,11 +60,6 @@ static struct irqaction timer_irqaction = {
 
 void __init time_init(void)
 {
-       /* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */
-       read_persistent_clock(&xtime);
-       set_normalized_timespec(&wall_to_monotonic,
-               -xtime.tv_sec, -xtime.tv_nsec);
-
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
        printk("Calibrating CPU frequency ");
        platform_calibrate_ccount();
index 5fe03de..2cc682b 100644 (file)
@@ -286,16 +286,16 @@ done:
 static struct cgroup_subsys_state *
 blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup)
 {
-       struct blkio_cgroup *blkcg, *parent_blkcg;
+       struct blkio_cgroup *blkcg;
+       struct cgroup *parent = cgroup->parent;
 
-       if (!cgroup->parent) {
+       if (!parent) {
                blkcg = &blkio_root_cgroup;
                goto done;
        }
 
        /* Currently we do not support hierarchy deeper than two level (0,1) */
-       parent_blkcg = cgroup_to_blkio_cgroup(cgroup->parent);
-       if (css_depth(&parent_blkcg->css) > 0)
+       if (parent != cgroup->top_cgroup)
                return ERR_PTR(-EINVAL);
 
        blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL);
index 1ba7e0a..4f0c06c 100644 (file)
@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data)
        struct request_queue *q = (struct request_queue *) data;
        unsigned long flags, next = 0;
        struct request *rq, *tmp;
+       int next_set = 0;
 
        spin_lock_irqsave(q->queue_lock, flags);
 
@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data)
                        if (blk_mark_rq_complete(rq))
                                continue;
                        blk_rq_timed_out(rq);
-               } else if (!next || time_after(next, rq->deadline))
+               } else if (!next_set || time_after(next, rq->deadline)) {
                        next = rq->deadline;
+                       next_set = 1;
+               }
        }
 
-       /*
-        * next can never be 0 here with the list non-empty, since we always
-        * bump ->deadline to 1 so we can detect if the timer was ever added
-        * or not. See comment in blk_add_timer()
-        */
-       if (next)
+       if (next_set)
                mod_timer(&q->timeout, round_jiffies_up(next));
 
        spin_unlock_irqrestore(q->queue_lock, flags);
index 838834b..5f127cf 100644 (file)
@@ -3694,8 +3694,10 @@ static void *cfq_init_queue(struct request_queue *q)
         * to make sure that cfq_put_cfqg() does not try to kfree root group
         */
        atomic_set(&cfqg->ref, 1);
+       rcu_read_lock();
        blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg, (void *)cfqd,
                                        0);
+       rcu_read_unlock();
 #endif
        /*
         * Not strictly needed (since RB_ROOT just clears the node and we
index 943f2ab..ce038d8 100644 (file)
@@ -324,6 +324,7 @@ struct dma_async_tx_descriptor *
 async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
                        struct page **blocks, struct async_submit_ctl *submit)
 {
+       void *scribble = submit->scribble;
        int non_zero_srcs, i;
 
        BUG_ON(faila == failb);
@@ -332,11 +333,13 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
 
        pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
 
-       /* we need to preserve the contents of 'blocks' for the async
-        * case, so punt to synchronous if a scribble buffer is not available
+       /* if a dma resource is not available or a scribble buffer is not
+        * available punt to the synchronous path.  In the 'dma not
+        * available' case be sure to use the scribble buffer to
+        * preserve the content of 'blocks' as the caller intended.
         */
-       if (!submit->scribble) {
-               void **ptrs = (void **) blocks;
+       if (!async_dma_find_channel(DMA_PQ) || !scribble) {
+               void **ptrs = scribble ? scribble : (void **) blocks;
 
                async_tx_quiesce(&submit->depend_tx);
                for (i = 0; i < disks; i++)
@@ -406,11 +409,13 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
 
        pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
 
-       /* we need to preserve the contents of 'blocks' for the async
-        * case, so punt to synchronous if a scribble buffer is not available
+       /* if a dma resource is not available or a scribble buffer is not
+        * available punt to the synchronous path.  In the 'dma not
+        * available' case be sure to use the scribble buffer to
+        * preserve the content of 'blocks' as the caller intended.
         */
-       if (!scribble) {
-               void **ptrs = (void **) blocks;
+       if (!async_dma_find_channel(DMA_PQ) || !scribble) {
+               void **ptrs = scribble ? scribble : (void **) blocks;
 
                async_tx_quiesce(&submit->depend_tx);
                for (i = 0; i < disks; i++)
index 2bb7348..05eb32e 100644 (file)
@@ -46,6 +46,12 @@ struct authenc_request_ctx {
        char tail[];
 };
 
+static void authenc_request_complete(struct aead_request *req, int err)
+{
+       if (err != -EINPROGRESS)
+               aead_request_complete(req, err);
+}
+
 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
                                 unsigned int keylen)
 {
@@ -142,7 +148,7 @@ static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq,
                                 crypto_aead_authsize(authenc), 1);
 
 out:
-       aead_request_complete(req, err);
+       authenc_request_complete(req, err);
 }
 
 static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int err)
@@ -208,7 +214,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
        err = crypto_ablkcipher_decrypt(abreq);
 
 out:
-       aead_request_complete(req, err);
+       authenc_request_complete(req, err);
 }
 
 static void authenc_verify_ahash_done(struct crypto_async_request *areq,
@@ -245,7 +251,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
        err = crypto_ablkcipher_decrypt(abreq);
 
 out:
-       aead_request_complete(req, err);
+       authenc_request_complete(req, err);
 }
 
 static u8 *crypto_authenc_ahash_fb(struct aead_request *req, unsigned int flags)
@@ -379,7 +385,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
                err = crypto_authenc_genicv(areq, iv, 0);
        }
 
-       aead_request_complete(areq, err);
+       authenc_request_complete(areq, err);
 }
 
 static int crypto_authenc_encrypt(struct aead_request *req)
@@ -420,7 +426,7 @@ static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
                err = crypto_authenc_genicv(areq, greq->giv, 0);
        }
 
-       aead_request_complete(areq, err);
+       authenc_request_complete(areq, err);
 }
 
 static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
index 34f1e10..f42a030 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_SFI)             += sfi/
 obj-$(CONFIG_PNP)              += pnp/
 obj-$(CONFIG_ARM_AMBA)         += amba/
 
+obj-$(CONFIG_VIRTIO)           += virtio/
 obj-$(CONFIG_XEN)              += xen/
 
 # regulators early, since some subsystems rely on them to initialize
@@ -108,7 +109,6 @@ obj-$(CONFIG_PPC_PS3)               += ps3/
 obj-$(CONFIG_OF)               += of/
 obj-$(CONFIG_SSB)              += ssb/
 obj-$(CONFIG_VHOST_NET)                += vhost/
-obj-$(CONFIG_VIRTIO)           += virtio/
 obj-$(CONFIG_VLYNQ)            += vlynq/
 obj-$(CONFIG_STAGING)          += staging/
 obj-y                          += platform/
index 19dacfd..6212213 100644 (file)
@@ -31,7 +31,7 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define ACPI_PROCESSOR_AGGREGATOR_CLASS        "processor_aggregator"
+#define ACPI_PROCESSOR_AGGREGATOR_CLASS        "acpi_pad"
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
 #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
 static DEFINE_MUTEX(isolated_cpus_lock);
index a610ebe..2fbfe51 100644 (file)
@@ -471,13 +471,18 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
                /* allow full data read from EC address space */
                if (obj_desc->field.region_obj->region.space_id ==
                        ACPI_ADR_SPACE_EC) {
-                       if (obj_desc->common_field.bit_length > 8)
-                               obj_desc->common_field.access_bit_width =
-                               ACPI_ROUND_UP(obj_desc->common_field.
-                                                       bit_length, 8);
+                       if (obj_desc->common_field.bit_length > 8) {
+                               unsigned width =
+                                       ACPI_ROUND_BITS_UP_TO_BYTES(
+                                       obj_desc->common_field.bit_length);
+                               // access_bit_width is u8, don't overflow it
+                               if (width > 8)
+                                       width = 8;
                                obj_desc->common_field.access_byte_width =
-                               ACPI_DIV_8(obj_desc->common_field.
-                                                       access_bit_width);
+                                                       width;
+                               obj_desc->common_field.access_bit_width =
+                                                       8 * width;
+                       }
                }
 
                ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
index 37132dc..743576b 100644 (file)
@@ -527,7 +527,7 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id,
        if (!event_is_open)
                return 0;
 
-       event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
+       event = kzalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC);
        if (!event)
                return -ENOMEM;
 
index 4bb18c9..1c527a1 100644 (file)
@@ -123,6 +123,10 @@ int acpi_hest_firmware_first_pci(struct pci_dev *pci)
 {
        acpi_status status = AE_NOT_FOUND;
        struct acpi_table_header *hest = NULL;
+
+       if (acpi_disabled)
+               return 0;
+
        status = acpi_get_table(ACPI_SIG_HEST, 1, &hest);
 
        if (ACPI_SUCCESS(status)) {
index b0a71ec..e4804fb 100644 (file)
@@ -401,11 +401,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
         * driver reported one, then use it. Exit in any case.
         */
        if (gsi < 0) {
+               u32 dev_gsi;
                dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
                /* Interrupt Line values above 0xF are forbidden */
-               if (dev->irq > 0 && (dev->irq <= 0xF)) {
-                       printk(" - using IRQ %d\n", dev->irq);
-                       acpi_register_gsi(&dev->dev, dev->irq,
+               if (dev->irq > 0 && (dev->irq <= 0xF) &&
+                   (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+                       printk(" - using ISA IRQ %d\n", dev->irq);
+                       acpi_register_gsi(&dev->dev, dev_gsi,
                                          ACPI_LEVEL_SENSITIVE,
                                          ACPI_ACTIVE_LOW);
                        return 0;
index e8c32a4..66f6729 100644 (file)
@@ -35,7 +35,7 @@
 #define ACPI_POWER_METER_NAME          "power_meter"
 ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
 #define ACPI_POWER_METER_DEVICE_NAME   "Power Meter"
-#define ACPI_POWER_METER_CLASS         "power_meter_resource"
+#define ACPI_POWER_METER_CLASS         "pwr_meter_resource"
 
 #define NUM_SENSORS                    17
 
index 36704b8..f8be23b 100644 (file)
@@ -18,7 +18,7 @@
 
 #define PREFIX "ACPI: "
 
-#define ACPI_SMB_HC_CLASS      "smbus_host_controller"
+#define ACPI_SMB_HC_CLASS      "smbus_host_ctl"
 #define ACPI_SMB_HC_DEVICE_NAME        "ACPI SMBus HC"
 
 struct acpi_smb_hc {
index f74834a..baa76bb 100644 (file)
@@ -450,6 +450,38 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                },
        },
        {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad T410",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T410"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad T510",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T510"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad W510",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W510"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Lenovo ThinkPad X201[s]",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+               DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201"),
+               },
+       },
+       {
        .callback = init_old_suspend_ordering,
        .ident = "Panasonic CF51-2L",
        .matches = {
@@ -458,6 +490,30 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
                },
        },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Dell Studio 1558",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1558"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Dell Studio 1557",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1557"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Dell Studio 1555",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Studio 1555"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index 9f6cfac..228740f 100644 (file)
@@ -879,6 +879,8 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain)
 void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
+       struct request_queue *q = qc->scsicmd->device->request_queue;
+       unsigned long flags;
 
        WARN_ON(!ap->ops->error_handler);
 
@@ -890,7 +892,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
         * Note that ATA_QCFLAG_FAILED is unconditionally set after
         * this function completes.
         */
+       spin_lock_irqsave(q->queue_lock, flags);
        blk_abort_request(qc->scsicmd->request);
+       spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
 /**
@@ -1624,6 +1628,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
        }
 
        /* okay, this error is ours */
+       memset(&tf, 0, sizeof(tf));
        rc = ata_eh_read_log_10h(dev, &tag, &tf);
        if (rc) {
                ata_link_printk(link, KERN_ERR, "failed to read log page 10h "
index 3c3172d..d94b8f0 100644 (file)
@@ -424,6 +424,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
        PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
        PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
        PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -444,6 +446,8 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
        PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
        PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
        PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
index 8ad4ffe..6e6b6a1 100644 (file)
@@ -80,20 +80,6 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
 }
 EXPORT_SYMBOL_GPL(iommu_detach_device);
 
-int iommu_map_range(struct iommu_domain *domain, unsigned long iova,
-                   phys_addr_t paddr, size_t size, int prot)
-{
-       return iommu_ops->map(domain, iova, paddr, size, prot);
-}
-EXPORT_SYMBOL_GPL(iommu_map_range);
-
-void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova,
-                     size_t size)
-{
-       iommu_ops->unmap(domain, iova, size);
-}
-EXPORT_SYMBOL_GPL(iommu_unmap_range);
-
 phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
                               unsigned long iova)
 {
@@ -107,3 +93,32 @@ int iommu_domain_has_cap(struct iommu_domain *domain,
        return iommu_ops->domain_has_cap(domain, cap);
 }
 EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
+
+int iommu_map(struct iommu_domain *domain, unsigned long iova,
+             phys_addr_t paddr, int gfp_order, int prot)
+{
+       unsigned long invalid_mask;
+       size_t size;
+
+       size         = 0x1000UL << gfp_order;
+       invalid_mask = size - 1;
+
+       BUG_ON((iova | paddr) & invalid_mask);
+
+       return iommu_ops->map(domain, iova, paddr, gfp_order, prot);
+}
+EXPORT_SYMBOL_GPL(iommu_map);
+
+int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)
+{
+       unsigned long invalid_mask;
+       size_t size;
+
+       size         = 0x1000UL << gfp_order;
+       invalid_mask = size - 1;
+
+       BUG_ON(iova & invalid_mask);
+
+       return iommu_ops->unmap(domain, iova, gfp_order);
+}
+EXPORT_SYMBOL_GPL(iommu_unmap);
index 4b4b565..765bcf0 100644 (file)
@@ -187,7 +187,7 @@ EXPORT_SYMBOL_GPL(platform_device_alloc);
  * released.
  */
 int platform_device_add_resources(struct platform_device *pdev,
-                                 struct resource *res, unsigned int num)
+                                 const struct resource *res, unsigned int num)
 {
        struct resource *r;
 
@@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
  */
 struct platform_device *platform_device_register_simple(const char *name,
                                                        int id,
-                                                       struct resource *res,
+                                                       const struct resource *res,
                                                        unsigned int num)
 {
        struct platform_device *pdev;
@@ -1254,6 +1254,26 @@ static int __init early_platform_driver_probe_id(char *class_str,
                }
 
                if (match) {
+                       /*
+                        * Set up a sensible init_name to enable
+                        * dev_name() and others to be used before the
+                        * rest of the driver core is initialized.
+                        */
+                       if (!match->dev.init_name && slab_is_available()) {
+                               if (match->id != -1)
+                                       match->dev.init_name =
+                                               kasprintf(GFP_KERNEL, "%s.%d",
+                                                         match->name,
+                                                         match->id);
+                               else
+                                       match->dev.init_name =
+                                               kasprintf(GFP_KERNEL, "%s",
+                                                         match->name);
+
+                               if (!match->dev.init_name)
+                                       return -ENOMEM;
+                       }
+
                        if (epdrv->pdrv->probe(match))
                                pr_warning("%s: unable to probe %s early.\n",
                                           class_str, match->name);
index 0182a22..832798a 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
@@ -1696,34 +1697,18 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
        return get_disk(unit[drive].gendisk);
 }
 
-static int __init amiga_floppy_init(void)
+static int __init amiga_floppy_probe(struct platform_device *pdev)
 {
        int i, ret;
 
-       if (!MACH_IS_AMIGA)
-               return -ENODEV;
-
-       if (!AMIGAHW_PRESENT(AMI_FLOPPY))
-               return -ENODEV;
-
        if (register_blkdev(FLOPPY_MAJOR,"fd"))
                return -EBUSY;
 
-       /*
-        *  We request DSKPTR, DSKLEN and DSKDATA only, because the other
-        *  floppy registers are too spreaded over the custom register space
-        */
-       ret = -EBUSY;
-       if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {
-               printk("fd: cannot get floppy registers\n");
-               goto out_blkdev;
-       }
-
        ret = -ENOMEM;
        if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
            NULL) {
                printk("fd: cannot get chip mem buffer\n");
-               goto out_memregion;
+               goto out_blkdev;
        }
 
        ret = -EBUSY;
@@ -1792,18 +1777,13 @@ out_irq2:
        free_irq(IRQ_AMIGA_DSKBLK, NULL);
 out_irq:
        amiga_chip_free(raw_buf);
-out_memregion:
-       release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
 out_blkdev:
        unregister_blkdev(FLOPPY_MAJOR,"fd");
        return ret;
 }
 
-module_init(amiga_floppy_init);
-#ifdef MODULE
-
 #if 0 /* not safe to unload */
-void cleanup_module(void)
+static int __exit amiga_floppy_remove(struct platform_device *pdev)
 {
        int i;
 
@@ -1820,12 +1800,25 @@ void cleanup_module(void)
        custom.dmacon = DMAF_DISK; /* disable DMA */
        amiga_chip_free(raw_buf);
        blk_cleanup_queue(floppy_queue);
-       release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
        unregister_blkdev(FLOPPY_MAJOR, "fd");
 }
 #endif
 
-#else
+static struct platform_driver amiga_floppy_driver = {
+       .driver   = {
+               .name   = "amiga-floppy",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init amiga_floppy_init(void)
+{
+       return platform_driver_probe(&amiga_floppy_driver, amiga_floppy_probe);
+}
+
+module_init(amiga_floppy_init);
+
+#ifndef MODULE
 static int __init amiga_floppy_setup (char *str)
 {
        int n;
@@ -1840,3 +1833,5 @@ static int __init amiga_floppy_setup (char *str)
 
 __setup("floppy=", amiga_floppy_setup);
 #endif
+
+MODULE_ALIAS("platform:amiga-floppy");
index 67e0fc5..93d1f9b 100644 (file)
@@ -1695,6 +1695,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
                        cf |= CF_DRY_RUN;
                else {
                        dev_err(DEV, "--dry-run is not supported by peer");
+                       kfree(p);
                        return 0;
                }
        }
index ed9f1de..3f096e7 100644 (file)
@@ -899,7 +899,8 @@ retry:
 
        drbd_thread_start(&mdev->asender);
 
-       drbd_send_protocol(mdev);
+       if (!drbd_send_protocol(mdev))
+               return -1;
        drbd_send_sync_param(mdev, &mdev->sync_conf);
        drbd_send_sizes(mdev, 0);
        drbd_send_uuids(mdev);
index 44bf6d1..d48a1df 100644 (file)
@@ -235,7 +235,7 @@ void drbd_endio_pri(struct bio *bio, int error)
        if (unlikely(error)) {
                what = (bio_data_dir(bio) == WRITE)
                        ? write_completed_with_error
-                       : (bio_rw(bio) == READA)
+                       : (bio_rw(bio) == READ)
                          ? read_completed_with_error
                          : read_ahead_completed_with_error;
        } else
index 034e6df..81c78b3 100644 (file)
@@ -164,12 +164,12 @@ unsigned long read_timer(void)
        unsigned long t, flags;
        int i;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        t = jiffies * 11932;
        outb_p(0, 0x43);
        i = inb_p(0x40);
        i |= inb(0x40) << 8;
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
        return(t - i);
 }
 #endif
index ddf1942..8a549db 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/compat.h>
 #include <linux/kthread.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
@@ -2984,7 +2985,7 @@ static void pkt_get_status(struct pkt_ctrl_command *ctrl_cmd)
        mutex_unlock(&ctl_mutex);
 }
 
-static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long pkt_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        struct pkt_ctrl_command ctrl_cmd;
@@ -3021,10 +3022,20 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
+static long pkt_ctl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       return pkt_ctl_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
 
 static const struct file_operations pkt_ctl_fops = {
-       .ioctl   = pkt_ctl_ioctl,
-       .owner   = THIS_MODULE,
+       .open           = nonseekable_open,
+       .unlocked_ioctl = pkt_ctl_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl   = pkt_ctl_compat_ioctl,
+#endif
+       .owner          = THIS_MODULE,
 };
 
 static struct miscdevice pkt_misc = {
index d41331b..aa4248e 100644 (file)
@@ -1817,8 +1817,6 @@ static int intel_845_configure(void)
        pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
        /* clear any possible error conditions */
        pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
-
-       intel_i830_setup_flush();
        return 0;
 }
 
@@ -2188,7 +2186,6 @@ static const struct agp_bridge_driver intel_845_driver = {
        .agp_destroy_page       = agp_generic_destroy_page,
        .agp_destroy_pages      = agp_generic_destroy_pages,
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
-       .chipset_flush          = intel_i830_chipset_flush,
 };
 
 static const struct agp_bridge_driver intel_850_driver = {
index fc8cf7a..4cd8b22 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/seq_file.h>
 #include <linux/dmi.h>
 #include <linux/capability.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -82,8 +83,7 @@ module_param(fan_mult, int, 0);
 MODULE_PARM_DESC(fan_mult, "Factor to multiply fan speed with");
 
 static int i8k_open_fs(struct inode *inode, struct file *file);
-static int i8k_ioctl(struct inode *, struct file *, unsigned int,
-                    unsigned long);
+static long i8k_ioctl(struct file *, unsigned int, unsigned long);
 
 static const struct file_operations i8k_fops = {
        .owner          = THIS_MODULE,
@@ -91,7 +91,7 @@ static const struct file_operations i8k_fops = {
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
-       .ioctl          = i8k_ioctl,
+       .unlocked_ioctl = i8k_ioctl,
 };
 
 struct smm_regs {
@@ -307,8 +307,8 @@ static int i8k_get_dell_signature(int req_fn)
        return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
 }
 
-static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-                    unsigned long arg)
+static int
+i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
 {
        int val = 0;
        int speed;
@@ -395,6 +395,17 @@ static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
        return 0;
 }
 
+static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+       long ret;
+
+       lock_kernel();
+       ret = i8k_ioctl_unlocked(fp, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 /*
  * Print the information for /proc/i8k.
  */
index 0fa2e4a..c1ab303 100644 (file)
@@ -879,8 +879,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
        if (tport == NULL)
                return -ENODEV;
        port = container_of(tport, struct isi_port, port);
-       card = &isi_card[BOARD(tty->index)];
 
+       tty->driver_data = port;
        return tty_port_open(tport, tty, filp);
 }
 
@@ -936,7 +936,12 @@ static void isicom_shutdown(struct tty_port *port)
 static void isicom_close(struct tty_struct *tty, struct file *filp)
 {
        struct isi_port *ip = tty->driver_data;
-       struct tty_port *port = &ip->port;
+       struct tty_port *port;
+
+       if (ip == NULL)
+               return;
+
+       port = &ip->port;
        if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
                return;
        tty_port_close(port, tty, filp);
index 4cd6c52..4e395c9 100644 (file)
@@ -827,6 +827,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
                return -ENODEV;
        if (portp->devnr < 1)
                return -ENODEV;
+
+       tty->driver_data = portp;
        return tty_port_open(&portp->port, tty, filp);
 }
 
index 4702305..d2692d4 100644 (file)
@@ -1011,6 +1011,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
        if (!info->ioaddr)
                return -ENODEV;
 
+       tty->driver_data = info;
        return tty_port_open(&info->port, tty, filp);
 }
 
@@ -1074,7 +1075,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
        struct mxser_port *info = tty->driver_data;
        struct tty_port *port = &info->port;
 
-       if (tty->index == MXSER_PORTS)
+       if (tty->index == MXSER_PORTS || info == NULL)
                return;
        if (tty_port_close_start(port, tty, filp) == 0)
                return;
index c9bc896..90b199f 100644 (file)
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
 
        xoutb(0, REG_FLAGS1(iobase));   /* clear detectCMM */
        /* last check before exit */
-       if (!io_detect_cm4000(iobase, dev))
-               count = -ENODEV;
+       if (!io_detect_cm4000(iobase, dev)) {
+               rc = -ENODEV;
+               goto release_io;
+       }
 
        if (test_bit(IS_INVREV, &dev->flags) && count > 0)
                str_invert_revert(dev->rbuf, count);
 
        if (copy_to_user(buf, dev->rbuf, count))
-               return -EFAULT;
+               rc = -EFAULT;
 
 release_io:
        clear_bit(LOCK_IO, &dev->flags);
index 0a8d1e5..b02332a 100644 (file)
@@ -909,6 +909,7 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
        if (error)
                return error;
 
+       tty->driver_data = port;
        return tty_port_open(&port->port, tty, filp);
 }
 
index 8dfd247..78a62eb 100644 (file)
@@ -627,7 +627,6 @@ static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
        char data;
        int char_count;
        int save_cnt;
-       int len;
 
        /* determine the channel and change to that context */
        channel = (u_short) (base_addr[CyLICR] >> 2);
@@ -1528,7 +1527,6 @@ static int
 cy_ioctl(struct tty_struct *tty, struct file *file,
         unsigned int cmd, unsigned long arg)
 {
-       unsigned long val;
        struct cyclades_port *info = tty->driver_data;
        int ret_val = 0;
        void __user *argp = (void __user *)arg;
index 0e511d6..6049fd7 100644 (file)
@@ -724,7 +724,6 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
 {
        struct stlport  *portp;
        struct stlbrd   *brdp;
-       struct tty_port *port;
        unsigned int    minordev, brdnr, panelnr;
        int             portnr;
 
@@ -754,7 +753,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
        portp = brdp->panels[panelnr]->ports[portnr];
        if (portp == NULL)
                return -ENODEV;
-       port = &portp->port;
+
+       tty->driver_data = portp;
        return tty_port_open(&portp->port, tty, filp);
 
 }
@@ -841,7 +841,8 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
        pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp);
 
        portp = tty->driver_data;
-       BUG_ON(portp == NULL);
+       if(portp == NULL)
+               return;
        tty_port_close(&portp->port, tty, filp);
 }
 
index 59de252..d4e8b21 100644 (file)
@@ -289,7 +289,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = {
 
 static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
 {
-       ftrace_dump();
+       ftrace_dump(DUMP_ALL);
 }
 static struct sysrq_key_op sysrq_ftrace_dump_op = {
        .handler        = sysrq_ftrace_dump,
index f5fc64f..4dc338f 100644 (file)
@@ -17,14 +17,16 @@ menuconfig TCG_TPM
          obtained at: <http://sourceforge.net/projects/trousers>.  To 
          compile this driver as a module, choose M here; the module 
          will be called tpm. If unsure, say N.
-         Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
+         Notes:
+         1) For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
          and CONFIG_PNPACPI.
+         2) Without ACPI enabled, the BIOS event log won't be accessible,
+         which is required to validate the PCR 0-7 values.
 
 if TCG_TPM
 
 config TCG_TIS
        tristate "TPM Interface Specification 1.2 Interface"
-       depends on PNP
        ---help---
          If you have a TPM security chip that is compliant with the
          TCG TIS 1.2 TPM specification say Yes and it will be accessible
index 068c816..05ad4a1 100644 (file)
@@ -1068,6 +1068,27 @@ void tpm_remove_hardware(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(tpm_remove_hardware);
 
+#define TPM_ORD_SAVESTATE cpu_to_be32(152)
+#define SAVESTATE_RESULT_SIZE 10
+
+static struct tpm_input_header savestate_header = {
+       .tag = TPM_TAG_RQU_COMMAND,
+       .length = cpu_to_be32(10),
+       .ordinal = TPM_ORD_SAVESTATE
+};
+
+/* Bug workaround - some TPM's don't flush the most
+ * recently changed pcr on suspend, so force the flush
+ * with an extend to the selected _unused_ non-volatile pcr.
+ */
+static int tpm_suspend_pcr;
+static int __init tpm_suspend_setup(char *str)
+{
+       get_option(&str, &tpm_suspend_pcr);
+       return 1;
+}
+__setup("tpm_suspend_pcr=", tpm_suspend_setup);
+
 /*
  * We are about to suspend. Save the TPM state
  * so that it can be restored.
@@ -1075,17 +1096,29 @@ EXPORT_SYMBOL_GPL(tpm_remove_hardware);
 int tpm_pm_suspend(struct device *dev, pm_message_t pm_state)
 {
        struct tpm_chip *chip = dev_get_drvdata(dev);
-       u8 savestate[] = {
-               0, 193,         /* TPM_TAG_RQU_COMMAND */
-               0, 0, 0, 10,    /* blob length (in bytes) */
-               0, 0, 0, 152    /* TPM_ORD_SaveState */
-       };
+       struct tpm_cmd_t cmd;
+       int rc;
+
+       u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
 
        if (chip == NULL)
                return -ENODEV;
 
-       tpm_transmit(chip, savestate, sizeof(savestate));
-       return 0;
+       /* for buggy tpm, flush pcrs with extend to selected dummy */
+       if (tpm_suspend_pcr) {
+               cmd.header.in = pcrextend_header;
+               cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
+               memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
+                      TPM_DIGEST_SIZE);
+               rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
+                                 "extending dummy pcr before suspend");
+       }
+
+       /* now do the actual savestate */
+       cmd.header.in = savestate_header;
+       rc = transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE,
+                         "sending savestate before suspend");
+       return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_pm_suspend);
 
index 9434599..24314a9 100644 (file)
@@ -598,7 +598,7 @@ out_err:
        tpm_remove_hardware(chip->dev);
        return rc;
 }
-
+#ifdef CONFIG_PNP
 static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
                                      const struct pnp_device_id *pnp_id)
 {
@@ -663,7 +663,7 @@ static struct pnp_driver tis_pnp_driver = {
 module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
                    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-
+#endif
 static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
 {
        return tpm_pm_suspend(&dev->dev, msg);
@@ -690,21 +690,21 @@ MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
 static int __init init_tis(void)
 {
        int rc;
+#ifdef CONFIG_PNP
+       if (!force)
+               return pnp_register_driver(&tis_pnp_driver);
+#endif
 
-       if (force) {
-               rc = platform_driver_register(&tis_drv);
-               if (rc < 0)
-                       return rc;
-               if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
-                       return PTR_ERR(pdev);
-               if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
-                       platform_device_unregister(pdev);
-                       platform_driver_unregister(&tis_drv);
-               }
+       rc = platform_driver_register(&tis_drv);
+       if (rc < 0)
                return rc;
+       if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
+               return PTR_ERR(pdev);
+       if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
+               platform_device_unregister(pdev);
+               platform_driver_unregister(&tis_drv);
        }
-
-       return pnp_register_driver(&tis_pnp_driver);
+       return rc;
 }
 
 static void __exit cleanup_tis(void)
@@ -728,12 +728,14 @@ static void __exit cleanup_tis(void)
                list_del(&i->list);
        }
        spin_unlock(&tis_lock);
-
-       if (force) {
-               platform_device_unregister(pdev);
-               platform_driver_unregister(&tis_drv);
-       } else
+#ifdef CONFIG_PNP
+       if (!force) {
                pnp_unregister_driver(&tis_pnp_driver);
+               return;
+       }
+#endif
+       platform_device_unregister(pdev);
+       platform_driver_unregister(&tis_drv);
 }
 
 module_init(init_tis);
index 6da962c..d71f0fc 100644 (file)
@@ -1875,6 +1875,7 @@ got_driver:
                 */
                if (filp->f_op == &hung_up_tty_fops)
                        filp->f_op = &tty_fops;
+               unlock_kernel();
                goto retry_open;
        }
        unlock_kernel();
index b314a99..d7be69f 100644 (file)
@@ -154,14 +154,14 @@ static int __init cs5535_mfgpt_init(void)
        if (cs5535_mfgpt_setup_irq(timer, MFGPT_CMP2, &timer_irq)) {
                printk(KERN_ERR DRV_NAME ": Could not set up IRQ %d\n",
                                timer_irq);
-               return -EIO;
+               goto err_timer;
        }
 
        /* And register it with the kernel */
        ret = setup_irq(timer_irq, &mfgptirq);
        if (ret) {
                printk(KERN_ERR DRV_NAME ": Unable to set up the interrupt.\n");
-               goto err;
+               goto err_irq;
        }
 
        /* Set the clock scale and enable the event mode for CMP2 */
@@ -184,8 +184,10 @@ static int __init cs5535_mfgpt_init(void)
 
        return 0;
 
-err:
+err_irq:
        cs5535_mfgpt_release_irq(cs5535_event_clock, MFGPT_CMP2, &timer_irq);
+err_timer:
+       cs5535_mfgpt_free_timer(cs5535_event_clock);
        printk(KERN_ERR DRV_NAME ": Unable to set up the MFGPT clock source\n");
        return -EIO;
 }
index 744f748..f6677cb 100644 (file)
@@ -150,13 +150,12 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
 
 static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
 {
-       struct sh_timer_config *cfg = p->pdev->dev.platform_data;
        int ret;
 
        /* enable clock */
        ret = clk_enable(p->clk);
        if (ret) {
-               pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
+               dev_err(&p->pdev->dev, "cannot enable clock\n");
                return ret;
        }
 
@@ -279,7 +278,7 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
                        delay = 1;
 
                if (!delay)
-                       pr_warning("sh_cmt: too long delay\n");
+                       dev_warn(&p->pdev->dev, "too long delay\n");
 
        } while (delay);
 }
@@ -289,7 +288,7 @@ static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
        unsigned long flags;
 
        if (delta > p->max_match_value)
-               pr_warning("sh_cmt: delta out of range\n");
+               dev_warn(&p->pdev->dev, "delta out of range\n");
 
        spin_lock_irqsave(&p->lock, flags);
        p->next_match_value = delta;
@@ -451,7 +450,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p,
        cs->resume = sh_cmt_clocksource_resume;
        cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
        cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
-       pr_info("sh_cmt: %s used as clock source\n", cs->name);
+       dev_info(&p->pdev->dev, "used as clock source\n");
        clocksource_register(cs);
        return 0;
 }
@@ -497,13 +496,11 @@ static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               pr_info("sh_cmt: %s used for periodic clock events\n",
-                       ced->name);
+               dev_info(&p->pdev->dev, "used for periodic clock events\n");
                sh_cmt_clock_event_start(p, 1);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
-               pr_info("sh_cmt: %s used for oneshot clock events\n",
-                       ced->name);
+               dev_info(&p->pdev->dev, "used for oneshot clock events\n");
                sh_cmt_clock_event_start(p, 0);
                break;
        case CLOCK_EVT_MODE_SHUTDOWN:
@@ -544,7 +541,7 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
        ced->set_next_event = sh_cmt_clock_event_next;
        ced->set_mode = sh_cmt_clock_event_mode;
 
-       pr_info("sh_cmt: %s used for clock events\n", ced->name);
+       dev_info(&p->pdev->dev, "used for clock events\n");
        clockevents_register_device(ced);
 }
 
@@ -601,22 +598,27 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
        /* map memory, let mapbase point to our channel */
        p->mapbase = ioremap_nocache(res->start, resource_size(res));
        if (p->mapbase == NULL) {
-               pr_err("sh_cmt: failed to remap I/O memory\n");
+               dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
                goto err0;
        }
 
        /* request irq using setup_irq() (too early for request_irq()) */
-       p->irqaction.name = cfg->name;
+       p->irqaction.name = dev_name(&p->pdev->dev);
        p->irqaction.handler = sh_cmt_interrupt;
        p->irqaction.dev_id = p;
-       p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+       p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
+                            IRQF_IRQPOLL  | IRQF_NOBALANCING;
 
        /* get hold of clock */
-       p->clk = clk_get(&p->pdev->dev, cfg->clk);
+       p->clk = clk_get(&p->pdev->dev, "cmt_fck");
        if (IS_ERR(p->clk)) {
-               pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
-               ret = PTR_ERR(p->clk);
-               goto err1;
+               dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
+               p->clk = clk_get(&p->pdev->dev, cfg->clk);
+               if (IS_ERR(p->clk)) {
+                       dev_err(&p->pdev->dev, "cannot get clock\n");
+                       ret = PTR_ERR(p->clk);
+                       goto err1;
+               }
        }
 
        if (resource_size(res) == 6) {
@@ -629,17 +631,17 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
                p->clear_bits = ~0xc000;
        }
 
-       ret = sh_cmt_register(p, cfg->name,
+       ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev),
                              cfg->clockevent_rating,
                              cfg->clocksource_rating);
        if (ret) {
-               pr_err("sh_cmt: registration failed\n");
+               dev_err(&p->pdev->dev, "registration failed\n");
                goto err1;
        }
 
        ret = setup_irq(irq, &p->irqaction);
        if (ret) {
-               pr_err("sh_cmt: failed to request irq %d\n", irq);
+               dev_err(&p->pdev->dev, "failed to request irq %d\n", irq);
                goto err1;
        }
 
@@ -654,11 +656,10 @@ err0:
 static int __devinit sh_cmt_probe(struct platform_device *pdev)
 {
        struct sh_cmt_priv *p = platform_get_drvdata(pdev);
-       struct sh_timer_config *cfg = pdev->dev.platform_data;
        int ret;
 
        if (p) {
-               pr_info("sh_cmt: %s kept as earlytimer\n", cfg->name);
+               dev_info(&pdev->dev, "kept as earlytimer\n");
                return 0;
        }
 
index 5fb78bf..ef7a5be 100644 (file)
@@ -119,13 +119,12 @@ static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start)
 
 static int sh_mtu2_enable(struct sh_mtu2_priv *p)
 {
-       struct sh_timer_config *cfg = p->pdev->dev.platform_data;
        int ret;
 
        /* enable clock */
        ret = clk_enable(p->clk);
        if (ret) {
-               pr_err("sh_mtu2: cannot enable clock \"%s\"\n", cfg->clk);
+               dev_err(&p->pdev->dev, "cannot enable clock\n");
                return ret;
        }
 
@@ -194,8 +193,7 @@ static void sh_mtu2_clock_event_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               pr_info("sh_mtu2: %s used for periodic clock events\n",
-                       ced->name);
+               dev_info(&p->pdev->dev, "used for periodic clock events\n");
                sh_mtu2_enable(p);
                break;
        case CLOCK_EVT_MODE_UNUSED:
@@ -222,13 +220,13 @@ static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p,
        ced->cpumask = cpumask_of(0);
        ced->set_mode = sh_mtu2_clock_event_mode;
 
-       pr_info("sh_mtu2: %s used for clock events\n", ced->name);
+       dev_info(&p->pdev->dev, "used for clock events\n");
        clockevents_register_device(ced);
 
        ret = setup_irq(p->irqaction.irq, &p->irqaction);
        if (ret) {
-               pr_err("sh_mtu2: failed to request irq %d\n",
-                      p->irqaction.irq);
+               dev_err(&p->pdev->dev, "failed to request irq %d\n",
+                       p->irqaction.irq);
                return;
        }
 }
@@ -274,26 +272,32 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
        /* map memory, let mapbase point to our channel */
        p->mapbase = ioremap_nocache(res->start, resource_size(res));
        if (p->mapbase == NULL) {
-               pr_err("sh_mtu2: failed to remap I/O memory\n");
+               dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
                goto err0;
        }
 
        /* setup data for setup_irq() (too early for request_irq()) */
-       p->irqaction.name = cfg->name;
+       p->irqaction.name = dev_name(&p->pdev->dev);
        p->irqaction.handler = sh_mtu2_interrupt;
        p->irqaction.dev_id = p;
        p->irqaction.irq = irq;
-       p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+       p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
+                            IRQF_IRQPOLL  | IRQF_NOBALANCING;
 
        /* get hold of clock */
-       p->clk = clk_get(&p->pdev->dev, cfg->clk);
+       p->clk = clk_get(&p->pdev->dev, "mtu2_fck");
        if (IS_ERR(p->clk)) {
-               pr_err("sh_mtu2: cannot get clock \"%s\"\n", cfg->clk);
-               ret = PTR_ERR(p->clk);
-               goto err1;
+               dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
+               p->clk = clk_get(&p->pdev->dev, cfg->clk);
+               if (IS_ERR(p->clk)) {
+                       dev_err(&p->pdev->dev, "cannot get clock\n");
+                       ret = PTR_ERR(p->clk);
+                       goto err1;
+               }
        }
 
-       return sh_mtu2_register(p, cfg->name, cfg->clockevent_rating);
+       return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev),
+                               cfg->clockevent_rating);
  err1:
        iounmap(p->mapbase);
  err0:
@@ -303,11 +307,10 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev)
 static int __devinit sh_mtu2_probe(struct platform_device *pdev)
 {
        struct sh_mtu2_priv *p = platform_get_drvdata(pdev);
-       struct sh_timer_config *cfg = pdev->dev.platform_data;
        int ret;
 
        if (p) {
-               pr_info("sh_mtu2: %s kept as earlytimer\n", cfg->name);
+               dev_info(&pdev->dev, "kept as earlytimer\n");
                return 0;
        }
 
index fc9ff1e..8e44e14 100644 (file)
@@ -107,13 +107,12 @@ static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start)
 
 static int sh_tmu_enable(struct sh_tmu_priv *p)
 {
-       struct sh_timer_config *cfg = p->pdev->dev.platform_data;
        int ret;
 
        /* enable clock */
        ret = clk_enable(p->clk);
        if (ret) {
-               pr_err("sh_tmu: cannot enable clock \"%s\"\n", cfg->clk);
+               dev_err(&p->pdev->dev, "cannot enable clock\n");
                return ret;
        }
 
@@ -229,7 +228,7 @@ static int sh_tmu_register_clocksource(struct sh_tmu_priv *p,
        cs->disable = sh_tmu_clocksource_disable;
        cs->mask = CLOCKSOURCE_MASK(32);
        cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
-       pr_info("sh_tmu: %s used as clock source\n", cs->name);
+       dev_info(&p->pdev->dev, "used as clock source\n");
        clocksource_register(cs);
        return 0;
 }
@@ -277,13 +276,11 @@ static void sh_tmu_clock_event_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               pr_info("sh_tmu: %s used for periodic clock events\n",
-                       ced->name);
+               dev_info(&p->pdev->dev, "used for periodic clock events\n");
                sh_tmu_clock_event_start(p, 1);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
-               pr_info("sh_tmu: %s used for oneshot clock events\n",
-                       ced->name);
+               dev_info(&p->pdev->dev, "used for oneshot clock events\n");
                sh_tmu_clock_event_start(p, 0);
                break;
        case CLOCK_EVT_MODE_UNUSED:
@@ -324,13 +321,13 @@ static void sh_tmu_register_clockevent(struct sh_tmu_priv *p,
        ced->set_next_event = sh_tmu_clock_event_next;
        ced->set_mode = sh_tmu_clock_event_mode;
 
-       pr_info("sh_tmu: %s used for clock events\n", ced->name);
+       dev_info(&p->pdev->dev, "used for clock events\n");
        clockevents_register_device(ced);
 
        ret = setup_irq(p->irqaction.irq, &p->irqaction);
        if (ret) {
-               pr_err("sh_tmu: failed to request irq %d\n",
-                      p->irqaction.irq);
+               dev_err(&p->pdev->dev, "failed to request irq %d\n",
+                       p->irqaction.irq);
                return;
        }
 }
@@ -379,26 +376,31 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
        /* map memory, let mapbase point to our channel */
        p->mapbase = ioremap_nocache(res->start, resource_size(res));
        if (p->mapbase == NULL) {
-               pr_err("sh_tmu: failed to remap I/O memory\n");
+               dev_err(&p->pdev->dev, "failed to remap I/O memory\n");
                goto err0;
        }
 
        /* setup data for setup_irq() (too early for request_irq()) */
-       p->irqaction.name = cfg->name;
+       p->irqaction.name = dev_name(&p->pdev->dev);
        p->irqaction.handler = sh_tmu_interrupt;
        p->irqaction.dev_id = p;
        p->irqaction.irq = irq;
-       p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+       p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \
+                            IRQF_IRQPOLL  | IRQF_NOBALANCING;
 
        /* get hold of clock */
-       p->clk = clk_get(&p->pdev->dev, cfg->clk);
+       p->clk = clk_get(&p->pdev->dev, "tmu_fck");
        if (IS_ERR(p->clk)) {
-               pr_err("sh_tmu: cannot get clock \"%s\"\n", cfg->clk);
-               ret = PTR_ERR(p->clk);
-               goto err1;
+               dev_warn(&p->pdev->dev, "using deprecated clock lookup\n");
+               p->clk = clk_get(&p->pdev->dev, cfg->clk);
+               if (IS_ERR(p->clk)) {
+                       dev_err(&p->pdev->dev, "cannot get clock\n");
+                       ret = PTR_ERR(p->clk);
+                       goto err1;
+               }
        }
 
-       return sh_tmu_register(p, cfg->name,
+       return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev),
                               cfg->clockevent_rating,
                               cfg->clocksource_rating);
  err1:
@@ -410,11 +412,10 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev)
 static int __devinit sh_tmu_probe(struct platform_device *pdev)
 {
        struct sh_tmu_priv *p = platform_get_drvdata(pdev);
-       struct sh_timer_config *cfg = pdev->dev.platform_data;
        int ret;
 
        if (p) {
-               pr_info("sh_tmu: %s kept as earlytimer\n", cfg->name);
+               dev_info(&pdev->dev, "kept as earlytimer\n");
                return 0;
        }
 
index 2d5d575..063b218 100644 (file)
@@ -662,32 +662,20 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
        return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
 }
 
-#define define_one_ro(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-#define define_one_ro0400(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0400, show_##_name, NULL)
-
-#define define_one_rw(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_ro0400(cpuinfo_cur_freq);
-define_one_ro(cpuinfo_min_freq);
-define_one_ro(cpuinfo_max_freq);
-define_one_ro(cpuinfo_transition_latency);
-define_one_ro(scaling_available_governors);
-define_one_ro(scaling_driver);
-define_one_ro(scaling_cur_freq);
-define_one_ro(bios_limit);
-define_one_ro(related_cpus);
-define_one_ro(affected_cpus);
-define_one_rw(scaling_min_freq);
-define_one_rw(scaling_max_freq);
-define_one_rw(scaling_governor);
-define_one_rw(scaling_setspeed);
+cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
+cpufreq_freq_attr_ro(cpuinfo_min_freq);
+cpufreq_freq_attr_ro(cpuinfo_max_freq);
+cpufreq_freq_attr_ro(cpuinfo_transition_latency);
+cpufreq_freq_attr_ro(scaling_available_governors);
+cpufreq_freq_attr_ro(scaling_driver);
+cpufreq_freq_attr_ro(scaling_cur_freq);
+cpufreq_freq_attr_ro(bios_limit);
+cpufreq_freq_attr_ro(related_cpus);
+cpufreq_freq_attr_ro(affected_cpus);
+cpufreq_freq_attr_rw(scaling_min_freq);
+cpufreq_freq_attr_rw(scaling_max_freq);
+cpufreq_freq_attr_rw(scaling_governor);
+cpufreq_freq_attr_rw(scaling_setspeed);
 
 static struct attribute *default_attrs[] = {
        &cpuinfo_min_freq.attr,
@@ -1113,6 +1101,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
        unsigned int cpu = sys_dev->id;
        unsigned long flags;
        struct cpufreq_policy *data;
+       struct kobject *kobj;
+       struct completion *cmp;
 #ifdef CONFIG_SMP
        struct sys_device *cpu_sys_dev;
        unsigned int j;
@@ -1141,10 +1131,11 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                dprintk("removing link\n");
                cpumask_clear_cpu(cpu, data->cpus);
                spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-               sysfs_remove_link(&sys_dev->kobj, "cpufreq");
+               kobj = &sys_dev->kobj;
                cpufreq_cpu_put(data);
                cpufreq_debug_enable_ratelimit();
                unlock_policy_rwsem_write(cpu);
+               sysfs_remove_link(kobj, "cpufreq");
                return 0;
        }
 #endif
@@ -1181,7 +1172,10 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                                data->governor->name, CPUFREQ_NAME_LEN);
 #endif
                        cpu_sys_dev = get_cpu_sysdev(j);
-                       sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
+                       kobj = &cpu_sys_dev->kobj;
+                       unlock_policy_rwsem_write(cpu);
+                       sysfs_remove_link(kobj, "cpufreq");
+                       lock_policy_rwsem_write(cpu);
                        cpufreq_cpu_put(data);
                }
        }
@@ -1192,19 +1186,22 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
        if (cpufreq_driver->target)
                __cpufreq_governor(data, CPUFREQ_GOV_STOP);
 
-       kobject_put(&data->kobj);
+       kobj = &data->kobj;
+       cmp = &data->kobj_unregister;
+       unlock_policy_rwsem_write(cpu);
+       kobject_put(kobj);
 
        /* we need to make sure that the underlying kobj is actually
         * not referenced anymore by anybody before we proceed with
         * unloading.
         */
        dprintk("waiting for dropping of refcount\n");
-       wait_for_completion(&data->kobj_unregister);
+       wait_for_completion(cmp);
        dprintk("wait complete\n");
 
+       lock_policy_rwsem_write(cpu);
        if (cpufreq_driver->exit)
                cpufreq_driver->exit(data);
-
        unlock_policy_rwsem_write(cpu);
 
        free_cpumask_var(data->related_cpus);
index 599a40b..526bfbf 100644 (file)
@@ -178,12 +178,8 @@ static ssize_t show_sampling_rate_min(struct kobject *kobj,
        return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
-#define define_one_ro(_name)           \
-static struct global_attr _name =      \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-define_one_ro(sampling_rate_max);
-define_one_ro(sampling_rate_min);
+define_one_global_ro(sampling_rate_max);
+define_one_global_ro(sampling_rate_min);
 
 /* cpufreq_conservative Governor Tunables */
 #define show_one(file_name, object)                                    \
@@ -221,12 +217,8 @@ show_one_old(freq_step);
 show_one_old(sampling_rate_min);
 show_one_old(sampling_rate_max);
 
-#define define_one_ro_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0444, show_##_name##_old, NULL)
-
-define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
-define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+cpufreq_freq_attr_ro_old(sampling_rate_min);
+cpufreq_freq_attr_ro_old(sampling_rate_max);
 
 /*** delete after deprecation time ***/
 
@@ -364,16 +356,12 @@ static ssize_t store_freq_step(struct kobject *a, struct attribute *b,
        return count;
 }
 
-#define define_one_rw(_name) \
-static struct global_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(sampling_rate);
-define_one_rw(sampling_down_factor);
-define_one_rw(up_threshold);
-define_one_rw(down_threshold);
-define_one_rw(ignore_nice_load);
-define_one_rw(freq_step);
+define_one_global_rw(sampling_rate);
+define_one_global_rw(sampling_down_factor);
+define_one_global_rw(up_threshold);
+define_one_global_rw(down_threshold);
+define_one_global_rw(ignore_nice_load);
+define_one_global_rw(freq_step);
 
 static struct attribute *dbs_attributes[] = {
        &sampling_rate_max.attr,
@@ -409,16 +397,12 @@ write_one_old(down_threshold);
 write_one_old(ignore_nice_load);
 write_one_old(freq_step);
 
-#define define_one_rw_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
-
-define_one_rw_old(sampling_rate_old, sampling_rate);
-define_one_rw_old(sampling_down_factor_old, sampling_down_factor);
-define_one_rw_old(up_threshold_old, up_threshold);
-define_one_rw_old(down_threshold_old, down_threshold);
-define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
-define_one_rw_old(freq_step_old, freq_step);
+cpufreq_freq_attr_rw_old(sampling_rate);
+cpufreq_freq_attr_rw_old(sampling_down_factor);
+cpufreq_freq_attr_rw_old(up_threshold);
+cpufreq_freq_attr_rw_old(down_threshold);
+cpufreq_freq_attr_rw_old(ignore_nice_load);
+cpufreq_freq_attr_rw_old(freq_step);
 
 static struct attribute *dbs_attributes_old[] = {
        &sampling_rate_max_old.attr,
@@ -444,6 +428,7 @@ static struct attribute_group dbs_attr_group_old = {
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
        unsigned int load = 0;
+       unsigned int max_load = 0;
        unsigned int freq_target;
 
        struct cpufreq_policy *policy;
@@ -501,6 +486,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                        continue;
 
                load = 100 * (wall_time - idle_time) / wall_time;
+
+               if (load > max_load)
+                       max_load = load;
        }
 
        /*
@@ -511,7 +499,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                return;
 
        /* Check for frequency increase */
-       if (load > dbs_tuners_ins.up_threshold) {
+       if (max_load > dbs_tuners_ins.up_threshold) {
                this_dbs_info->down_skip = 0;
 
                /* if we are already at full speed then break out early */
@@ -538,7 +526,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
         * can support the current CPU usage without triggering the up
         * policy. To be safe, we focus 10 points under the threshold.
         */
-       if (load < (dbs_tuners_ins.down_threshold - 10)) {
+       if (max_load < (dbs_tuners_ins.down_threshold - 10)) {
                freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
 
                this_dbs_info->requested_freq -= freq_target;
index bd444dc..e131421 100644 (file)
@@ -73,6 +73,7 @@ enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
 
 struct cpu_dbs_info_s {
        cputime64_t prev_cpu_idle;
+       cputime64_t prev_cpu_iowait;
        cputime64_t prev_cpu_wall;
        cputime64_t prev_cpu_nice;
        struct cpufreq_policy *cur_policy;
@@ -108,6 +109,7 @@ static struct dbs_tuners {
        unsigned int down_differential;
        unsigned int ignore_nice;
        unsigned int powersave_bias;
+       unsigned int io_is_busy;
 } dbs_tuners_ins = {
        .up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
        .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL,
@@ -148,6 +150,16 @@ static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
        return idle_time;
 }
 
+static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall)
+{
+       u64 iowait_time = get_cpu_iowait_time_us(cpu, wall);
+
+       if (iowait_time == -1ULL)
+               return 0;
+
+       return iowait_time;
+}
+
 /*
  * Find right freq to be set now with powersave_bias on.
  * Returns the freq_hi to be used right now and will set freq_hi_jiffies,
@@ -234,12 +246,8 @@ static ssize_t show_sampling_rate_min(struct kobject *kobj,
        return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
-#define define_one_ro(_name)           \
-static struct global_attr _name =      \
-__ATTR(_name, 0444, show_##_name, NULL)
-
-define_one_ro(sampling_rate_max);
-define_one_ro(sampling_rate_min);
+define_one_global_ro(sampling_rate_max);
+define_one_global_ro(sampling_rate_min);
 
 /* cpufreq_ondemand Governor Tunables */
 #define show_one(file_name, object)                                    \
@@ -249,6 +257,7 @@ static ssize_t show_##file_name                                             \
        return sprintf(buf, "%u\n", dbs_tuners_ins.object);             \
 }
 show_one(sampling_rate, sampling_rate);
+show_one(io_is_busy, io_is_busy);
 show_one(up_threshold, up_threshold);
 show_one(ignore_nice_load, ignore_nice);
 show_one(powersave_bias, powersave_bias);
@@ -274,12 +283,8 @@ show_one_old(powersave_bias);
 show_one_old(sampling_rate_min);
 show_one_old(sampling_rate_max);
 
-#define define_one_ro_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0444, show_##_name##_old, NULL)
-
-define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
-define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+cpufreq_freq_attr_ro_old(sampling_rate_min);
+cpufreq_freq_attr_ro_old(sampling_rate_max);
 
 /*** delete after deprecation time ***/
 
@@ -299,6 +304,23 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
        return count;
 }
 
+static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
+                                  const char *buf, size_t count)
+{
+       unsigned int input;
+       int ret;
+
+       ret = sscanf(buf, "%u", &input);
+       if (ret != 1)
+               return -EINVAL;
+
+       mutex_lock(&dbs_mutex);
+       dbs_tuners_ins.io_is_busy = !!input;
+       mutex_unlock(&dbs_mutex);
+
+       return count;
+}
+
 static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
                                  const char *buf, size_t count)
 {
@@ -376,14 +398,11 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
        return count;
 }
 
-#define define_one_rw(_name) \
-static struct global_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(sampling_rate);
-define_one_rw(up_threshold);
-define_one_rw(ignore_nice_load);
-define_one_rw(powersave_bias);
+define_one_global_rw(sampling_rate);
+define_one_global_rw(io_is_busy);
+define_one_global_rw(up_threshold);
+define_one_global_rw(ignore_nice_load);
+define_one_global_rw(powersave_bias);
 
 static struct attribute *dbs_attributes[] = {
        &sampling_rate_max.attr,
@@ -392,6 +411,7 @@ static struct attribute *dbs_attributes[] = {
        &up_threshold.attr,
        &ignore_nice_load.attr,
        &powersave_bias.attr,
+       &io_is_busy.attr,
        NULL
 };
 
@@ -415,14 +435,10 @@ write_one_old(up_threshold);
 write_one_old(ignore_nice_load);
 write_one_old(powersave_bias);
 
-#define define_one_rw_old(object, _name)       \
-static struct freq_attr object =               \
-__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
-
-define_one_rw_old(sampling_rate_old, sampling_rate);
-define_one_rw_old(up_threshold_old, up_threshold);
-define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
-define_one_rw_old(powersave_bias_old, powersave_bias);
+cpufreq_freq_attr_rw_old(sampling_rate);
+cpufreq_freq_attr_rw_old(up_threshold);
+cpufreq_freq_attr_rw_old(ignore_nice_load);
+cpufreq_freq_attr_rw_old(powersave_bias);
 
 static struct attribute *dbs_attributes_old[] = {
        &sampling_rate_max_old.attr,
@@ -470,14 +486,15 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 
        for_each_cpu(j, policy->cpus) {
                struct cpu_dbs_info_s *j_dbs_info;
-               cputime64_t cur_wall_time, cur_idle_time;
-               unsigned int idle_time, wall_time;
+               cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time;
+               unsigned int idle_time, wall_time, iowait_time;
                unsigned int load, load_freq;
                int freq_avg;
 
                j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
 
                cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
+               cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time);
 
                wall_time = (unsigned int) cputime64_sub(cur_wall_time,
                                j_dbs_info->prev_cpu_wall);
@@ -487,6 +504,10 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                                j_dbs_info->prev_cpu_idle);
                j_dbs_info->prev_cpu_idle = cur_idle_time;
 
+               iowait_time = (unsigned int) cputime64_sub(cur_iowait_time,
+                               j_dbs_info->prev_cpu_iowait);
+               j_dbs_info->prev_cpu_iowait = cur_iowait_time;
+
                if (dbs_tuners_ins.ignore_nice) {
                        cputime64_t cur_nice;
                        unsigned long cur_nice_jiffies;
@@ -504,6 +525,16 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
                        idle_time += jiffies_to_usecs(cur_nice_jiffies);
                }
 
+               /*
+                * For the purpose of ondemand, waiting for disk IO is an
+                * indication that you're performance critical, and not that
+                * the system is actually idle. So subtract the iowait time
+                * from the cpu idle time.
+                */
+
+               if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time)
+                       idle_time -= iowait_time;
+
                if (unlikely(!wall_time || wall_time < idle_time))
                        continue;
 
@@ -617,6 +648,29 @@ static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
        cancel_delayed_work_sync(&dbs_info->work);
 }
 
+/*
+ * Not all CPUs want IO time to be accounted as busy; this dependson how
+ * efficient idling at a higher frequency/voltage is.
+ * Pavel Machek says this is not so for various generations of AMD and old
+ * Intel systems.
+ * Mike Chan (androidlcom) calis this is also not true for ARM.
+ * Because of this, whitelist specific known (series) of CPUs by default, and
+ * leave all others up to the user.
+ */
+static int should_io_be_busy(void)
+{
+#if defined(CONFIG_X86)
+       /*
+        * For Intel, Core 2 (model 15) andl later have an efficient idle.
+        */
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+           boot_cpu_data.x86 == 6 &&
+           boot_cpu_data.x86_model >= 15)
+               return 1;
+#endif
+       return 0;
+}
+
 static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                                   unsigned int event)
 {
@@ -679,6 +733,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
                        dbs_tuners_ins.sampling_rate =
                                max(min_sampling_rate,
                                    latency * LATENCY_MULTIPLIER);
+                       dbs_tuners_ins.io_is_busy = should_io_be_busy();
                }
                mutex_unlock(&dbs_mutex);
 
index 1aea715..f8e57c6 100644 (file)
@@ -100,7 +100,6 @@ struct menu_device {
        int             needs_update;
 
        unsigned int    expected_us;
-       unsigned int    measured_us;
        u64             predicted_us;
        unsigned int    exit_us;
        unsigned int    bucket;
@@ -187,14 +186,14 @@ static int menu_select(struct cpuidle_device *dev)
        int i;
        int multiplier;
 
-       data->last_state_idx = 0;
-       data->exit_us = 0;
-
        if (data->needs_update) {
                menu_update(dev);
                data->needs_update = 0;
        }
 
+       data->last_state_idx = 0;
+       data->exit_us = 0;
+
        /* Special case when user has set very strict latency requirement */
        if (unlikely(latency_req == 0))
                return 0;
@@ -294,7 +293,7 @@ static void menu_update(struct cpuidle_device *dev)
        new_factor = data->correction_factor[data->bucket]
                        * (DECAY - 1) / DECAY;
 
-       if (data->expected_us > 0 && data->measured_us < MAX_INTERESTING)
+       if (data->expected_us > 0 && measured_us < MAX_INTERESTING)
                new_factor += RESOLUTION * measured_us / data->expected_us;
        else
                /*
index 7cc31b3..323afef 100644 (file)
@@ -26,8 +26,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
-
-#include <asm/dmaengine.h>
+#include <linux/sh_dma.h>
 
 #include "shdma.h"
 
@@ -45,7 +44,7 @@ enum sh_dmae_desc_status {
 #define LOG2_DEFAULT_XFER_SIZE 2
 
 /* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
-static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
+static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SH_DMA_SLAVE_NUMBER)];
 
 static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all);
 
@@ -190,7 +189,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
        struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
                                                struct sh_dmae_device, common);
        struct sh_dmae_pdata *pdata = shdev->pdata;
-       struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
+       const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
        u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
        int shift = chan_pdata->dmars_bit;
 
@@ -266,8 +265,8 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan)
        return NULL;
 }
 
-static struct sh_dmae_slave_config *sh_dmae_find_slave(
-       struct sh_dmae_chan *sh_chan, enum sh_dmae_slave_chan_id slave_id)
+static const struct sh_dmae_slave_config *sh_dmae_find_slave(
+       struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param)
 {
        struct dma_device *dma_dev = sh_chan->common.device;
        struct sh_dmae_device *shdev = container_of(dma_dev,
@@ -275,11 +274,11 @@ static struct sh_dmae_slave_config *sh_dmae_find_slave(
        struct sh_dmae_pdata *pdata = shdev->pdata;
        int i;
 
-       if ((unsigned)slave_id >= SHDMA_SLAVE_NUMBER)
+       if (param->slave_id >= SH_DMA_SLAVE_NUMBER)
                return NULL;
 
        for (i = 0; i < pdata->slave_num; i++)
-               if (pdata->slave[i].slave_id == slave_id)
+               if (pdata->slave[i].slave_id == param->slave_id)
                        return pdata->slave + i;
 
        return NULL;
@@ -290,6 +289,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
        struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
        struct sh_desc *desc;
        struct sh_dmae_slave *param = chan->private;
+       int ret;
 
        pm_runtime_get_sync(sh_chan->dev);
 
@@ -298,14 +298,18 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
         * never runs concurrently with itself or free_chan_resources.
         */
        if (param) {
-               struct sh_dmae_slave_config *cfg;
+               const struct sh_dmae_slave_config *cfg;
 
-               cfg = sh_dmae_find_slave(sh_chan, param->slave_id);
-               if (!cfg)
-                       return -EINVAL;
+               cfg = sh_dmae_find_slave(sh_chan, param);
+               if (!cfg) {
+                       ret = -EINVAL;
+                       goto efindslave;
+               }
 
-               if (test_and_set_bit(param->slave_id, sh_dmae_slave_used))
-                       return -EBUSY;
+               if (test_and_set_bit(param->slave_id, sh_dmae_slave_used)) {
+                       ret = -EBUSY;
+                       goto etestused;
+               }
 
                param->config = cfg;
 
@@ -334,10 +338,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
        }
        spin_unlock_bh(&sh_chan->desc_lock);
 
-       if (!sh_chan->descs_allocated)
-               pm_runtime_put(sh_chan->dev);
+       if (!sh_chan->descs_allocated) {
+               ret = -ENOMEM;
+               goto edescalloc;
+       }
 
        return sh_chan->descs_allocated;
+
+edescalloc:
+       if (param)
+               clear_bit(param->slave_id, sh_dmae_slave_used);
+etestused:
+efindslave:
+       pm_runtime_put(sh_chan->dev);
+       return ret;
 }
 
 /*
@@ -559,12 +573,14 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
 {
        struct sh_dmae_slave *param;
        struct sh_dmae_chan *sh_chan;
+       dma_addr_t slave_addr;
 
        if (!chan)
                return NULL;
 
        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) {
@@ -577,7 +593,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg(
         * if (param != NULL), this is a successfully requested slave channel,
         * therefore param->config != NULL too.
         */
-       return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &param->config->addr,
+       return sh_dmae_prep_sg(sh_chan, sgl, sg_len, &slave_addr,
                               direction, flags);
 }
 
@@ -858,7 +874,7 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
                                        int irq, unsigned long flags)
 {
        int err;
-       struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
+       const struct sh_dmae_channel *chan_pdata = &shdev->pdata->channel[id];
        struct platform_device *pdev = to_platform_device(shdev->common.dev);
        struct sh_dmae_chan *new_sh_chan;
 
index 153609a..4021275 100644 (file)
@@ -17,8 +17,8 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 
-#include <asm/dmaengine.h>
-
+#define SH_DMAC_MAX_CHANNELS 6
+#define SH_DMA_SLAVE_NUMBER 256
 #define SH_DMA_TCR_MAX 0x00FFFFFF      /* 16MB */
 
 struct device;
index 3ebc610..75fcf1a 100644 (file)
@@ -1359,3 +1359,5 @@ module_exit(txx9dmac_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("TXx9 DMA Controller driver");
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
+MODULE_ALIAS("platform:txx9dmac");
+MODULE_ALIAS("platform:txx9dmac-chan");
index f5b6d9f..97e64bc 100644 (file)
@@ -294,7 +294,6 @@ wrong_ls_mce:
 void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
 {
        u32 ec  = ERROR_CODE(regs->nbsl);
-       u32 xec = EXT_ERROR_CODE(regs->nbsl);
 
        if (!handle_errors)
                return;
@@ -324,7 +323,7 @@ void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
                pr_cont("\n");
        }
 
-       pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+       pr_emerg("%s.\n", EXT_ERR_MSG(regs->nbsl));
 
        if (BUS_ERROR(ec) && nb_bus_decoder)
                nb_bus_decoder(node_id, regs);
@@ -374,7 +373,7 @@ static int amd_decode_mce(struct notifier_block *nb, unsigned long val,
                 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
 
        /* do the two bits[14:13] together */
-       ecc = m->status & (3ULL << 45);
+       ecc = (m->status >> 45) & 0x3;
        if (ecc)
                pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
 
index 702dcc9..14a34d9 100644 (file)
@@ -960,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
                u.packet.header_length = GET_HEADER_LENGTH(control);
 
                if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
+                       if (u.packet.header_length % 4 != 0)
+                               return -EINVAL;
                        header_length = u.packet.header_length;
                } else {
                        /*
@@ -969,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
                        if (ctx->header_size == 0) {
                                if (u.packet.header_length > 0)
                                        return -EINVAL;
-                       } else if (u.packet.header_length % ctx->header_size != 0) {
+                       } else if (u.packet.header_length == 0 ||
+                                  u.packet.header_length % ctx->header_size != 0) {
                                return -EINVAL;
                        }
                        header_length = 0;
@@ -1354,24 +1357,24 @@ static int dispatch_ioctl(struct client *client,
                return -ENODEV;
 
        if (_IOC_TYPE(cmd) != '#' ||
-           _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
+           _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
+           _IOC_SIZE(cmd) > sizeof(buffer))
                return -EINVAL;
 
-       if (_IOC_DIR(cmd) & _IOC_WRITE) {
-               if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-                   copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
+       if (_IOC_DIR(cmd) == _IOC_READ)
+               memset(&buffer, 0, _IOC_SIZE(cmd));
+
+       if (_IOC_DIR(cmd) & _IOC_WRITE)
+               if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
                        return -EFAULT;
-       }
 
        ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
        if (ret < 0)
                return ret;
 
-       if (_IOC_DIR(cmd) & _IOC_READ) {
-               if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-                   copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
+       if (_IOC_DIR(cmd) & _IOC_READ)
+               if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
                        return -EFAULT;
-       }
 
        return ret;
 }
index 3784a47..8f5aebf 100644 (file)
@@ -190,7 +190,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
        for (try = 0; try < 5; try++) {
                new = allocate ? old - bandwidth : old + bandwidth;
                if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
-                       break;
+                       return -EBUSY;
 
                data[0] = cpu_to_be32(old);
                data[1] = cpu_to_be32(new);
@@ -218,7 +218,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
                u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
 {
        __be32 c, all, old;
-       int i, retry = 5;
+       int i, ret = -EIO, retry = 5;
 
        old = all = allocate ? cpu_to_be32(~0) : 0;
 
@@ -226,6 +226,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
                if (!(channels_mask & 1 << i))
                        continue;
 
+               ret = -EBUSY;
+
                c = cpu_to_be32(1 << (31 - i));
                if ((old & c) != (all & c))
                        continue;
@@ -251,12 +253,16 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
 
                        /* 1394-1995 IRM, fall through to retry. */
                default:
-                       if (retry--)
+                       if (retry) {
+                               retry--;
                                i--;
+                       } else {
+                               ret = -EIO;
+                       }
                }
        }
 
-       return -EIO;
+       return ret;
 }
 
 static void deallocate_channel(struct fw_card *card, int irm_id,
index 0cf4d7f..94b16e0 100644 (file)
@@ -1158,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
                              struct fw_packet *packet, u32 csr)
 {
        struct fw_packet response;
-       int tcode, length, ext_tcode, sel;
+       int tcode, length, ext_tcode, sel, try;
        __be32 *payload, lock_old;
        u32 lock_arg, lock_data;
 
@@ -1185,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci,
        reg_write(ohci, OHCI1394_CSRCompareData, lock_arg);
        reg_write(ohci, OHCI1394_CSRControl, sel);
 
-       if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
-               lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData));
-       else
-               fw_notify("swap not done yet\n");
+       for (try = 0; try < 20; try++)
+               if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) {
+                       lock_old = cpu_to_be32(reg_read(ohci,
+                                                       OHCI1394_CSRData));
+                       fw_fill_response(&response, packet->header,
+                                        RCODE_COMPLETE,
+                                        &lock_old, sizeof(lock_old));
+                       goto out;
+               }
+
+       fw_error("swap not done (CSR lock timeout)\n");
+       fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
-       fw_fill_response(&response, packet->header,
-                        RCODE_COMPLETE, &lock_old, sizeof(lock_old));
  out:
        fw_core_handle_response(&ohci->card, &response);
 }
 
 static void handle_local_request(struct context *ctx, struct fw_packet *packet)
 {
-       u64 offset;
-       u32 csr;
+       u64 offset, csr;
 
        if (ctx == &ctx->ohci->at_request_ctx) {
                packet->ack = ACK_PENDING;
index 76be229..eb0c3fe 100644 (file)
@@ -416,7 +416,8 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
        return 0;
 
 free_sd:
-       sysfs_put(pdesc->value_sd);
+       if (pdesc)
+               sysfs_put(pdesc->value_sd);
 free_id:
        idr_remove(&pdesc_idr, id);
        desc->flags &= GPIO_FLAGS_MASK;
index 753219c..41a9388 100644 (file)
@@ -80,8 +80,8 @@ static int it8761e_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
        u16 reg;
        u8 bit;
 
-       bit = gpio_num % 7;
-       reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
+       bit = gpio_num % 8;
+       reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;
 
        return !!(inb(reg) & (1 << bit));
 }
@@ -91,8 +91,8 @@ static int it8761e_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
        u8 curr_dirs;
        u8 io_reg, bit;
 
-       bit = gpio_num % 7;
-       io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
+       bit = gpio_num % 8;
+       io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;
 
        spin_lock(&sio_lock);
 
@@ -116,8 +116,8 @@ static void it8761e_gpio_set(struct gpio_chip *gc,
        u8 curr_vals, bit;
        u16 reg;
 
-       bit = gpio_num % 7;
-       reg = (gpio_num >= 7) ? gpio_ba + 1 : gpio_ba;
+       bit = gpio_num % 8;
+       reg = (gpio_num >= 8) ? gpio_ba + 1 : gpio_ba;
 
        spin_lock(&sio_lock);
 
@@ -135,8 +135,8 @@ static int it8761e_gpio_direction_out(struct gpio_chip *gc,
 {
        u8 curr_dirs, io_reg, bit;
 
-       bit = gpio_num % 7;
-       io_reg = (gpio_num >= 7) ? GPIO2X_IO : GPIO1X_IO;
+       bit = gpio_num % 8;
+       io_reg = (gpio_num >= 8) ? GPIO2X_IO : GPIO1X_IO;
 
        it8761e_gpio_set(gc, gpio_num, val);
 
@@ -200,7 +200,7 @@ static int __init it8761e_gpio_init(void)
                return -EBUSY;
 
        it8761e_gpio_chip.base = -1;
-       it8761e_gpio_chip.ngpio = 14;
+       it8761e_gpio_chip.ngpio = 16;
 
        err = gpiochip_add(&it8761e_gpio_chip);
        if (err < 0)
index 7d521e1..b827c97 100644 (file)
@@ -252,6 +252,18 @@ static void pca953x_irq_bus_lock(unsigned int irq)
 static void pca953x_irq_bus_sync_unlock(unsigned int irq)
 {
        struct pca953x_chip *chip = get_irq_chip_data(irq);
+       uint16_t new_irqs;
+       uint16_t level;
+
+       /* Look for any newly setup interrupt */
+       new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
+       new_irqs &= ~chip->reg_direction;
+
+       while (new_irqs) {
+               level = __ffs(new_irqs);
+               pca953x_gpio_direction_input(&chip->gpio_chip, level);
+               new_irqs &= ~(1 << level);
+       }
 
        mutex_unlock(&chip->irq_lock);
 }
@@ -278,7 +290,7 @@ static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
        else
                chip->irq_trig_raise &= ~mask;
 
-       return pca953x_gpio_direction_input(&chip->gpio_chip, level);
+       return 0;
 }
 
 static struct irq_chip pca953x_irq_chip = {
index 5ad8f77..105701a 100644 (file)
@@ -91,6 +91,12 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
        gpiodir = readb(chip->base + GPIODIR);
        gpiodir |= 1 << offset;
        writeb(gpiodir, chip->base + GPIODIR);
+
+       /*
+        * gpio value is set again, because pl061 doesn't allow to set value of
+        * a gpio pin before configuring it in OUT mode.
+        */
+       writeb(!!value << offset, chip->base + (1 << (offset + 2)));
        spin_unlock_irqrestore(&chip->lock, flags);
 
        return 0;
@@ -183,7 +189,7 @@ static int pl061_irq_type(unsigned irq, unsigned trigger)
                gpioibe &= ~(1 << offset);
                if (trigger & IRQ_TYPE_EDGE_RISING)
                        gpioiev |= 1 << offset;
-               else
+               else if (trigger & IRQ_TYPE_EDGE_FALLING)
                        gpioiev &= ~(1 << offset);
        }
        writeb(gpioibe, chip->base + GPIOIBE);
@@ -204,7 +210,7 @@ static struct irq_chip pl061_irqchip = {
 
 static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct list_head *chip_list = get_irq_chip_data(irq);
+       struct list_head *chip_list = get_irq_data(irq);
        struct list_head *ptr;
        struct pl061_gpio *chip;
 
@@ -297,9 +303,9 @@ static int __init pl061_probe(struct amba_device *dev, struct amba_id *id)
                        goto iounmap;
                }
                INIT_LIST_HEAD(chip_list);
-               set_irq_chip_data(irq, chip_list);
+               set_irq_data(irq, chip_list);
        } else
-               chip_list = get_irq_chip_data(irq);
+               chip_list = get_irq_data(irq);
        list_add(&chip->list, chip_list);
 
        for (i = 0; i < PL061_GPIO_NR; i++) {
index 3bd8727..a263b70 100644 (file)
@@ -476,6 +476,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
        unsigned long irqflags;
 
        spin_lock_irqsave(&dev->vbl_lock, irqflags);
+       dev->driver->disable_vblank(dev, crtc);
        DRM_WAKEUP(&dev->vbl_queue[crtc]);
        dev->vblank_enabled[crtc] = 0;
        dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
index e4865f9..7732268 100644 (file)
@@ -77,7 +77,7 @@ static void *agp_remap(unsigned long offset, unsigned long size,
                    && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
                    (offset + size))
                        break;
-       if (!agpmem)
+       if (&agpmem->head == &dev->agp->memory)
                return NULL;
 
        /*
index b743411..a0c365f 100644 (file)
@@ -516,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)
        }
        driver = dev->driver;
 
-       drm_vblank_cleanup(dev);
-
        drm_lastclose(dev);
 
        if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -537,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)
                dev->agp = NULL;
        }
 
+       drm_vblank_cleanup(dev);
+
        list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
                drm_rmmap(dev, r_list->map);
        drm_ht_remove(&dev->map_hash);
index 1a1825b..25bbd30 100644 (file)
@@ -354,7 +354,10 @@ static struct bin_attribute edid_attr = {
 int drm_sysfs_connector_add(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       int ret = 0, i, j;
+       int attr_cnt = 0;
+       int opt_cnt = 0;
+       int i;
+       int ret = 0;
 
        /* We shouldn't get called more than once for the same connector */
        BUG_ON(device_is_registered(&connector->kdev));
@@ -377,8 +380,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
 
        /* Standard attributes */
 
-       for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) {
-               ret = device_create_file(&connector->kdev, &connector_attrs[i]);
+       for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) {
+               ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]);
                if (ret)
                        goto err_out_files;
        }
@@ -394,8 +397,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
                case DRM_MODE_CONNECTOR_SVIDEO:
                case DRM_MODE_CONNECTOR_Component:
                case DRM_MODE_CONNECTOR_TV:
-                       for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
-                               ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
+                       for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) {
+                               ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]);
                                if (ret)
                                        goto err_out_files;
                        }
@@ -414,10 +417,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
        return 0;
 
 err_out_files:
-       if (i > 0)
-               for (j = 0; j < i; j++)
-                       device_remove_file(&connector->kdev,
-                                          &connector_attrs[i]);
+       for (i = 0; i < opt_cnt; i++)
+               device_remove_file(&connector->kdev, &connector_attrs_opt1[i]);
+       for (i = 0; i < attr_cnt; i++)
+               device_remove_file(&connector->kdev, &connector_attrs[i]);
        device_unregister(&connector->kdev);
 
 out:
index b574503..a0b8447 100644 (file)
@@ -226,7 +226,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
                } else {
                        struct drm_i915_gem_object *obj_priv;
 
-                       obj_priv = obj->driver_private;
+                       obj_priv = to_intel_bo(obj);
                        seq_printf(m, "Fenced object[%2d] = %p: %s "
                                   "%08x %08zx %08x %s %08x %08x %d",
                                   i, obj, get_pin_flag(obj_priv),
index 2dc9393..c3cfafc 100644 (file)
@@ -1357,6 +1357,8 @@ static void i915_setup_compression(struct drm_device *dev, int size)
 
        dev_priv->cfb_size = size;
 
+       dev_priv->compressed_fb = compressed_fb;
+
        if (IS_GM45(dev)) {
                g4x_disable_fbc(dev);
                I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
@@ -1364,12 +1366,22 @@ static void i915_setup_compression(struct drm_device *dev, int size)
                i8xx_disable_fbc(dev);
                I915_WRITE(FBC_CFB_BASE, cfb_base);
                I915_WRITE(FBC_LL_BASE, ll_base);
+               dev_priv->compressed_llb = compressed_llb;
        }
 
        DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
                  ll_base, size >> 20);
 }
 
+static void i915_cleanup_compression(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       drm_mm_put_block(dev_priv->compressed_fb);
+       if (!IS_GM45(dev))
+               drm_mm_put_block(dev_priv->compressed_llb);
+}
+
 /* true = enable decode, false = disable decoder */
 static unsigned int i915_vga_set_decode(void *cookie, bool state)
 {
@@ -1787,6 +1799,8 @@ int i915_driver_unload(struct drm_device *dev)
                mutex_lock(&dev->struct_mutex);
                i915_gem_cleanup_ringbuffer(dev);
                mutex_unlock(&dev->struct_mutex);
+               if (I915_HAS_FBC(dev) && i915_powersave)
+                       i915_cleanup_compression(dev);
                drm_mm_takedown(&dev_priv->vram);
                i915_gem_lastclose(dev);
 
index 4b26919..cc03537 100644 (file)
@@ -69,7 +69,8 @@ const static struct intel_device_info intel_845g_info = {
 };
 
 const static struct intel_device_info intel_i85x_info = {
-       .is_i8xx = 1, .is_mobile = 1, .cursor_needs_physical = 1,
+       .is_i8xx = 1, .is_i85x = 1, .is_mobile = 1,
+       .cursor_needs_physical = 1,
 };
 
 const static struct intel_device_info intel_i865g_info = {
@@ -80,14 +81,14 @@ const static struct intel_device_info intel_i915g_info = {
        .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i915gm_info = {
-       .is_i9xx = 1,  .is_mobile = 1, .has_fbc = 1,
+       .is_i9xx = 1,  .is_mobile = 1,
        .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945g_info = {
        .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945gm_info = {
-       .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+       .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
        .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 
@@ -151,7 +152,7 @@ const static struct pci_device_id pciidlist[] = {
        INTEL_VGA_DEVICE(0x3577, &intel_i830_info),
        INTEL_VGA_DEVICE(0x2562, &intel_845g_info),
        INTEL_VGA_DEVICE(0x3582, &intel_i85x_info),
-       INTEL_VGA_DEVICE(0x35e8, &intel_i85x_info),
+       INTEL_VGA_DEVICE(0x358e, &intel_i85x_info),
        INTEL_VGA_DEVICE(0x2572, &intel_i865g_info),
        INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),
        INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),
@@ -361,7 +362,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
            !dev_priv->mm.suspended) {
                drm_i915_ring_buffer_t *ring = &dev_priv->ring;
                struct drm_gem_object *obj = ring->ring_obj;
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
                dev_priv->mm.suspended = 0;
 
                /* Stop the ring if it's running. */
index aba8260..6e47900 100644 (file)
@@ -195,6 +195,7 @@ struct intel_overlay;
 struct intel_device_info {
        u8 is_mobile : 1;
        u8 is_i8xx : 1;
+       u8 is_i85x : 1;
        u8 is_i915g : 1;
        u8 is_i9xx : 1;
        u8 is_i945gm : 1;
@@ -235,11 +236,14 @@ typedef struct drm_i915_private {
 
        drm_dma_handle_t *status_page_dmah;
        void *hw_status_page;
+       void *seqno_page;
        dma_addr_t dma_status_page;
        uint32_t counter;
        unsigned int status_gfx_addr;
+       unsigned int seqno_gfx_addr;
        drm_local_map_t hws_map;
        struct drm_gem_object *hws_obj;
+       struct drm_gem_object *seqno_obj;
        struct drm_gem_object *pwrctx;
 
        struct resource mch_res;
@@ -611,6 +615,8 @@ typedef struct drm_i915_private {
        /* Reclocking support */
        bool render_reclock_avail;
        bool lvds_downclock_avail;
+       /* indicate whether the LVDS EDID is OK */
+       bool lvds_edid_good;
        /* indicates the reduced downclock for LVDS*/
        int lvds_downclock;
        struct work_struct idle_work;
@@ -628,6 +634,9 @@ typedef struct drm_i915_private {
        u8 max_delay;
 
        enum no_fbc_reason no_fbc_reason;
+
+       struct drm_mm_node *compressed_fb;
+       struct drm_mm_node *compressed_llb;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -731,6 +740,8 @@ struct drm_i915_gem_object {
        atomic_t pending_flip;
 };
 
+#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private)
+
 /**
  * Request queue structure.
  *
@@ -1066,7 +1077,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define IS_I830(dev)           ((dev)->pci_device == 0x3577)
 #define IS_845G(dev)           ((dev)->pci_device == 0x2562)
-#define IS_I85X(dev)           ((dev)->pci_device == 0x3582)
+#define IS_I85X(dev)           (INTEL_INFO(dev)->is_i85x)
 #define IS_I865G(dev)          ((dev)->pci_device == 0x2572)
 #define IS_GEN2(dev)           (INTEL_INFO(dev)->is_i8xx)
 #define IS_I915G(dev)          (INTEL_INFO(dev)->is_i915g)
@@ -1131,6 +1142,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define HAS_PCH_SPLIT(dev) (IS_IRONLAKE(dev) ||        \
                            IS_GEN6(dev))
+#define HAS_PIPE_CONTROL(dev) (IS_IRONLAKE(dev) || IS_GEN6(dev))
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
index 368d726..ef3d91d 100644 (file)
@@ -163,7 +163,7 @@ fast_shmem_read(struct page **pages,
 static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
 {
        drm_i915_private_t *dev_priv = obj->dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
                obj_priv->tiling_mode != I915_TILING_NONE;
@@ -264,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
                          struct drm_i915_gem_pread *args,
                          struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
@@ -285,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
 
        while (remain > 0) {
@@ -354,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
                          struct drm_i915_gem_pread *args,
                          struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct mm_struct *mm = current->mm;
        struct page **user_pages;
        ssize_t remain;
@@ -403,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
 
        while (remain > 0) {
@@ -479,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Bounds check source.
         *
@@ -581,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        drm_i915_private_t *dev_priv = dev->dev_private;
        ssize_t remain;
        loff_t offset, page_base;
@@ -605,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret)
                goto fail;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = obj_priv->gtt_offset + args->offset;
 
        while (remain > 0) {
@@ -655,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        drm_i915_private_t *dev_priv = dev->dev_private;
        ssize_t remain;
        loff_t gtt_page_base, offset;
@@ -699,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret)
                goto out_unpin_object;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = obj_priv->gtt_offset + args->offset;
 
        while (remain > 0) {
@@ -761,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
                           struct drm_i915_gem_pwrite *args,
                           struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
@@ -781,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
        obj_priv->dirty = 1;
 
@@ -829,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                           struct drm_i915_gem_pwrite *args,
                           struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct mm_struct *mm = current->mm;
        struct page **user_pages;
        ssize_t remain;
@@ -877,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
        obj_priv->dirty = 1;
 
@@ -952,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Bounds check destination.
         *
@@ -1034,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -1096,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
        DRM_INFO("%s: sw_finish %d (%p %zd)\n",
                 __func__, args->handle, obj, obj->size);
 #endif
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Pinned buffers may be scanout, so flush the cache */
        if (obj_priv->pin_count)
@@ -1167,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        struct drm_gem_object *obj = vma->vm_private_data;
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        pgoff_t page_offset;
        unsigned long pfn;
        int ret = 0;
@@ -1234,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_gem_mm *mm = dev->mm_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_map_list *list;
        struct drm_local_map *map;
        int ret = 0;
@@ -1305,7 +1305,7 @@ void
 i915_gem_release_mmap(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (dev->dev_mapping)
                unmap_mapping_range(dev->dev_mapping,
@@ -1316,7 +1316,7 @@ static void
 i915_gem_free_mmap_offset(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_gem_mm *mm = dev->mm_private;
        struct drm_map_list *list;
 
@@ -1347,7 +1347,7 @@ static uint32_t
 i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int start, i;
 
        /*
@@ -1406,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 
        mutex_lock(&dev->struct_mutex);
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->madv != I915_MADV_WILLNEED) {
                DRM_ERROR("Attempting to mmap a purgeable buffer\n");
@@ -1450,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 void
 i915_gem_object_put_pages(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size / PAGE_SIZE;
        int i;
 
@@ -1486,7 +1486,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        /* Add a reference if we're newly entering the active list. */
        if (!obj_priv->active) {
@@ -1506,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        BUG_ON(!obj_priv->active);
        list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list);
@@ -1517,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 static void
 i915_gem_object_truncate(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct inode *inode;
 
        inode = obj->filp->f_path.dentry->d_inode;
@@ -1538,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
        if (obj_priv->pin_count != 0)
@@ -1588,6 +1588,13 @@ i915_gem_process_flushing_list(struct drm_device *dev,
        }
 }
 
+#define PIPE_CONTROL_FLUSH(addr)                                       \
+       OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |          \
+                PIPE_CONTROL_DEPTH_STALL);                             \
+       OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);                       \
+       OUT_RING(0);                                                    \
+       OUT_RING(0);                                                    \
+
 /**
  * Creates a new sequence number, emitting a write of it to the status page
  * plus an interrupt, which will trigger i915_user_interrupt_handler.
@@ -1622,13 +1629,47 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv,
        if (dev_priv->mm.next_gem_seqno == 0)
                dev_priv->mm.next_gem_seqno++;
 
-       BEGIN_LP_RING(4);
-       OUT_RING(MI_STORE_DWORD_INDEX);
-       OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
-       OUT_RING(seqno);
+       if (HAS_PIPE_CONTROL(dev)) {
+               u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
 
-       OUT_RING(MI_USER_INTERRUPT);
-       ADVANCE_LP_RING();
+               /*
+                * Workaround qword write incoherence by flushing the
+                * PIPE_NOTIFY buffers out to memory before requesting
+                * an interrupt.
+                */
+               BEGIN_LP_RING(32);
+               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128; /* write to separate cachelines */
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               scratch_addr += 128;
+               PIPE_CONTROL_FLUSH(scratch_addr);
+               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+                        PIPE_CONTROL_NOTIFY);
+               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
+               OUT_RING(seqno);
+               OUT_RING(0);
+               ADVANCE_LP_RING();
+       } else {
+               BEGIN_LP_RING(4);
+               OUT_RING(MI_STORE_DWORD_INDEX);
+               OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+               OUT_RING(seqno);
+
+               OUT_RING(MI_USER_INTERRUPT);
+               ADVANCE_LP_RING();
+       }
 
        DRM_DEBUG_DRIVER("%d\n", seqno);
 
@@ -1752,7 +1793,10 @@ i915_get_gem_seqno(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
-       return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
+       if (HAS_PIPE_CONTROL(dev))
+               return ((volatile u32 *)(dev_priv->seqno_page))[0];
+       else
+               return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
 }
 
 /**
@@ -1965,7 +2009,7 @@ static int
 i915_gem_object_wait_rendering(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
        /* This function only exists to support waiting for existing rendering,
@@ -1997,7 +2041,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret = 0;
 
 #if WATCH_BUF
@@ -2173,7 +2217,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
 #if WATCH_LRU
                        DRM_INFO("%s: evicting %p\n", __func__, obj);
 #endif
-                       obj_priv = obj->driver_private;
+                       obj_priv = to_intel_bo(obj);
                        BUG_ON(obj_priv->pin_count != 0);
                        BUG_ON(obj_priv->active);
 
@@ -2244,7 +2288,7 @@ int
 i915_gem_object_get_pages(struct drm_gem_object *obj,
                          gfp_t gfpmask)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count, i;
        struct address_space *mapping;
        struct inode *inode;
@@ -2297,7 +2341,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint64_t val;
 
@@ -2319,7 +2363,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint64_t val;
 
@@ -2339,7 +2383,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        int tile_width;
        uint32_t fence_reg, val;
@@ -2362,6 +2406,12 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
        pitch_val = obj_priv->stride / tile_width;
        pitch_val = ffs(pitch_val) - 1;
 
+       if (obj_priv->tiling_mode == I915_TILING_Y &&
+           HAS_128_BYTE_Y_TILING(dev))
+               WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL);
+       else
+               WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL);
+
        val = obj_priv->gtt_offset;
        if (obj_priv->tiling_mode == I915_TILING_Y)
                val |= 1 << I830_FENCE_TILING_Y_SHIFT;
@@ -2381,7 +2431,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint32_t val;
        uint32_t pitch_val;
@@ -2425,7 +2475,7 @@ static int i915_find_fence_reg(struct drm_device *dev)
                if (!reg->obj)
                        return i;
 
-               obj_priv = reg->obj->driver_private;
+               obj_priv = to_intel_bo(reg->obj);
                if (!obj_priv->pin_count)
                    avail++;
        }
@@ -2480,7 +2530,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_i915_fence_reg *reg = NULL;
        int ret;
 
@@ -2547,7 +2597,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (IS_GEN6(dev)) {
                I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
@@ -2583,7 +2633,7 @@ int
 i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
                return 0;
@@ -2621,7 +2671,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_mm_node *free_space;
        gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN;
        int ret;
@@ -2728,7 +2778,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 void
 i915_gem_clflush_object(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object      *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
 
        /* If we don't have a page list set up, then we're not pinned
         * to GPU, and we can ignore the cache flush because it'll happen
@@ -2829,7 +2879,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
 int
 i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
@@ -2879,7 +2929,7 @@ int
 i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
@@ -3092,7 +3142,7 @@ static void
 i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 {
        struct drm_device               *dev = obj->dev;
-       struct drm_i915_gem_object      *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
        uint32_t                        invalidate_domains = 0;
        uint32_t                        flush_domains = 0;
        uint32_t                        old_read_domains;
@@ -3177,7 +3227,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 static void
 i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (!obj_priv->page_cpu_valid)
                return;
@@ -3217,7 +3267,7 @@ static int
 i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
                                          uint64_t offset, uint64_t size)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_read_domains;
        int i, ret;
 
@@ -3286,7 +3336,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int i, ret;
        void __iomem *reloc_page;
        bool need_fence;
@@ -3337,7 +3387,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                        i915_gem_object_unpin(obj);
                        return -EBADF;
                }
-               target_obj_priv = target_obj->driver_private;
+               target_obj_priv = to_intel_bo(target_obj);
 
 #if WATCH_RELOC
                DRM_INFO("%s: obj %p offset %08x target %d "
@@ -3689,7 +3739,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,
                prepare_to_wait(&dev_priv->pending_flip_queue,
                                &wait, TASK_INTERRUPTIBLE);
                for (i = 0; i < count; i++) {
-                       obj_priv = object_list[i]->driver_private;
+                       obj_priv = to_intel_bo(object_list[i]);
                        if (atomic_read(&obj_priv->pending_flip) > 0)
                                break;
                }
@@ -3798,7 +3848,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                        goto err;
                }
 
-               obj_priv = object_list[i]->driver_private;
+               obj_priv = to_intel_bo(object_list[i]);
                if (obj_priv->in_execbuffer) {
                        DRM_ERROR("Object %p appears more than once in object list\n",
                                   object_list[i]);
@@ -3924,7 +3974,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
                uint32_t old_write_domain = obj->write_domain;
 
                obj->write_domain = obj->pending_write_domain;
@@ -3999,7 +4049,7 @@ err:
 
        for (i = 0; i < args->buffer_count; i++) {
                if (object_list[i]) {
-                       obj_priv = object_list[i]->driver_private;
+                       obj_priv = to_intel_bo(object_list[i]);
                        obj_priv->in_execbuffer = false;
                }
                drm_gem_object_unreference(object_list[i]);
@@ -4177,7 +4227,7 @@ int
 i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -4210,7 +4260,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
        obj_priv->pin_count--;
@@ -4250,7 +4300,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
                mutex_unlock(&dev->struct_mutex);
                return -EBADF;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->madv != I915_MADV_WILLNEED) {
                DRM_ERROR("Attempting to pin a purgeable buffer\n");
@@ -4307,7 +4357,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
                return -EBADF;
        }
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        if (obj_priv->pin_filp != file_priv) {
                DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
                          args->handle);
@@ -4349,7 +4399,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
         */
        i915_gem_retire_requests(dev);
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        /* Don't count being on the flushing list against the object being
         * done.  Otherwise, a buffer left on the flushing list but not getting
         * flushed (because nobody's flushing that domain) won't ever return
@@ -4395,7 +4445,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
        }
 
        mutex_lock(&dev->struct_mutex);
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->pin_count) {
                drm_gem_object_unreference(obj);
@@ -4456,7 +4506,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
 void i915_gem_free_object(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        trace_i915_gem_object_destroy(obj);
 
@@ -4546,6 +4596,49 @@ i915_gem_idle(struct drm_device *dev)
        return 0;
 }
 
+/*
+ * 965+ support PIPE_CONTROL commands, which provide finer grained control
+ * over cache flushing.
+ */
+static int
+i915_gem_init_pipe_control(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_gem_object *obj;
+       struct drm_i915_gem_object *obj_priv;
+       int ret;
+
+       obj = drm_gem_object_alloc(dev, 4096);
+       if (obj == NULL) {
+               DRM_ERROR("Failed to allocate seqno page\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+       obj_priv = to_intel_bo(obj);
+       obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
+
+       ret = i915_gem_object_pin(obj, 4096);
+       if (ret)
+               goto err_unref;
+
+       dev_priv->seqno_gfx_addr = obj_priv->gtt_offset;
+       dev_priv->seqno_page =  kmap(obj_priv->pages[0]);
+       if (dev_priv->seqno_page == NULL)
+               goto err_unpin;
+
+       dev_priv->seqno_obj = obj;
+       memset(dev_priv->seqno_page, 0, PAGE_SIZE);
+
+       return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err_unref:
+       drm_gem_object_unreference(obj);
+err:
+       return ret;
+}
+
 static int
 i915_gem_init_hws(struct drm_device *dev)
 {
@@ -4563,15 +4656,16 @@ i915_gem_init_hws(struct drm_device *dev)
        obj = drm_gem_object_alloc(dev, 4096);
        if (obj == NULL) {
                DRM_ERROR("Failed to allocate status page\n");
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
 
        ret = i915_gem_object_pin(obj, 4096);
        if (ret != 0) {
                drm_gem_object_unreference(obj);
-               return ret;
+               goto err_unref;
        }
 
        dev_priv->status_gfx_addr = obj_priv->gtt_offset;
@@ -4580,10 +4674,16 @@ i915_gem_init_hws(struct drm_device *dev)
        if (dev_priv->hw_status_page == NULL) {
                DRM_ERROR("Failed to map status page.\n");
                memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
-               i915_gem_object_unpin(obj);
-               drm_gem_object_unreference(obj);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_unpin;
        }
+
+       if (HAS_PIPE_CONTROL(dev)) {
+               ret = i915_gem_init_pipe_control(dev);
+               if (ret)
+                       goto err_unpin;
+       }
+
        dev_priv->hws_obj = obj;
        memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
        if (IS_GEN6(dev)) {
@@ -4596,6 +4696,30 @@ i915_gem_init_hws(struct drm_device *dev)
        DRM_DEBUG_DRIVER("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
 
        return 0;
+
+err_unpin:
+       i915_gem_object_unpin(obj);
+err_unref:
+       drm_gem_object_unreference(obj);
+err:
+       return 0;
+}
+
+static void
+i915_gem_cleanup_pipe_control(struct drm_device *dev)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_gem_object *obj;
+       struct drm_i915_gem_object *obj_priv;
+
+       obj = dev_priv->seqno_obj;
+       obj_priv = to_intel_bo(obj);
+       kunmap(obj_priv->pages[0]);
+       i915_gem_object_unpin(obj);
+       drm_gem_object_unreference(obj);
+       dev_priv->seqno_obj = NULL;
+
+       dev_priv->seqno_page = NULL;
 }
 
 static void
@@ -4609,7 +4733,7 @@ i915_gem_cleanup_hws(struct drm_device *dev)
                return;
 
        obj = dev_priv->hws_obj;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        kunmap(obj_priv->pages[0]);
        i915_gem_object_unpin(obj);
@@ -4619,6 +4743,9 @@ i915_gem_cleanup_hws(struct drm_device *dev)
        memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
        dev_priv->hw_status_page = NULL;
 
+       if (HAS_PIPE_CONTROL(dev))
+               i915_gem_cleanup_pipe_control(dev);
+
        /* Write high address into HWS_PGA when disabling. */
        I915_WRITE(HWS_PGA, 0x1ffff000);
 }
@@ -4643,7 +4770,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
                i915_gem_cleanup_hws(dev);
                return -ENOMEM;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        ret = i915_gem_object_pin(obj, 4096);
        if (ret != 0) {
@@ -4936,7 +5063,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
        int ret;
        int page_count;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        if (!obj_priv->phys_obj)
                return;
 
@@ -4975,7 +5102,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
        if (id > I915_MAX_PHYS_OBJECT)
                return -EINVAL;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->phys_obj) {
                if (obj_priv->phys_obj->id == id)
@@ -5026,7 +5153,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
                     struct drm_i915_gem_pwrite *args,
                     struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        void *obj_addr;
        int ret;
        char __user *user_data;
index e602614..35507cf 100644 (file)
@@ -72,7 +72,7 @@ void
 i915_gem_dump_object(struct drm_gem_object *obj, int len,
                     const char *where, uint32_t mark)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page;
 
        DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
@@ -137,7 +137,7 @@ void
 i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page;
        uint32_t *gtt_mapping;
        uint32_t *backing_map = NULL;
index c01c878..4bdccef 100644 (file)
@@ -202,21 +202,17 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
                 * reg, so dont bother to check the size */
                if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
                        return false;
-       } else if (IS_I9XX(dev)) {
-               uint32_t pitch_val = ffs(stride / tile_width) - 1;
-
-               /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB)
-                * instead of 4 (2KB) on 945s.
-                */
-               if (pitch_val > I915_FENCE_MAX_PITCH_VAL ||
-                   size > (I830_FENCE_MAX_SIZE_VAL << 20))
+       } else if (IS_GEN3(dev) || IS_GEN2(dev)) {
+               if (stride > 8192)
                        return false;
-       } else {
-               uint32_t pitch_val = ffs(stride / tile_width) - 1;
 
-               if (pitch_val > I830_FENCE_MAX_PITCH_VAL ||
-                   size > (I830_FENCE_MAX_SIZE_VAL << 19))
-                       return false;
+               if (IS_GEN3(dev)) {
+                       if (size > I830_FENCE_MAX_SIZE_VAL << 20)
+                               return false;
+               } else {
+                       if (size > I830_FENCE_MAX_SIZE_VAL << 19)
+                               return false;
+               }
        }
 
        /* 965+ just needs multiples of tile width */
@@ -240,7 +236,7 @@ bool
 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->gtt_space == NULL)
                return true;
@@ -280,7 +276,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
                drm_gem_object_unreference_unlocked(obj);
@@ -364,7 +360,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -427,7 +423,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
@@ -456,7 +452,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
index 49c458b..df6a9cd 100644 (file)
@@ -260,10 +260,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
 
        if (mode_config->num_connector) {
                list_for_each_entry(connector, &mode_config->connector_list, head) {
-                       struct intel_output *intel_output = to_intel_output(connector);
+                       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        
-                       if (intel_output->hot_plug)
-                               (*intel_output->hot_plug) (intel_output);
+                       if (intel_encoder->hot_plug)
+                               (*intel_encoder->hot_plug) (intel_encoder);
                }
        }
        /* Just fire off a uevent and let userspace tell us what to do */
@@ -349,7 +349,7 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
                                READ_BREADCRUMB(dev_priv);
        }
 
-       if (gt_iir & GT_USER_INTERRUPT) {
+       if (gt_iir & GT_PIPE_NOTIFY) {
                u32 seqno = i915_get_gem_seqno(dev);
                dev_priv->mm.irq_gem_seqno = seqno;
                trace_i915_gem_request_complete(dev, seqno);
@@ -444,7 +444,7 @@ i915_error_object_create(struct drm_device *dev,
        if (src == NULL)
                return NULL;
 
-       src_priv = src->driver_private;
+       src_priv = to_intel_bo(src);
        if (src_priv->pages == NULL)
                return NULL;
 
@@ -456,11 +456,15 @@ i915_error_object_create(struct drm_device *dev,
 
        for (page = 0; page < page_count; page++) {
                void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC);
+               unsigned long flags;
+
                if (d == NULL)
                        goto unwind;
-               s = kmap_atomic(src_priv->pages[page], KM_USER0);
+               local_irq_save(flags);
+               s = kmap_atomic(src_priv->pages[page], KM_IRQ0);
                memcpy(d, s, PAGE_SIZE);
-               kunmap_atomic(s, KM_USER0);
+               kunmap_atomic(s, KM_IRQ0);
+               local_irq_restore(flags);
                dst->pages[page] = d;
        }
        dst->page_count = page_count;
@@ -1005,7 +1009,7 @@ void i915_user_irq_get(struct drm_device *dev)
        spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
        if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1)) {
                if (HAS_PCH_SPLIT(dev))
-                       ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+                       ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
                else
                        i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
        }
@@ -1021,7 +1025,7 @@ void i915_user_irq_put(struct drm_device *dev)
        BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
        if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
                if (HAS_PCH_SPLIT(dev))
-                       ironlake_disable_graphics_irq(dev_priv, GT_USER_INTERRUPT);
+                       ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY);
                else
                        i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
        }
@@ -1305,7 +1309,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
        /* enable kind of interrupts always enabled */
        u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
                           DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
-       u32 render_mask = GT_USER_INTERRUPT;
+       u32 render_mask = GT_PIPE_NOTIFY;
        u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
                           SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
 
index 7cc8410..8fcc75c 100644 (file)
@@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_opregion *opregion = &dev_priv->opregion;
        struct drm_connector *connector;
+       acpi_handle handle;
+       struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
+       unsigned long long device_id;
+       acpi_status status;
        int i = 0;
 
+       handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
+       if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
+               return;
+
+       if (acpi_is_video_device(acpi_dev))
+               acpi_video_bus = acpi_dev;
+       else {
+               list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
+                       if (acpi_is_video_device(acpi_cdev)) {
+                               acpi_video_bus = acpi_cdev;
+                               break;
+                       }
+               }
+       }
+
+       if (!acpi_video_bus) {
+               printk(KERN_WARNING "No ACPI video bus found\n");
+               return;
+       }
+
+       list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
+               if (i >= 8) {
+                       dev_printk (KERN_ERR, &dev->pdev->dev,
+                                   "More than 8 outputs detected\n");
+                       return;
+               }
+               status =
+                       acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
+                                               NULL, &device_id);
+               if (ACPI_SUCCESS(status)) {
+                       if (!device_id)
+                               goto blind_set;
+                       opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
+                       i++;
+               }
+       }
+
+end:
+       /* If fewer than 8 outputs, the list must be null terminated */
+       if (i < 8)
+               opregion->acpi->didl[i] = 0;
+       return;
+
+blind_set:
+       i = 0;
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                int output_type = ACPI_OTHER_OUTPUT;
                if (i >= 8) {
@@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)
                opregion->acpi->didl[i] |= (1<<31) | output_type | i;
                i++;
        }
-
-       /* If fewer than 8 outputs, the list must be null terminated */
-       if (i < 8)
-               opregion->acpi->didl[i] = 0;
+       goto end;
 }
 
 int intel_opregion_init(struct drm_device *dev, int resume)
index cbbf59f..4cbc521 100644 (file)
 #define   ASYNC_FLIP                (1<<22)
 #define   DISPLAY_PLANE_A           (0<<20)
 #define   DISPLAY_PLANE_B           (1<<20)
+#define GFX_OP_PIPE_CONTROL    ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
+#define   PIPE_CONTROL_QW_WRITE        (1<<14)
+#define   PIPE_CONTROL_DEPTH_STALL (1<<13)
+#define   PIPE_CONTROL_WC_FLUSH        (1<<12)
+#define   PIPE_CONTROL_IS_FLUSH        (1<<11) /* MBZ on Ironlake */
+#define   PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
+#define   PIPE_CONTROL_ISP_DIS (1<<9)
+#define   PIPE_CONTROL_NOTIFY  (1<<8)
+#define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
+#define   PIPE_CONTROL_STALL_EN        (1<<1) /* in addr word, Ironlake+ only */
 
 /*
  * Fence registers
 #define   I830_FENCE_SIZE_BITS(size)   ((ffs((size) >> 19) - 1) << 8)
 #define   I830_FENCE_PITCH_SHIFT       4
 #define   I830_FENCE_REG_VALID         (1<<0)
-#define   I915_FENCE_MAX_PITCH_VAL     0x10
+#define   I915_FENCE_MAX_PITCH_VAL     4
 #define   I830_FENCE_MAX_PITCH_VAL     6
 #define   I830_FENCE_MAX_SIZE_VAL      (1<<8)
 
 #define DEIER   0x4400c
 
 /* GT interrupt */
+#define GT_PIPE_NOTIFY         (1 << 4)
 #define GT_SYNC_STATUS          (1 << 2)
 #define GT_USER_INTERRUPT       (1 << 0)
 
index 38110ce..759c2ef 100644 (file)
@@ -247,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
 
 static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        /* CRT should always be at 0, but check anyway */
-       if (intel_output->type != INTEL_OUTPUT_ANALOG)
+       if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
                return false;
 
-       return intel_ddc_probe(intel_output);
+       return intel_ddc_probe(intel_encoder);
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -387,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
 static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc;
        int dpms_mode;
        enum drm_connector_status status;
@@ -405,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
 
        /* for pre-945g platforms use load detect */
        if (encoder->crtc && encoder->crtc->enabled) {
-               status = intel_crt_load_detect(encoder->crtc, intel_output);
+               status = intel_crt_load_detect(encoder->crtc, intel_encoder);
        } else {
-               crtc = intel_get_load_detect_pipe(intel_output,
+               crtc = intel_get_load_detect_pipe(intel_encoder,
                                                  NULL, &dpms_mode);
                if (crtc) {
-                       status = intel_crt_load_detect(crtc, intel_output);
-                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+                       status = intel_crt_load_detect(crtc, intel_encoder);
+                       intel_release_load_detect_pipe(intel_encoder, dpms_mode);
                } else
                        status = connector_status_unknown;
        }
@@ -421,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
 
 static void intel_crt_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       intel_i2c_destroy(intel_output->ddc_bus);
+       intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
        kfree(connector);
@@ -432,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector)
 static int intel_crt_get_modes(struct drm_connector *connector)
 {
        int ret;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct i2c_adapter *ddcbus;
        struct drm_device *dev = connector->dev;
 
 
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        if (ret || !IS_G4X(dev))
                goto end;
 
-       ddcbus = intel_output->ddc_bus;
+       ddcbus = intel_encoder->ddc_bus;
        /* Try to probe digital port for output in DVI-I -> VGA mode. */
-       intel_output->ddc_bus =
+       intel_encoder->ddc_bus =
                intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
 
-       if (!intel_output->ddc_bus) {
-               intel_output->ddc_bus = ddcbus;
+       if (!intel_encoder->ddc_bus) {
+               intel_encoder->ddc_bus = ddcbus;
                dev_printk(KERN_ERR, &connector->dev->pdev->dev,
                           "DDC bus registration failed for CRTDDC_D.\n");
                goto end;
        }
        /* Try to get modes by GPIOD port */
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        intel_i2c_destroy(ddcbus);
 
 end:
@@ -506,23 +506,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
 void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 i2c_reg;
 
-       intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output)
+       intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
+       if (!intel_encoder)
                return;
 
-       connector = &intel_output->base;
-       drm_connector_init(dev, &intel_output->base,
+       connector = &intel_encoder->base;
+       drm_connector_init(dev, &intel_encoder->base,
                           &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,
                         DRM_MODE_ENCODER_DAC);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
 
        /* Set up the DDC bus. */
        if (HAS_PCH_SPLIT(dev))
@@ -533,22 +533,22 @@ void intel_crt_init(struct drm_device *dev)
                if (dev_priv->crt_ddc_bus != 0)
                        i2c_reg = dev_priv->crt_ddc_bus;
        }
-       intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
-       if (!intel_output->ddc_bus) {
+       intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
+       if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
                return;
        }
 
-       intel_output->type = INTEL_OUTPUT_ANALOG;
-       intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+       intel_encoder->type = INTEL_OUTPUT_ANALOG;
+       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                   (1 << INTEL_ANALOG_CLONE_BIT) |
                                   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
        drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
        drm_sysfs_connector_add(connector);
index e7e753b..c7502b6 100644 (file)
@@ -747,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
     list_for_each_entry(l_entry, &mode_config->connector_list, head) {
            if (l_entry->encoder &&
                l_entry->encoder->crtc == crtc) {
-                   struct intel_output *intel_output = to_intel_output(l_entry);
-                   if (intel_output->type == type)
+                   struct intel_encoder *intel_encoder = to_intel_encoder(l_entry);
+                   if (intel_encoder->type == type)
                            return true;
            }
     }
     return false;
 }
 
-struct drm_connector *
-intel_pipe_get_output (struct drm_crtc *crtc)
+static struct drm_connector *
+intel_pipe_get_connector (struct drm_crtc *crtc)
 {
     struct drm_device *dev = crtc->dev;
     struct drm_mode_config *mode_config = &dev->mode_config;
@@ -1003,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = crtc->fb;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int plane, i;
        u32 fbc_ctl, fbc_ctl2;
@@ -1080,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = crtc->fb;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :
                     DPFC_CTL_PLANEB);
@@ -1176,7 +1176,7 @@ static void intel_update_fbc(struct drm_crtc *crtc,
                return;
 
        intel_fb = to_intel_framebuffer(fb);
-       obj_priv = intel_fb->obj->driver_private;
+       obj_priv = to_intel_bo(intel_fb->obj);
 
        /*
         * If FBC is already on, we just have to verify that we can
@@ -1243,7 +1243,7 @@ out_disable:
 static int
 intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        u32 alignment;
        int ret;
 
@@ -1323,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
        intel_fb = to_intel_framebuffer(crtc->fb);
        obj = intel_fb->obj;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
        ret = intel_pin_and_fence_fb_obj(dev, obj);
@@ -1401,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
        if (old_fb) {
                intel_fb = to_intel_framebuffer(old_fb);
-               obj_priv = intel_fb->obj->driver_private;
+               obj_priv = to_intel_bo(intel_fb->obj);
                i915_gem_object_unpin(intel_fb->obj);
        }
        intel_increase_pllclock(crtc, true);
@@ -2917,7 +2917,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
        int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
        int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int refclk, num_outputs = 0;
+       int refclk, num_connectors = 0;
        intel_clock_t clock, reduced_clock;
        u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
        bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
@@ -2943,19 +2943,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        drm_vblank_pre_modeset(dev, pipe);
 
        list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
                if (!connector->encoder || connector->encoder->crtc != crtc)
                        continue;
 
-               switch (intel_output->type) {
+               switch (intel_encoder->type) {
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
                case INTEL_OUTPUT_SDVO:
                case INTEL_OUTPUT_HDMI:
                        is_sdvo = true;
-                       if (intel_output->needs_tv_clock)
+                       if (intel_encoder->needs_tv_clock)
                                is_tv = true;
                        break;
                case INTEL_OUTPUT_DVO:
@@ -2975,10 +2975,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                        break;
                }
 
-               num_outputs++;
+               num_connectors++;
        }
 
-       if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+       if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) {
                refclk = dev_priv->lvds_ssc_freq * 1000;
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
                                        refclk / 1000);
@@ -3049,8 +3049,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                if (is_edp) {
                        struct drm_connector *edp;
                        target_clock = mode->clock;
-                       edp = intel_pipe_get_output(crtc);
-                       intel_edp_link_config(to_intel_output(edp),
+                       edp = intel_pipe_get_connector(crtc);
+                       intel_edp_link_config(to_intel_encoder(edp),
                                        &lane, &link_bw);
                } else {
                        /* DP over FDI requires target mode clock
@@ -3231,7 +3231,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                /* XXX: just matching BIOS for now */
                /*      dpll |= PLL_REF_INPUT_TVCLKINBC; */
                dpll |= 3;
-       else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+       else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2)
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
@@ -3511,7 +3511,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        if (!bo)
                return -ENOENT;
 
-       obj_priv = bo->driver_private;
+       obj_priv = to_intel_bo(bo);
 
        if (bo->size < width * height * 4) {
                DRM_ERROR("buffer is to small\n");
@@ -3655,9 +3655,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
  * detection.
  *
  * It will be up to the load-detect code to adjust the pipe as appropriate for
- * its requirements.  The pipe will be connected to no other outputs.
+ * its requirements.  The pipe will be connected to no other encoders.
  *
- * Currently this code will only succeed if there is a pipe with no outputs
+ * Currently this code will only succeed if there is a pipe with no encoders
  * configured for it.  In the future, it could choose to temporarily disable
  * some outputs to free up a pipe for its use.
  *
@@ -3670,14 +3670,14 @@ static struct drm_display_mode load_detect_mode = {
                 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 };
 
-struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                            struct drm_display_mode *mode,
                                            int *dpms_mode)
 {
        struct intel_crtc *intel_crtc;
        struct drm_crtc *possible_crtc;
        struct drm_crtc *supported_crtc =NULL;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = NULL;
        struct drm_device *dev = encoder->dev;
        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
@@ -3729,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
        }
 
        encoder->crtc = crtc;
-       intel_output->base.encoder = encoder;
-       intel_output->load_detect_temp = true;
+       intel_encoder->base.encoder = encoder;
+       intel_encoder->load_detect_temp = true;
 
        intel_crtc = to_intel_crtc(crtc);
        *dpms_mode = intel_crtc->dpms_mode;
@@ -3755,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
        return crtc;
 }
 
-void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
+void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_crtc *crtc = encoder->crtc;
        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-       if (intel_output->load_detect_temp) {
+       if (intel_encoder->load_detect_temp) {
                encoder->crtc = NULL;
-               intel_output->base.encoder = NULL;
-               intel_output->load_detect_temp = false;
+               intel_encoder->base.encoder = NULL;
+               intel_encoder->load_detect_temp = false;
                crtc->enabled = drm_helper_crtc_in_use(crtc);
                drm_helper_disable_unused_functions(dev);
        }
 
-       /* Switch crtc and output back off if necessary */
+       /* Switch crtc and encoder back off if necessary */
        if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
                if (encoder->crtc == crtc)
                        encoder_funcs->dpms(encoder, dpms_mode);
@@ -4156,7 +4156,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
        work = intel_crtc->unpin_work;
        if (work == NULL || !work->pending) {
                if (work && !work->pending) {
-                       obj_priv = work->pending_flip_obj->driver_private;
+                       obj_priv = to_intel_bo(work->pending_flip_obj);
                        DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
                                         obj_priv,
                                         atomic_read(&obj_priv->pending_flip));
@@ -4181,7 +4181,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
-       obj_priv = work->pending_flip_obj->driver_private;
+       obj_priv = to_intel_bo(work->pending_flip_obj);
 
        /* Initial scanout buffer will have a 0 pending flip count */
        if ((atomic_read(&obj_priv->pending_flip) == 0) ||
@@ -4252,7 +4252,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        ret = intel_pin_and_fence_fb_obj(dev, obj);
        if (ret != 0) {
                DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-                         obj->driver_private);
+                         to_intel_bo(obj));
                kfree(work);
                intel_crtc->unpin_work = NULL;
                mutex_unlock(&dev->struct_mutex);
@@ -4266,7 +4266,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        crtc->fb = fb;
        i915_gem_object_flush_write_domain(obj);
        drm_vblank_get(dev, intel_crtc->pipe);
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        atomic_inc(&obj_priv->pending_flip);
        work->pending_flip_obj = obj;
 
@@ -4399,8 +4399,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
        int entry = 0;
 
         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               if (type_mask & intel_output->clone_mask)
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               if (type_mask & intel_encoder->clone_mask)
                        index_mask |= (1 << entry);
                entry++;
        }
@@ -4495,12 +4495,12 @@ static void intel_setup_outputs(struct drm_device *dev)
                intel_tv_init(dev);
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               struct drm_encoder *encoder = &intel_output->enc;
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               struct drm_encoder *encoder = &intel_encoder->enc;
 
-               encoder->possible_crtcs = intel_output->crtc_mask;
+               encoder->possible_crtcs = intel_encoder->crtc_mask;
                encoder->possible_clones = intel_connector_clones(dev,
-                                               intel_output->clone_mask);
+                                               intel_encoder->clone_mask);
        }
 }
 
@@ -4779,14 +4779,14 @@ void intel_init_clock_gating(struct drm_device *dev)
                struct drm_i915_gem_object *obj_priv = NULL;
 
                if (dev_priv->pwrctx) {
-                       obj_priv = dev_priv->pwrctx->driver_private;
+                       obj_priv = to_intel_bo(dev_priv->pwrctx);
                } else {
                        struct drm_gem_object *pwrctx;
 
                        pwrctx = intel_alloc_power_context(dev);
                        if (pwrctx) {
                                dev_priv->pwrctx = pwrctx;
-                               obj_priv = pwrctx->driver_private;
+                               obj_priv = to_intel_bo(pwrctx);
                        }
                }
 
@@ -4815,7 +4815,7 @@ static void intel_init_display(struct drm_device *dev)
                        dev_priv->display.fbc_enabled = g4x_fbc_enabled;
                        dev_priv->display.enable_fbc = g4x_enable_fbc;
                        dev_priv->display.disable_fbc = g4x_disable_fbc;
-               } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) {
+               } else if (IS_I965GM(dev)) {
                        dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
                        dev_priv->display.enable_fbc = i8xx_enable_fbc;
                        dev_priv->display.disable_fbc = i8xx_disable_fbc;
@@ -4853,17 +4853,18 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.update_wm = g4x_update_wm;
        else if (IS_I965G(dev))
                dev_priv->display.update_wm = i965_update_wm;
-       else if (IS_I9XX(dev) || IS_MOBILE(dev)) {
+       else if (IS_I9XX(dev)) {
                dev_priv->display.update_wm = i9xx_update_wm;
                dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+       } else if (IS_I85X(dev)) {
+               dev_priv->display.update_wm = i9xx_update_wm;
+               dev_priv->display.get_fifo_size = i85x_get_fifo_size;
        } else {
-               if (IS_I85X(dev))
-                       dev_priv->display.get_fifo_size = i85x_get_fifo_size;
-               else if (IS_845G(dev))
+               dev_priv->display.update_wm = i830_update_wm;
+               if (IS_845G(dev))
                        dev_priv->display.get_fifo_size = i845_get_fifo_size;
                else
                        dev_priv->display.get_fifo_size = i830_get_fifo_size;
-               dev_priv->display.update_wm = i830_update_wm;
        }
 }
 
@@ -4957,7 +4958,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
        if (dev_priv->pwrctx) {
                struct drm_i915_gem_object *obj_priv;
 
-               obj_priv = dev_priv->pwrctx->driver_private;
+               obj_priv = to_intel_bo(dev_priv->pwrctx);
                I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
                I915_READ(PWRCTXA);
                i915_gem_object_unpin(dev_priv->pwrctx);
@@ -4978,9 +4979,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
 */
 struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       return &intel_output->enc;
+       return &intel_encoder->enc;
 }
 
 /*
index 8e283f7..77e40cf 100644 (file)
@@ -55,23 +55,23 @@ struct intel_dp_priv {
        uint8_t link_bw;
        uint8_t lane_count;
        uint8_t dpcd[4];
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct i2c_adapter adapter;
        struct i2c_algo_dp_aux_data algo;
 };
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
                    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
 
 void
-intel_edp_link_config (struct intel_output *intel_output,
+intel_edp_link_config (struct intel_encoder *intel_encoder,
                int *lane_num, int *link_bw)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
        *lane_num = dp_priv->lane_count;
        if (dp_priv->link_bw == DP_LINK_BW_1_62)
@@ -81,9 +81,9 @@ intel_edp_link_config (struct intel_output *intel_output,
 }
 
 static int
-intel_dp_max_lane_count(struct intel_output *intel_output)
+intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int max_lane_count = 4;
 
        if (dp_priv->dpcd[0] >= 0x11) {
@@ -99,9 +99,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output)
 }
 
 static int
-intel_dp_max_link_bw(struct intel_output *intel_output)
+intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int max_link_bw = dp_priv->dpcd[1];
 
        switch (max_link_bw) {
@@ -127,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw)
 /* I think this is a fiction */
 static int
 intel_dp_link_required(struct drm_device *dev,
-                      struct intel_output *intel_output, int pixel_clock)
+                      struct intel_encoder *intel_encoder, int pixel_clock)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                return (pixel_clock * dev_priv->edp_bpp) / 8;
        else
                return pixel_clock * 3;
@@ -141,11 +141,11 @@ static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
-       int max_lanes = intel_dp_max_lane_count(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
+       int max_lanes = intel_dp_max_lane_count(intel_encoder);
 
-       if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+       if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
                        > max_link_clock * max_lanes)
                return MODE_CLOCK_HIGH;
 
@@ -209,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)
 }
 
 static int
-intel_dp_aux_ch(struct intel_output *intel_output,
+intel_dp_aux_ch(struct intel_encoder *intel_encoder,
                uint8_t *send, int send_bytes,
                uint8_t *recv, int recv_size)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint32_t output_reg = dp_priv->output_reg;
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t ch_ctl = output_reg + 0x10;
        uint32_t ch_data = ch_ctl + 4;
@@ -230,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
         * and would like to run at 2MHz. So, take the
         * hrawclk value and divide by 2 and use that
         */
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                aux_clock_divider = 225; /* eDP input clock at 450Mhz */
        else if (HAS_PCH_SPLIT(dev))
                aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
@@ -313,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
 
 /* Write data to the aux channel in native mode */
 static int
-intel_dp_aux_native_write(struct intel_output *intel_output,
+intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
                          uint16_t address, uint8_t *send, int send_bytes)
 {
        int ret;
@@ -330,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
        memcpy(&msg[4], send, send_bytes);
        msg_bytes = send_bytes + 4;
        for (;;) {
-               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1);
+               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
                if (ret < 0)
                        return ret;
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
@@ -345,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
 
 /* Write a single byte to the aux channel in native mode */
 static int
-intel_dp_aux_native_write_1(struct intel_output *intel_output,
+intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
                            uint16_t address, uint8_t byte)
 {
-       return intel_dp_aux_native_write(intel_output, address, &byte, 1);
+       return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
 }
 
 /* read bytes from a native aux channel */
 static int
-intel_dp_aux_native_read(struct intel_output *intel_output,
+intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
                         uint16_t address, uint8_t *recv, int recv_bytes)
 {
        uint8_t msg[4];
@@ -372,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
        reply_bytes = recv_bytes + 1;
 
        for (;;) {
-               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes,
+               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
                                      reply, reply_bytes);
                if (ret == 0)
                        return -EPROTO;
@@ -398,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        struct intel_dp_priv *dp_priv = container_of(adapter,
                                                     struct intel_dp_priv,
                                                     adapter);
-       struct intel_output *intel_output = dp_priv->intel_output;
+       struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
        uint16_t address = algo_data->address;
        uint8_t msg[5];
        uint8_t reply[2];
@@ -437,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        }
 
        for (;;) {
-         ret = intel_dp_aux_ch(intel_output,
+         ret = intel_dp_aux_ch(intel_encoder,
                                msg, msg_bytes,
                                reply, reply_bytes);
                if (ret < 0) {
@@ -465,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 }
 
 static int
-intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
+intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
        DRM_DEBUG_KMS("i2c_init %s\n", name);
        dp_priv->algo.running = false;
@@ -480,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
        strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
        dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
        dp_priv->adapter.algo_data = &dp_priv->algo;
-       dp_priv->adapter.dev.parent = &intel_output->base.kdev;
+       dp_priv->adapter.dev.parent = &intel_encoder->base.kdev;
        
        return i2c_dp_aux_add_bus(&dp_priv->adapter);
 }
@@ -489,18 +489,18 @@ static bool
 intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                    struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int lane_count, clock;
-       int max_lane_count = intel_dp_max_lane_count(intel_output);
-       int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0;
+       int max_lane_count = intel_dp_max_lane_count(intel_encoder);
+       int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
 
-                       if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+                       if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
                                        <= link_avail) {
                                dp_priv->link_bw = bws[clock];
                                dp_priv->lane_count = lane_count;
@@ -562,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
        struct intel_dp_m_n m_n;
 
        /*
-        * Find the lane count in the intel_output private
+        * Find the lane count in the intel_encoder private
         */
        list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
                if (!connector->encoder || connector->encoder->crtc != crtc)
                        continue;
 
-               if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
+               if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
                        lane_count = dp_priv->lane_count;
                        break;
                }
@@ -626,9 +626,9 @@ static void
 intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-       struct drm_crtc *crtc = intel_output->enc.crtc;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_crtc *crtc = intel_encoder->enc.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
        dp_priv->DP = (DP_LINK_TRAIN_OFF |
@@ -667,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        if (intel_crtc->pipe == 1)
                dp_priv->DP |= DP_PIPEB_SELECT;
 
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                /* don't miss out required setting for eDP */
                dp_priv->DP |= DP_PLL_ENABLE;
                if (adjusted_mode->clock < 200000)
@@ -702,22 +702,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
 static void
 intel_dp_dpms(struct drm_encoder *encoder, int mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t dp_reg = I915_READ(dp_priv->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
                if (dp_reg & DP_PORT_EN) {
-                       intel_dp_link_down(intel_output, dp_priv->DP);
-                       if (IS_eDP(intel_output))
+                       intel_dp_link_down(intel_encoder, dp_priv->DP);
+                       if (IS_eDP(intel_encoder))
                                ironlake_edp_backlight_off(dev);
                }
        } else {
                if (!(dp_reg & DP_PORT_EN)) {
-                       intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
-                       if (IS_eDP(intel_output))
+                       intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
+                       if (IS_eDP(intel_encoder))
                                ironlake_edp_backlight_on(dev);
                }
        }
@@ -729,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_output *intel_output,
+intel_dp_get_link_status(struct intel_encoder *intel_encoder,
                         uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        int ret;
 
-       ret = intel_dp_aux_native_read(intel_output,
+       ret = intel_dp_aux_native_read(intel_encoder,
                                       DP_LANE0_1_STATUS,
                                       link_status, DP_LINK_STATUS_SIZE);
        if (ret != DP_LINK_STATUS_SIZE)
@@ -752,13 +752,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
 static void
 intel_dp_save(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        dp_priv->save_DP = I915_READ(dp_priv->output_reg);
-       intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
+       intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,
                                 dp_priv->save_link_configuration,
                                 sizeof (dp_priv->save_link_configuration));
 }
@@ -825,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
 }
 
 static void
-intel_get_adjust_train(struct intel_output *intel_output,
+intel_get_adjust_train(struct intel_encoder *intel_encoder,
                       uint8_t link_status[DP_LINK_STATUS_SIZE],
                       int lane_count,
                       uint8_t train_set[4])
@@ -942,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
 }
 
 static bool
-intel_dp_set_link_train(struct intel_output *intel_output,
+intel_dp_set_link_train(struct intel_encoder *intel_encoder,
                        uint32_t dp_reg_value,
                        uint8_t dp_train_pat,
                        uint8_t train_set[4],
                        bool first)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        int ret;
 
        I915_WRITE(dp_priv->output_reg, dp_reg_value);
@@ -958,11 +958,11 @@ intel_dp_set_link_train(struct intel_output *intel_output,
        if (first)
                intel_wait_for_vblank(dev);
 
-       intel_dp_aux_native_write_1(intel_output,
+       intel_dp_aux_native_write_1(intel_encoder,
                                    DP_TRAINING_PATTERN_SET,
                                    dp_train_pat);
 
-       ret = intel_dp_aux_native_write(intel_output,
+       ret = intel_dp_aux_native_write(intel_encoder,
                                        DP_TRAINING_LANE0_SET, train_set, 4);
        if (ret != 4)
                return false;
@@ -971,12 +971,12 @@ intel_dp_set_link_train(struct intel_output *intel_output,
 }
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
                    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint8_t train_set[4];
        uint8_t link_status[DP_LINK_STATUS_SIZE];
        int i;
@@ -987,7 +987,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
        int tries;
 
        /* Write the link configuration data */
-       intel_dp_aux_native_write(intel_output, 0x100,
+       intel_dp_aux_native_write(intel_encoder, 0x100,
                                  link_configuration, DP_LINK_CONFIGURATION_SIZE);
 
        DP |= DP_PORT_EN;
@@ -1001,14 +1001,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                uint32_t    signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
                DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
-               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1,
+               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,
                                             DP_TRAINING_PATTERN_1, train_set, first))
                        break;
                first = false;
                /* Set training pattern 1 */
 
                udelay(100);
-               if (!intel_dp_get_link_status(intel_output, link_status))
+               if (!intel_dp_get_link_status(intel_encoder, link_status))
                        break;
 
                if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
@@ -1033,7 +1033,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
                /* Compute new train_set as requested by target */
-               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
        }
 
        /* channel equalization */
@@ -1045,13 +1045,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
                /* channel eq pattern */
-               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2,
+               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,
                                             DP_TRAINING_PATTERN_2, train_set,
                                             false))
                        break;
 
                udelay(400);
-               if (!intel_dp_get_link_status(intel_output, link_status))
+               if (!intel_dp_get_link_status(intel_encoder, link_status))
                        break;
 
                if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
@@ -1064,26 +1064,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                        break;
 
                /* Compute new train_set as requested by target */
-               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
                ++tries;
        }
 
        I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);
        POSTING_READ(dp_priv->output_reg);
-       intel_dp_aux_native_write_1(intel_output,
+       intel_dp_aux_native_write_1(intel_encoder,
                                    DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        DRM_DEBUG_KMS("\n");
 
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                DP &= ~DP_PLL_ENABLE;
                I915_WRITE(dp_priv->output_reg, DP);
                POSTING_READ(dp_priv->output_reg);
@@ -1096,7 +1096,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
 
        udelay(17000);
 
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                DP |= DP_LINK_TRAIN_OFF;
        I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(dp_priv->output_reg);
@@ -1105,13 +1105,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
 static void
 intel_dp_restore(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        if (dp_priv->save_DP & DP_PORT_EN)
-               intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration);
+               intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);
        else
-               intel_dp_link_down(intel_output,  dp_priv->save_DP);
+               intel_dp_link_down(intel_encoder,  dp_priv->save_DP);
 }
 
 /*
@@ -1124,32 +1124,32 @@ intel_dp_restore(struct drm_connector *connector)
  */
 
 static void
-intel_dp_check_link_status(struct intel_output *intel_output)
+intel_dp_check_link_status(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint8_t link_status[DP_LINK_STATUS_SIZE];
 
-       if (!intel_output->enc.crtc)
+       if (!intel_encoder->enc.crtc)
                return;
 
-       if (!intel_dp_get_link_status(intel_output, link_status)) {
-               intel_dp_link_down(intel_output, dp_priv->DP);
+       if (!intel_dp_get_link_status(intel_encoder, link_status)) {
+               intel_dp_link_down(intel_encoder, dp_priv->DP);
                return;
        }
 
        if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
-               intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
+               intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
 }
 
 static enum drm_connector_status
 ironlake_dp_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        enum drm_connector_status status;
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_output,
+       if (intel_dp_aux_native_read(intel_encoder,
                                     0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
        {
@@ -1168,10 +1168,10 @@ ironlake_dp_detect(struct drm_connector *connector)
 static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint32_t temp, bit;
        enum drm_connector_status status;
 
@@ -1210,7 +1210,7 @@ intel_dp_detect(struct drm_connector *connector)
                return connector_status_disconnected;
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_output,
+       if (intel_dp_aux_native_read(intel_encoder,
                                     0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
        {
@@ -1222,20 +1222,20 @@ intel_dp_detect(struct drm_connector *connector)
 
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
 
        /* We should parse the EDID data and find out if it has an audio sink
         */
 
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        if (ret)
                return ret;
 
        /* if eDP has no EDID, try to use fixed panel mode from VBT */
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                if (dev_priv->panel_fixed_mode != NULL) {
                        struct drm_display_mode *mode;
                        mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1249,13 +1249,13 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 static void
 intel_dp_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
@@ -1291,12 +1291,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
 };
 
 void
-intel_dp_hot_plug(struct intel_output *intel_output)
+intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
-               intel_dp_check_link_status(intel_output);
+               intel_dp_check_link_status(intel_encoder);
 }
 
 void
@@ -1304,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_dp_priv *dp_priv;
        const char *name = NULL;
 
-       intel_output = kcalloc(sizeof(struct intel_output) + 
+       intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
-       if (!intel_output)
+       if (!intel_encoder)
                return;
 
-       dp_priv = (struct intel_dp_priv *)(intel_output + 1);
+       dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_dp_connector_funcs,
                           DRM_MODE_CONNECTOR_DisplayPort);
        drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
        if (output_reg == DP_A)
-               intel_output->type = INTEL_OUTPUT_EDP;
+               intel_encoder->type = INTEL_OUTPUT_EDP;
        else
-               intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+               intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 
        if (output_reg == DP_B || output_reg == PCH_DP_B)
-               intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
        else if (output_reg == DP_C || output_reg == PCH_DP_C)
-               intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
        else if (output_reg == DP_D || output_reg == PCH_DP_D)
-               intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
-       if (IS_eDP(intel_output))
-               intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+       if (IS_eDP(intel_encoder))
+               intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
 
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
 
-       dp_priv->intel_output = intel_output;
+       dp_priv->intel_encoder = intel_encoder;
        dp_priv->output_reg = output_reg;
        dp_priv->has_audio = false;
        dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
-       intel_output->dev_priv = dp_priv;
+       intel_encoder->dev_priv = dp_priv;
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
                         DRM_MODE_ENCODER_TMDS);
-       drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
        drm_sysfs_connector_add(connector);
 
        /* Set up the DDC bus. */
@@ -1378,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                        break;
        }
 
-       intel_dp_i2c_init(intel_output, name);
+       intel_dp_i2c_init(intel_encoder, name);
 
-       intel_output->ddc_bus = &dp_priv->adapter;
-       intel_output->hot_plug = intel_dp_hot_plug;
+       intel_encoder->ddc_bus = &dp_priv->adapter;
+       intel_encoder->hot_plug = intel_dp_hot_plug;
 
        if (output_reg == DP_A) {
                /* initialize panel mode from VBT if available for eDP */
index 3a467ca..e302537 100644 (file)
@@ -95,7 +95,7 @@ struct intel_framebuffer {
 };
 
 
-struct intel_output {
+struct intel_encoder {
        struct drm_connector base;
 
        struct drm_encoder enc;
@@ -105,7 +105,7 @@ struct intel_output {
        bool load_detect_temp;
        bool needs_tv_clock;
        void *dev_priv;
-       void (*hot_plug)(struct intel_output *);
+       void (*hot_plug)(struct intel_encoder *);
        int crtc_mask;
        int clone_mask;
 };
@@ -152,15 +152,15 @@ struct intel_crtc {
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
-#define to_intel_output(x) container_of(x, struct intel_output, base)
-#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
+#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
+#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
 
 struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
                                     const char *name);
 void intel_i2c_destroy(struct i2c_adapter *adapter);
-int intel_ddc_get_modes(struct intel_output *intel_output);
-extern bool intel_ddc_probe(struct intel_output *intel_output);
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder);
+extern bool intel_ddc_probe(struct intel_encoder *intel_encoder);
 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
 void intel_i2c_reset_gmbus(struct drm_device *dev);
 
@@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                 struct drm_display_mode *adjusted_mode);
-extern void intel_edp_link_config (struct intel_output *, int *, int *);
+extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 
 
 extern int intel_panel_fitter_pipe (struct drm_device *dev);
@@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 extern void intel_wait_for_vblank(struct drm_device *dev);
 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_output *intel_output,
+extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                                   struct drm_display_mode *mode,
                                                   int *dpms_mode);
-extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
+extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
                                           int dpms_mode);
 
 extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
index 0427ca5..ebf213c 100644 (file)
@@ -80,8 +80,8 @@ static struct intel_dvo_device intel_dvo_devices[] = {
 static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        u32 dvo_reg = dvo->dvo_reg;
        u32 temp = I915_READ(dvo_reg);
 
@@ -99,8 +99,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 static void intel_dvo_save(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* Each output should probably just save the registers it touches,
         * but for now, use more overkill.
@@ -115,8 +115,8 @@ static void intel_dvo_save(struct drm_connector *connector)
 static void intel_dvo_restore(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        dvo->dev_ops->restore(dvo);
 
@@ -128,8 +128,8 @@ static void intel_dvo_restore(struct drm_connector *connector)
 static int intel_dvo_mode_valid(struct drm_connector *connector,
                                struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -150,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
                                 struct drm_display_mode *mode,
                                 struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* If we have timings from the BIOS for the panel, put them in
         * to the adjusted mode.  The CRTC will be set up for this mode,
@@ -186,8 +186,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        int pipe = intel_crtc->pipe;
        u32 dvo_val;
        u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
@@ -241,23 +241,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
  */
 static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        return dvo->dev_ops->detect(dvo);
 }
 
 static int intel_dvo_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* We should probably have an i2c driver get_modes function for those
         * devices which will have a fixed set of modes determined by the chip
         * (TV-out, for example), but for now with just TMDS and LVDS,
         * that's not the case.
         */
-       intel_ddc_get_modes(intel_output);
+       intel_ddc_get_modes(intel_encoder);
        if (!list_empty(&connector->probed_modes))
                return 1;
 
@@ -275,8 +275,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
 
 static void intel_dvo_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        if (dvo) {
                if (dvo->dev_ops->destroy)
@@ -286,13 +286,13 @@ static void intel_dvo_destroy (struct drm_connector *connector)
                /* no need, in i830_dvoices[] now */
                //kfree(dvo);
        }
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 #ifdef RANDR_GET_CRTC_INTERFACE
@@ -300,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
 
        return intel_pipe_to_crtc(pScrn, pipe);
@@ -352,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        uint32_t dvo_reg = dvo->dvo_reg;
        uint32_t dvo_val = I915_READ(dvo_reg);
        struct drm_display_mode *mode = NULL;
@@ -383,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
 
 void intel_dvo_init(struct drm_device *dev)
 {
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_dvo_device *dvo;
        struct i2c_adapter *i2cbus = NULL;
        int ret = 0;
        int i;
        int encoder_type = DRM_MODE_ENCODER_NONE;
-       intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output)
+       intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
+       if (!intel_encoder)
                return;
 
        /* Set up the DDC bus */
-       intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
-       if (!intel_output->ddc_bus)
+       intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
+       if (!intel_encoder->ddc_bus)
                goto free_intel;
 
        /* Now, try to find a controller */
        for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
-               struct drm_connector *connector = &intel_output->base;
+               struct drm_connector *connector = &intel_encoder->base;
                int gpio;
 
                dvo = &intel_dvo_devices[i];
@@ -435,11 +435,11 @@ void intel_dvo_init(struct drm_device *dev)
                if (!ret)
                        continue;
 
-               intel_output->type = INTEL_OUTPUT_DVO;
-               intel_output->crtc_mask = (1 << 0) | (1 << 1);
+               intel_encoder->type = INTEL_OUTPUT_DVO;
+               intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
                switch (dvo->type) {
                case INTEL_DVO_CHIP_TMDS:
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                (1 << INTEL_DVO_TMDS_CLONE_BIT) |
                                (1 << INTEL_ANALOG_CLONE_BIT);
                        drm_connector_init(dev, connector,
@@ -448,7 +448,7 @@ void intel_dvo_init(struct drm_device *dev)
                        encoder_type = DRM_MODE_ENCODER_TMDS;
                        break;
                case INTEL_DVO_CHIP_LVDS:
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                (1 << INTEL_DVO_LVDS_CLONE_BIT);
                        drm_connector_init(dev, connector,
                                           &intel_dvo_connector_funcs,
@@ -463,16 +463,16 @@ void intel_dvo_init(struct drm_device *dev)
                connector->interlace_allowed = false;
                connector->doublescan_allowed = false;
 
-               intel_output->dev_priv = dvo;
-               intel_output->i2c_bus = i2cbus;
+               intel_encoder->dev_priv = dvo;
+               intel_encoder->i2c_bus = i2cbus;
 
-               drm_encoder_init(dev, &intel_output->enc,
+               drm_encoder_init(dev, &intel_encoder->enc,
                                 &intel_dvo_enc_funcs, encoder_type);
-               drm_encoder_helper_add(&intel_output->enc,
+               drm_encoder_helper_add(&intel_encoder->enc,
                                       &intel_dvo_helper_funcs);
 
-               drm_mode_connector_attach_encoder(&intel_output->base,
-                                                 &intel_output->enc);
+               drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                                 &intel_encoder->enc);
                if (dvo->type == INTEL_DVO_CHIP_LVDS) {
                        /* For our LVDS chipsets, we should hopefully be able
                         * to dig the fixed panel mode out of the BIOS data.
@@ -490,10 +490,10 @@ void intel_dvo_init(struct drm_device *dev)
                return;
        }
 
-       intel_i2c_destroy(intel_output->ddc_bus);
+       intel_i2c_destroy(intel_encoder->ddc_bus);
        /* Didn't find a chip, so tear down. */
        if (i2cbus != NULL)
                intel_i2c_destroy(i2cbus);
 free_intel:
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
index 69bbef9..8a0b3bc 100644 (file)
@@ -144,7 +144,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
                ret = -ENOMEM;
                goto out;
        }
-       obj_priv = fbo->driver_private;
+       obj_priv = to_intel_bo(fbo);
 
        mutex_lock(&dev->struct_mutex);
 
index 1ed02f6..48cade0 100644 (file)
@@ -51,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 sdvox;
 
        sdvox = SDVO_ENCODING_HDMI |
@@ -74,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 temp;
 
        temp = I915_READ(hdmi_priv->sdvox_reg);
@@ -110,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
        hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
 }
@@ -120,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
        I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
        POSTING_READ(hdmi_priv->sdvox_reg);
@@ -151,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        struct edid *edid = NULL;
        enum drm_connector_status status = connector_status_disconnected;
 
        hdmi_priv->has_hdmi_sink = false;
-       edid = drm_get_edid(&intel_output->base,
-                           intel_output->ddc_bus);
+       edid = drm_get_edid(&intel_encoder->base,
+                           intel_encoder->ddc_bus);
 
        if (edid) {
                if (edid->input & DRM_EDID_INPUT_DIGITAL) {
                        status = connector_status_connected;
                        hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
                }
-               intel_output->base.display_info.raw_edid = NULL;
+               intel_encoder->base.display_info.raw_edid = NULL;
                kfree(edid);
        }
 
@@ -174,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector)
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        /* We should parse the EDID data and find out if it's an HDMI sink so
         * we can send audio to it.
         */
 
-       return intel_ddc_get_modes(intel_output);
+       return intel_ddc_get_modes(intel_encoder);
 }
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
@@ -230,63 +230,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_hdmi_priv *hdmi_priv;
 
-       intel_output = kcalloc(sizeof(struct intel_output) +
+       intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
-       if (!intel_output)
+       if (!intel_encoder)
                return;
-       hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1);
+       hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
                           DRM_MODE_CONNECTOR_HDMIA);
        drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
 
-       intel_output->type = INTEL_OUTPUT_HDMI;
+       intel_encoder->type = INTEL_OUTPUT_HDMI;
 
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
        /* Set up the DDC bus. */
        if (sdvox_reg == SDVOB) {
-               intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+               intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == SDVOC) {
-               intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+               intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIB) {
-               intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
+               intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
                                                                "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIC) {
-               intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
+               intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
                                                                "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMID) {
-               intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
+               intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
                                                                "HDMID");
                dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
        }
-       if (!intel_output->ddc_bus)
+       if (!intel_encoder->ddc_bus)
                goto err_connector;
 
        hdmi_priv->sdvox_reg = sdvox_reg;
-       intel_output->dev_priv = hdmi_priv;
+       intel_encoder->dev_priv = hdmi_priv;
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
                         DRM_MODE_ENCODER_TMDS);
-       drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
        drm_sysfs_connector_add(connector);
 
        /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -302,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 
 err_connector:
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 
        return;
 }
index 216e9f5..b66806a 100644 (file)
@@ -239,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
        struct drm_encoder *tmp_encoder;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
        u32 pfit_control = 0, pfit_pgm_ratios = 0;
        int left_border = 0, right_border = 0, top_border = 0;
        int bottom_border = 0;
@@ -587,8 +587,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
 
        /*
         * The LVDS pin pair will already have been turned on in the
@@ -635,14 +635,16 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
 static int intel_lvds_get_modes(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret = 0;
 
-       ret = intel_ddc_get_modes(intel_output);
+       if (dev_priv->lvds_edid_good) {
+               ret = intel_ddc_get_modes(intel_encoder);
 
-       if (ret)
-               return ret;
+               if (ret)
+                       return ret;
+       }
 
        /* Didn't get an EDID, so
         * Set wide sync ranges so we get all modes
@@ -715,11 +717,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
 static void intel_lvds_destroy(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        if (dev_priv->lid_notifier.notifier_call)
                acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
        drm_sysfs_connector_remove(connector);
@@ -732,13 +734,13 @@ static int intel_lvds_set_property(struct drm_connector *connector,
                                   uint64_t value)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output =
-                       to_intel_output(connector);
+       struct intel_encoder *intel_encoder =
+                       to_intel_encoder(connector);
 
        if (property == dev->mode_config.scaling_mode_property &&
                                connector->encoder) {
                struct drm_crtc *crtc = connector->encoder->crtc;
-               struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+               struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
                if (value == DRM_MODE_SCALE_NONE) {
                        DRM_DEBUG_KMS("no scaling not supported\n");
                        return 0;
@@ -858,6 +860,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "Clientron U800",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
+               },
+       },
 
        { }     /* terminating entry */
 };
@@ -968,7 +978,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
 void intel_lvds_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct drm_connector *connector;
        struct drm_encoder *encoder;
        struct drm_display_mode *scan; /* *modes, *bios_mode; */
@@ -996,40 +1006,40 @@ void intel_lvds_init(struct drm_device *dev)
                gpio = PCH_GPIOC;
        }
 
-       intel_output = kzalloc(sizeof(struct intel_output) +
+       intel_encoder = kzalloc(sizeof(struct intel_encoder) +
                                sizeof(struct intel_lvds_priv), GFP_KERNEL);
-       if (!intel_output) {
+       if (!intel_encoder) {
                return;
        }
 
-       connector = &intel_output->base;
-       encoder = &intel_output->enc;
-       drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
+       connector = &intel_encoder->base;
+       encoder = &intel_encoder->enc;
+       drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs,
                           DRM_MODE_CONNECTOR_LVDS);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
                         DRM_MODE_ENCODER_LVDS);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-       intel_output->type = INTEL_OUTPUT_LVDS;
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+       intel_encoder->type = INTEL_OUTPUT_LVDS;
 
-       intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
-       intel_output->crtc_mask = (1 << 1);
+       intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+       intel_encoder->crtc_mask = (1 << 1);
        drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
 
-       lvds_priv = (struct intel_lvds_priv *)(intel_output + 1);
-       intel_output->dev_priv = lvds_priv;
+       lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
+       intel_encoder->dev_priv = lvds_priv;
        /* create the scaling mode property */
        drm_mode_create_scaling_mode_property(dev);
        /*
         * the initial panel fitting mode will be FULL_SCREEN.
         */
 
-       drm_connector_attach_property(&intel_output->base,
+       drm_connector_attach_property(&intel_encoder->base,
                                      dev->mode_config.scaling_mode_property,
                                      DRM_MODE_SCALE_FULLSCREEN);
        lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
@@ -1044,8 +1054,8 @@ void intel_lvds_init(struct drm_device *dev)
         */
 
        /* Set up the DDC bus. */
-       intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
-       if (!intel_output->ddc_bus) {
+       intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
+       if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
                goto failed;
@@ -1055,7 +1065,10 @@ void intel_lvds_init(struct drm_device *dev)
         * Attempt to get the fixed panel mode from DDC.  Assume that the
         * preferred mode is the right one.
         */
-       intel_ddc_get_modes(intel_output);
+       dev_priv->lvds_edid_good = true;
+
+       if (!intel_ddc_get_modes(intel_encoder))
+               dev_priv->lvds_edid_good = false;
 
        list_for_each_entry(scan, &connector->probed_modes, head) {
                mutex_lock(&dev->mode_config.mutex);
@@ -1133,9 +1146,9 @@ out:
 
 failed:
        DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_connector_cleanup(connector);
        drm_encoder_cleanup(encoder);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
index 89d303d..8e5c83b 100644 (file)
@@ -34,7 +34,7 @@
  * intel_ddc_probe
  *
  */
-bool intel_ddc_probe(struct intel_output *intel_output)
+bool intel_ddc_probe(struct intel_encoder *intel_encoder)
 {
        u8 out_buf[] = { 0x0, 0x0};
        u8 buf[2];
@@ -54,9 +54,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)
                }
        };
 
-       intel_i2c_quirk_set(intel_output->base.dev, true);
-       ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
-       intel_i2c_quirk_set(intel_output->base.dev, false);
+       intel_i2c_quirk_set(intel_encoder->base.dev, true);
+       ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2);
+       intel_i2c_quirk_set(intel_encoder->base.dev, false);
        if (ret == 2)
                return true;
 
@@ -69,19 +69,19 @@ bool intel_ddc_probe(struct intel_output *intel_output)
  *
  * Fetch the EDID information from @connector using the DDC bus.
  */
-int intel_ddc_get_modes(struct intel_output *intel_output)
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder)
 {
        struct edid *edid;
        int ret = 0;
 
-       intel_i2c_quirk_set(intel_output->base.dev, true);
-       edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
-       intel_i2c_quirk_set(intel_output->base.dev, false);
+       intel_i2c_quirk_set(intel_encoder->base.dev, true);
+       edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus);
+       intel_i2c_quirk_set(intel_encoder->base.dev, false);
        if (edid) {
-               drm_mode_connector_update_edid_property(&intel_output->base,
+               drm_mode_connector_update_edid_property(&intel_encoder->base,
                                                        edid);
-               ret = drm_add_edid_modes(&intel_output->base, edid);
-               intel_output->base.display_info.raw_edid = NULL;
+               ret = drm_add_edid_modes(&intel_encoder->base, edid);
+               intel_encoder->base.display_info.raw_edid = NULL;
                kfree(edid);
        }
 
index 60595fc..6d524a1 100644 (file)
@@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
        int ret, tmp_width;
        struct overlay_registers *regs;
        bool scale_changed = false;
-       struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+       struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
        struct drm_device *dev = overlay->dev;
 
        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
        intel_overlay_continue(overlay, scale_changed);
 
        overlay->old_vid_bo = overlay->vid_bo;
-       overlay->vid_bo = new_bo->driver_private;
+       overlay->vid_bo = to_intel_bo(new_bo);
 
        return 0;
 
@@ -1344,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev)
        reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
        if (!reg_bo)
                goto out_free;
-       overlay->reg_bo = reg_bo->driver_private;
+       overlay->reg_bo = to_intel_bo(reg_bo);
 
        if (OVERLAY_NONPHYSICAL(dev)) {
                ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
index 26e13a0..87d9536 100644 (file)
@@ -54,7 +54,7 @@ struct intel_sdvo_priv {
        u8 slave_addr;
 
        /* Register for the SDVO device: SDVOB or SDVOC */
-       int output_device;
+       int sdvo_reg;
 
        /* Active outputs controlled by this SDVO output */
        uint16_t controlled_output;
@@ -124,7 +124,7 @@ struct intel_sdvo_priv {
         */
        struct intel_sdvo_encode encode;
 
-       /* DDC bus used by this SDVO output */
+       /* DDC bus used by this SDVO encoder */
        uint8_t ddc_bus;
 
        /* Mac mini hack -- use the same DDC as the analog connector */
@@ -162,22 +162,22 @@ struct intel_sdvo_priv {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags);
 
 /**
  * Writes the SDVOB or SDVOC with the given value, but always writes both
  * SDVOB and SDVOC to work around apparent hardware issues (according to
  * comments in the BIOS).
  */
-static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
+static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv   *sdvo_priv = intel_encoder->dev_priv;
        u32 bval = val, cval = val;
        int i;
 
-       if (sdvo_priv->output_device == SDVOB) {
+       if (sdvo_priv->sdvo_reg == SDVOB) {
                cval = I915_READ(SDVOC);
        } else {
                bval = I915_READ(SDVOB);
@@ -196,10 +196,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
        }
 }
 
-static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
+static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
                                 u8 *ch)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2];
        u8 buf[2];
        int ret;
@@ -222,7 +222,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
        out_buf[0] = addr;
        out_buf[1] = 0;
 
-       if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2)
+       if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
        {
                *ch = buf[0];
                return true;
@@ -232,10 +232,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
        return false;
 }
 
-static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
+static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
                                  u8 ch)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2];
        struct i2c_msg msgs[] = {
                {
@@ -249,7 +249,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
        out_buf[0] = addr;
        out_buf[1] = ch;
 
-       if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
+       if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
        {
                return true;
        }
@@ -353,13 +353,13 @@ static const struct _sdvo_cmd_name {
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
 };
 
-#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
+#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC")
+#define SDVO_PRIV(encoder)   ((struct intel_sdvo_priv *) (encoder)->dev_priv)
 
-static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
                                   void *args, int args_len)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int i;
 
        DRM_DEBUG_KMS("%s: W: %02X ",
@@ -379,19 +379,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
        DRM_LOG_KMS("\n");
 }
 
-static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
                                 void *args, int args_len)
 {
        int i;
 
-       intel_sdvo_debug_write(intel_output, cmd, args, args_len);
+       intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
 
        for (i = 0; i < args_len; i++) {
-               intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
+               intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
                                      ((u8*)args)[i]);
        }
 
-       intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
+       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
 }
 
 static const char *cmd_status_names[] = {
@@ -404,11 +404,11 @@ static const char *cmd_status_names[] = {
        "Scaling not supported"
 };
 
-static void intel_sdvo_debug_response(struct intel_output *intel_output,
+static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
                                      void *response, int response_len,
                                      u8 status)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int i;
 
        DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
@@ -423,7 +423,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
        DRM_LOG_KMS("\n");
 }
 
-static u8 intel_sdvo_read_response(struct intel_output *intel_output,
+static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
                                   void *response, int response_len)
 {
        int i;
@@ -433,16 +433,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output,
        while (retry--) {
                /* Read the command response */
                for (i = 0; i < response_len; i++) {
-                       intel_sdvo_read_byte(intel_output,
+                       intel_sdvo_read_byte(intel_encoder,
                                             SDVO_I2C_RETURN_0 + i,
                                             &((u8 *)response)[i]);
                }
 
                /* read the return status */
-               intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
+               intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
                                     &status);
 
-               intel_sdvo_debug_response(intel_output, response, response_len,
+               intel_sdvo_debug_response(intel_encoder, response, response_len,
                                          status);
                if (status != SDVO_CMD_STATUS_PENDING)
                        return status;
@@ -470,10 +470,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
  * another I2C transaction after issuing the DDC bus switch, it will be
  * switched to the internal SDVO register.
  */
-static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
+static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
                                              u8 target)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
        struct i2c_msg msgs[] = {
                {
@@ -497,10 +497,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
                },
        };
 
-       intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+       intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
                                        &target, 1);
        /* write the DDC switch command argument */
-       intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
 
        out_buf[0] = SDVO_I2C_OPCODE;
        out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
@@ -509,7 +509,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
        ret_value[0] = 0;
        ret_value[1] = 0;
 
-       ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+       ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
        if (ret != 3) {
                /* failure in I2C transfer */
                DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
@@ -523,7 +523,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
        return;
 }
 
-static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
+static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
 {
        struct intel_sdvo_set_target_input_args targets = {0};
        u8 status;
@@ -534,10 +534,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
        if (target_1)
                targets.target_1 = 1;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
                             sizeof(targets));
 
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
@@ -548,13 +548,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
  * This function is making an assumption about the layout of the response,
  * which should be checked against the docs.
  */
-static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
 {
        struct intel_sdvo_get_trained_inputs_response response;
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -563,29 +563,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo
        return true;
 }
 
-static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,
                                          u16 *outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
                                          u16 outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
                             sizeof(outputs));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
+static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
                                               int mode)
 {
        u8 status, state = SDVO_ENCODER_STATE_ON;
@@ -605,24 +605,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output
                break;
        }
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
                             sizeof(state));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
                                                   int *clock_min,
                                                   int *clock_max)
 {
        struct intel_sdvo_pixel_clock_range clocks;
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
+       status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
 
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -634,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou
        return true;
 }
 
-static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
+static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
                                         u16 outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
                             sizeof(outputs));
 
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,
                                  struct intel_sdvo_dtd *dtd)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &dtd->part1,
+       intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
                                          sizeof(dtd->part1));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &dtd->part2,
+       intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
                                          sizeof(dtd->part2));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -666,60 +666,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
        return true;
 }
 
-static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_get_timing(intel_output,
+       return intel_sdvo_get_timing(intel_encoder,
                                     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_get_timing(intel_output,
+       return intel_sdvo_get_timing(intel_encoder,
                                     SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
                                  struct intel_sdvo_dtd *dtd)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
        return true;
 }
 
-static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_set_timing(intel_output,
+       return intel_sdvo_set_timing(intel_encoder,
                                     SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_set_timing(intel_output,
+       return intel_sdvo_set_timing(intel_encoder,
                                     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
 static bool
-intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
                                         uint16_t clock,
                                         uint16_t width,
                                         uint16_t height)
 {
        struct intel_sdvo_preferred_input_timing_args args;
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        uint8_t status;
 
        memset(&args, 0, sizeof(args));
@@ -733,32 +733,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
            sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
                args.scaled = 1;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+       intel_sdvo_write_cmd(intel_encoder,
+                            SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
                             &args, sizeof(args));
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
        return true;
 }
 
-static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
                                                  struct intel_sdvo_dtd *dtd)
 {
        bool status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(output, &dtd->part1,
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
                                          sizeof(dtd->part1));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(output, &dtd->part2,
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
                                          sizeof(dtd->part2));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -766,12 +767,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
        return false;
 }
 
-static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
+static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)
 {
        u8 response, status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, 1);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, 1);
 
        if (status != SDVO_CMD_STATUS_SUCCESS) {
                DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
@@ -783,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
        return response;
 }
 
-static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -877,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
                mode->flags |= DRM_MODE_FLAG_PVSYNC;
 }
 
-static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
                                       struct intel_sdvo_encode *encode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
-       status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
        if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
                memset(encode, 0, sizeof(*encode));
                return false;
@@ -892,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output,
        return true;
 }
 
-static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
+                                 uint8_t mode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
-       status = intel_sdvo_read_response(output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
                                       uint8_t mode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
-       status = intel_sdvo_read_response(output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
 #if 0
-static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
 {
        int i, j;
        uint8_t set_buf_index[2];
@@ -923,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
        uint8_t buf[48];
        uint8_t *pos;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
-       intel_sdvo_read_response(output, &av_split, 1);
+       intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+       intel_sdvo_read_response(encoder, &av_split, 1);
 
        for (i = 0; i <= av_split; i++) {
                set_buf_index[0] = i; set_buf_index[1] = 0;
-               intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+               intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
                                     set_buf_index, 2);
-               intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
-               intel_sdvo_read_response(output, &buf_size, 1);
+               intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+               intel_sdvo_read_response(encoder, &buf_size, 1);
 
                pos = buf;
                for (j = 0; j <= buf_size; j += 8) {
-                       intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+                       intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
                                             NULL, 0);
-                       intel_sdvo_read_response(output, pos, 8);
+                       intel_sdvo_read_response(encoder, pos, 8);
                        pos += 8;
                }
        }
 }
 #endif
 
-static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
-                               uint8_t *data, int8_t size, uint8_t tx_rate)
+static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
+                                   int index,
+                                   uint8_t *data, int8_t size, uint8_t tx_rate)
 {
     uint8_t set_buf_index[2];
 
     set_buf_index[0] = index;
     set_buf_index[1] = 0;
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
+                        set_buf_index, 2);
 
     for (; size > 0; size -= 8) {
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
        data += 8;
     }
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
 }
 
 static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
@@ -1034,7 +1038,7 @@ struct dip_infoframe {
        } __attribute__ ((packed)) u;
 } __attribute__((packed));
 
-static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
                                         struct drm_display_mode * mode)
 {
        struct dip_infoframe avi_if = {
@@ -1045,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
 
        avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
                                                    4 + avi_if.len);
-       intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+       intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
+                               4 + avi_if.len,
                                SDVO_HBUF_TX_VSYNC);
 }
 
-static void intel_sdvo_set_tv_format(struct intel_output *output)
+static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
 {
 
        struct intel_sdvo_tv_format format;
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        uint32_t format_map, i;
        uint8_t status;
 
@@ -1066,10 +1071,10 @@ static void intel_sdvo_set_tv_format(struct intel_output *output)
        memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
                        sizeof(format) : sizeof(format_map));
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,
                             sizeof(format));
 
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                DRM_DEBUG_KMS("%s: Failed to set TV format\n",
                          SDVO_NAME(sdvo_priv));
@@ -1079,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                                  struct drm_display_mode *mode,
                                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *dev_priv = output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
 
        if (dev_priv->is_tv) {
                struct intel_sdvo_dtd output_dtd;
@@ -1095,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 
                /* Set output timings */
                intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             dev_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &output_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
                /* Set the input timing to the screen. Assume always input 0. */
-               intel_sdvo_set_target_input(output, true, false);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
-               success = intel_sdvo_create_preferred_input_timing(output,
+               success = intel_sdvo_create_preferred_input_timing(intel_encoder,
                                                                   mode->clock / 10,
                                                                   mode->hdisplay,
                                                                   mode->vdisplay);
                if (success) {
                        struct intel_sdvo_dtd input_dtd;
 
-                       intel_sdvo_get_preferred_input_timing(output,
+                       intel_sdvo_get_preferred_input_timing(intel_encoder,
                                                             &input_dtd);
                        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
                        dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1133,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                intel_sdvo_get_dtd_from_mode(&output_dtd,
                                dev_priv->sdvo_lvds_fixed_mode);
 
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             dev_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &output_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
                /* Set the input timing to the screen. Assume always input 0. */
-               intel_sdvo_set_target_input(output, true, false);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
                success = intel_sdvo_create_preferred_input_timing(
-                               output,
+                               intel_encoder,
                                mode->clock / 10,
                                mode->hdisplay,
                                mode->vdisplay);
@@ -1150,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                if (success) {
                        struct intel_sdvo_dtd input_dtd;
 
-                       intel_sdvo_get_preferred_input_timing(output,
+                       intel_sdvo_get_preferred_input_timing(intel_encoder,
                                                             &input_dtd);
                        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
                        dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1182,8 +1187,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u32 sdvox = 0;
        int sdvo_pixel_multiply;
        struct intel_sdvo_in_out_map in_out;
@@ -1202,12 +1207,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        in_out.in0 = sdvo_priv->controlled_output;
        in_out.in1 = 0;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
                             &in_out, sizeof(in_out));
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        if (sdvo_priv->is_hdmi) {
-               intel_sdvo_set_avi_infoframe(output, mode);
+               intel_sdvo_set_avi_infoframe(intel_encoder, mode);
                sdvox |= SDVO_AUDIO_ENABLE;
        }
 
@@ -1224,16 +1229,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         */
        if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
                /* Set the output timing to the screen */
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             sdvo_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &input_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
        }
 
        /* Set the input timing to the screen. Assume always input 0. */
-       intel_sdvo_set_target_input(output, true, false);
+       intel_sdvo_set_target_input(intel_encoder, true, false);
 
        if (sdvo_priv->is_tv)
-               intel_sdvo_set_tv_format(output);
+               intel_sdvo_set_tv_format(intel_encoder);
 
        /* We would like to use intel_sdvo_create_preferred_input_timing() to
         * provide the device with a timing it can support, if it supports that
@@ -1241,29 +1246,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         * output the preferred timing, and we don't support that currently.
         */
 #if 0
-       success = intel_sdvo_create_preferred_input_timing(output, clock,
+       success = intel_sdvo_create_preferred_input_timing(encoder, clock,
                                                           width, height);
        if (success) {
                struct intel_sdvo_dtd *input_dtd;
 
-               intel_sdvo_get_preferred_input_timing(output, &input_dtd);
-               intel_sdvo_set_input_timing(output, &input_dtd);
+               intel_sdvo_get_preferred_input_timing(encoder, &input_dtd);
+               intel_sdvo_set_input_timing(encoder, &input_dtd);
        }
 #else
-       intel_sdvo_set_input_timing(output, &input_dtd);
+       intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
 #endif
 
        switch (intel_sdvo_get_pixel_multiplier(mode)) {
        case 1:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_1X);
                break;
        case 2:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_2X);
                break;
        case 4:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_4X);
                break;
        }
@@ -1274,8 +1279,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
                        SDVO_VSYNC_ACTIVE_HIGH |
                        SDVO_HSYNC_ACTIVE_HIGH;
        } else {
-               sdvox |= I915_READ(sdvo_priv->output_device);
-               switch (sdvo_priv->output_device) {
+               sdvox |= I915_READ(sdvo_priv->sdvo_reg);
+               switch (sdvo_priv->sdvo_reg) {
                case SDVOB:
                        sdvox &= SDVOB_PRESERVE_MASK;
                        break;
@@ -1299,26 +1304,26 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
 
        if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
                sdvox |= SDVO_STALL_SELECT;
-       intel_sdvo_write_sdvox(output, sdvox);
+       intel_sdvo_write_sdvox(intel_encoder, sdvox);
 }
 
 static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u32 temp;
 
        if (mode != DRM_MODE_DPMS_ON) {
-               intel_sdvo_set_active_outputs(intel_output, 0);
+               intel_sdvo_set_active_outputs(intel_encoder, 0);
                if (0)
-                       intel_sdvo_set_encoder_power_state(intel_output, mode);
+                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
 
                if (mode == DRM_MODE_DPMS_OFF) {
-                       temp = I915_READ(sdvo_priv->output_device);
+                       temp = I915_READ(sdvo_priv->sdvo_reg);
                        if ((temp & SDVO_ENABLE) != 0) {
-                               intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
+                               intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
                        }
                }
        } else {
@@ -1326,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
                int i;
                u8 status;
 
-               temp = I915_READ(sdvo_priv->output_device);
+               temp = I915_READ(sdvo_priv->sdvo_reg);
                if ((temp & SDVO_ENABLE) == 0)
-                       intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
+                       intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
                for (i = 0; i < 2; i++)
                  intel_wait_for_vblank(dev);
 
-               status = intel_sdvo_get_trained_inputs(intel_output, &input1,
+               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
                                                       &input2);
 
 
@@ -1346,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
                }
 
                if (0)
-                       intel_sdvo_set_encoder_power_state(intel_output, mode);
-               intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
+                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
+               intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output);
        }
        return;
 }
@@ -1356,22 +1361,22 @@ static void intel_sdvo_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int o;
 
-       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
-       intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
+       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder);
+       intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs);
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               intel_sdvo_set_target_input(intel_output, true, false);
-               intel_sdvo_get_input_timing(intel_output,
+               intel_sdvo_set_target_input(intel_encoder, true, false);
+               intel_sdvo_get_input_timing(intel_encoder,
                                            &sdvo_priv->save_input_dtd_1);
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               intel_sdvo_set_target_input(intel_output, false, true);
-               intel_sdvo_get_input_timing(intel_output,
+               intel_sdvo_set_target_input(intel_encoder, false, true);
+               intel_sdvo_get_input_timing(intel_encoder,
                                            &sdvo_priv->save_input_dtd_2);
        }
 
@@ -1380,8 +1385,8 @@ static void intel_sdvo_save(struct drm_connector *connector)
                u16  this_output = (1 << o);
                if (sdvo_priv->caps.output_flags & this_output)
                {
-                       intel_sdvo_set_target_output(intel_output, this_output);
-                       intel_sdvo_get_output_timing(intel_output,
+                       intel_sdvo_set_target_output(intel_encoder, this_output);
+                       intel_sdvo_get_output_timing(intel_encoder,
                                                     &sdvo_priv->save_output_dtd[o]);
                }
        }
@@ -1389,66 +1394,66 @@ static void intel_sdvo_save(struct drm_connector *connector)
                /* XXX: Save TV format/enhancements. */
        }
 
-       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
+       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg);
 }
 
 static void intel_sdvo_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int o;
        int i;
        bool input1, input2;
        u8 status;
 
-       intel_sdvo_set_active_outputs(intel_output, 0);
+       intel_sdvo_set_active_outputs(intel_encoder, 0);
 
        for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
        {
                u16  this_output = (1 << o);
                if (sdvo_priv->caps.output_flags & this_output) {
-                       intel_sdvo_set_target_output(intel_output, this_output);
-                       intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
+                       intel_sdvo_set_target_output(intel_encoder, this_output);
+                       intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]);
                }
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               intel_sdvo_set_target_input(intel_output, true, false);
-               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
+               intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1);
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               intel_sdvo_set_target_input(intel_output, false, true);
-               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
+               intel_sdvo_set_target_input(intel_encoder, false, true);
+               intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2);
        }
 
-       intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
+       intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult);
 
        if (sdvo_priv->is_tv) {
                /* XXX: Restore TV format/enhancements. */
        }
 
-       intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
+       intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX);
 
        if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
        {
                for (i = 0; i < 2; i++)
                        intel_wait_for_vblank(dev);
-               status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
+               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);
                if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
                        DRM_DEBUG_KMS("First %s output reported failure to "
                                        "sync\n", SDVO_NAME(sdvo_priv));
        }
 
-       intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
+       intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs);
 }
 
 static int intel_sdvo_mode_valid(struct drm_connector *connector,
                                 struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -1473,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -1488,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc
 struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
 {
        struct drm_connector *connector = NULL;
-       struct intel_output *iout = NULL;
+       struct intel_encoder *iout = NULL;
        struct intel_sdvo_priv *sdvo;
 
        /* find the sdvo connector */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               iout = to_intel_output(connector);
+               iout = to_intel_encoder(connector);
 
                if (iout->type != INTEL_OUTPUT_SDVO)
                        continue;
 
                sdvo = iout->dev_priv;
 
-               if (sdvo->output_device == SDVOB && sdvoB)
+               if (sdvo->sdvo_reg == SDVOB && sdvoB)
                        return connector;
 
-               if (sdvo->output_device == SDVOC && !sdvoB)
+               if (sdvo->sdvo_reg == SDVOC && !sdvoB)
                        return connector;
 
        }
@@ -1515,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
 {
        u8 response[2];
        u8 status;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        DRM_DEBUG_KMS("\n");
 
        if (!connector)
                return 0;
 
-       intel_output = to_intel_output(connector);
+       intel_encoder = to_intel_encoder(connector);
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
        if (response[0] !=0)
                return 1;
@@ -1536,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
 {
        u8 response[2];
        u8 status;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-       intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+       intel_sdvo_read_response(intel_encoder, &response, 2);
 
        if (on) {
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-               status = intel_sdvo_read_response(intel_output, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+               status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
        } else {
                response[0] = 0;
                response[1] = 0;
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
        }
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-       intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+       intel_sdvo_read_response(intel_encoder, &response, 2);
 }
 
 static bool
-intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int caps = 0;
 
        if (sdvo_priv->caps.output_flags &
@@ -1593,11 +1598,11 @@ static struct drm_connector *
 intel_find_analog_connector(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               intel_output = to_intel_output(connector);
-               if (intel_output->type == INTEL_OUTPUT_ANALOG)
+               intel_encoder = to_intel_encoder(connector);
+               if (intel_encoder->type == INTEL_OUTPUT_ANALOG)
                        return connector;
        }
        return NULL;
@@ -1622,16 +1627,16 @@ intel_analog_is_connected(struct drm_device *dev)
 enum drm_connector_status
 intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        enum drm_connector_status status = connector_status_connected;
        struct edid *edid = NULL;
 
-       edid = drm_get_edid(&intel_output->base,
-                           intel_output->ddc_bus);
+       edid = drm_get_edid(&intel_encoder->base,
+                           intel_encoder->ddc_bus);
 
        /* This is only applied to SDVO cards with multiple outputs */
-       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
                uint8_t saved_ddc, temp_ddc;
                saved_ddc = sdvo_priv->ddc_bus;
                temp_ddc = sdvo_priv->ddc_bus >> 1;
@@ -1641,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
                 */
                while(temp_ddc > 1) {
                        sdvo_priv->ddc_bus = temp_ddc;
-                       edid = drm_get_edid(&intel_output->base,
-                               intel_output->ddc_bus);
+                       edid = drm_get_edid(&intel_encoder->base,
+                               intel_encoder->ddc_bus);
                        if (edid) {
                                /*
                                 * When we can get the EDID, maybe it is the
@@ -1661,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
         */
        if (edid == NULL &&
            sdvo_priv->analog_ddc_bus &&
-           !intel_analog_is_connected(intel_output->base.dev))
-               edid = drm_get_edid(&intel_output->base,
+           !intel_analog_is_connected(intel_encoder->base.dev))
+               edid = drm_get_edid(&intel_encoder->base,
                                    sdvo_priv->analog_ddc_bus);
        if (edid != NULL) {
                /* Don't report the output as connected if it's a DVI-I
@@ -1677,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
                }
 
                kfree(edid);
-               intel_output->base.display_info.raw_edid = NULL;
+               intel_encoder->base.display_info.raw_edid = NULL;
 
        } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
                status = connector_status_disconnected;
@@ -1689,16 +1694,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 {
        uint16_t response;
        u8 status;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-       intel_sdvo_write_cmd(intel_output,
+       intel_sdvo_write_cmd(intel_encoder,
                             SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
        if (sdvo_priv->is_tv) {
                /* add 30ms delay when the output type is SDVO-TV */
                mdelay(30);
        }
-       status = intel_sdvo_read_response(intel_output, &response, 2);
+       status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
        DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
 
@@ -1708,10 +1713,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
        if (response == 0)
                return connector_status_disconnected;
 
-       if (intel_sdvo_multifunc_encoder(intel_output) &&
+       if (intel_sdvo_multifunc_encoder(intel_encoder) &&
                sdvo_priv->attached_output != response) {
                if (sdvo_priv->controlled_output != response &&
-                       intel_sdvo_output_setup(intel_output, response) != true)
+                       intel_sdvo_output_setup(intel_encoder, response) != true)
                        return connector_status_unknown;
                sdvo_priv->attached_output = response;
        }
@@ -1720,12 +1725,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int num_modes;
 
        /* set the bus switch and get the modes */
-       num_modes = intel_ddc_get_modes(intel_output);
+       num_modes = intel_ddc_get_modes(intel_encoder);
 
        /*
         * Mac mini hack.  On this device, the DVI-I connector shares one DDC
@@ -1735,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
         */
        if (num_modes == 0 &&
            sdvo_priv->analog_ddc_bus &&
-           !intel_analog_is_connected(intel_output->base.dev)) {
+           !intel_analog_is_connected(intel_encoder->base.dev)) {
                struct i2c_adapter *digital_ddc_bus;
 
                /* Switch to the analog ddc bus and try that
                 */
-               digital_ddc_bus = intel_output->ddc_bus;
-               intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
+               digital_ddc_bus = intel_encoder->ddc_bus;
+               intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus;
 
-               (void) intel_ddc_get_modes(intel_output);
+               (void) intel_ddc_get_modes(intel_encoder);
 
-               intel_output->ddc_bus = digital_ddc_bus;
+               intel_encoder->ddc_bus = digital_ddc_bus;
        }
 }
 
@@ -1816,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[] = {
 
 static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 {
-       struct intel_output *output = to_intel_output(connector);
+       struct intel_encoder *output = to_intel_encoder(connector);
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
        struct intel_sdvo_sdtv_resolution_request tv_res;
        uint32_t reply = 0, format_map = 0;
@@ -1858,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 
 static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct drm_display_mode *newmode;
 
        /*
@@ -1868,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
         * Assume that the preferred modes are
         * arranged in priority order.
         */
-       intel_ddc_get_modes(intel_output);
+       intel_ddc_get_modes(intel_encoder);
        if (list_empty(&connector->probed_modes) == false)
                goto end;
 
@@ -1897,7 +1902,7 @@ end:
 
 static int intel_sdvo_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *output = to_intel_output(connector);
+       struct intel_encoder *output = to_intel_encoder(connector);
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 
        if (sdvo_priv->is_tv)
@@ -1915,8 +1920,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
 static
 void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct drm_device *dev = connector->dev;
 
        if (sdvo_priv->is_tv) {
@@ -1953,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 
 static void intel_sdvo_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        if (sdvo_priv->analog_ddc_bus)
                intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
 
@@ -1977,7 +1982,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
 
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static int
@@ -1985,9 +1990,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
                        struct drm_property *property,
                        uint64_t val)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = encoder->crtc;
        int ret = 0;
        bool changed = false;
@@ -2095,8 +2100,8 @@ intel_sdvo_set_property(struct drm_connector *connector,
                        sdvo_priv->cur_brightness = temp_value;
                }
                if (cmd) {
-                       intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2);
-                       status = intel_sdvo_read_response(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
+                       status = intel_sdvo_read_response(intel_encoder,
                                                                NULL, 0);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO command \n");
@@ -2191,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
 }
 
 static bool
-intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output)
 {
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
        uint8_t status;
@@ -2205,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
        return true;
 }
 
-static struct intel_output *
-intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+static struct intel_encoder *
+intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
 {
        struct drm_device *dev = chan->drm_dev;
        struct drm_connector *connector;
-       struct intel_output *intel_output = NULL;
+       struct intel_encoder *intel_encoder = NULL;
 
        list_for_each_entry(connector,
                        &dev->mode_config.connector_list, head) {
-               if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
-                       intel_output = to_intel_output(connector);
+               if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) {
+                       intel_encoder = to_intel_encoder(connector);
                        break;
                }
        }
-       return intel_output;
+       return intel_encoder;
 }
 
 static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
                                  struct i2c_msg msgs[], int num)
 {
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_sdvo_priv *sdvo_priv;
        struct i2c_algo_bit_data *algo_data;
        const struct i2c_algorithm *algo;
 
        algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
-       intel_output =
-               intel_sdvo_chan_to_intel_output(
+       intel_encoder =
+               intel_sdvo_chan_to_intel_encoder(
                                (struct intel_i2c_chan *)(algo_data->data));
-       if (intel_output == NULL)
+       if (intel_encoder == NULL)
                return -EINVAL;
 
-       sdvo_priv = intel_output->dev_priv;
-       algo = intel_output->i2c_bus->algo;
+       sdvo_priv = intel_encoder->dev_priv;
+       algo = intel_encoder->i2c_bus->algo;
 
-       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+       intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
        return algo->master_xfer(i2c_adap, msgs, num);
 }
 
@@ -2249,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
 };
 
 static u8
-intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
+intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct sdvo_device_mapping *my_mapping, *other_mapping;
 
-       if (output_device == SDVOB) {
+       if (sdvo_reg == SDVOB) {
                my_mapping = &dev_priv->sdvo_mappings[0];
                other_mapping = &dev_priv->sdvo_mappings[1];
        } else {
@@ -2279,7 +2284,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
        /* No SDVO device info is found for another DVO port,
         * so use mapping assumption we had before BIOS parsing.
         */
-       if (output_device == SDVOB)
+       if (sdvo_reg == SDVOB)
                return 0x70;
        else
                return 0x72;
@@ -2305,15 +2310,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
 {
-       struct drm_connector *connector = &intel_output->base;
-       struct drm_encoder *encoder = &intel_output->enc;
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct drm_connector *connector = &intel_encoder->base;
+       struct drm_encoder *encoder = &intel_encoder->enc;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        bool ret = true, registered = false;
 
        sdvo_priv->is_tv = false;
-       intel_output->needs_tv_clock = false;
+       intel_encoder->needs_tv_clock = false;
        sdvo_priv->is_lvds = false;
 
        if (device_is_registered(&connector->kdev)) {
@@ -2331,16 +2336,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
                connector->connector_type = DRM_MODE_CONNECTOR_DVID;
 
-               if (intel_sdvo_get_supp_encode(intel_output,
+               if (intel_sdvo_get_supp_encode(intel_encoder,
                                               &sdvo_priv->encode) &&
-                   intel_sdvo_get_digital_encoding_mode(intel_output) &&
+                   intel_sdvo_get_digital_encoding_mode(intel_encoder) &&
                    sdvo_priv->is_hdmi) {
                        /* enable hdmi encoding mode if supported */
-                       intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
-                       intel_sdvo_set_colorimetry(intel_output,
+                       intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
+                       intel_sdvo_set_colorimetry(intel_encoder,
                                                   SDVO_COLORIMETRY_RGB256);
                        connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                        (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
                }
@@ -2351,21 +2356,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
-               intel_output->needs_tv_clock = true;
-               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+               intel_encoder->needs_tv_clock = true;
+               intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_RGB0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_RGB1) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_CVBS0) {
 
@@ -2373,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
-               intel_output->needs_tv_clock = true;
-               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+               intel_encoder->needs_tv_clock = true;
+               intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_LVDS0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
-               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
                                        (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_LVDS1) {
 
@@ -2389,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
-               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
                                        (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else {
 
@@ -2402,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                              bytes[0], bytes[1]);
                ret = false;
        }
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
        if (ret && registered)
                ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
@@ -2414,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
 
 static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 {
-      struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+      struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct intel_sdvo_tv_format format;
        uint32_t format_map, i;
        uint8_t status;
 
-       intel_sdvo_set_target_output(intel_output,
+       intel_sdvo_set_target_output(intel_encoder,
                                     sdvo_priv->controlled_output);
 
-       intel_sdvo_write_cmd(intel_output,
+       intel_sdvo_write_cmd(intel_encoder,
                             SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output,
+       status = intel_sdvo_read_response(intel_encoder,
                                          &format, sizeof(format));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return;
@@ -2463,16 +2468,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 
 static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct intel_sdvo_enhancements_reply sdvo_data;
        struct drm_device *dev = connector->dev;
        uint8_t status;
        uint16_t response, data_value[2];
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
                                                NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &sdvo_data,
+       status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
                                        sizeof(sdvo_data));
        if (status != SDVO_CMD_STATUS_SUCCESS) {
                DRM_DEBUG_KMS(" incorrect response is returned\n");
@@ -2488,18 +2493,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                 * property
                 */
                if (sdvo_data.overscan_h) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO max "
                                                "h_overscan\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
@@ -2529,18 +2534,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.overscan_v) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO max "
                                                "v_overscan\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
@@ -2570,17 +2575,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.position_h) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_POSITION_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
@@ -2601,17 +2606,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.position_v) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_POSITION_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
@@ -2634,17 +2639,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        }
        if (sdvo_priv->is_tv) {
                if (sdvo_data.saturation) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_SATURATION, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
@@ -2666,17 +2671,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.contrast) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_CONTRAST, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
@@ -2697,17 +2702,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.hue) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_HUE, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_HUE, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
@@ -2730,17 +2735,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        }
        if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
                if (sdvo_data.brightness) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
@@ -2765,81 +2770,81 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        return;
 }
 
-bool intel_sdvo_init(struct drm_device *dev, int output_device)
+bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_sdvo_priv *sdvo_priv;
 
        u8 ch[0x40];
        int i;
 
-       intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
-       if (!intel_output) {
+       intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+       if (!intel_encoder) {
                return false;
        }
 
-       sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
-       sdvo_priv->output_device = output_device;
+       sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
+       sdvo_priv->sdvo_reg = sdvo_reg;
 
-       intel_output->dev_priv = sdvo_priv;
-       intel_output->type = INTEL_OUTPUT_SDVO;
+       intel_encoder->dev_priv = sdvo_priv;
+       intel_encoder->type = INTEL_OUTPUT_SDVO;
 
        /* setup the DDC bus. */
-       if (output_device == SDVOB)
-               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
+       if (sdvo_reg == SDVOB)
+               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
        else
-               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
+               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
-       if (!intel_output->i2c_bus)
+       if (!intel_encoder->i2c_bus)
                goto err_inteloutput;
 
-       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
+       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
 
        /* Save the bit-banging i2c functionality for use by the DDC wrapper */
-       intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality;
+       intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
 
        /* Read the regs to test if we can talk to the device */
        for (i = 0; i < 0x40; i++) {
-               if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
+               if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
                        DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
-                                       output_device == SDVOB ? 'B' : 'C');
+                                       sdvo_reg == SDVOB ? 'B' : 'C');
                        goto err_i2c;
                }
        }
 
        /* setup the DDC bus. */
-       if (output_device == SDVOB) {
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+       if (sdvo_reg == SDVOB) {
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
                sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
                                                "SDVOB/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
        } else {
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
                sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
                                                "SDVOC/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
        }
 
-       if (intel_output->ddc_bus == NULL)
+       if (intel_encoder->ddc_bus == NULL)
                goto err_i2c;
 
        /* Wrap with our custom algo which switches to DDC mode */
-       intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
+       intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
 
        /* In default case sdvo lvds is false */
-       intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
+       intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
 
-       if (intel_sdvo_output_setup(intel_output,
+       if (intel_sdvo_output_setup(intel_encoder,
                                    sdvo_priv->caps.output_flags) != true) {
                DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
-                         output_device == SDVOB ? 'B' : 'C');
+                         sdvo_reg == SDVOB ? 'B' : 'C');
                goto err_i2c;
        }
 
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
                           connector->connector_type);
 
@@ -2848,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        connector->doublescan_allowed = 0;
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 
-       drm_encoder_init(dev, &intel_output->enc,
-                       &intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
+       drm_encoder_init(dev, &intel_encoder->enc,
+                       &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type);
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
        if (sdvo_priv->is_tv)
                intel_sdvo_tv_create_property(connector);
 
@@ -2865,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        intel_sdvo_select_ddc_bus(sdvo_priv);
 
        /* Set the input timing to the screen. Assume always input 0. */
-       intel_sdvo_set_target_input(intel_output, true, false);
+       intel_sdvo_set_target_input(intel_encoder, true, false);
 
-       intel_sdvo_get_input_pixel_clock_range(intel_output,
+       intel_sdvo_get_input_pixel_clock_range(intel_encoder,
                                               &sdvo_priv->pixel_clock_min,
                                               &sdvo_priv->pixel_clock_max);
 
@@ -2894,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 err_i2c:
        if (sdvo_priv->analog_ddc_bus != NULL)
                intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
-       if (intel_output->ddc_bus != NULL)
-               intel_i2c_destroy(intel_output->ddc_bus);
-       if (intel_output->i2c_bus != NULL)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->ddc_bus != NULL)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
+       if (intel_encoder->i2c_bus != NULL)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
 err_inteloutput:
-       kfree(intel_output);
+       kfree(intel_encoder);
 
        return false;
 }
index 552ec11..d7d39b2 100644 (file)
@@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
        int i;
 
        tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
@@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
        struct drm_crtc *crtc = connector->encoder->crtc;
        struct intel_crtc *intel_crtc;
        int i;
@@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format)
 }
 
 static const struct tv_mode *
-intel_tv_mode_find (struct intel_output *intel_output)
+intel_tv_mode_find (struct intel_encoder *intel_encoder)
 {
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
 
        return intel_tv_mode_lookup(tv_priv->tv_format);
 }
@@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output)
 static enum drm_mode_status
 intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
        /* Ensure TV refresh is close to desired refresh */
        if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 {
        struct drm_device *dev = encoder->dev;
        struct drm_mode_config *drm_config = &dev->mode_config;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
        struct drm_encoder *other_encoder;
 
        if (!tv_mode)
@@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        u32 tv_ctl;
        u32 hctl1, hctl2, hctl3;
        u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = {
  * \return false if TV is disconnected.
  */
 static int
-intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
@@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
  */
 static void intel_tv_find_better_format(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        int i;
 
        if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
@@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector)
 {
        struct drm_crtc *crtc;
        struct drm_display_mode mode;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        int dpms_mode;
        int type = tv_priv->type;
 
@@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector)
        drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
        if (encoder->crtc && encoder->crtc->enabled) {
-               type = intel_tv_detect_type(encoder->crtc, intel_output);
+               type = intel_tv_detect_type(encoder->crtc, intel_encoder);
        } else {
-               crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
+               crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode);
                if (crtc) {
-                       type = intel_tv_detect_type(crtc, intel_output);
-                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+                       type = intel_tv_detect_type(crtc, intel_encoder);
+                       intel_release_load_detect_pipe(intel_encoder, dpms_mode);
                } else
                        type = -1;
        }
@@ -1525,8 +1525,8 @@ static void
 intel_tv_chose_preferred_modes(struct drm_connector *connector,
                               struct drm_display_mode *mode_ptr)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
        if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
                mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1550,8 +1550,8 @@ static int
 intel_tv_get_modes(struct drm_connector *connector)
 {
        struct drm_display_mode *mode_ptr;
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        int j, count = 0;
        u64 tmp;
 
@@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector)
 static void
 intel_tv_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 
@@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
                      uint64_t val)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = encoder->crtc;
        int ret = 0;
        bool changed = false;
@@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_tv_priv *tv_priv;
        u32 tv_dac_on, tv_dac_off, save_tv_dac;
        char **tv_format_names;
@@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev)
            (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
                return;
 
-       intel_output = kzalloc(sizeof(struct intel_output) +
+       intel_encoder = kzalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_tv_priv), GFP_KERNEL);
-       if (!intel_output) {
+       if (!intel_encoder) {
                return;
        }
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
 
        drm_connector_init(dev, connector, &intel_tv_connector_funcs,
                           DRM_MODE_CONNECTOR_SVIDEO);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
                         DRM_MODE_ENCODER_TVDAC);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-       tv_priv = (struct intel_tv_priv *)(intel_output + 1);
-       intel_output->type = INTEL_OUTPUT_TVOUT;
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
-       intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
-       intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
-       intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
-       intel_output->dev_priv = tv_priv;
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+       tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
+       intel_encoder->type = INTEL_OUTPUT_TVOUT;
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
+       intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
+       intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
+       intel_encoder->dev_priv = tv_priv;
        tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
 
        /* BIOS margin values */
@@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev)
 
        tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
        drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
index bcec2d7..1d56983 100644 (file)
@@ -908,11 +908,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++), shift;
        uint32_t saved, dst;
        int dptr = *ptr;
+       uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
        SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
        SDEBUG("   shift: %d\n", shift);
        dst <<= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
        SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -922,11 +927,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++), shift;
        uint32_t saved, dst;
        int dptr = *ptr;
+       uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
        SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
        SDEBUG("   shift: %d\n", shift);
        dst >>= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
        SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
index 6732b5d..27e2c71 100644 (file)
@@ -2912,7 +2912,7 @@ typedef struct _ATOM_ANALOG_TV_INFO_V1_2
   UCHAR                    ucTV_BootUpDefaultStandard; 
   UCHAR                    ucExt_TV_ASIC_ID;
   UCHAR                    ucExt_TV_ASIC_SlaveAddr;
-  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING];
+  ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING_V1_2];
 }ATOM_ANALOG_TV_INFO_V1_2;
 
 typedef struct _ATOM_DPCD_INFO
index fd4ef6d..a87990b 100644 (file)
@@ -521,6 +521,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
                                if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
                                        adjusted_clock = mode->clock * 2;
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+                                       pll->algo = PLL_ALGO_LEGACY;
+                                       pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+                               }
                        } else {
                                if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
                                        pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
index c958049..cf60c0b 100644 (file)
@@ -2891,7 +2891,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
 {
        struct radeon_bo *robj;
        unsigned long size;
-       unsigned u, i, w, h;
+       unsigned u, i, w, h, d;
        int ret;
 
        for (u = 0; u < track->num_texture; u++) {
@@ -2923,20 +2923,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
                        h = h / (1 << i);
                        if (track->textures[u].roundup_h)
                                h = roundup_pow_of_two(h);
+                       if (track->textures[u].tex_coord_type == 1) {
+                               d = (1 << track->textures[u].txdepth) / (1 << i);
+                               if (!d)
+                                       d = 1;
+                       } else {
+                               d = 1;
+                       }
                        if (track->textures[u].compress_format) {
 
-                               size += r100_track_compress_size(track->textures[u].compress_format, w, h);
+                               size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;
                                /* compressed textures are block based */
                        } else
-                               size += w * h;
+                               size += w * h * d;
                }
                size *= track->textures[u].cpp;
 
                switch (track->textures[u].tex_coord_type) {
                case 0:
-                       break;
                case 1:
-                       size *= (1 << track->textures[u].txdepth);
                        break;
                case 2:
                        if (track->separate_cube) {
@@ -2970,7 +2975,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
 
        for (i = 0; i < track->num_cb; i++) {
                if (track->cb[i].robj == NULL) {
-                       if (!(track->fastfill || track->color_channel_mask ||
+                       if (!(track->zb_cb_clear || track->color_channel_mask ||
                              track->blend_read_enable)) {
                                continue;
                        }
@@ -3007,7 +3012,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
                }
        }
        prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
-       nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+       if (track->vap_vf_cntl & (1 << 14)) {
+               nverts = track->vap_alt_nverts;
+       } else {
+               nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+       }
        switch (prim_walk) {
        case 1:
                for (i = 0; i < track->num_arrays; i++) {
index b27a699..f47cdca 100644 (file)
@@ -64,6 +64,7 @@ struct r100_cs_track {
        unsigned                        maxy;
        unsigned                        vtx_size;
        unsigned                        vap_vf_cntl;
+       unsigned                        vap_alt_nverts;
        unsigned                        immd_dwords;
        unsigned                        num_arrays;
        unsigned                        max_indx;
@@ -74,7 +75,7 @@ struct r100_cs_track {
        struct r100_cs_track_texture    textures[R300_TRACK_MAX_TEXTURE];
        bool                            z_enabled;
        bool                            separate_cube;
-       bool                            fastfill;
+       bool                            zb_cb_clear;
        bool                            blend_read_enable;
 };
 
index 2b9affe..a5ff807 100644 (file)
@@ -324,13 +324,12 @@ void r300_gpu_init(struct radeon_device *rdev)
        uint32_t gb_tile_config, tmp;
 
        r100_hdp_reset(rdev);
-       /* FIXME: rv380 one pipes ? */
        if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
-           (rdev->family == CHIP_R350)) {
+           (rdev->family == CHIP_R350 && rdev->pdev->device != 0x4148)) {
                /* r300,r350 */
                rdev->num_gb_pipes = 2;
        } else {
-               /* rv350,rv370,rv380,r300 AD */
+               /* rv350,rv370,rv380,r300 AD, r350 AH */
                rdev->num_gb_pipes = 1;
        }
        rdev->num_z_pipes = 1;
@@ -730,6 +729,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* VAP_VF_MAX_VTX_INDX */
                track->max_indx = idx_value & 0x00FFFFFFUL;
                break;
+       case 0x2088:
+               /* VAP_ALT_NUM_VERTICES - only valid on r500 */
+               if (p->rdev->family < CHIP_RV515)
+                       goto fail;
+               track->vap_alt_nverts = idx_value & 0xFFFFFF;
+               break;
        case 0x43E4:
                /* SC_SCISSOR1 */
                track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
@@ -767,7 +772,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                tmp = idx_value & ~(0x7 << 16);
                tmp |= tile_flags;
                ib[idx] = tmp;
-
                i = (reg - 0x4E38) >> 2;
                track->cb[i].pitch = idx_value & 0x3FFE;
                switch (((idx_value >> 21) & 0xF)) {
@@ -1040,7 +1044,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                break;
        case 0x4d1c:
                /* ZB_BW_CNTL */
-               track->fastfill = !!(idx_value & (1 << 2));
+               track->zb_cb_clear = !!(idx_value & (1 << 5));
                break;
        case 0x4e04:
                /* RB3D_BLENDCNTL */
@@ -1052,11 +1056,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        break;
                /* fallthrough do not move */
        default:
-               printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
-                      reg, idx);
-               return -EINVAL;
+               goto fail;
        }
        return 0;
+fail:
+       printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+              reg, idx);
+       return -EINVAL;
 }
 
 static int r300_packet3_check(struct radeon_cs_parser *p,
index ea46d55..c5c2742 100644 (file)
@@ -921,7 +921,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
 
        ptr_addr = drm_buffer_read_object(cmdbuf->buffer,
                        sizeof(stack_ptr_addr), &stack_ptr_addr);
-       ref_age_base = (u32 *)(unsigned long)*ptr_addr;
+       ref_age_base = (u32 *)(unsigned long)get_unaligned(ptr_addr);
 
        for (i=0; i < header.scratch.n_bufs; i++) {
                buf_idx = drm_buffer_pointer_to_dword(cmdbuf->buffer, 0);
index 3dc968c..c2bda4a 100644 (file)
@@ -59,6 +59,12 @@ void r420_pipes_init(struct radeon_device *rdev)
        /* get max number of pipes */
        gb_pipe_select = RREG32(0x402C);
        num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
+
+       /* SE chips have 1 pipe */
+       if ((rdev->pdev->device == 0x5e4c) ||
+           (rdev->pdev->device == 0x5e4f))
+               num_pipes = 1;
+
        rdev->num_gb_pipes = num_pipes;
        tmp = 0;
        switch (num_pipes) {
index dac7042..1d89805 100644 (file)
@@ -35,7 +35,7 @@
  */
 static int r600_audio_chipset_supported(struct radeon_device *rdev)
 {
-       return rdev->family >= CHIP_R600
+       return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR)
                || rdev->family == CHIP_RS600
                || rdev->family == CHIP_RS690
                || rdev->family == CHIP_RS740;
index 029fa14..2616b82 100644 (file)
@@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
        struct radeon_device *rdev = dev->dev_private;
        uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!offset)
                return;
 
@@ -484,6 +487,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!radeon_encoder->hdmi_offset) {
                r600_hdmi_assign_block(encoder);
                if (!radeon_encoder->hdmi_offset) {
@@ -525,6 +531,9 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!radeon_encoder->hdmi_offset) {
                dev_err(rdev->dev, "Disabling not enabled HDMI\n");
                return;
index c445779..28e473f 100644 (file)
@@ -134,12 +134,10 @@ int radeon_agp_init(struct radeon_device *rdev)
        int ret;
 
        /* Acquire AGP. */
-       if (!rdev->ddev->agp->acquired) {
-               ret = drm_agp_acquire(rdev->ddev);
-               if (ret) {
-                       DRM_ERROR("Unable to acquire AGP: %d\n", ret);
-                       return ret;
-               }
+       ret = drm_agp_acquire(rdev->ddev);
+       if (ret) {
+               DRM_ERROR("Unable to acquire AGP: %d\n", ret);
+               return ret;
        }
 
        ret = drm_agp_info(rdev->ddev, &info);
index 5673665..9916d82 100644 (file)
@@ -1264,7 +1264,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
        switch (crev) {
        case 1:
                tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
-               if (index > MAX_SUPPORTED_TV_TIMING)
+               if (index >= MAX_SUPPORTED_TV_TIMING)
                        return false;
 
                mode->crtc_htotal = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
@@ -1302,7 +1302,7 @@ bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
                break;
        case 2:
                tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
-               if (index > MAX_SUPPORTED_TV_TIMING_V1_2)
+               if (index >= MAX_SUPPORTED_TV_TIMING_V1_2)
                        return false;
 
                dtd_timings = &tv_info_v1_2->aModeTimings[index];
index 3fba505..4559a53 100644 (file)
@@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
 {
        struct drm_device *dev = connector->dev;
        struct drm_connector *conflict;
+       struct radeon_connector *radeon_conflict;
        int i;
 
        list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
                if (conflict == connector)
                        continue;
 
+               radeon_conflict = to_radeon_connector(conflict);
                for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
                        if (conflict->encoder_ids[i] == 0)
                                break;
@@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
                                if (conflict->status != connector_status_connected)
                                        continue;
 
+                               if (radeon_conflict->use_digital)
+                                       continue;
+
                                if (priority == true) {
                                        DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
                                        DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
@@ -287,6 +292,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
 
        if (property == rdev->mode_info.coherent_mode_property) {
                struct radeon_encoder_atom_dig *dig;
+               bool new_coherent_mode;
 
                /* need to find digital encoder on connector */
                encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
@@ -299,8 +305,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
                        return 0;
 
                dig = radeon_encoder->enc_priv;
-               dig->coherent_mode = val ? true : false;
-               radeon_property_change_mode(&radeon_encoder->base);
+               new_coherent_mode = val ? true : false;
+               if (dig->coherent_mode != new_coherent_mode) {
+                       dig->coherent_mode = new_coherent_mode;
+                       radeon_property_change_mode(&radeon_encoder->base);
+               }
        }
 
        if (property == rdev->mode_info.tv_std_property) {
@@ -1307,6 +1316,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
                        radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
                        if (!radeon_connector->ddc_bus)
                                goto failed;
+               }
+               if (connector_type == DRM_MODE_CONNECTOR_DVII) {
                        radeon_connector->dac_load_detect = true;
                        drm_connector_attach_property(&radeon_connector->base,
                                                      rdev->mode_info.load_detect_property,
index 419630d..2f042a3 100644 (file)
@@ -435,14 +435,19 @@ static void radeon_init_pipes(struct drm_device *dev)
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
                gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
                dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+               /* SE cards have 1 pipe */
+               if ((dev->pdev->device == 0x5e4c) ||
+                   (dev->pdev->device == 0x5e4f))
+                       dev_priv->num_gb_pipes = 1;
        } else {
                /* R3xx */
                if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
                     dev->pdev->device != 0x4144) ||
-                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350 &&
+                    dev->pdev->device != 0x4148)) {
                        dev_priv->num_gb_pipes = 2;
                } else {
-                       /* RV3xx/R300 AD */
+                       /* RV3xx/R300 AD/R350 AH */
                        dev_priv->num_gb_pipes = 1;
                }
        }
index bddf17f..7b629e3 100644 (file)
 #include "radeon.h"
 #include "atom.h"
 
+static const char radeon_family_name[][16] = {
+       "R100",
+       "RV100",
+       "RS100",
+       "RV200",
+       "RS200",
+       "R200",
+       "RV250",
+       "RS300",
+       "RV280",
+       "R300",
+       "R350",
+       "RV350",
+       "RV380",
+       "R420",
+       "R423",
+       "RV410",
+       "RS400",
+       "RS480",
+       "RS600",
+       "RS690",
+       "RS740",
+       "RV515",
+       "R520",
+       "RV530",
+       "RV560",
+       "RV570",
+       "R580",
+       "R600",
+       "RV610",
+       "RV630",
+       "RV670",
+       "RV620",
+       "RV635",
+       "RS780",
+       "RS880",
+       "RV770",
+       "RV730",
+       "RV710",
+       "RV740",
+       "CEDAR",
+       "REDWOOD",
+       "JUNIPER",
+       "CYPRESS",
+       "HEMLOCK",
+       "LAST",
+};
+
 /*
  * Clear GPU surface registers.
  */
@@ -526,7 +574,6 @@ int radeon_device_init(struct radeon_device *rdev,
        int r;
        int dma_bits;
 
-       DRM_INFO("radeon: Initializing kernel modesetting.\n");
        rdev->shutdown = false;
        rdev->dev = &pdev->dev;
        rdev->ddev = ddev;
@@ -538,6 +585,10 @@ int radeon_device_init(struct radeon_device *rdev,
        rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        rdev->gpu_lockup = false;
        rdev->accel_working = false;
+
+       DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
+               radeon_family_name[rdev->family], pdev->vendor, pdev->device);
+
        /* mutex initialization are all done here so we
         * can recall function without having locking issues */
        mutex_init(&rdev->cs_mutex);
index b8d6728..bb1c122 100644 (file)
@@ -86,12 +86,12 @@ static void evergreen_crtc_load_lut(struct drm_crtc *crtc)
        WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_GREEN + radeon_crtc->crtc_offset, 0xffff);
        WREG32(EVERGREEN_DC_LUT_WHITE_OFFSET_RED + radeon_crtc->crtc_offset, 0xffff);
 
-       WREG32(EVERGREEN_DC_LUT_RW_MODE, radeon_crtc->crtc_id);
-       WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK, 0x00000007);
+       WREG32(EVERGREEN_DC_LUT_RW_MODE + radeon_crtc->crtc_offset, 0);
+       WREG32(EVERGREEN_DC_LUT_WRITE_EN_MASK + radeon_crtc->crtc_offset, 0x00000007);
 
-       WREG32(EVERGREEN_DC_LUT_RW_INDEX, 0);
+       WREG32(EVERGREEN_DC_LUT_RW_INDEX + radeon_crtc->crtc_offset, 0);
        for (i = 0; i < 256; i++) {
-               WREG32(EVERGREEN_DC_LUT_30_COLOR,
+               WREG32(EVERGREEN_DC_LUT_30_COLOR + radeon_crtc->crtc_offset,
                       (radeon_crtc->lut_r[i] << 20) |
                       (radeon_crtc->lut_g[i] << 10) |
                       (radeon_crtc->lut_b[i] << 0));
index 055a517..b3749d4 100644 (file)
  * - 2.0.0 - initial interface
  * - 2.1.0 - add square tiling interface
  * - 2.2.0 - add r6xx/r7xx const buffer support
+ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       2
+#define KMS_DRIVER_MINOR       3
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
@@ -215,6 +216,7 @@ static struct drm_driver driver_old = {
                 .mmap = drm_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
+                .read = drm_read,
 #ifdef CONFIG_COMPAT
                 .compat_ioctl = radeon_compat_ioctl,
 #endif
@@ -303,6 +305,7 @@ static struct drm_driver kms_driver = {
                 .mmap = radeon_mmap,
                 .poll = drm_poll,
                 .fasync = drm_fasync,
+                .read = drm_read,
 #ifdef CONFIG_COMPAT
                 .compat_ioctl = radeon_kms_compat_ioctl,
 #endif
index c52fc30..c5ddaf5 100644 (file)
@@ -254,6 +254,53 @@ radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder)
        return dig_connector;
 }
 
+void radeon_panel_mode_fixup(struct drm_encoder *encoder,
+                            struct drm_display_mode *adjusted_mode)
+{
+       struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+       struct drm_device *dev = encoder->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+       unsigned hblank = native_mode->htotal - native_mode->hdisplay;
+       unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
+       unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
+       unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
+       unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
+       unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
+
+       adjusted_mode->clock = native_mode->clock;
+       adjusted_mode->flags = native_mode->flags;
+
+       if (ASIC_IS_AVIVO(rdev)) {
+               adjusted_mode->hdisplay = native_mode->hdisplay;
+               adjusted_mode->vdisplay = native_mode->vdisplay;
+       }
+
+       adjusted_mode->htotal = native_mode->hdisplay + hblank;
+       adjusted_mode->hsync_start = native_mode->hdisplay + hover;
+       adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
+
+       adjusted_mode->vtotal = native_mode->vdisplay + vblank;
+       adjusted_mode->vsync_start = native_mode->vdisplay + vover;
+       adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
+
+       drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+
+       if (ASIC_IS_AVIVO(rdev)) {
+               adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
+               adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
+       }
+
+       adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
+       adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
+       adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
+
+       adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
+       adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
+       adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
+
+}
+
 static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
                                   struct drm_display_mode *mode,
                                   struct drm_display_mode *adjusted_mode)
@@ -275,18 +322,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
                adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
 
        /* get the native mode for LVDS */
-       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-               struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-               int mode_id = adjusted_mode->base.id;
-               *adjusted_mode = *native_mode;
-               if (!ASIC_IS_AVIVO(rdev)) {
-                       adjusted_mode->hdisplay = mode->hdisplay;
-                       adjusted_mode->vdisplay = mode->vdisplay;
-                       adjusted_mode->crtc_hdisplay = mode->hdisplay;
-                       adjusted_mode->crtc_vdisplay = mode->vdisplay;
-               }
-               adjusted_mode->base.id = mode_id;
-       }
+       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+               radeon_panel_mode_fixup(encoder, adjusted_mode);
 
        /* get the native mode for TV */
        if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
@@ -865,6 +902,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v3.acConfig.fCoherentMode = 1;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v3.acConfig.fDualLinkConnector = 1;
                }
        } else if (ASIC_IS_DCE32(rdev)) {
                args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
@@ -888,6 +927,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v2.acConfig.fCoherentMode = 1;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v2.acConfig.fDualLinkConnector = 1;
                }
        } else {
                args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
@@ -1322,7 +1363,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 
        radeon_encoder->pixel_clock = adjusted_mode->clock;
 
-       if (ASIC_IS_AVIVO(rdev)) {
+       if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) {
                if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
                        atombios_yuv_setup(encoder, true);
                else
@@ -1373,8 +1414,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
                atombios_dac_setup(encoder, ATOM_ENABLE);
-               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-                       atombios_tv_setup(encoder, ATOM_ENABLE);
+               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
+                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+                               atombios_tv_setup(encoder, ATOM_ENABLE);
+                       else
+                               atombios_tv_setup(encoder, ATOM_DISABLE);
+               }
                break;
        }
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
index 93c7d5d..e329066 100644 (file)
@@ -36,7 +36,7 @@
  * Radeon chip families
  */
 enum radeon_family {
-       CHIP_R100,
+       CHIP_R100 = 0,
        CHIP_RV100,
        CHIP_RS100,
        CHIP_RV200,
@@ -99,4 +99,5 @@ enum radeon_chip_flags {
        RADEON_IS_PCI = 0x00800000UL,
        RADEON_IS_IGPGART = 0x01000000UL,
 };
+
 #endif
index d3657dc..c633319 100644 (file)
@@ -165,7 +165,7 @@ u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
 {
        struct radeon_device *rdev = dev->dev_private;
 
-       if (crtc < 0 || crtc > 1) {
+       if (crtc < 0 || crtc >= rdev->num_crtc) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
                return -EINVAL;
        }
@@ -177,7 +177,7 @@ int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
 {
        struct radeon_device *rdev = dev->dev_private;
 
-       if (crtc < 0 || crtc > 1) {
+       if (crtc < 0 || crtc >= rdev->num_crtc) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
                return -EINVAL;
        }
@@ -191,7 +191,7 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
 {
        struct radeon_device *rdev = dev->dev_private;
 
-       if (crtc < 0 || crtc > 1) {
+       if (crtc < 0 || crtc >= rdev->num_crtc) {
                DRM_ERROR("Invalid crtc %d\n", crtc);
                return;
        }
index 2441cca..0274abe 100644 (file)
@@ -228,16 +228,8 @@ static bool radeon_legacy_mode_fixup(struct drm_encoder *encoder,
        drm_mode_set_crtcinfo(adjusted_mode, 0);
 
        /* get the native mode for LVDS */
-       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-               struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
-               int mode_id = adjusted_mode->base.id;
-               *adjusted_mode = *native_mode;
-               adjusted_mode->hdisplay = mode->hdisplay;
-               adjusted_mode->vdisplay = mode->vdisplay;
-               adjusted_mode->crtc_hdisplay = mode->hdisplay;
-               adjusted_mode->crtc_vdisplay = mode->vdisplay;
-               adjusted_mode->base.id = mode_id;
-       }
+       if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+               radeon_panel_mode_fixup(encoder, adjusted_mode);
 
        return true;
 }
index 0b8e327..5413fcd 100644 (file)
@@ -558,6 +558,8 @@ extern int radeon_static_clocks_init(struct drm_device *dev);
 bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
                                        struct drm_display_mode *mode,
                                        struct drm_display_mode *adjusted_mode);
+void radeon_panel_mode_fixup(struct drm_encoder *encoder,
+                            struct drm_display_mode *adjusted_mode);
 void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
 
 /* legacy tv */
index 40ab6d9..cc5316d 100644 (file)
@@ -424,7 +424,7 @@ static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
                if ((*cmd & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
                    (*cmd & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
                        u32 *cmd3 = drm_buffer_pointer_to_dword(cmdbuf->buffer, 3);
-                       offset = *cmd << 10;
+                       offset = *cmd3 << 10;
                        if (radeon_check_and_fixup_offset
                            (dev_priv, file_priv, &offset)) {
                                DRM_ERROR("Invalid second packet offset\n");
@@ -2895,9 +2895,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
                        return rv;
                rv = drm_buffer_copy_from_user(cmdbuf->buffer, buffer,
                                                cmdbuf->bufsz);
-               if (rv)
+               if (rv) {
+                       drm_buffer_free(cmdbuf->buffer);
                        return rv;
-       }
+               }
+       } else
+               goto done;
 
        orig_nbox = cmdbuf->nbox;
 
@@ -2905,8 +2908,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
                int temp;
                temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
 
-               if (cmdbuf->bufsz != 0)
-                       drm_buffer_free(cmdbuf->buffer);
+               drm_buffer_free(cmdbuf->buffer);
 
                return temp;
        }
@@ -3012,16 +3014,15 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data,
                }
        }
 
-       if (cmdbuf->bufsz != 0)
-               drm_buffer_free(cmdbuf->buffer);
+       drm_buffer_free(cmdbuf->buffer);
 
+      done:
        DRM_DEBUG("DONE\n");
        COMMIT_RING();
        return 0;
 
       err:
-       if (cmdbuf->bufsz != 0)
-               drm_buffer_free(cmdbuf->buffer);
+       drm_buffer_free(cmdbuf->buffer);
        return -EINVAL;
 }
 
index 19c4663..1e97b2d 100644 (file)
@@ -125,6 +125,8 @@ r300 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 989f7a0..e958980 100644 (file)
@@ -125,6 +125,8 @@ r420 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 6801b86..83e8bc0 100644 (file)
@@ -125,6 +125,8 @@ rs600 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 38abf63..1e46233 100644 (file)
@@ -35,6 +35,7 @@ rv515 0x6d40
 0x1DA8 VAP_VPORT_ZSCALE
 0x1DAC VAP_VPORT_ZOFFSET
 0x2080 VAP_CNTL
+0x208C VAP_INDEX_OFFSET
 0x2090 VAP_OUT_VTX_FMT_0
 0x2094 VAP_OUT_VTX_FMT_1
 0x20B0 VAP_VTE_CNTL
@@ -158,6 +159,8 @@ rv515 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index abf824c..a81bc7a 100644 (file)
@@ -159,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
        WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
        tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
-       tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
+       tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1);
        WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
        tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
index dd47b2a..0e3754a 100644 (file)
@@ -1716,40 +1716,12 @@ int ttm_bo_wait(struct ttm_buffer_object *bo,
 }
 EXPORT_SYMBOL(ttm_bo_wait);
 
-void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
-{
-       atomic_set(&bo->reserved, 0);
-       wake_up_all(&bo->event_queue);
-}
-
-int ttm_bo_block_reservation(struct ttm_buffer_object *bo, bool interruptible,
-                            bool no_wait)
-{
-       int ret;
-
-       while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
-               if (no_wait)
-                       return -EBUSY;
-               else if (interruptible) {
-                       ret = wait_event_interruptible
-                           (bo->event_queue, atomic_read(&bo->reserved) == 0);
-                       if (unlikely(ret != 0))
-                               return ret;
-               } else {
-                       wait_event(bo->event_queue,
-                                  atomic_read(&bo->reserved) == 0);
-               }
-       }
-       return 0;
-}
-
 int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait)
 {
        int ret = 0;
 
        /*
-        * Using ttm_bo_reserve instead of ttm_bo_block_reservation
-        * makes sure the lru lists are updated.
+        * Using ttm_bo_reserve makes sure the lru lists are updated.
         */
 
        ret = ttm_bo_reserve(bo, true, no_wait, false, 0);
index 3d172ef..de41e55 100644 (file)
@@ -204,7 +204,6 @@ static int __ttm_vt_unlock(struct ttm_lock *lock)
        lock->flags &= ~TTM_VT_LOCK;
        wake_up_all(&lock->queue);
        spin_unlock(&lock->lock);
-       printk(KERN_INFO TTM_PFX "vt unlock.\n");
 
        return ret;
 }
@@ -265,10 +264,8 @@ int ttm_vt_lock(struct ttm_lock *lock,
                                   ttm_lock_type, &ttm_vt_lock_remove, NULL);
        if (ret)
                (void)__ttm_vt_unlock(lock);
-       else {
+       else
                lock->vt_holder = tfile;
-               printk(KERN_INFO TTM_PFX "vt lock.\n");
-       }
 
        return ret;
 }
index 6ec04ac..6efac81 100644 (file)
@@ -75,7 +75,7 @@ int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_
 
        DRM_DEBUG("\n");
 
-       if (fx->lock > VIA_NR_XVMC_LOCKS)
+       if (fx->lock >= VIA_NR_XVMC_LOCKS)
                return -EFAULT;
 
        lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
index d6d1149..c8768f3 100644 (file)
@@ -276,8 +276,10 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
 
        mutex_lock(&vgasr_mutex);
 
-       if (!vgasr_priv.active)
-               return -EINVAL;
+       if (!vgasr_priv.active) {
+               cnt = -EINVAL;
+               goto out;
+       }
 
        /* pwr off the device not in use */
        if (strncmp(usercmd, "OFF", 3) == 0) {
index 7e597d7..24663a8 100644 (file)
@@ -59,6 +59,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 
 static const struct hid_device_id ch_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, ch_devices);
index 2e2aa75..143e788 100644 (file)
@@ -1043,13 +1043,8 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
 
        if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event)
                hid->hiddev_report_event(hid, report);
-       if (hid->claimed & HID_CLAIMED_HIDRAW) {
-               /* numbered reports need to be passed with the report num */
-               if (report_enum->numbered)
-                       hidraw_report_event(hid, data - 1, size + 1);
-               else
-                       hidraw_report_event(hid, data, size);
-       }
+       if (hid->claimed & HID_CLAIMED_HIDRAW)
+               hidraw_report_event(hid, data, size);
 
        for (a = 0; a < report->maxfield; a++)
                hid_input_field(hid, report->field[a], cdata, interrupt);
@@ -1296,6 +1291,7 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
index 797e064..09d2764 100644 (file)
 
 #define USB_VENDOR_ID_CHERRY           0x046a
 #define USB_DEVICE_ID_CHERRY_CYMOTION  0x0023
+#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR    0x0027
 
 #define USB_VENDOR_ID_CHIC             0x05fe
 #define USB_DEVICE_ID_CHIC_GAMEPAD     0x0014
index 9b24fc5..4777bbf 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  HID driver for N-Trig touchscreens
  *
- *  Copyright (c) 2008 Rafi Rubin
- *  Copyright (c) 2009 Stephane Chatty
+ *  Copyright (c) 2008-2010 Rafi Rubin
+ *  Copyright (c) 2009-2010 Stephane Chatty
  *
  */
 
@@ -15,6 +15,8 @@
 
 #include <linux/device.h>
 #include <linux/hid.h>
+#include <linux/usb.h>
+#include "usbhid/usbhid.h"
 #include <linux/module.h>
 #include <linux/slab.h>
 
 
 #define NTRIG_DUPLICATE_USAGES 0x001
 
-#define nt_map_key_clear(c)    hid_map_usage_clear(hi, usage, bit, max, \
-                                       EV_KEY, (c))
-
 struct ntrig_data {
        /* Incoming raw values for a single contact */
        __u16 x, y, w, h;
        __u16 id;
-       __u8 confidence;
+
+       bool tipswitch;
+       bool confidence;
+       bool first_contact_touch;
 
        bool reading_mt;
-       __u8 first_contact_confidence;
 
        __u8 mt_footer[4];
        __u8 mt_foot_count;
@@ -139,9 +140,10 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
                case 0xff000001:
                        /* Tag indicating the start of a multitouch group */
                        nd->reading_mt = 1;
-                       nd->first_contact_confidence = 0;
+                       nd->first_contact_touch = 0;
                        break;
                case HID_DG_TIPSWITCH:
+                       nd->tipswitch = value;
                        /* Prevent emission of touch until validated */
                        return 1;
                case HID_DG_CONFIDENCE:
@@ -169,8 +171,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
                         * to emit a normal (X, Y) position
                         */
                        if (!nd->reading_mt) {
+                               /*
+                                * TipSwitch indicates the presence of a
+                                * finger in single touch mode.
+                                */
+                               input_report_key(input, BTN_TOUCH,
+                                                nd->tipswitch);
                                input_report_key(input, BTN_TOOL_DOUBLETAP,
-                                                (nd->confidence != 0));
+                                                nd->tipswitch);
                                input_event(input, EV_ABS, ABS_X, nd->x);
                                input_event(input, EV_ABS, ABS_Y, nd->y);
                        }
@@ -209,7 +217,13 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 
                        /* emit a normal (X, Y) for the first point only */
                        if (nd->id == 0) {
-                               nd->first_contact_confidence = nd->confidence;
+                               /*
+                                * TipSwitch is superfluous in multitouch
+                                * mode.  The footer events tell us
+                                * if there is a finger on the screen or
+                                * not.
+                                */
+                               nd->first_contact_touch = nd->confidence;
                                input_event(input, EV_ABS, ABS_X, nd->x);
                                input_event(input, EV_ABS, ABS_Y, nd->y);
                        }
@@ -239,30 +253,11 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 
                        nd->reading_mt = 0;
 
-                       if (nd->first_contact_confidence) {
-                               switch (value) {
-                               case 0: /* for single touch devices */
-                               case 1:
-                                       input_report_key(input,
-                                                       BTN_TOOL_DOUBLETAP, 1);
-                                       break;
-                               case 2:
-                                       input_report_key(input,
-                                                       BTN_TOOL_TRIPLETAP, 1);
-                                       break;
-                               case 3:
-                               default:
-                                       input_report_key(input,
-                                                       BTN_TOOL_QUADTAP, 1);
-                               }
+                       if (nd->first_contact_touch) {
+                               input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
                                input_report_key(input, BTN_TOUCH, 1);
                        } else {
-                               input_report_key(input,
-                                               BTN_TOOL_DOUBLETAP, 0);
-                               input_report_key(input,
-                                               BTN_TOOL_TRIPLETAP, 0);
-                               input_report_key(input,
-                                               BTN_TOOL_QUADTAP, 0);
+                               input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
                                input_report_key(input, BTN_TOUCH, 0);
                        }
                        break;
@@ -286,6 +281,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
        struct ntrig_data *nd;
        struct hid_input *hidinput;
        struct input_dev *input;
+       struct hid_report *report;
 
        if (id->driver_data)
                hdev->quirks |= HID_QUIRK_MULTI_INPUT;
@@ -327,13 +323,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
                        __clear_bit(BTN_TOOL_PEN, input->keybit);
                        __clear_bit(BTN_TOOL_FINGER, input->keybit);
                        __clear_bit(BTN_0, input->keybit);
-                       /*
-                        * A little something special to enable
-                        * two and three finger taps.
-                        */
                        __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
-                       __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
-                       __set_bit(BTN_TOOL_QUADTAP, input->keybit);
                        /*
                         * The physical touchscreen (single touch)
                         * input has a value for physical, whereas
@@ -349,6 +339,12 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
                }
        }
 
+       /* This is needed for devices with more recent firmware versions */
+       report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
+       if (report)
+               usbhid_submit_report(hdev, report, USB_DIR_OUT);
+
+
        return 0;
 err_free:
        kfree(nd);
index 7502a4b..402d557 100644 (file)
@@ -76,7 +76,7 @@ static int sony_set_operational_usb(struct hid_device *hdev)
 
 static int sony_set_operational_bt(struct hid_device *hdev)
 {
-       unsigned char buf[] = { 0x53, 0xf4,  0x42, 0x03, 0x00, 0x00 };
+       unsigned char buf[] = { 0xf4,  0x42, 0x03, 0x00, 0x00 };
        return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
 }
 
index f7700cf..f947d83 100644 (file)
@@ -277,7 +277,6 @@ static int __init wacom_init(void)
        ret = hid_register_driver(&wacom_driver);
        if (ret)
                printk(KERN_ERR "can't register wacom driver\n");
-       printk(KERN_ERR "wacom driver registered\n");
        return ret;
 }
 
index 56d06cd..7b85b69 100644 (file)
@@ -999,13 +999,6 @@ static int usbhid_start(struct hid_device *hid)
                }
        }
 
-       init_waitqueue_head(&usbhid->wait);
-       INIT_WORK(&usbhid->reset_work, hid_reset);
-       INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
-       setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
-
-       spin_lock_init(&usbhid->lock);
-
        usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
        if (!usbhid->urbctrl) {
                ret = -ENOMEM;
@@ -1179,6 +1172,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
        usbhid->intf = intf;
        usbhid->ifnum = interface->desc.bInterfaceNumber;
 
+       init_waitqueue_head(&usbhid->wait);
+       INIT_WORK(&usbhid->reset_work, hid_reset);
+       INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
+       setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
+       spin_lock_init(&usbhid->lock);
+
        ret = hid_add_device(hid);
        if (ret) {
                if (ret != -ENODEV)
index c1605b5..f085c18 100644 (file)
@@ -142,6 +142,12 @@ static const char *temperature_sensors_sets[][41] = {
          "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
          "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
          NULL },
+/* Set 17: iMac 9,1 */
+       { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
+         "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
+/* Set 18: MacBook Pro 2,2 */
+       { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
+         "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
 };
 
 /* List of keys used to read/write fan speeds */
@@ -189,6 +195,9 @@ static unsigned int applesmc_accelerometer;
 /* Indicates whether this computer has light sensors and keyboard backlight. */
 static unsigned int applesmc_light;
 
+/* The number of fans handled by the driver */
+static unsigned int fans_handled;
+
 /* Indicates which temperature sensors set to use. */
 static unsigned int applesmc_temperature_set;
 
@@ -1350,6 +1359,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
        { .accelerometer = 1, .light = 1, .temperature_set = 15 },
 /* MacPro3,1: temperature set 16 */
        { .accelerometer = 0, .light = 0, .temperature_set = 16 },
+/* iMac 9,1: light sensor only, temperature set 17 */
+       { .accelerometer = 0, .light = 0, .temperature_set = 17 },
+/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
+       { .accelerometer = 1, .light = 1, .temperature_set = 18 },
 };
 
 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1375,6 +1388,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
                &applesmc_dmi_data[9]},
+       { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
+         DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
+               &applesmc_dmi_data[18]},
        { applesmc_dmi_match, "Apple MacBook Pro", {
          DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
@@ -1415,6 +1432,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
                &applesmc_dmi_data[4]},
+       { applesmc_dmi_match, "Apple iMac 9,1", {
+         DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
+               &applesmc_dmi_data[17]},
        { applesmc_dmi_match, "Apple iMac 8", {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
@@ -1474,39 +1495,24 @@ static int __init applesmc_init(void)
 
        /* create fan files */
        count = applesmc_get_fan_count();
-       if (count < 0) {
+       if (count < 0)
                printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
-       } else {
+       else
                printk(KERN_INFO "applesmc: %d fans found.\n", count);
 
-               switch (count) {
-               default:
-                       printk(KERN_WARNING "applesmc: More than 4 fans found,"
-                                       " but at most 4 fans are supported"
-                                               " by the driver.\n");
-               case 4:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[3]);
-                       if (ret)
-                               goto out_key_enumeration;
-               case 3:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[2]);
-                       if (ret)
-                               goto out_key_enumeration;
-               case 2:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[1]);
-                       if (ret)
-                               goto out_key_enumeration;
-               case 1:
-                       ret = sysfs_create_group(&pdev->dev.kobj,
-                                                &fan_attribute_groups[0]);
-                       if (ret)
-                               goto out_fan_1;
-               case 0:
-                       ;
-               }
+       if (count > 4) {
+               count = 4;
+               printk(KERN_WARNING "applesmc: More than 4 fans found,"
+                      " but at most 4 fans are supported"
+                      " by the driver.\n");
+       }
+
+       while (fans_handled < count) {
+               ret = sysfs_create_group(&pdev->dev.kobj,
+                                        &fan_attribute_groups[fans_handled]);
+               if (ret)
+                       goto out_fans;
+               fans_handled++;
        }
 
        for (i = 0;
@@ -1575,10 +1581,10 @@ out_accelerometer:
                applesmc_release_accelerometer();
 out_temperature:
        sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
-out_fan_1:
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
-out_key_enumeration:
+out_fans:
+       while (fans_handled)
+               sysfs_remove_group(&pdev->dev.kobj,
+                                  &fan_attribute_groups[--fans_handled]);
        sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
 out_name:
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
@@ -1604,8 +1610,9 @@ static void __exit applesmc_exit(void)
        if (applesmc_accelerometer)
                applesmc_release_accelerometer();
        sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
-       sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
+       while (fans_handled)
+               sysfs_remove_group(&pdev->dev.kobj,
+                                  &fan_attribute_groups[--fans_handled]);
        sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr);
        platform_device_unregister(pdev);
index 7f94810..0f388ad 100644 (file)
@@ -268,8 +268,11 @@ static ssize_t store_fan16(struct device *dev,
        if (strict_strtol(buf, 10, &reqval))
                return -EINVAL;
 
+       /* If a minimum RPM of zero is requested, then we set the register to
+          0xffff. This value allows the fan to be stopped completely without
+          generating an alarm. */
        reqval =
-           (SENSORS_LIMIT((reqval) <= 0 ? 0 : 5400000 / (reqval), 0, 65534));
+           (reqval <= 0 ? 0xffff : SENSORS_LIMIT(5400000 / reqval, 0, 0xfffe));
 
        mutex_lock(&data->update_lock);
        data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
@@ -285,8 +288,9 @@ static ssize_t store_fan16(struct device *dev,
  * Voltages are scaled in the device so that the nominal voltage
  * is 3/4ths of the 0-255 range (i.e. 192).
  * If all voltages are 'normal' then all voltage registers will
- * read 0xC0.  This doesn't help us if we don't have a point of refernce.
- * The data sheet however provides us with the full scale value for each
+ * read 0xC0.
+ *
+ * The data sheet provides us with the 3/4 scale value for each voltage
  * which is stored in in_scaling.  The sda->index parameter value provides
  * the index into in_scaling.
  *
@@ -295,7 +299,7 @@ static ssize_t store_fan16(struct device *dev,
  */
 
 static int asc7621_in_scaling[] = {
-       3320, 3000, 4380, 6640, 16000
+       2500, 2250, 3300, 5000, 12000
 };
 
 static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
@@ -306,19 +310,12 @@ static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
        u8 nr = sda->index;
 
        mutex_lock(&data->update_lock);
-       regval = (data->reg[param->msb[0]] * asc7621_in_scaling[nr]) / 256;
-
-       /* The LSB value is a 2-bit scaling of the MSB's LSbit value.
-        * I.E.  If the maximim voltage for this input is 6640 millivolts then
-        * a MSB register value of 0 = 0mv and 255 = 6640mv.
-        * A 1 step change therefore represents 25.9mv (6640 / 256).
-        * The extra 2-bits therefore represent increments of 6.48mv.
-        */
-       regval += ((asc7621_in_scaling[nr] / 256) / 4) *
-           (data->reg[param->lsb[0]] >> 6);
-
+       regval = (data->reg[param->msb[0]] << 8) | (data->reg[param->lsb[0]]);
        mutex_unlock(&data->update_lock);
 
+       /* The LSB value is a 2-bit scaling of the MSB's LSbit value. */
+       regval = (regval >> 6) * asc7621_in_scaling[nr] / (0xc0 << 2);
+
        return sprintf(buf, "%u\n", regval);
 }
 
@@ -331,7 +328,7 @@ static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
 
        return sprintf(buf, "%u\n",
                       ((data->reg[param->msb[0]] *
-                        asc7621_in_scaling[nr]) / 256));
+                        asc7621_in_scaling[nr]) / 0xc0));
 }
 
 static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
@@ -344,9 +341,11 @@ static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
        if (strict_strtol(buf, 10, &reqval))
                return -EINVAL;
 
-       reqval = SENSORS_LIMIT(reqval, 0, asc7621_in_scaling[nr]);
+       reqval = SENSORS_LIMIT(reqval, 0, 0xffff);
+
+       reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
 
-       reqval = (reqval * 255 + 128) / asc7621_in_scaling[nr];
+       reqval = SENSORS_LIMIT(reqval, 0, 0xff);
 
        mutex_lock(&data->update_lock);
        data->reg[param->msb[0]] = reqval;
@@ -846,11 +845,11 @@ static struct asc7621_param asc7621_params[] = {
        PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
        PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
 
-       PREAD(in0_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 0, bitmask),
-       PREAD(in1_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 1, bitmask),
-       PREAD(in2_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 2, bitmask),
-       PREAD(in3_alarm, 3, PRI_LOW, 0x41, 0, 0x01, 3, bitmask),
-       PREAD(in4_alarm, 4, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
+       PREAD(in0_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 0, bitmask),
+       PREAD(in1_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 1, bitmask),
+       PREAD(in2_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 2, bitmask),
+       PREAD(in3_alarm, 3, PRI_HIGH, 0x41, 0, 0x01, 3, bitmask),
+       PREAD(in4_alarm, 4, PRI_HIGH, 0x42, 0, 0x01, 0, bitmask),
 
        PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
        PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
@@ -862,10 +861,10 @@ static struct asc7621_param asc7621_params[] = {
        PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
        PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
 
-       PREAD(fan1_alarm, 0, PRI_LOW, 0x42, 0, 0x01, 0, bitmask),
-       PREAD(fan2_alarm, 1, PRI_LOW, 0x42, 0, 0x01, 1, bitmask),
-       PREAD(fan3_alarm, 2, PRI_LOW, 0x42, 0, 0x01, 2, bitmask),
-       PREAD(fan4_alarm, 3, PRI_LOW, 0x42, 0, 0x01, 3, bitmask),
+       PREAD(fan1_alarm, 0, PRI_HIGH, 0x42, 0, 0x01, 2, bitmask),
+       PREAD(fan2_alarm, 1, PRI_HIGH, 0x42, 0, 0x01, 3, bitmask),
+       PREAD(fan3_alarm, 2, PRI_HIGH, 0x42, 0, 0x01, 4, bitmask),
+       PREAD(fan4_alarm, 3, PRI_HIGH, 0x42, 0, 0x01, 5, bitmask),
 
        PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
        PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
@@ -886,10 +885,10 @@ static struct asc7621_param asc7621_params[] = {
        PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
        PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
 
-       PREAD(temp1_alarm, 0, PRI_LOW, 0x41, 0, 0x01, 4, bitmask),
-       PREAD(temp2_alarm, 1, PRI_LOW, 0x41, 0, 0x01, 5, bitmask),
-       PREAD(temp3_alarm, 2, PRI_LOW, 0x41, 0, 0x01, 6, bitmask),
-       PREAD(temp4_alarm, 3, PRI_LOW, 0x43, 0, 0x01, 0, bitmask),
+       PREAD(temp1_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 4, bitmask),
+       PREAD(temp2_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 5, bitmask),
+       PREAD(temp3_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 6, bitmask),
+       PREAD(temp4_alarm, 3, PRI_HIGH, 0x43, 0, 0x01, 0, bitmask),
 
        PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
        PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
@@ -898,7 +897,7 @@ static struct asc7621_param asc7621_params[] = {
 
        PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
        PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
-       PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x64, 0, 0x01, 3, bitmask),
+       PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x63, 0, 0x01, 3, bitmask),
        PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
 
        PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
index 75f3fa5..16c4202 100644 (file)
@@ -1169,15 +1169,19 @@ static int atk_create_files(struct atk_data *data)
        int err;
 
        list_for_each_entry(s, &data->sensor_list, list) {
+               sysfs_attr_init(&s->input_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->input_attr);
                if (err)
                        return err;
+               sysfs_attr_init(&s->label_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->label_attr);
                if (err)
                        return err;
+               sysfs_attr_init(&s->limit1_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->limit1_attr);
                if (err)
                        return err;
+               sysfs_attr_init(&s->limit2_attr.attr);
                err = device_create_file(data->hwmon_dev, &s->limit2_attr);
                if (err)
                        return err;
index be475e8..7580f55 100644 (file)
@@ -217,6 +217,10 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
        AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
        AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
        AXIS_DMI_MATCH("HDX18", "HP HDX 18", x_inverted),
+       AXIS_DMI_MATCH("HPB432x", "HP ProBook 432", xy_rotated_left),
+       AXIS_DMI_MATCH("HPB442x", "HP ProBook 442", xy_rotated_left),
+       AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted),
+       AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap),
        { NULL, }
 /* Laptop models without axis info (yet):
  * "NC6910" "HP Compaq 6910"
@@ -324,8 +328,8 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
        lis3lv02d_joystick_disable();
        lis3lv02d_poweroff(&lis3_dev);
 
-       flush_work(&hpled_led.work);
        led_classdev_unregister(&hpled_led.led_classdev);
+       flush_work(&hpled_led.work);
 
        return lis3lv02d_remove_fs(&lis3_dev);
 }
index 1002bef..5be09c0 100644 (file)
@@ -539,14 +539,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
 
        struct it87_data *data = dev_get_drvdata(dev);
        long val;
+       u8 reg;
 
        if (strict_strtol(buf, 10, &val) < 0)
                return -EINVAL;
 
-       mutex_lock(&data->update_lock);
-
-       data->sensor &= ~(1 << nr);
-       data->sensor &= ~(8 << nr);
+       reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+       reg &= ~(1 << nr);
+       reg &= ~(8 << nr);
        if (val == 2) { /* backwards compatibility */
                dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
                         "instead\n");
@@ -554,14 +554,16 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
        }
        /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
        if (val == 3)
-               data->sensor |= 1 << nr;
+               reg |= 1 << nr;
        else if (val == 4)
-               data->sensor |= 8 << nr;
-       else if (val != 0) {
-               mutex_unlock(&data->update_lock);
+               reg |= 8 << nr;
+       else if (val != 0)
                return -EINVAL;
-       }
+
+       mutex_lock(&data->update_lock);
+       data->sensor = reg;
        it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+       data->valid = 0;        /* Force cache refresh */
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -1841,14 +1843,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
                        it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
        }
 
-       /* Check if temperature channels are reset manually or by some reason */
-       tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
-       if ((tmp & 0x3f) == 0) {
-               /* Temp1,Temp3=thermistor; Temp2=thermal diode */
-               tmp = (tmp & 0xc0) | 0x2a;
-               it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp);
-       }
-       data->sensor = tmp;
+       /* Temperature channels are not forcibly enabled, as they can be
+        * set to two different sensor types and we can't guess which one
+        * is correct for a given system. These channels can be enabled at
+        * run-time through the temp{1-3}_type sysfs accessors if needed. */
 
        /* Check if voltage monitors are reset manually or by some reason */
        tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
index 6b2d8ae..a610e78 100644 (file)
@@ -303,13 +303,13 @@ error_ret:
  **/
 static inline int sht15_calc_temp(struct sht15_data *data)
 {
-       int d1 = 0;
+       int d1 = temppoints[0].d1;
        int i;
 
-       for (i = 1; i < ARRAY_SIZE(temppoints); i++)
+       for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
                /* Find pointer to interpolate */
                if (data->supply_uV > temppoints[i - 1].vdd) {
-                       d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+                       d1 = (data->supply_uV - temppoints[i - 1].vdd)
                                * (temppoints[i].d1 - temppoints[i - 1].d1)
                                / (temppoints[i].vdd - temppoints[i - 1].vdd)
                                + temppoints[i - 1].d1;
@@ -542,7 +542,12 @@ static int __devinit sht15_probe(struct platform_device *pdev)
 /* If a regulator is available, query what the supply voltage actually is!*/
        data->reg = regulator_get(data->dev, "vcc");
        if (!IS_ERR(data->reg)) {
-               data->supply_uV = regulator_get_voltage(data->reg);
+               int voltage;
+
+               voltage = regulator_get_voltage(data->reg);
+               if (voltage)
+                       data->supply_uV = voltage;
+
                regulator_enable(data->reg);
                /* setup a notifier block to update this if another device
                 *  causes the voltage to change */
index 9c6170c..87ab056 100644 (file)
@@ -564,7 +564,7 @@ config I2C_STU300
 
 config I2C_VERSATILE
        tristate "ARM Versatile/Realview I2C bus support"
-       depends on ARCH_VERSATILE || ARCH_REALVIEW
+       depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
        select I2C_ALGOBIT
        help
          Say yes if you want to support the I2C serial bus on ARMs Versatile
index f7e27b7..d1ff940 100644 (file)
@@ -146,10 +146,10 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
                                "<%s> I2C Interrupted\n", __func__);
                        return -EINTR;
                }
-               if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+               if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> I2C bus is busy\n", __func__);
-                       return -EIO;
+                       return -ETIMEDOUT;
                }
                schedule();
        }
@@ -444,6 +444,8 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
                        result = i2c_imx_read(i2c_imx, &msgs[i]);
                else
                        result = i2c_imx_write(i2c_imx, &msgs[i]);
+               if (result)
+                       goto fail0;
        }
 
 fail0:
index a2481f4..0e9f85d 100644 (file)
@@ -447,7 +447,7 @@ static struct i2c_adapter octeon_i2c_ops = {
 /**
  * octeon_i2c_setclock - Calculate and set clock divisors.
  */
-static int __init octeon_i2c_setclock(struct octeon_i2c *i2c)
+static int __devinit octeon_i2c_setclock(struct octeon_i2c *i2c)
 {
        int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
        int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
@@ -490,7 +490,7 @@ static int __init octeon_i2c_setclock(struct octeon_i2c *i2c)
        return 0;
 }
 
-static int __init octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
+static int __devinit octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
 {
        u8 status;
        int tries;
index 6bd0f19..389ac60 100644 (file)
@@ -903,6 +903,11 @@ omap_i2c_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dev);
 
+       if (cpu_is_omap7xx())
+               dev->reg_shift = 1;
+       else
+               dev->reg_shift = 2;
+
        if ((r = omap_i2c_get_clocks(dev)) != 0)
                goto err_iounmap;
 
@@ -926,11 +931,6 @@ omap_i2c_probe(struct platform_device *pdev)
                dev->b_hw = 1; /* Enable hardware fixes */
        }
 
-       if (cpu_is_omap7xx())
-               dev->reg_shift = 1;
-       else
-               dev->reg_shift = 2;
-
        /* reset ASAP, clearing any IRQs */
        omap_i2c_init(dev);
 
index 2471033..a97e3fe 100644 (file)
@@ -173,6 +173,9 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
                /* We still have something to talk about... */
                val = *alg_data->mif.buf++;
 
+               if (alg_data->mif.len == 1)
+                       val |= stop_bit;
+
                alg_data->mif.len--;
                iowrite32(val, I2C_REG_TX(alg_data));
 
@@ -246,6 +249,9 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
                        __func__);
 
                if (alg_data->mif.len == 1) {
+                       /* Last byte, do not acknowledge next rcv. */
+                       val |= stop_bit;
+
                        /*
                         * Enable interrupt RFDAIE (data in Rx fifo),
                         * and disable DRMIE (need data for Tx)
@@ -633,6 +639,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
         */
 
        tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+       if (tmp > 0x3FF)
+               tmp = 0x3FF;
        iowrite32(tmp, I2C_REG_CKH(alg_data));
        iowrite32(tmp, I2C_REG_CKL(alg_data));
 
index 1f5b38b..495be45 100644 (file)
@@ -498,7 +498,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
        int i = 0;
 
        /* Locate the apropriate clock setting */
-       while (i < ARRAY_SIZE(stu300_clktable) &&
+       while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
               stu300_clktable[i].rate < clkrate)
                i++;
 
index 3202a86..c2258a5 100644 (file)
 #include "i2c-core.h"
 
 
-/* core_lock protects i2c_adapter_idr, userspace_devices, and guarantees
+/* core_lock protects i2c_adapter_idr, and guarantees
    that device detection, deletion of detected devices, and attach_adapter
    and detach_adapter calls are serialized */
 static DEFINE_MUTEX(core_lock);
 static DEFINE_IDR(i2c_adapter_idr);
-static LIST_HEAD(userspace_devices);
 
 static struct device_type i2c_client_type;
 static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
@@ -117,8 +116,10 @@ static int i2c_device_probe(struct device *dev)
        dev_dbg(dev, "probe\n");
 
        status = driver->probe(client, i2c_match_id(driver->id_table, client));
-       if (status)
+       if (status) {
                client->driver = NULL;
+               i2c_set_clientdata(client, NULL);
+       }
        return status;
 }
 
@@ -139,8 +140,10 @@ static int i2c_device_remove(struct device *dev)
                dev->driver = NULL;
                status = 0;
        }
-       if (status == 0)
+       if (status == 0) {
                client->driver = NULL;
+               i2c_set_clientdata(client, NULL);
+       }
        return status;
 }
 
@@ -538,9 +541,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
                return -EEXIST;
 
        /* Keep track of the added device */
-       mutex_lock(&core_lock);
-       list_add_tail(&client->detected, &userspace_devices);
-       mutex_unlock(&core_lock);
+       i2c_lock_adapter(adap);
+       list_add_tail(&client->detected, &adap->userspace_clients);
+       i2c_unlock_adapter(adap);
        dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
                 info.type, info.addr);
 
@@ -579,9 +582,10 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
 
        /* Make sure the device was added through sysfs */
        res = -ENOENT;
-       mutex_lock(&core_lock);
-       list_for_each_entry_safe(client, next, &userspace_devices, detected) {
-               if (client->addr == addr && client->adapter == adap) {
+       i2c_lock_adapter(adap);
+       list_for_each_entry_safe(client, next, &adap->userspace_clients,
+                                detected) {
+               if (client->addr == addr) {
                        dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
                                 "delete_device", client->name, client->addr);
 
@@ -591,7 +595,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
                        break;
                }
        }
-       mutex_unlock(&core_lock);
+       i2c_unlock_adapter(adap);
 
        if (res < 0)
                dev_err(dev, "%s: Can't find device in list\n",
@@ -673,6 +677,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
        }
 
        rt_mutex_init(&adap->bus_lock);
+       INIT_LIST_HEAD(&adap->userspace_clients);
 
        /* Set default timeout to 1 second if not already set */
        if (adap->timeout == 0)
@@ -875,14 +880,15 @@ int i2c_del_adapter(struct i2c_adapter *adap)
                return res;
 
        /* Remove devices instantiated from sysfs */
-       list_for_each_entry_safe(client, next, &userspace_devices, detected) {
-               if (client->adapter == adap) {
-                       dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
-                               client->name, client->addr);
-                       list_del(&client->detected);
-                       i2c_unregister_device(client);
-               }
+       i2c_lock_adapter(adap);
+       list_for_each_entry_safe(client, next, &adap->userspace_clients,
+                                detected) {
+               dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
+                       client->addr);
+               list_del(&client->detected);
+               i2c_unregister_device(client);
        }
+       i2c_unlock_adapter(adap);
 
        /* Detach any active clients. This can't fail, thus we do not
           checking the returned value. */
@@ -1260,12 +1266,23 @@ static int i2c_detect_address(struct i2c_client *temp_client,
                return 0;
 
        /* Make sure there is something at this address */
-       if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
-               return 0;
+       if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) {
+               /* Special probe for FSC hwmon chips */
+               union i2c_smbus_data dummy;
 
-       /* Prevent 24RF08 corruption */
-       if ((addr & ~0x0f) == 0x50)
-               i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
+               if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
+                                  I2C_SMBUS_BYTE_DATA, &dummy) < 0)
+                       return 0;
+       } else {
+               if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+                                  I2C_SMBUS_QUICK, NULL) < 0)
+                       return 0;
+
+               /* Prevent 24RF08 corruption */
+               if ((addr & ~0x0f) == 0x50)
+                       i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
+                                      I2C_SMBUS_QUICK, NULL);
+       }
 
        /* Finally call the custom detection function */
        memset(&info, 0, sizeof(struct i2c_board_info));
index ab87e4f..b854508 100644 (file)
@@ -409,6 +409,8 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
        PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
        PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+       PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
        PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -429,6 +431,8 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
        PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
        PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
        PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
index 7e18bcf..46239e4 100644 (file)
@@ -59,11 +59,11 @@ static unsigned int get_time_pit(void)
        unsigned long flags;
        unsigned int count;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
        outb_p(0x00, 0x43);
        count = inb_p(0x40);
        count |= inb_p(0x40) << 8;
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        return count;
 }
index afd4e2b..9c79bd5 100644 (file)
@@ -660,7 +660,14 @@ static int input_default_setkeycode(struct input_dev *dev,
 int input_get_keycode(struct input_dev *dev,
                      unsigned int scancode, unsigned int *keycode)
 {
-       return dev->getkeycode(dev, scancode, keycode);
+       unsigned long flags;
+       int retval;
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+       retval = dev->getkeycode(dev, scancode, keycode);
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       return retval;
 }
 EXPORT_SYMBOL(input_get_keycode);
 
index c52bec4..423e0e6 100644 (file)
@@ -929,6 +929,24 @@ static const struct input_device_id joydev_ids[] = {
                .evbit = { BIT_MASK(EV_ABS) },
                .absbit = { BIT_MASK(ABS_THROTTLE) },
        },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = {[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_GAMEPAD)] = BIT_MASK(BTN_GAMEPAD) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+                               INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(BTN_TRIGGER_HAPPY)] = BIT_MASK(BTN_TRIGGER_HAPPY) },
+       },
        { }     /* Terminating entry */
 };
 
index 1c0b529..4afe0a3 100644 (file)
@@ -146,11 +146,11 @@ static unsigned int get_time_pit(void)
         unsigned long flags;
         unsigned int count;
 
-        spin_lock_irqsave(&i8253_lock, flags);
+        raw_spin_lock_irqsave(&i8253_lock, flags);
         outb_p(0x00, 0x43);
         count = inb_p(0x40);
         count |= inb_p(0x40) << 8;
-        spin_unlock_irqrestore(&i8253_lock, flags);
+        raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
         return count;
 }
index b1edd77..405febd 100644 (file)
@@ -54,6 +54,9 @@ static signed short btn_avb_wheel[] =
 static signed short abs_joystick[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
 
+static signed short abs_joystick_rudder[] =
+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 };
+
 static signed short abs_avb_pegasus[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
   ABS_HAT1X, ABS_HAT1Y, -1 };
@@ -76,8 +79,9 @@ static struct iforce_device iforce_device[] = {
        { 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x061c, 0xc084, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce },
        { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",       btn_wheel, abs_wheel, ff_iforce }, //?
+       { 0x06f8, 0x0001, "Guillemot Jet Leader Force Feedback",        btn_joystick, abs_joystick_rudder, ff_iforce },
        { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",      btn_wheel, abs_wheel, ff_iforce }, //?
-       { 0x06f8, 0x0004, "Gullemot Jet Leader 3D",                     btn_joystick, abs_joystick, ff_iforce }, //?
+       { 0x06f8, 0xa302, "Guillemot Jet Leader 3D",                    btn_joystick, abs_joystick, ff_iforce }, //?
        { 0x06d6, 0x29bc, "Trust Force Feedback Race Master",           btn_wheel, abs_wheel, ff_iforce },
        { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",         btn_joystick, abs_joystick, ff_iforce }
 };
index b41303d..6c96631 100644 (file)
@@ -212,6 +212,7 @@ static struct usb_device_id iforce_usb_ids [] = {
        { USB_DEVICE(0x061c, 0xc0a4) },         /* ACT LABS Force RS */
        { USB_DEVICE(0x061c, 0xc084) },         /* ACT LABS Force RS */
        { USB_DEVICE(0x06f8, 0x0001) },         /* Guillemot Race Leader Force Feedback */
+       { USB_DEVICE(0x06f8, 0x0003) },         /* Guillemot Jet Leader Force Feedback */
        { USB_DEVICE(0x06f8, 0x0004) },         /* Guillemot Force Feedback Racing Wheel */
        { USB_DEVICE(0x06f8, 0xa302) },         /* Guillemot Jet Leader 3D */
        { }                                     /* Terminating entry */
index 64c1023..a829338 100644 (file)
@@ -143,19 +143,6 @@ config KEYBOARD_BFIN
          To compile this driver as a module, choose M here: the
          module will be called bf54x-keys.
 
-config KEYBOARD_CORGI
-       tristate "Corgi keyboard (deprecated)"
-       depends on PXA_SHARPSL
-       help
-         Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
-         series of PDAs.
-
-         This driver is now deprecated, use generic GPIO based matrix
-         keyboard driver instead.
-
-         To compile this driver as a module, choose M here: the
-         module will be called corgikbd.
-
 config KEYBOARD_LKKBD
        tristate "DECstation/VAXstation LK201/LK401 keyboard"
        select SERIO
@@ -339,19 +326,6 @@ config KEYBOARD_PXA930_ROTARY
          To compile this driver as a module, choose M here: the
          module will be called pxa930_rotary.
 
-config KEYBOARD_SPITZ
-       tristate "Spitz keyboard (deprecated)"
-       depends on PXA_SHARPSL
-       help
-         Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
-         SL-C3000 and Sl-C3100 series of PDAs.
-
-         This driver is now deprecated, use generic GPIO based matrix
-         keyboard driver instead.
-
-         To compile this driver as a module, choose M here: the
-         module will be called spitzkbd.
-
 config KEYBOARD_STOWAWAY
        tristate "Stowaway keyboard"
        select SERIO
@@ -414,28 +388,6 @@ config KEYBOARD_TWL4030
          To compile this driver as a module, choose M here: the
          module will be called twl4030_keypad.
 
-config KEYBOARD_TOSA
-       tristate "Tosa keyboard (deprecated)"
-       depends on MACH_TOSA
-       help
-         Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
-
-         This driver is now deprecated, use generic GPIO based matrix
-         keyboard driver instead.
-
-         To compile this driver as a module, choose M here: the
-         module will be called tosakbd.
-
-config KEYBOARD_TOSA_USE_EXT_KEYCODES
-       bool "Tosa keyboard: use extended keycodes"
-       depends on KEYBOARD_TOSA
-       help
-         Say Y here to enable the tosa keyboard driver to generate extended
-         (>= 127) keycodes. Be aware, that they can't be correctly interpreted
-         by either console keyboard driver or by Kdrive keybd driver.
-
-         Say Y only if you know, what you are doing!
-
 config KEYBOARD_XTKBD
        tristate "XT keyboard"
        select SERIO
index 706c6b5..9a74127 100644 (file)
@@ -11,7 +11,6 @@ obj-$(CONFIG_KEYBOARD_AMIGA)          += amikbd.o
 obj-$(CONFIG_KEYBOARD_ATARI)           += atakbd.o
 obj-$(CONFIG_KEYBOARD_ATKBD)           += atkbd.o
 obj-$(CONFIG_KEYBOARD_BFIN)            += bf54x-keys.o
-obj-$(CONFIG_KEYBOARD_CORGI)           += corgikbd.o
 obj-$(CONFIG_KEYBOARD_DAVINCI)         += davinci_keyscan.o
 obj-$(CONFIG_KEYBOARD_EP93XX)          += ep93xx_keypad.o
 obj-$(CONFIG_KEYBOARD_GPIO)            += gpio_keys.o
@@ -33,10 +32,8 @@ obj-$(CONFIG_KEYBOARD_PXA27x)                += pxa27x_keypad.o
 obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)   += pxa930_rotary.o
 obj-$(CONFIG_KEYBOARD_QT2160)          += qt2160.o
 obj-$(CONFIG_KEYBOARD_SH_KEYSC)                += sh_keysc.o
-obj-$(CONFIG_KEYBOARD_SPITZ)           += spitzkbd.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)                += stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)          += sunkbd.o
-obj-$(CONFIG_KEYBOARD_TOSA)            += tosakbd.o
 obj-$(CONFIG_KEYBOARD_TWL4030)         += twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)           += xtkbd.o
 obj-$(CONFIG_KEYBOARD_W90P910)         += w90p910_keypad.o
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
deleted file mode 100644 (file)
index 634af6a..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- *  Keyboard driver for Sharp Corgi models (SL-C7xx)
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  Based on xtkbd.c/locomkbd.c
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <mach/corgi.h>
-#include <mach/pxa2xx-gpio.h>
-#include <asm/hardware/scoop.h>
-
-#define KB_ROWS                                8
-#define KB_COLS                                12
-#define KB_ROWMASK(r)          (1 << (r))
-#define SCANCODE(r,c)          ( ((r)<<4) + (c) + 1 )
-/* zero code, 124 scancodes */
-#define        NR_SCANCODES            ( SCANCODE(KB_ROWS-1,KB_COLS-1) +1 +1 )
-
-#define SCAN_INTERVAL          (50) /* ms */
-#define HINGE_SCAN_INTERVAL    (250) /* ms */
-
-#define CORGI_KEY_CALENDER     KEY_F1
-#define CORGI_KEY_ADDRESS      KEY_F2
-#define CORGI_KEY_FN           KEY_F3
-#define CORGI_KEY_CANCEL       KEY_F4
-#define CORGI_KEY_OFF          KEY_SUSPEND
-#define CORGI_KEY_EXOK         KEY_F5
-#define CORGI_KEY_EXCANCEL     KEY_F6
-#define CORGI_KEY_EXJOGDOWN    KEY_F7
-#define CORGI_KEY_EXJOGUP      KEY_F8
-#define CORGI_KEY_JAP1         KEY_LEFTCTRL
-#define CORGI_KEY_JAP2         KEY_LEFTALT
-#define CORGI_KEY_MAIL         KEY_F10
-#define CORGI_KEY_OK           KEY_F11
-#define CORGI_KEY_MENU         KEY_F12
-
-static unsigned char corgikbd_keycode[NR_SCANCODES] = {
-       0,                                                                                                                /* 0 */
-       0, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, 0, 0, 0, 0, 0, 0, 0,                               /* 1-16 */
-       0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, 0, 0, 0, 0, 0, 0, 0,                                   /* 17-32 */
-       KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0,                                 /* 33-48 */
-       CORGI_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,         /* 49-64 */
-       CORGI_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0,     /* 65-80 */
-       CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0,            /* 81-96 */
-       KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0,  /* 97-112 */
-       CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0,   /* 113-124 */
-};
-
-
-struct corgikbd {
-       unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)];
-       struct input_dev *input;
-
-       spinlock_t lock;
-       struct timer_list timer;
-       struct timer_list htimer;
-
-       unsigned int suspended;
-       unsigned long suspend_jiffies;
-};
-
-#define KB_DISCHARGE_DELAY     10
-#define KB_ACTIVATE_DELAY      10
-
-/* Helper functions for reading the keyboard matrix
- * Note: We should really be using the generic gpio functions to alter
- *       GPDR but it requires a function call per GPIO bit which is
- *       excessive when we need to access 12 bits at once, multiple times.
- * These functions must be called within local_irq_save()/local_irq_restore()
- * or similar.
- */
-static inline void corgikbd_discharge_all(void)
-{
-       /* STROBE All HiZ */
-       GPCR2  = CORGI_GPIO_ALL_STROBE_BIT;
-       GPDR2 &= ~CORGI_GPIO_ALL_STROBE_BIT;
-}
-
-static inline void corgikbd_activate_all(void)
-{
-       /* STROBE ALL -> High */
-       GPSR2  = CORGI_GPIO_ALL_STROBE_BIT;
-       GPDR2 |= CORGI_GPIO_ALL_STROBE_BIT;
-
-       udelay(KB_DISCHARGE_DELAY);
-
-       /* Clear any interrupts we may have triggered when altering the GPIO lines */
-       GEDR1 = CORGI_GPIO_HIGH_SENSE_BIT;
-       GEDR2 = CORGI_GPIO_LOW_SENSE_BIT;
-}
-
-static inline void corgikbd_activate_col(int col)
-{
-       /* STROBE col -> High, not col -> HiZ */
-       GPSR2 = CORGI_GPIO_STROBE_BIT(col);
-       GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col);
-}
-
-static inline void corgikbd_reset_col(int col)
-{
-       /* STROBE col -> Low */
-       GPCR2 = CORGI_GPIO_STROBE_BIT(col);
-       /* STROBE col -> out, not col -> HiZ */
-       GPDR2 = (GPDR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(col);
-}
-
-#define GET_ROWS_STATUS(c)     (((GPLR1 & CORGI_GPIO_HIGH_SENSE_BIT) >> CORGI_GPIO_HIGH_SENSE_RSHIFT) | ((GPLR2 & CORGI_GPIO_LOW_SENSE_BIT) << CORGI_GPIO_LOW_SENSE_LSHIFT))
-
-/*
- * The corgi keyboard only generates interrupts when a key is pressed.
- * When a key is pressed, we enable a timer which then scans the
- * keyboard to detect when the key is released.
- */
-
-/* Scan the hardware keyboard and push any changes up through the input layer */
-static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data)
-{
-       unsigned int row, col, rowd;
-       unsigned long flags;
-       unsigned int num_pressed;
-
-       if (corgikbd_data->suspended)
-               return;
-
-       spin_lock_irqsave(&corgikbd_data->lock, flags);
-
-       num_pressed = 0;
-       for (col = 0; col < KB_COLS; col++) {
-               /*
-                * Discharge the output driver capacitatance
-                * in the keyboard matrix. (Yes it is significant..)
-                */
-
-               corgikbd_discharge_all();
-               udelay(KB_DISCHARGE_DELAY);
-
-               corgikbd_activate_col(col);
-               udelay(KB_ACTIVATE_DELAY);
-
-               rowd = GET_ROWS_STATUS(col);
-               for (row = 0; row < KB_ROWS; row++) {
-                       unsigned int scancode, pressed;
-
-                       scancode = SCANCODE(row, col);
-                       pressed = rowd & KB_ROWMASK(row);
-
-                       input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
-
-                       if (pressed)
-                               num_pressed++;
-
-                       if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
-                                       && time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
-                               input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
-                               corgikbd_data->suspend_jiffies=jiffies;
-                       }
-               }
-               corgikbd_reset_col(col);
-       }
-
-       corgikbd_activate_all();
-
-       input_sync(corgikbd_data->input);
-
-       /* if any keys are pressed, enable the timer */
-       if (num_pressed)
-               mod_timer(&corgikbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));
-
-       spin_unlock_irqrestore(&corgikbd_data->lock, flags);
-}
-
-/*
- * corgi keyboard interrupt handler.
- */
-static irqreturn_t corgikbd_interrupt(int irq, void *dev_id)
-{
-       struct corgikbd *corgikbd_data = dev_id;
-
-       if (!timer_pending(&corgikbd_data->timer)) {
-               /** wait chattering delay **/
-               udelay(20);
-               corgikbd_scankeyboard(corgikbd_data);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- * corgi timer checking for released keys
- */
-static void corgikbd_timer_callback(unsigned long data)
-{
-       struct corgikbd *corgikbd_data = (struct corgikbd *) data;
-       corgikbd_scankeyboard(corgikbd_data);
-}
-
-/*
- * The hinge switches generate no interrupt so they need to be
- * monitored by a timer.
- *
- * We debounce the switches and pass them to the input system.
- *
- *  gprr == 0x00 - Keyboard with Landscape Screen
- *          0x08 - No Keyboard with Portrait Screen
- *          0x0c - Keyboard and Screen Closed
- */
-
-#define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
-#define HINGE_STABLE_COUNT 2
-static int sharpsl_hinge_state;
-static int hinge_count;
-
-static void corgikbd_hinge_timer(unsigned long data)
-{
-       struct corgikbd *corgikbd_data = (struct corgikbd *) data;
-       unsigned long gprr;
-       unsigned long flags;
-
-       gprr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_GPRR) & (CORGI_SCP_SWA | CORGI_SCP_SWB);
-       gprr |= (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0);
-       if (gprr != sharpsl_hinge_state) {
-               hinge_count = 0;
-               sharpsl_hinge_state = gprr;
-       } else if (hinge_count < HINGE_STABLE_COUNT) {
-               hinge_count++;
-               if (hinge_count >= HINGE_STABLE_COUNT) {
-                       spin_lock_irqsave(&corgikbd_data->lock, flags);
-
-                       input_report_switch(corgikbd_data->input, SW_LID, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
-                       input_report_switch(corgikbd_data->input, SW_TABLET_MODE, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
-                       input_report_switch(corgikbd_data->input, SW_HEADPHONE_INSERT, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0));
-                       input_sync(corgikbd_data->input);
-
-                       spin_unlock_irqrestore(&corgikbd_data->lock, flags);
-               }
-       }
-       mod_timer(&corgikbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-}
-
-#ifdef CONFIG_PM
-static int corgikbd_suspend(struct platform_device *dev, pm_message_t state)
-{
-       int i;
-       struct corgikbd *corgikbd = platform_get_drvdata(dev);
-
-       corgikbd->suspended = 1;
-       /* strobe 0 is the power key so this can't be made an input for
-          powersaving therefore i = 1 */
-       for (i = 1; i < CORGI_KEY_STROBE_NUM; i++)
-               pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_IN);
-
-       return 0;
-}
-
-static int corgikbd_resume(struct platform_device *dev)
-{
-       int i;
-       struct corgikbd *corgikbd = platform_get_drvdata(dev);
-
-       for (i = 1; i < CORGI_KEY_STROBE_NUM; i++)
-               pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
-
-       /* Upon resume, ignore the suspend key for a short while */
-       corgikbd->suspend_jiffies=jiffies;
-       corgikbd->suspended = 0;
-
-       return 0;
-}
-#else
-#define corgikbd_suspend       NULL
-#define corgikbd_resume                NULL
-#endif
-
-static int __devinit corgikbd_probe(struct platform_device *pdev)
-{
-       struct corgikbd *corgikbd;
-       struct input_dev *input_dev;
-       int i, err = -ENOMEM;
-
-       corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL);
-       input_dev = input_allocate_device();
-       if (!corgikbd || !input_dev)
-               goto fail;
-
-       platform_set_drvdata(pdev, corgikbd);
-
-       corgikbd->input = input_dev;
-       spin_lock_init(&corgikbd->lock);
-
-       /* Init Keyboard rescan timer */
-       init_timer(&corgikbd->timer);
-       corgikbd->timer.function = corgikbd_timer_callback;
-       corgikbd->timer.data = (unsigned long) corgikbd;
-
-       /* Init Hinge Timer */
-       init_timer(&corgikbd->htimer);
-       corgikbd->htimer.function = corgikbd_hinge_timer;
-       corgikbd->htimer.data = (unsigned long) corgikbd;
-
-       corgikbd->suspend_jiffies=jiffies;
-
-       memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
-
-       input_dev->name = "Corgi Keyboard";
-       input_dev->phys = "corgikbd/input0";
-       input_dev->id.bustype = BUS_HOST;
-       input_dev->id.vendor = 0x0001;
-       input_dev->id.product = 0x0001;
-       input_dev->id.version = 0x0100;
-       input_dev->dev.parent = &pdev->dev;
-
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
-               BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
-       input_dev->keycode = corgikbd->keycode;
-       input_dev->keycodesize = sizeof(unsigned char);
-       input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
-
-       for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
-               set_bit(corgikbd->keycode[i], input_dev->keybit);
-       clear_bit(0, input_dev->keybit);
-       set_bit(SW_LID, input_dev->swbit);
-       set_bit(SW_TABLET_MODE, input_dev->swbit);
-       set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
-
-       err = input_register_device(corgikbd->input);
-       if (err)
-               goto fail;
-
-       mod_timer(&corgikbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-
-       /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
-       for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) {
-               pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN);
-               if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt,
-                               IRQF_DISABLED | IRQF_TRIGGER_RISING,
-                               "corgikbd", corgikbd))
-                       printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i);
-       }
-
-       /* Set Strobe lines as outputs - set high */
-       for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
-               pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
-
-       /* Setup the headphone jack as an input */
-       pxa_gpio_mode(CORGI_GPIO_AK_INT | GPIO_IN);
-
-       return 0;
-
- fail: input_free_device(input_dev);
-       kfree(corgikbd);
-       return err;
-}
-
-static int __devexit corgikbd_remove(struct platform_device *pdev)
-{
-       int i;
-       struct corgikbd *corgikbd = platform_get_drvdata(pdev);
-
-       for (i = 0; i < CORGI_KEY_SENSE_NUM; i++)
-               free_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd);
-
-       del_timer_sync(&corgikbd->htimer);
-       del_timer_sync(&corgikbd->timer);
-
-       input_unregister_device(corgikbd->input);
-
-       kfree(corgikbd);
-
-       return 0;
-}
-
-static struct platform_driver corgikbd_driver = {
-       .probe          = corgikbd_probe,
-       .remove         = __devexit_p(corgikbd_remove),
-       .suspend        = corgikbd_suspend,
-       .resume         = corgikbd_resume,
-       .driver         = {
-               .name   = "corgi-keyboard",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init corgikbd_init(void)
-{
-       return platform_driver_register(&corgikbd_driver);
-}
-
-static void __exit corgikbd_exit(void)
-{
-       platform_driver_unregister(&corgikbd_driver);
-}
-
-module_init(corgikbd_init);
-module_exit(corgikbd_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
-MODULE_DESCRIPTION("Corgi Keyboard Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:corgi-keyboard");
index ffc25cf..b443e08 100644 (file)
@@ -374,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
        input_dev->name         = pdev->name;
        input_dev->id.bustype   = BUS_HOST;
        input_dev->dev.parent   = &pdev->dev;
-       input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       input_dev->evbit[0]     = BIT_MASK(EV_KEY);
+       if (!pdata->no_autorepeat)
+               input_dev->evbit[0] |= BIT_MASK(EV_REP);
        input_dev->open         = matrix_keypad_start;
        input_dev->close        = matrix_keypad_stop;
 
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
deleted file mode 100644 (file)
index 1396742..0000000
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- *  Keyboard driver for Sharp Spitz, Borzoi and Akita (SL-Cxx00 series)
- *
- *  Copyright (c) 2005 Richard Purdie
- *
- *  Based on corgikbd.c
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <mach/spitz.h>
-#include <mach/pxa2xx-gpio.h>
-
-#define KB_ROWS                        7
-#define KB_COLS                        11
-#define KB_ROWMASK(r)          (1 << (r))
-#define SCANCODE(r,c)          (((r)<<4) + (c) + 1)
-#define        NR_SCANCODES            ((KB_ROWS<<4) + 1)
-
-#define SCAN_INTERVAL          (50) /* ms */
-#define HINGE_SCAN_INTERVAL    (150) /* ms */
-
-#define SPITZ_KEY_CALENDER     KEY_F1
-#define SPITZ_KEY_ADDRESS      KEY_F2
-#define SPITZ_KEY_FN           KEY_F3
-#define SPITZ_KEY_CANCEL       KEY_F4
-#define SPITZ_KEY_EXOK         KEY_F5
-#define SPITZ_KEY_EXCANCEL     KEY_F6
-#define SPITZ_KEY_EXJOGDOWN    KEY_F7
-#define SPITZ_KEY_EXJOGUP      KEY_F8
-#define SPITZ_KEY_JAP1         KEY_LEFTALT
-#define SPITZ_KEY_JAP2         KEY_RIGHTCTRL
-#define SPITZ_KEY_SYNC         KEY_F9
-#define SPITZ_KEY_MAIL         KEY_F10
-#define SPITZ_KEY_OK           KEY_F11
-#define SPITZ_KEY_MENU         KEY_F12
-
-static unsigned char spitzkbd_keycode[NR_SCANCODES] = {
-       0,                                                                                                                /* 0 */
-       KEY_LEFTCTRL, KEY_1, KEY_3, KEY_5, KEY_6, KEY_7, KEY_9, KEY_0, KEY_BACKSPACE, SPITZ_KEY_EXOK, SPITZ_KEY_EXCANCEL, 0, 0, 0, 0, 0,  /* 1-16 */
-       0, KEY_2, KEY_4, KEY_R, KEY_Y, KEY_8, KEY_I, KEY_O, KEY_P, SPITZ_KEY_EXJOGDOWN, SPITZ_KEY_EXJOGUP, 0, 0, 0, 0, 0, /* 17-32 */
-       KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0,                                 /* 33-48 */
-       SPITZ_KEY_ADDRESS, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,         /* 49-64 */
-       SPITZ_KEY_CALENDER, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0,    /* 65-80 */
-       SPITZ_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, SPITZ_KEY_FN, 0, 0, 0, 0, 0,      /* 81-96 */
-       KEY_SYSRQ, SPITZ_KEY_JAP1, SPITZ_KEY_JAP2, SPITZ_KEY_CANCEL, SPITZ_KEY_OK, SPITZ_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0  /* 97-112 */
-};
-
-static int spitz_strobes[] = {
-       SPITZ_GPIO_KEY_STROBE0,
-       SPITZ_GPIO_KEY_STROBE1,
-       SPITZ_GPIO_KEY_STROBE2,
-       SPITZ_GPIO_KEY_STROBE3,
-       SPITZ_GPIO_KEY_STROBE4,
-       SPITZ_GPIO_KEY_STROBE5,
-       SPITZ_GPIO_KEY_STROBE6,
-       SPITZ_GPIO_KEY_STROBE7,
-       SPITZ_GPIO_KEY_STROBE8,
-       SPITZ_GPIO_KEY_STROBE9,
-       SPITZ_GPIO_KEY_STROBE10,
-};
-
-static int spitz_senses[] = {
-       SPITZ_GPIO_KEY_SENSE0,
-       SPITZ_GPIO_KEY_SENSE1,
-       SPITZ_GPIO_KEY_SENSE2,
-       SPITZ_GPIO_KEY_SENSE3,
-       SPITZ_GPIO_KEY_SENSE4,
-       SPITZ_GPIO_KEY_SENSE5,
-       SPITZ_GPIO_KEY_SENSE6,
-};
-
-struct spitzkbd {
-       unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
-       struct input_dev *input;
-       char phys[32];
-
-       spinlock_t lock;
-       struct timer_list timer;
-       struct timer_list htimer;
-
-       unsigned int suspended;
-       unsigned long suspend_jiffies;
-};
-
-#define KB_DISCHARGE_DELAY     10
-#define KB_ACTIVATE_DELAY      10
-
-/* Helper functions for reading the keyboard matrix
- * Note: We should really be using the generic gpio functions to alter
- *       GPDR but it requires a function call per GPIO bit which is
- *       excessive when we need to access 11 bits at once, multiple times.
- * These functions must be called within local_irq_save()/local_irq_restore()
- * or similar.
- */
-static inline void spitzkbd_discharge_all(void)
-{
-       /* STROBE All HiZ */
-       GPCR0  =  SPITZ_GPIO_G0_STROBE_BIT;
-       GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
-       GPCR1  =  SPITZ_GPIO_G1_STROBE_BIT;
-       GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
-       GPCR2  =  SPITZ_GPIO_G2_STROBE_BIT;
-       GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
-       GPCR3  =  SPITZ_GPIO_G3_STROBE_BIT;
-       GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
-}
-
-static inline void spitzkbd_activate_all(void)
-{
-       /* STROBE ALL -> High */
-       GPSR0  =  SPITZ_GPIO_G0_STROBE_BIT;
-       GPDR0 |=  SPITZ_GPIO_G0_STROBE_BIT;
-       GPSR1  =  SPITZ_GPIO_G1_STROBE_BIT;
-       GPDR1 |=  SPITZ_GPIO_G1_STROBE_BIT;
-       GPSR2  =  SPITZ_GPIO_G2_STROBE_BIT;
-       GPDR2 |=  SPITZ_GPIO_G2_STROBE_BIT;
-       GPSR3  =  SPITZ_GPIO_G3_STROBE_BIT;
-       GPDR3 |=  SPITZ_GPIO_G3_STROBE_BIT;
-
-       udelay(KB_DISCHARGE_DELAY);
-
-       /* Clear any interrupts we may have triggered when altering the GPIO lines */
-       GEDR0 = SPITZ_GPIO_G0_SENSE_BIT;
-       GEDR1 = SPITZ_GPIO_G1_SENSE_BIT;
-       GEDR2 = SPITZ_GPIO_G2_SENSE_BIT;
-       GEDR3 = SPITZ_GPIO_G3_SENSE_BIT;
-}
-
-static inline void spitzkbd_activate_col(int col)
-{
-       int gpio = spitz_strobes[col];
-       GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
-       GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
-       GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
-       GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
-       GPSR(gpio) = GPIO_bit(gpio);
-       GPDR(gpio) |= GPIO_bit(gpio);
-}
-
-static inline void spitzkbd_reset_col(int col)
-{
-       int gpio = spitz_strobes[col];
-       GPDR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
-       GPDR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
-       GPDR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
-       GPDR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
-       GPCR(gpio) = GPIO_bit(gpio);
-       GPDR(gpio) |= GPIO_bit(gpio);
-}
-
-static inline int spitzkbd_get_row_status(int col)
-{
-       return ((GPLR0 >> 12) & 0x01) | ((GPLR0 >> 16) & 0x02)
-               | ((GPLR2 >> 25) & 0x04) | ((GPLR1 << 1) & 0x08)
-               | ((GPLR1 >> 0) & 0x10) | ((GPLR1 >> 1) & 0x60);
-}
-
-/*
- * The spitz keyboard only generates interrupts when a key is pressed.
- * When a key is pressed, we enable a timer which then scans the
- * keyboard to detect when the key is released.
- */
-
-/* Scan the hardware keyboard and push any changes up through the input layer */
-static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data)
-{
-       unsigned int row, col, rowd;
-       unsigned long flags;
-       unsigned int num_pressed, pwrkey = ((GPLR(SPITZ_GPIO_ON_KEY) & GPIO_bit(SPITZ_GPIO_ON_KEY)) != 0);
-
-       if (spitzkbd_data->suspended)
-               return;
-
-       spin_lock_irqsave(&spitzkbd_data->lock, flags);
-
-       num_pressed = 0;
-       for (col = 0; col < KB_COLS; col++) {
-               /*
-                * Discharge the output driver capacitatance
-                * in the keyboard matrix. (Yes it is significant..)
-                */
-
-               spitzkbd_discharge_all();
-               udelay(KB_DISCHARGE_DELAY);
-
-               spitzkbd_activate_col(col);
-               udelay(KB_ACTIVATE_DELAY);
-
-               rowd = spitzkbd_get_row_status(col);
-               for (row = 0; row < KB_ROWS; row++) {
-                       unsigned int scancode, pressed;
-
-                       scancode = SCANCODE(row, col);
-                       pressed = rowd & KB_ROWMASK(row);
-
-                       input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
-
-                       if (pressed)
-                               num_pressed++;
-               }
-               spitzkbd_reset_col(col);
-       }
-
-       spitzkbd_activate_all();
-
-       input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
-       input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey);
-
-       if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
-               input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
-               spitzkbd_data->suspend_jiffies = jiffies;
-       }
-
-       input_sync(spitzkbd_data->input);
-
-       /* if any keys are pressed, enable the timer */
-       if (num_pressed)
-               mod_timer(&spitzkbd_data->timer, jiffies + msecs_to_jiffies(SCAN_INTERVAL));
-
-       spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
-}
-
-/*
- * spitz keyboard interrupt handler.
- */
-static irqreturn_t spitzkbd_interrupt(int irq, void *dev_id)
-{
-       struct spitzkbd *spitzkbd_data = dev_id;
-
-       if (!timer_pending(&spitzkbd_data->timer)) {
-               /** wait chattering delay **/
-               udelay(20);
-               spitzkbd_scankeyboard(spitzkbd_data);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- * spitz timer checking for released keys
- */
-static void spitzkbd_timer_callback(unsigned long data)
-{
-       struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
-
-       spitzkbd_scankeyboard(spitzkbd_data);
-}
-
-/*
- * The hinge switches generate an interrupt.
- * We debounce the switches and pass them to the input system.
- */
-
-static irqreturn_t spitzkbd_hinge_isr(int irq, void *dev_id)
-{
-       struct spitzkbd *spitzkbd_data = dev_id;
-
-       if (!timer_pending(&spitzkbd_data->htimer))
-               mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-
-       return IRQ_HANDLED;
-}
-
-#define HINGE_STABLE_COUNT 2
-static int sharpsl_hinge_state;
-static int hinge_count;
-
-static void spitzkbd_hinge_timer(unsigned long data)
-{
-       struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
-       unsigned long state;
-       unsigned long flags;
-
-       state = GPLR(SPITZ_GPIO_SWA) & (GPIO_bit(SPITZ_GPIO_SWA)|GPIO_bit(SPITZ_GPIO_SWB));
-       state |= (GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT));
-       if (state != sharpsl_hinge_state) {
-               hinge_count = 0;
-               sharpsl_hinge_state = state;
-       } else if (hinge_count < HINGE_STABLE_COUNT) {
-               hinge_count++;
-       }
-
-       if (hinge_count >= HINGE_STABLE_COUNT) {
-               spin_lock_irqsave(&spitzkbd_data->lock, flags);
-
-               input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
-               input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
-               input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0));
-               input_sync(spitzkbd_data->input);
-
-               spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
-       } else {
-               mod_timer(&spitzkbd_data->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-       }
-}
-
-#ifdef CONFIG_PM
-static int spitzkbd_suspend(struct platform_device *dev, pm_message_t state)
-{
-       int i;
-       struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
-       spitzkbd->suspended = 1;
-
-       /* Set Strobe lines as inputs - *except* strobe line 0 leave this
-          enabled so we can detect a power button press for resume */
-       for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
-               pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
-
-       return 0;
-}
-
-static int spitzkbd_resume(struct platform_device *dev)
-{
-       int i;
-       struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
-
-       for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
-               pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
-
-       /* Upon resume, ignore the suspend key for a short while */
-       spitzkbd->suspend_jiffies = jiffies;
-       spitzkbd->suspended = 0;
-
-       return 0;
-}
-#else
-#define spitzkbd_suspend       NULL
-#define spitzkbd_resume                NULL
-#endif
-
-static int __devinit spitzkbd_probe(struct platform_device *dev)
-{
-       struct spitzkbd *spitzkbd;
-       struct input_dev *input_dev;
-       int i, err = -ENOMEM;
-
-       spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
-       input_dev = input_allocate_device();
-       if (!spitzkbd || !input_dev)
-               goto fail;
-
-       platform_set_drvdata(dev, spitzkbd);
-       strcpy(spitzkbd->phys, "spitzkbd/input0");
-
-       spin_lock_init(&spitzkbd->lock);
-
-       /* Init Keyboard rescan timer */
-       init_timer(&spitzkbd->timer);
-       spitzkbd->timer.function = spitzkbd_timer_callback;
-       spitzkbd->timer.data = (unsigned long) spitzkbd;
-
-       /* Init Hinge Timer */
-       init_timer(&spitzkbd->htimer);
-       spitzkbd->htimer.function = spitzkbd_hinge_timer;
-       spitzkbd->htimer.data = (unsigned long) spitzkbd;
-
-       spitzkbd->suspend_jiffies = jiffies;
-
-       spitzkbd->input = input_dev;
-
-       input_dev->name = "Spitz Keyboard";
-       input_dev->phys = spitzkbd->phys;
-       input_dev->dev.parent = &dev->dev;
-
-       input_dev->id.bustype = BUS_HOST;
-       input_dev->id.vendor = 0x0001;
-       input_dev->id.product = 0x0001;
-       input_dev->id.version = 0x0100;
-
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
-               BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
-       input_dev->keycode = spitzkbd->keycode;
-       input_dev->keycodesize = sizeof(unsigned char);
-       input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
-
-       memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
-       for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
-               set_bit(spitzkbd->keycode[i], input_dev->keybit);
-       clear_bit(0, input_dev->keybit);
-       set_bit(KEY_SUSPEND, input_dev->keybit);
-       set_bit(SW_LID, input_dev->swbit);
-       set_bit(SW_TABLET_MODE, input_dev->swbit);
-       set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
-
-       err = input_register_device(input_dev);
-       if (err)
-               goto fail;
-
-       mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
-
-       /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
-       for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) {
-               pxa_gpio_mode(spitz_senses[i] | GPIO_IN);
-               if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt,
-                               IRQF_DISABLED|IRQF_TRIGGER_RISING,
-                               "Spitzkbd Sense", spitzkbd))
-                       printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i);
-       }
-
-       /* Set Strobe lines as outputs - set high */
-       for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
-               pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
-
-       pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
-       pxa_gpio_mode(SPITZ_GPIO_ON_KEY | GPIO_IN);
-       pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN);
-       pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN);
-
-       request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt,
-                   IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                   "Spitzkbd Sync", spitzkbd);
-       request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt,
-                   IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                   "Spitzkbd PwrOn", spitzkbd);
-       request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr,
-                   IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                   "Spitzkbd SWA", spitzkbd);
-       request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr,
-                   IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                   "Spitzkbd SWB", spitzkbd);
-       request_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd_hinge_isr,
-                   IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                   "Spitzkbd HP", spitzkbd);
-
-       return 0;
-
- fail: input_free_device(input_dev);
-       kfree(spitzkbd);
-       return err;
-}
-
-static int __devexit spitzkbd_remove(struct platform_device *dev)
-{
-       int i;
-       struct spitzkbd *spitzkbd = platform_get_drvdata(dev);
-
-       for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++)
-               free_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd);
-
-       free_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd);
-       free_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd);
-       free_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd);
-       free_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd);
-       free_irq(SPITZ_IRQ_GPIO_AK_INT, spitzkbd);
-
-       del_timer_sync(&spitzkbd->htimer);
-       del_timer_sync(&spitzkbd->timer);
-
-       input_unregister_device(spitzkbd->input);
-
-       kfree(spitzkbd);
-
-       return 0;
-}
-
-static struct platform_driver spitzkbd_driver = {
-       .probe          = spitzkbd_probe,
-       .remove         = __devexit_p(spitzkbd_remove),
-       .suspend        = spitzkbd_suspend,
-       .resume         = spitzkbd_resume,
-       .driver         = {
-               .name   = "spitz-keyboard",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init spitzkbd_init(void)
-{
-       return platform_driver_register(&spitzkbd_driver);
-}
-
-static void __exit spitzkbd_exit(void)
-{
-       platform_driver_unregister(&spitzkbd_driver);
-}
-
-module_init(spitzkbd_init);
-module_exit(spitzkbd_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
-MODULE_DESCRIPTION("Spitz Keyboard Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:spitz-keyboard");
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
deleted file mode 100644 (file)
index 3910f26..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- *  Keyboard driver for Sharp Tosa models (SL-6000x)
- *
- *  Copyright (c) 2005 Dirk Opfer
- *  Copyright (c) 2007 Dmitry Baryshkov
- *
- *  Based on xtkbd.c/locomkbd.c/corgikbd.c
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/input.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-
-#include <mach/gpio.h>
-#include <mach/tosa.h>
-
-#define KB_ROWMASK(r)          (1 << (r))
-#define SCANCODE(r, c)         (((r)<<4) + (c) + 1)
-#define NR_SCANCODES           SCANCODE(TOSA_KEY_SENSE_NUM - 1, TOSA_KEY_STROBE_NUM - 1) + 1
-
-#define SCAN_INTERVAL          (HZ/10)
-
-#define KB_DISCHARGE_DELAY     10
-#define KB_ACTIVATE_DELAY      10
-
-static unsigned short tosakbd_keycode[NR_SCANCODES] = {
-0,
-0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P,
-0, 0, 0, 0, 0, 0, 0, 0,
-KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA,
-0, 0, 0, 0, 0, 0, 0, 0,
-KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT,
-0, 0, 0, 0, 0, 0, 0, 0,
-KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESSBOOK, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK,
-KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, 0,
-KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDAR, TOSA_KEY_HOMEPAGE, KEY_LEFTCTRL, TOSA_KEY_LIGHT,
-0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,
-KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0,
-0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0,
-KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
-0, 0, 0,
-};
-
-struct tosakbd {
-       unsigned short keycode[ARRAY_SIZE(tosakbd_keycode)];
-       struct input_dev *input;
-       bool suspended;
-       spinlock_t lock; /* protect kbd scanning */
-       struct timer_list timer;
-};
-
-
-/* Helper functions for reading the keyboard matrix
- * Note: We should really be using the generic gpio functions to alter
- *       GPDR but it requires a function call per GPIO bit which is
- *       excessive when we need to access 12 bits at once, multiple times.
- * These functions must be called within local_irq_save()/local_irq_restore()
- * or similar.
- */
-#define GET_ROWS_STATUS(c)     ((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT)
-
-static inline void tosakbd_discharge_all(void)
-{
-       /* STROBE All HiZ */
-       GPCR1  = TOSA_GPIO_HIGH_STROBE_BIT;
-       GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT;
-       GPCR2  = TOSA_GPIO_LOW_STROBE_BIT;
-       GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT;
-}
-
-static inline void tosakbd_activate_all(void)
-{
-       /* STROBE ALL -> High */
-       GPSR1  = TOSA_GPIO_HIGH_STROBE_BIT;
-       GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT;
-       GPSR2  = TOSA_GPIO_LOW_STROBE_BIT;
-       GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT;
-
-       udelay(KB_DISCHARGE_DELAY);
-
-       /* STATE CLEAR */
-       GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT;
-}
-
-static inline void tosakbd_activate_col(int col)
-{
-       if (col <= 5) {
-               /* STROBE col -> High, not col -> HiZ */
-               GPSR1 = TOSA_GPIO_STROBE_BIT(col);
-               GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-       } else {
-               /* STROBE col -> High, not col -> HiZ */
-               GPSR2 = TOSA_GPIO_STROBE_BIT(col);
-               GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-       }
-}
-
-static inline void tosakbd_reset_col(int col)
-{
-       if (col <= 5) {
-               /* STROBE col -> Low */
-               GPCR1 = TOSA_GPIO_STROBE_BIT(col);
-               /* STROBE col -> out, not col -> HiZ */
-               GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-       } else {
-               /* STROBE col -> Low */
-               GPCR2 = TOSA_GPIO_STROBE_BIT(col);
-               /* STROBE col -> out, not col -> HiZ */
-               GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
-       }
-}
-/*
- * The tosa keyboard only generates interrupts when a key is pressed.
- * So when a key is pressed, we enable a timer.  This timer scans the
- * keyboard, and this is how we detect when the key is released.
- */
-
-/* Scan the hardware keyboard and push any changes up through the input layer */
-static void tosakbd_scankeyboard(struct platform_device *dev)
-{
-       struct tosakbd *tosakbd = platform_get_drvdata(dev);
-       unsigned int row, col, rowd;
-       unsigned long flags;
-       unsigned int num_pressed = 0;
-
-       spin_lock_irqsave(&tosakbd->lock, flags);
-
-       if (tosakbd->suspended)
-               goto out;
-
-       for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) {
-               /*
-                * Discharge the output driver capacitatance
-                * in the keyboard matrix. (Yes it is significant..)
-                */
-               tosakbd_discharge_all();
-               udelay(KB_DISCHARGE_DELAY);
-
-               tosakbd_activate_col(col);
-               udelay(KB_ACTIVATE_DELAY);
-
-               rowd = GET_ROWS_STATUS(col);
-
-               for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) {
-                       unsigned int scancode, pressed;
-                       scancode = SCANCODE(row, col);
-                       pressed = rowd & KB_ROWMASK(row);
-
-                       if (pressed && !tosakbd->keycode[scancode])
-                               dev_warn(&dev->dev,
-                                               "unhandled scancode: 0x%02x\n",
-                                               scancode);
-
-                       input_report_key(tosakbd->input,
-                                       tosakbd->keycode[scancode],
-                                       pressed);
-                       if (pressed)
-                               num_pressed++;
-               }
-
-               tosakbd_reset_col(col);
-       }
-
-       tosakbd_activate_all();
-
-       input_sync(tosakbd->input);
-
-       /* if any keys are pressed, enable the timer */
-       if (num_pressed)
-               mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL);
-
- out:
-       spin_unlock_irqrestore(&tosakbd->lock, flags);
-}
-
-/*
- * tosa keyboard interrupt handler.
- */
-static irqreturn_t tosakbd_interrupt(int irq, void *__dev)
-{
-       struct platform_device *dev = __dev;
-       struct tosakbd *tosakbd = platform_get_drvdata(dev);
-
-       if (!timer_pending(&tosakbd->timer)) {
-               /** wait chattering delay **/
-               udelay(20);
-               tosakbd_scankeyboard(dev);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- * tosa timer checking for released keys
- */
-static void tosakbd_timer_callback(unsigned long __dev)
-{
-       struct platform_device *dev = (struct platform_device *)__dev;
-
-       tosakbd_scankeyboard(dev);
-}
-
-#ifdef CONFIG_PM
-static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
-{
-       struct tosakbd *tosakbd = platform_get_drvdata(dev);
-       unsigned long flags;
-
-       spin_lock_irqsave(&tosakbd->lock, flags);
-       tosakbd->suspended = true;
-       spin_unlock_irqrestore(&tosakbd->lock, flags);
-
-       del_timer_sync(&tosakbd->timer);
-
-       return 0;
-}
-
-static int tosakbd_resume(struct platform_device *dev)
-{
-       struct tosakbd *tosakbd = platform_get_drvdata(dev);
-
-       tosakbd->suspended = false;
-       tosakbd_scankeyboard(dev);
-
-       return 0;
-}
-#else
-#define tosakbd_suspend                NULL
-#define tosakbd_resume         NULL
-#endif
-
-static int __devinit tosakbd_probe(struct platform_device *pdev) {
-
-       int i;
-       struct tosakbd *tosakbd;
-       struct input_dev *input_dev;
-       int error;
-
-       tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL);
-       if (!tosakbd)
-               return -ENOMEM;
-
-       input_dev = input_allocate_device();
-       if (!input_dev) {
-               kfree(tosakbd);
-               return -ENOMEM;
-       }
-
-       platform_set_drvdata(pdev, tosakbd);
-
-       spin_lock_init(&tosakbd->lock);
-
-       /* Init Keyboard rescan timer */
-       init_timer(&tosakbd->timer);
-       tosakbd->timer.function = tosakbd_timer_callback;
-       tosakbd->timer.data = (unsigned long) pdev;
-
-       tosakbd->input = input_dev;
-
-       input_set_drvdata(input_dev, tosakbd);
-       input_dev->name = "Tosa Keyboard";
-       input_dev->phys = "tosakbd/input0";
-       input_dev->dev.parent = &pdev->dev;
-
-       input_dev->id.bustype = BUS_HOST;
-       input_dev->id.vendor = 0x0001;
-       input_dev->id.product = 0x0001;
-       input_dev->id.version = 0x0100;
-
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-       input_dev->keycode = tosakbd->keycode;
-       input_dev->keycodesize = sizeof(tosakbd->keycode[0]);
-       input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);
-
-       memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode));
-
-       for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
-               __set_bit(tosakbd->keycode[i], input_dev->keybit);
-       __clear_bit(KEY_RESERVED, input_dev->keybit);
-
-       /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
-       for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
-               int gpio = TOSA_GPIO_KEY_SENSE(i);
-               int irq;
-               error = gpio_request(gpio, "tosakbd");
-               if (error < 0) {
-                       printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
-                               " error %d\n", gpio, error);
-                       goto fail;
-               }
-
-               error = gpio_direction_input(TOSA_GPIO_KEY_SENSE(i));
-               if (error < 0) {
-                       printk(KERN_ERR "tosakbd: failed to configure input"
-                               " direction for GPIO %d, error %d\n",
-                               gpio, error);
-                       gpio_free(gpio);
-                       goto fail;
-               }
-
-               irq = gpio_to_irq(gpio);
-               if (irq < 0) {
-                       error = irq;
-                       printk(KERN_ERR "gpio-keys: Unable to get irq number"
-                               " for GPIO %d, error %d\n",
-                               gpio, error);
-                       gpio_free(gpio);
-                       goto fail;
-               }
-
-               error = request_irq(irq, tosakbd_interrupt,
-                                       IRQF_DISABLED | IRQF_TRIGGER_RISING,
-                                       "tosakbd", pdev);
-
-               if (error) {
-                       printk("tosakbd: Can't get IRQ: %d: error %d!\n",
-                                       irq, error);
-                       gpio_free(gpio);
-                       goto fail;
-               }
-       }
-
-       /* Set Strobe lines as outputs - set high */
-       for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) {
-               int gpio = TOSA_GPIO_KEY_STROBE(i);
-               error = gpio_request(gpio, "tosakbd");
-               if (error < 0) {
-                       printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
-                               " error %d\n", gpio, error);
-                       goto fail2;
-               }
-
-               error = gpio_direction_output(gpio, 1);
-               if (error < 0) {
-                       printk(KERN_ERR "tosakbd: failed to configure input"
-                               " direction for GPIO %d, error %d\n",
-                               gpio, error);
-                       gpio_free(gpio);
-                       goto fail2;
-               }
-
-       }
-
-       error = input_register_device(input_dev);
-       if (error) {
-               printk(KERN_ERR "tosakbd: Unable to register input device, "
-                       "error: %d\n", error);
-               goto fail2;
-       }
-
-       printk(KERN_INFO "input: Tosa Keyboard Registered\n");
-
-       return 0;
-
-fail2:
-       while (--i >= 0)
-               gpio_free(TOSA_GPIO_KEY_STROBE(i));
-
-       i = TOSA_KEY_SENSE_NUM;
-fail:
-       while (--i >= 0) {
-               free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), pdev);
-               gpio_free(TOSA_GPIO_KEY_SENSE(i));
-       }
-
-       platform_set_drvdata(pdev, NULL);
-       input_free_device(input_dev);
-       kfree(tosakbd);
-
-       return error;
-}
-
-static int __devexit tosakbd_remove(struct platform_device *dev)
-{
-       int i;
-       struct tosakbd *tosakbd = platform_get_drvdata(dev);
-
-       for (i = 0; i < TOSA_KEY_STROBE_NUM; i++)
-               gpio_free(TOSA_GPIO_KEY_STROBE(i));
-
-       for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
-               free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), dev);
-               gpio_free(TOSA_GPIO_KEY_SENSE(i));
-       }
-
-       del_timer_sync(&tosakbd->timer);
-
-       input_unregister_device(tosakbd->input);
-
-       kfree(tosakbd);
-
-       return 0;
-}
-
-static struct platform_driver tosakbd_driver = {
-       .probe          = tosakbd_probe,
-       .remove         = __devexit_p(tosakbd_remove),
-       .suspend        = tosakbd_suspend,
-       .resume         = tosakbd_resume,
-       .driver         = {
-               .name   = "tosa-keyboard",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __devinit tosakbd_init(void)
-{
-       return platform_driver_register(&tosakbd_driver);
-}
-
-static void __exit tosakbd_exit(void)
-{
-       platform_driver_unregister(&tosakbd_driver);
-}
-
-module_init(tosakbd_init);
-module_exit(tosakbd_exit);
-
-MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
-MODULE_DESCRIPTION("Tosa Keyboard Driver");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:tosa-keyboard");
index 614b65d..e8bbc61 100644 (file)
  * Module and Version Information, Module Parameters
  */
 
-#define ATI_REMOTE_VENDOR_ID   0x0bc7
-#define ATI_REMOTE_PRODUCT_ID  0x004
-#define LOLA_REMOTE_PRODUCT_ID 0x002
-#define MEDION_REMOTE_PRODUCT_ID 0x006
+#define ATI_REMOTE_VENDOR_ID           0x0bc7
+#define LOLA_REMOTE_PRODUCT_ID         0x0002
+#define LOLA2_REMOTE_PRODUCT_ID                0x0003
+#define ATI_REMOTE_PRODUCT_ID          0x0004
+#define NVIDIA_REMOTE_PRODUCT_ID       0x0005
+#define MEDION_REMOTE_PRODUCT_ID       0x0006
 
 #define DRIVER_VERSION         "2.2.1"
 #define DRIVER_AUTHOR           "Torrey Hoffman <thoffman@arnor.net>"
@@ -142,8 +144,10 @@ MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec
 #define err(format, arg...) printk(KERN_ERR format , ## arg)
 
 static struct usb_device_id ati_remote_table[] = {
-       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
        { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA2_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
+       { USB_DEVICE(ATI_REMOTE_VENDOR_ID, NVIDIA_REMOTE_PRODUCT_ID) },
        { USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) },
        {}      /* Terminating entry */
 };
index ea4e1fd..f080dd3 100644 (file)
@@ -30,7 +30,7 @@ MODULE_ALIAS("platform:pcspkr");
 #include <asm/i8253.h>
 #else
 #include <asm/8253pit.h>
-static DEFINE_SPINLOCK(i8253_lock);
+static DEFINE_RAW_SPINLOCK(i8253_lock);
 #endif
 
 static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -50,7 +50,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
        if (value > 20 && value < 32767)
                count = PIT_TICK_RATE / value;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
 
        if (count) {
                /* set command for counter 2, 2 byte write */
@@ -65,7 +65,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
                outb(inb_p(0x61) & 0xFC, 0x61);
        }
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 
        return 0;
 }
index 4f8fe08..b89879b 100644 (file)
@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = {
        .disconnect             = bcm5974_disconnect,
        .suspend                = bcm5974_suspend,
        .resume                 = bcm5974_resume,
-       .reset_resume           = bcm5974_resume,
        .id_table               = bcm5974_table,
        .supports_autosuspend   = 1,
 };
index a138b5d..112b4ee 100644 (file)
                        printk(KERN_DEBUG format, ##arg);       \
        } while (0)
 
+static bool force_elantech;
+module_param_named(force_elantech, force_elantech, bool, 0644);
+MODULE_PARM_DESC(force_elantech, "Force the Elantech PS/2 protocol extension to be used, 1 = enabled, 0 = disabled (default).");
+
 /*
  * Send a Synaptics style sliced query command
  */
@@ -181,14 +185,18 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
        int fingers;
        static int old_fingers;
 
-       if (etd->fw_version_maj == 0x01) {
-               /* byte 0:  D   U  p1  p2   1  p3   R   L
-                  byte 1:  f   0  th  tw  x9  x8  y9  y8 */
+       if (etd->fw_version < 0x020000) {
+               /*
+                * byte 0:  D   U  p1  p2   1  p3   R   L
+                * byte 1:  f   0  th  tw  x9  x8  y9  y8
+                */
                fingers = ((packet[1] & 0x80) >> 7) +
                                ((packet[1] & 0x30) >> 4);
        } else {
-               /* byte 0: n1  n0  p2  p1   1  p3   R   L
-                  byte 1:  0   0   0   0  x9  x8  y9  y8 */
+               /*
+                * byte 0: n1  n0  p2  p1   1  p3   R   L
+                * byte 1:  0   0   0   0  x9  x8  y9  y8
+                */
                fingers = (packet[0] & 0xc0) >> 6;
        }
 
@@ -202,13 +210,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
 
        input_report_key(dev, BTN_TOUCH, fingers != 0);
 
-       /* byte 2: x7  x6  x5  x4  x3  x2  x1  x0
-          byte 3: y7  y6  y5  y4  y3  y2  y1  y0 */
+       /*
+        * byte 2: x7  x6  x5  x4  x3  x2  x1  x0
+        * byte 3: y7  y6  y5  y4  y3  y2  y1  y0
+        */
        if (fingers) {
                input_report_abs(dev, ABS_X,
                        ((packet[1] & 0x0c) << 6) | packet[2]);
-               input_report_abs(dev, ABS_Y, ETP_YMAX_V1 -
-                       (((packet[1] & 0x03) << 8) | packet[3]));
+               input_report_abs(dev, ABS_Y,
+                       ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
        }
 
        input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
@@ -217,7 +227,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
        input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
        input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
 
-       if ((etd->fw_version_maj == 0x01) &&
+       if (etd->fw_version < 0x020000 &&
            (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
                /* rocker up */
                input_report_key(dev, BTN_FORWARD, packet[0] & 0x40);
@@ -247,34 +257,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
 
        switch (fingers) {
        case 1:
-               /* byte 1: x15 x14 x13 x12 x11 x10 x9  x8
-                  byte 2: x7  x6  x5  x4  x4  x2  x1  x0 */
-               input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]);
-               /* byte 4: y15 y14 y13 y12 y11 y10 y8  y8
-                  byte 5: y7  y6  y5  y4  y3  y2  y1  y0 */
-               input_report_abs(dev, ABS_Y, ETP_YMAX_V2 -
-                       ((packet[4] << 8) | packet[5]));
+               /*
+                * byte 1:  .   .   .   .   .  x10 x9  x8
+                * byte 2: x7  x6  x5  x4  x4  x2  x1  x0
+                */
+               input_report_abs(dev, ABS_X,
+                       ((packet[1] & 0x07) << 8) | packet[2]);
+               /*
+                * byte 4:  .   .   .   .   .   .  y9  y8
+                * byte 5: y7  y6  y5  y4  y3  y2  y1  y0
+                */
+               input_report_abs(dev, ABS_Y,
+                       ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
                break;
 
        case 2:
-               /* The coordinate of each finger is reported separately with
-                  a lower resolution for two finger touches */
-               /* byte 0:  .   .  ay8 ax8  .   .   .   .
-                  byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */
+               /*
+                * The coordinate of each finger is reported separately
+                * with a lower resolution for two finger touches:
+                * byte 0:  .   .  ay8 ax8  .   .   .   .
+                * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
+                */
                x1 = ((packet[0] & 0x10) << 4) | packet[1];
                /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
                y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
-               /* byte 3:  .   .  by8 bx8  .   .   .   .
-                  byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */
+               /*
+                * byte 3:  .   .  by8 bx8  .   .   .   .
+                * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
+                */
                x2 = ((packet[3] & 0x10) << 4) | packet[4];
                /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
                y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
-               /* For compatibility with the X Synaptics driver scale up one
-                  coordinate and report as ordinary mouse movent */
+               /*
+                * For compatibility with the X Synaptics driver scale up
+                * one coordinate and report as ordinary mouse movent
+                */
                input_report_abs(dev, ABS_X, x1 << 2);
                input_report_abs(dev, ABS_Y, y1 << 2);
-               /* For compatibility with the proprietary X Elantech driver
-                  report both coordinates as hat coordinates */
+               /*
+                * For compatibility with the proprietary X Elantech driver
+                * report both coordinates as hat coordinates
+                */
                input_report_abs(dev, ABS_HAT0X, x1);
                input_report_abs(dev, ABS_HAT0Y, y1);
                input_report_abs(dev, ABS_HAT1X, x2);
@@ -298,7 +321,7 @@ static int elantech_check_parity_v1(struct psmouse *psmouse)
        unsigned char p1, p2, p3;
 
        /* Parity bits are placed differently */
-       if (etd->fw_version_maj == 0x01) {
+       if (etd->fw_version < 0x020000) {
                /* byte 0:  D   U  p1  p2   1  p3   R   L */
                p1 = (packet[0] & 0x20) >> 5;
                p2 = (packet[0] & 0x10) >> 4;
@@ -434,7 +457,7 @@ static void elantech_set_input_params(struct psmouse *psmouse)
        switch (etd->hw_version) {
        case 1:
                /* Rocker button */
-               if ((etd->fw_version_maj == 0x01) &&
+               if (etd->fw_version < 0x020000 &&
                    (etd->capabilities & ETP_CAP_HAS_ROCKER)) {
                        __set_bit(BTN_FORWARD, dev->keybit);
                        __set_bit(BTN_BACK, dev->keybit);
@@ -596,8 +619,12 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties)
                 param[0], param[1], param[2]);
 
        if (param[0] == 0 || param[1] != 0) {
-               pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
-               return -1;
+               if (!force_elantech) {
+                       pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n");
+                       return -1;
+               }
+
+               pr_debug("elantech.c: Probably not a real Elantech touchpad. Enabling anyway due to force_elantech.\n");
        }
 
        if (set_properties) {
@@ -659,14 +686,14 @@ int elantech_init(struct psmouse *psmouse)
                pr_err("elantech.c: failed to query firmware version.\n");
                goto init_fail;
        }
-       etd->fw_version_maj = param[0];
-       etd->fw_version_min = param[2];
+
+       etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2];
 
        /*
         * Assume every version greater than this is new EeePC style
         * hardware with 6 byte packets
         */
-       if (etd->fw_version_maj >= 0x02 && etd->fw_version_min >= 0x30) {
+       if (etd->fw_version >= 0x020030) {
                etd->hw_version = 2;
                /* For now show extra debug information */
                etd->debug = 1;
@@ -676,8 +703,9 @@ int elantech_init(struct psmouse *psmouse)
                etd->hw_version = 1;
                etd->paritycheck = 1;
        }
-       pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d\n",
-               etd->hw_version, etd->fw_version_maj, etd->fw_version_min);
+
+       pr_info("elantech.c: assuming hardware version %d, firmware version %d.%d.%d\n",
+               etd->hw_version, param[0], param[1], param[2]);
 
        if (synaptics_send_cmd(psmouse, ETP_CAPABILITIES_QUERY, param)) {
                pr_err("elantech.c: failed to query capabilities.\n");
@@ -692,8 +720,8 @@ int elantech_init(struct psmouse *psmouse)
         * a touch action starts causing the mouse cursor or scrolled page
         * to jump. Enable a workaround.
         */
-       if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) {
-               pr_info("elantech.c: firmware version 2.34 detected, "
+       if (etd->fw_version == 0x020022) {
+               pr_info("elantech.c: firmware version 2.0.34 detected, "
                        "enabling jumpy cursor workaround\n");
                etd->jumpy_cursor = 1;
        }
index feac5f7..ac57bde 100644 (file)
@@ -100,11 +100,10 @@ struct elantech_data {
        unsigned char reg_26;
        unsigned char debug;
        unsigned char capabilities;
-       unsigned char fw_version_maj;
-       unsigned char fw_version_min;
-       unsigned char hw_version;
        unsigned char paritycheck;
        unsigned char jumpy_cursor;
+       unsigned char hw_version;
+       unsigned int  fw_version;
        unsigned char parity[256];
 };
 
index d8c0c8d..a3c9731 100644 (file)
@@ -110,6 +110,7 @@ static struct workqueue_struct *kpsmoused_wq;
 struct psmouse_protocol {
        enum psmouse_type type;
        bool maxproto;
+       bool ignore_parity; /* Protocol should ignore parity errors from KBC */
        const char *name;
        const char *alias;
        int (*detect)(struct psmouse *, bool);
@@ -288,7 +289,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
        if (psmouse->state == PSMOUSE_IGNORE)
                goto out;
 
-       if (flags & (SERIO_PARITY|SERIO_TIMEOUT)) {
+       if (unlikely((flags & SERIO_TIMEOUT) ||
+                    ((flags & SERIO_PARITY) && !psmouse->ignore_parity))) {
+
                if (psmouse->state == PSMOUSE_ACTIVATED)
                        printk(KERN_WARNING "psmouse.c: bad data from KBC -%s%s\n",
                                flags & SERIO_TIMEOUT ? " timeout" : "",
@@ -759,6 +762,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .name           = "PS/2",
                .alias          = "bare",
                .maxproto       = true,
+               .ignore_parity  = true,
                .detect         = ps2bare_detect,
        },
 #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
@@ -786,6 +790,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .name           = "ImPS/2",
                .alias          = "imps",
                .maxproto       = true,
+               .ignore_parity  = true,
                .detect         = intellimouse_detect,
        },
        {
@@ -793,6 +798,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
                .name           = "ImExPS/2",
                .alias          = "exps",
                .maxproto       = true,
+               .ignore_parity  = true,
                .detect         = im_explorer_detect,
        },
 #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
@@ -1222,6 +1228,7 @@ static void psmouse_disconnect(struct serio *serio)
 static int psmouse_switch_protocol(struct psmouse *psmouse,
                                   const struct psmouse_protocol *proto)
 {
+       const struct psmouse_protocol *selected_proto;
        struct input_dev *input_dev = psmouse->dev;
 
        input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
@@ -1245,9 +1252,14 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
                        return -1;
 
                psmouse->type = proto->type;
-       } else
+               selected_proto = proto;
+       } else {
                psmouse->type = psmouse_extensions(psmouse,
                                                   psmouse_max_proto, true);
+               selected_proto = psmouse_protocol_by_type(psmouse->type);
+       }
+
+       psmouse->ignore_parity = selected_proto->ignore_parity;
 
        /*
         * If mouse's packet size is 3 there is no point in polling the
@@ -1267,7 +1279,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse,
                psmouse->resync_time = 0;
 
        snprintf(psmouse->devname, sizeof(psmouse->devname), "%s %s %s",
-                psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
+                selected_proto->name, psmouse->vendor, psmouse->name);
 
        input_dev->name = psmouse->devname;
        input_dev->phys = psmouse->phys;
@@ -1382,6 +1394,7 @@ static int psmouse_reconnect(struct serio *serio)
        struct psmouse *psmouse = serio_get_drvdata(serio);
        struct psmouse *parent = NULL;
        struct serio_driver *drv = serio->drv;
+       unsigned char type;
        int rc = -1;
 
        if (!drv || !psmouse) {
@@ -1401,10 +1414,15 @@ static int psmouse_reconnect(struct serio *serio)
        if (psmouse->reconnect) {
                if (psmouse->reconnect(psmouse))
                        goto out;
-       } else if (psmouse_probe(psmouse) < 0 ||
-                  psmouse->type != psmouse_extensions(psmouse,
-                                               psmouse_max_proto, false)) {
-               goto out;
+       } else {
+               psmouse_reset(psmouse);
+
+               if (psmouse_probe(psmouse) < 0)
+                       goto out;
+
+               type = psmouse_extensions(psmouse, psmouse_max_proto, false);
+               if (psmouse->type != type)
+                       goto out;
        }
 
        /* ok, the device type (and capabilities) match the old one,
index e053bdd..593e910 100644 (file)
@@ -47,6 +47,7 @@ struct psmouse {
        unsigned char pktcnt;
        unsigned char pktsize;
        unsigned char type;
+       bool ignore_parity;
        bool acks_disable_command;
        unsigned int model;
        unsigned long last;
index 026df60..ebd7a99 100644 (file)
@@ -137,7 +137,8 @@ static int synaptics_capability(struct psmouse *psmouse)
        if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
                return -1;
        priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
-       priv->ext_cap = 0;
+       priv->ext_cap = priv->ext_cap_0c = 0;
+
        if (!SYN_CAP_VALID(priv->capabilities))
                return -1;
 
@@ -150,7 +151,7 @@ static int synaptics_capability(struct psmouse *psmouse)
        if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
                if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
                        printk(KERN_ERR "Synaptics claims to have extended capabilities,"
-                              " but I'm not able to read them.");
+                              " but I'm not able to read them.\n");
                } else {
                        priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
 
@@ -162,6 +163,16 @@ static int synaptics_capability(struct psmouse *psmouse)
                                priv->ext_cap &= 0xff0fff;
                }
        }
+
+       if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 4) {
+               if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB_0C, cap)) {
+                       printk(KERN_ERR "Synaptics claims to have extended capability 0x0c,"
+                              " but I'm not able to read it.\n");
+               } else {
+                       priv->ext_cap_0c = (cap[0] << 16) | (cap[1] << 8) | cap[2];
+               }
+       }
+
        return 0;
 }
 
@@ -348,7 +359,15 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
                hw->left  = (buf[0] & 0x01) ? 1 : 0;
                hw->right = (buf[0] & 0x02) ? 1 : 0;
 
-               if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
+               if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+                       /*
+                        * Clickpad's button is transmitted as middle button,
+                        * however, since it is primary button, we will report
+                        * it as BTN_LEFT.
+                        */
+                       hw->left = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
+
+               } else if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
                        hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
                        if (hw->w == 2)
                                hw->scroll = (signed char)(buf[1]);
@@ -593,6 +612,12 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 
        dev->absres[ABS_X] = priv->x_res;
        dev->absres[ABS_Y] = priv->y_res;
+
+       if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+               /* Clickpads report only left button */
+               __clear_bit(BTN_RIGHT, dev->keybit);
+               __clear_bit(BTN_MIDDLE, dev->keybit);
+       }
 }
 
 static void synaptics_disconnect(struct psmouse *psmouse)
@@ -697,10 +722,10 @@ int synaptics_init(struct psmouse *psmouse)
 
        priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
 
-       printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n",
+       printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
                SYN_ID_MODEL(priv->identity),
                SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
-               priv->model_id, priv->capabilities, priv->ext_cap);
+               priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c);
 
        set_input_params(psmouse->dev, priv);
 
index f0f40a3..ae37c5d 100644 (file)
@@ -18,6 +18,7 @@
 #define SYN_QUE_SERIAL_NUMBER_SUFFIX   0x07
 #define SYN_QUE_RESOLUTION             0x08
 #define SYN_QUE_EXT_CAPAB              0x09
+#define SYN_QUE_EXT_CAPAB_0C           0x0c
 
 /* synatics modes */
 #define SYN_BIT_ABSOLUTE_MODE          (1 << 7)
@@ -48,6 +49,8 @@
 #define SYN_CAP_VALID(c)               ((((c) & 0x00ff00) >> 8) == 0x47)
 #define SYN_EXT_CAP_REQUESTS(c)                (((c) & 0x700000) >> 20)
 #define SYN_CAP_MULTI_BUTTON_NO(ec)    (((ec) & 0x00f000) >> 12)
+#define SYN_CAP_PRODUCT_ID(ec)         (((ec) & 0xff0000) >> 16)
+#define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100100)
 
 /* synaptics modes query bits */
 #define SYN_MODE_ABSOLUTE(m)           ((m) & (1 << 7))
@@ -96,6 +99,7 @@ struct synaptics_data {
        unsigned long int model_id;             /* Model-ID */
        unsigned long int capabilities;         /* Capabilities */
        unsigned long int ext_cap;              /* Extended Capabilities */
+       unsigned long int ext_cap_0c;           /* Ext Caps from 0x0c query */
        unsigned long int identity;             /* Identification */
        int x_res;                              /* X resolution in units/mm */
        int y_res;                              /* Y resolution in units/mm */
index 577688b..6440a8f 100644 (file)
@@ -39,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
 
 static bool i8042_nomux;
 module_param_named(nomux, i8042_nomux, bool, 0);
-MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
 
 static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
index 82ae18d..0142483 100644 (file)
@@ -68,12 +68,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
                                    unsigned int scancode,
                                    unsigned int *keycode)
 {
-       const struct key_entry *key =
-                       sparse_keymap_entry_from_scancode(dev, scancode);
+       const struct key_entry *key;
 
-       if (key && key->type == KE_KEY) {
-               *keycode = key->keycode;
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       *keycode = key->keycode;
+                       return 0;
+               }
        }
 
        return -EINVAL;
@@ -86,17 +88,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev,
        struct key_entry *key;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
-       key = sparse_keymap_entry_from_scancode(dev, scancode);
-       if (key && key->type == KE_KEY) {
-               old_keycode = key->keycode;
-               key->keycode = keycode;
-               set_bit(keycode, dev->keybit);
-               if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
-                       clear_bit(old_keycode, dev->keybit);
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       old_keycode = key->keycode;
+                       key->keycode = keycode;
+                       set_bit(keycode, dev->keybit);
+                       if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+                               clear_bit(old_keycode, dev->keybit);
+                       return 0;
+               }
        }
 
        return -EINVAL;
@@ -164,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev,
        return 0;
 
  err_out:
-       kfree(keymap);
+       kfree(map);
        return error;
 
 }
@@ -176,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup);
  *
  * This function is used to free memory allocated by sparse keymap
  * in an input device that was set up by sparse_keymap_setup().
+ * NOTE: It is safe to cal this function while input device is
+ * still registered (however the drivers should care not to try to
+ * use freed keymap and thus have to shut off interrups/polling
+ * before freeing the keymap).
  */
 void sparse_keymap_free(struct input_dev *dev)
 {
+       unsigned long flags;
+
+       /*
+        * Take event lock to prevent racing with input_get_keycode()
+        * and input_set_keycode() if we are called while input device
+        * is still registered.
+        */
+       spin_lock_irqsave(&dev->event_lock, flags);
+
        kfree(dev->keycode);
        dev->keycode = NULL;
        dev->keycodemax = 0;
-       dev->getkeycode = NULL;
-       dev->setkeycode = NULL;
+
+       spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 EXPORT_SYMBOL(sparse_keymap_free);
 
index 8b5d287..f465025 100644 (file)
@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf)
        int rv;
 
        mutex_lock(&wacom->lock);
-       if (wacom->open) {
+
+       /* switch to wacom mode first */
+       wacom_query_tablet_data(intf, features);
+
+       if (wacom->open)
                rv = usb_submit_urb(wacom->irq, GFP_NOIO);
-               /* switch to wacom mode if needed */
-               if (!wacom_retrieve_hid_descriptor(intf, features))
-                       wacom_query_tablet_data(intf, features);
-       } else
+       else
                rv = 0;
+
        mutex_unlock(&wacom->lock);
 
        return rv;
index b3ba343..4a852d8 100644 (file)
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
        struct wacom_features *features = &wacom->features;
        unsigned char *data = wacom->data;
-       int x, y, prox;
-       int rw = 0;
-       int retval = 0;
+       int x, y, rw;
+       static int penData = 0;
 
        if (data[0] != WACOM_REPORT_PENABLED) {
                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
-               goto exit;
+               return 0;
        }
 
-       prox = data[1] & 0x80;
-       if (prox || wacom->id[0]) {
-               if (prox) {
-                       switch ((data[1] >> 5) & 3) {
+       if (data[1] & 0x80) {
+               /* in prox and not a pad data */
+               penData = 1;
+
+               switch ((data[1] >> 5) & 3) {
 
                        case 0: /* Pen */
                                wacom->tool[0] = BTN_TOOL_PEN;
@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 2: /* Mouse with wheel */
                                wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
+                               if (features->type == WACOM_G4 || features->type == WACOM_MO) {
+                                       rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
+                                       wacom_report_rel(wcombo, REL_WHEEL, -rw);
+                               } else
+                                       wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
                                /* fall through */
 
                        case 3: /* Mouse without wheel */
                                wacom->tool[0] = BTN_TOOL_MOUSE;
                                wacom->id[0] = CURSOR_DEVICE_ID;
+                               wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
+                               wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
+                               if (features->type == WACOM_G4 || features->type == WACOM_MO)
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
+                               else
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
-                       }
                }
                x = wacom_le16_to_cpu(&data[2]);
                y = wacom_le16_to_cpu(&data[4]);
@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
                        wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
-               } else {
-                       wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
-                       wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-                       if (features->type == WACOM_G4 ||
-                                       features->type == WACOM_MO) {
-                               wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
-                               rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
-                       } else {
-                               wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
-                               rw = -(signed)data[6];
-                       }
-                       wacom_report_rel(wcombo, REL_WHEEL, rw);
                }
-
-               if (!prox)
-                       wacom->id[0] = 0;
                wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
-               wacom_report_key(wcombo, wacom->tool[0], prox);
-               wacom_input_sync(wcombo); /* sync last event */
+               wacom_report_key(wcombo, wacom->tool[0], 1);
+       } else if (wacom->id[0]) {
+               wacom_report_abs(wcombo, ABS_X, 0);
+               wacom_report_abs(wcombo, ABS_Y, 0);
+               if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+                       wacom_report_key(wcombo, BTN_LEFT, 0);
+                       wacom_report_key(wcombo, BTN_RIGHT, 0);
+                       wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+               } else {
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+               }
+               wacom->id[0] = 0;
+               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+               wacom_report_key(wcombo, wacom->tool[0], 0);
        }
 
        /* send pad data */
        switch (features->type) {
            case WACOM_G4:
-               prox = data[7] & 0xf8;
-               if (prox || wacom->id[1]) {
+               if (data[7] & 0xf8) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
-                       if (!prox)
-                               wacom->id[1] = 0;
-                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
+                       wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
+                       wacom_report_rel(wcombo, REL_WHEEL, 0);
+                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
-               retval = 1;
                break;
            case WACOM_MO:
-               prox = (data[7] & 0xf8) || data[8];
-               if (prox || wacom->id[1]) {
+               if ((data[7] & 0xf8) || (data[8] & 0xff)) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
                        wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
                        wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-                       if (!prox)
-                               wacom->id[1] = 0;
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
+                       wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
+                       wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
+                       wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
+                       wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
+                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
-               retval = 1;
                break;
        }
-exit:
-       return retval;
+       return 1;
 }
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
 static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
 {
        wacom_report_abs(wcombo, ABS_X,
-               data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8));
+               (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_Y,
-               data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8));
+               (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
        wacom_report_key(wcombo, wacom->tool[idx], 1);
        if (idx)
@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 
                touchInProx = 0;
 
-               if (!wacom->id[0]) { /* first in prox */
-                       /* Going into proximity select tool */
-                       wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-                       if (wacom->tool[0] == BTN_TOOL_PEN)
-                               wacom->id[0] = STYLUS_DEVICE_ID;
-                       else
-                               wacom->id[0] = ERASER_DEVICE_ID;
-               }
-               wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
-               wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
-               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-               pressure = ((data[7] & 0x01) << 8) | data[6];
-               if (pressure < 0)
-                       pressure = features->pressure_max + pressure + 1;
-               wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-               wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
-               if (!prox) { /* out-prox */
+               if (prox) { /* in prox */
+                       if (!wacom->id[0]) {
+                               /* Going into proximity select tool */
+                               wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+                               if (wacom->tool[0] == BTN_TOOL_PEN)
+                                       wacom->id[0] = STYLUS_DEVICE_ID;
+                               else
+                                       wacom->id[0] = ERASER_DEVICE_ID;
+                       }
+                       wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+                       wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+                       wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+                       wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+                       pressure = ((data[7] & 0x01) << 8) | data[6];
+                       if (pressure < 0)
+                               pressure = features->pressure_max + pressure + 1;
+                       wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+                       wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
+               } else {
+                       wacom_report_abs(wcombo, ABS_X, 0);
+                       wacom_report_abs(wcombo, ABS_Y, 0);
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
                        wacom->id[0] = 0;
                        /* pen is out so touch can be enabled now */
                        touchInProx = 1;
index 8a8fa4d..6c0f171 100644 (file)
@@ -99,22 +99,6 @@ config TOUCHSCREEN_BITSY
          To compile this driver as a module, choose M here: the
          module will be called h3600_ts_input.
 
-config TOUCHSCREEN_CORGI
-       tristate "SharpSL (Corgi and Spitz series) touchscreen driver (DEPRECATED)"
-       depends on PXA_SHARPSL
-       select CORGI_SSP_DEPRECATED
-       help
-         Say Y here to enable the driver for the touchscreen on the
-         Sharp SL-C7xx and SL-Cxx00 series of PDAs.
-
-         If unsure, say N.
-
-         To compile this driver as a module, choose M here: the
-         module will be called corgi_ts.
-
-         NOTE: this driver is deprecated, try enable SPI and generic
-         ADS7846-based touchscreen driver.
-
 config TOUCHSCREEN_DA9034
        tristate "Touchscreen support for Dialog Semiconductor DA9034"
        depends on PMIC_DA903X
@@ -158,8 +142,8 @@ config TOUCHSCREEN_FUJITSU
          module will be called fujitsu-ts.
 
 config TOUCHSCREEN_S3C2410
-       tristate "Samsung S3C2410 touchscreen input driver"
-       depends on ARCH_S3C2410
+       tristate "Samsung S3C2410/generic touchscreen input driver"
+       depends on ARCH_S3C2410 || SAMSUNG_DEV_TS
        select S3C24XX_ADC
        help
          Say Y here if you have the s3c2410 touchscreen.
index 7fef7d5..41145d0 100644 (file)
@@ -12,7 +12,6 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879)      += ad7879.o
 obj-$(CONFIG_TOUCHSCREEN_ADS7846)      += ads7846.o
 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o
 obj-$(CONFIG_TOUCHSCREEN_BITSY)                += h3600_ts_input.o
-obj-$(CONFIG_TOUCHSCREEN_CORGI)                += corgi_ts.o
 obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)      += dynapro.o
 obj-$(CONFIG_TOUCHSCREEN_GUNZE)                += gunze.o
 obj-$(CONFIG_TOUCHSCREEN_EETI)         += eeti_ts.o
index e019d53..0d2d7e5 100644 (file)
@@ -156,9 +156,14 @@ struct ser_req {
        u16                     reset;
        u16                     ref_on;
        u16                     command;
-       u16                     sample;
        struct spi_message      msg;
        struct spi_transfer     xfer[6];
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       u16 sample ____cacheline_aligned;
 };
 
 struct ad7877 {
@@ -182,8 +187,6 @@ struct ad7877 {
        u8                      averaging;
        u8                      pen_down_acc_interval;
 
-       u16                     conversion_data[AD7877_NR_SENSE];
-
        struct spi_transfer     xfer[AD7877_NR_SENSE + 2];
        struct spi_message      msg;
 
@@ -195,6 +198,12 @@ struct ad7877 {
        spinlock_t              lock;
        struct timer_list       timer;          /* P: lock */
        unsigned                pending:1;      /* P: lock */
+
+       /*
+        * DMA (thus cache coherency maintenance) requires the
+        * transfer buffers to live in their own cache lines.
+        */
+       u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned;
 };
 
 static int gpio3;
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
deleted file mode 100644 (file)
index 94a1919..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- *  Touchscreen driver for Sharp SL-C7xx and SL-Cxx00 models
- *
- *  Copyright (c) 2004-2005 Richard Purdie
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- *
- */
-
-
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-
-#include <mach/sharpsl.h>
-#include <mach/hardware.h>
-#include <mach/pxa2xx-gpio.h>
-
-
-#define PWR_MODE_ACTIVE                0
-#define PWR_MODE_SUSPEND       1
-
-#define X_AXIS_MAX             3830
-#define X_AXIS_MIN             150
-#define Y_AXIS_MAX             3830
-#define Y_AXIS_MIN             190
-#define PRESSURE_MIN           0
-#define PRESSURE_MAX           15000
-
-struct ts_event {
-       short pressure;
-       short x;
-       short y;
-};
-
-struct corgi_ts {
-       struct input_dev *input;
-       struct timer_list timer;
-       struct ts_event tc;
-       int pendown;
-       int power_mode;
-       int irq_gpio;
-       struct corgits_machinfo *machinfo;
-};
-
-#ifdef CONFIG_PXA25x
-#define CCNT(a)                asm volatile ("mrc p14, 0, %0, C1, C0, 0" : "=r"(a))
-#define PMNC_GET(x)    asm volatile ("mrc p14, 0, %0, C0, C0, 0" : "=r"(x))
-#define PMNC_SET(x)    asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(x))
-#endif
-#ifdef CONFIG_PXA27x
-#define CCNT(a)                asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
-#define PMNC_GET(x)    asm volatile ("mrc p14, 0, %0, C0, C1, 0" : "=r"(x))
-#define PMNC_SET(x)    asm volatile ("mcr p14, 0, %0, C0, C1, 0" : : "r"(x))
-#endif
-
-/* ADS7846 Touch Screen Controller bit definitions */
-#define ADSCTRL_PD0            (1u << 0)       /* PD0 */
-#define ADSCTRL_PD1            (1u << 1)       /* PD1 */
-#define ADSCTRL_DFR            (1u << 2)       /* SER/DFR */
-#define ADSCTRL_MOD            (1u << 3)       /* Mode */
-#define ADSCTRL_ADR_SH 4       /* Address setting */
-#define ADSCTRL_STS            (1u << 7)       /* Start Bit */
-
-/* External Functions */
-extern unsigned int get_clk_frequency_khz(int info);
-
-static unsigned long calc_waittime(struct corgi_ts *corgi_ts)
-{
-       unsigned long hsync_invperiod = corgi_ts->machinfo->get_hsync_invperiod();
-
-       if (hsync_invperiod)
-               return get_clk_frequency_khz(0)*1000/hsync_invperiod;
-       else
-               return 0;
-}
-
-static int sync_receive_data_send_cmd(struct corgi_ts *corgi_ts, int doRecive, int doSend,
-               unsigned int address, unsigned long wait_time)
-{
-       unsigned long timer1 = 0, timer2, pmnc = 0;
-       int pos = 0;
-
-       if (wait_time && doSend) {
-               PMNC_GET(pmnc);
-               if (!(pmnc & 0x01))
-                       PMNC_SET(0x01);
-
-               /* polling HSync */
-               corgi_ts->machinfo->wait_hsync();
-               /* get CCNT */
-               CCNT(timer1);
-       }
-
-       if (doRecive)
-               pos = corgi_ssp_ads7846_get();
-
-       if (doSend) {
-               int cmd = ADSCTRL_PD0 | ADSCTRL_PD1 | (address << ADSCTRL_ADR_SH) | ADSCTRL_STS;
-               /* dummy command */
-               corgi_ssp_ads7846_put(cmd);
-               corgi_ssp_ads7846_get();
-
-               if (wait_time) {
-                       /* Wait after HSync */
-                       CCNT(timer2);
-                       if (timer2-timer1 > wait_time) {
-                               /* too slow - timeout, try again */
-                               corgi_ts->machinfo->wait_hsync();
-                               /* get CCNT */
-                               CCNT(timer1);
-                               /* Wait after HSync */
-                               CCNT(timer2);
-                       }
-                       while (timer2 - timer1 < wait_time)
-                               CCNT(timer2);
-               }
-               corgi_ssp_ads7846_put(cmd);
-               if (wait_time && !(pmnc & 0x01))
-                       PMNC_SET(pmnc);
-       }
-       return pos;
-}
-
-static int read_xydata(struct corgi_ts *corgi_ts)
-{
-       unsigned int x, y, z1, z2;
-       unsigned long flags, wait_time;
-
-       /* critical section */
-       local_irq_save(flags);
-       corgi_ssp_ads7846_lock();
-       wait_time = calc_waittime(corgi_ts);
-
-       /* Y-axis */
-       sync_receive_data_send_cmd(corgi_ts, 0, 1, 1u, wait_time);
-
-       /* Y-axis */
-       sync_receive_data_send_cmd(corgi_ts, 1, 1, 1u, wait_time);
-
-       /* X-axis */
-       y = sync_receive_data_send_cmd(corgi_ts, 1, 1, 5u, wait_time);
-
-       /* Z1 */
-       x = sync_receive_data_send_cmd(corgi_ts, 1, 1, 3u, wait_time);
-
-       /* Z2 */
-       z1 = sync_receive_data_send_cmd(corgi_ts, 1, 1, 4u, wait_time);
-       z2 = sync_receive_data_send_cmd(corgi_ts, 1, 0, 4u, wait_time);
-
-       /* Power-Down Enable */
-       corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-       corgi_ssp_ads7846_get();
-
-       corgi_ssp_ads7846_unlock();
-       local_irq_restore(flags);
-
-       if (x== 0 || y == 0 || z1 == 0 || (x * (z2 - z1) / z1) >= 15000) {
-               corgi_ts->tc.pressure = 0;
-               return 0;
-       }
-
-       corgi_ts->tc.x = x;
-       corgi_ts->tc.y = y;
-       corgi_ts->tc.pressure = (x * (z2 - z1)) / z1;
-       return 1;
-}
-
-static void new_data(struct corgi_ts *corgi_ts)
-{
-       struct input_dev *dev = corgi_ts->input;
-
-       if (corgi_ts->power_mode != PWR_MODE_ACTIVE)
-               return;
-
-       if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0)
-               return;
-
-       input_report_abs(dev, ABS_X, corgi_ts->tc.x);
-       input_report_abs(dev, ABS_Y, corgi_ts->tc.y);
-       input_report_abs(dev, ABS_PRESSURE, corgi_ts->tc.pressure);
-       input_report_key(dev, BTN_TOUCH, corgi_ts->pendown);
-       input_sync(dev);
-}
-
-static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer)
-{
-       if ((GPLR(IRQ_TO_GPIO(corgi_ts->irq_gpio)) & GPIO_bit(IRQ_TO_GPIO(corgi_ts->irq_gpio))) == 0) {
-               /* Disable Interrupt */
-               set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_NONE);
-               if (read_xydata(corgi_ts)) {
-                       corgi_ts->pendown = 1;
-                       new_data(corgi_ts);
-               }
-               mod_timer(&corgi_ts->timer, jiffies + HZ / 100);
-       } else {
-               if (corgi_ts->pendown == 1 || corgi_ts->pendown == 2) {
-                       mod_timer(&corgi_ts->timer, jiffies + HZ / 100);
-                       corgi_ts->pendown++;
-                       return;
-               }
-
-               if (corgi_ts->pendown) {
-                       corgi_ts->tc.pressure = 0;
-                       new_data(corgi_ts);
-               }
-
-               /* Enable Falling Edge */
-               set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING);
-               corgi_ts->pendown = 0;
-       }
-}
-
-static void corgi_ts_timer(unsigned long data)
-{
-       struct corgi_ts *corgits_data = (struct corgi_ts *) data;
-
-       ts_interrupt_main(corgits_data, 1);
-}
-
-static irqreturn_t ts_interrupt(int irq, void *dev_id)
-{
-       struct corgi_ts *corgits_data = dev_id;
-
-       ts_interrupt_main(corgits_data, 0);
-       return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_PM
-static int corgits_suspend(struct platform_device *dev, pm_message_t state)
-{
-       struct corgi_ts *corgi_ts = platform_get_drvdata(dev);
-
-       if (corgi_ts->pendown) {
-               del_timer_sync(&corgi_ts->timer);
-               corgi_ts->tc.pressure = 0;
-               new_data(corgi_ts);
-               corgi_ts->pendown = 0;
-       }
-       corgi_ts->power_mode = PWR_MODE_SUSPEND;
-
-       corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-
-       return 0;
-}
-
-static int corgits_resume(struct platform_device *dev)
-{
-       struct corgi_ts *corgi_ts = platform_get_drvdata(dev);
-
-       corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-       /* Enable Falling Edge */
-       set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING);
-       corgi_ts->power_mode = PWR_MODE_ACTIVE;
-
-       return 0;
-}
-#else
-#define corgits_suspend                NULL
-#define corgits_resume         NULL
-#endif
-
-static int __devinit corgits_probe(struct platform_device *pdev)
-{
-       struct corgi_ts *corgi_ts;
-       struct input_dev *input_dev;
-       int err = -ENOMEM;
-
-       corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL);
-       input_dev = input_allocate_device();
-       if (!corgi_ts || !input_dev)
-               goto fail1;
-
-       platform_set_drvdata(pdev, corgi_ts);
-
-       corgi_ts->machinfo = pdev->dev.platform_data;
-       corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
-
-       if (corgi_ts->irq_gpio < 0) {
-               err = -ENODEV;
-               goto fail1;
-       }
-
-       corgi_ts->input = input_dev;
-
-       init_timer(&corgi_ts->timer);
-       corgi_ts->timer.data = (unsigned long) corgi_ts;
-       corgi_ts->timer.function = corgi_ts_timer;
-
-       input_dev->name = "Corgi Touchscreen";
-       input_dev->phys = "corgits/input0";
-       input_dev->id.bustype = BUS_HOST;
-       input_dev->id.vendor = 0x0001;
-       input_dev->id.product = 0x0002;
-       input_dev->id.version = 0x0100;
-       input_dev->dev.parent = &pdev->dev;
-
-       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-       input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
-       input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
-       input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
-
-       pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
-
-       /* Initiaize ADS7846 Difference Reference mode */
-       corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-       mdelay(5);
-       corgi_ssp_ads7846_putget((3u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-       mdelay(5);
-       corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-       mdelay(5);
-       corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-       mdelay(5);
-
-       if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) {
-               err = -EBUSY;
-               goto fail1;
-       }
-
-       err = input_register_device(corgi_ts->input);
-       if (err)
-               goto fail2;
-
-       corgi_ts->power_mode = PWR_MODE_ACTIVE;
-
-       /* Enable Falling Edge */
-       set_irq_type(corgi_ts->irq_gpio, IRQ_TYPE_EDGE_FALLING);
-
-       return 0;
-
- fail2:        free_irq(corgi_ts->irq_gpio, corgi_ts);
- fail1:        input_free_device(input_dev);
-       kfree(corgi_ts);
-       return err;
-}
-
-static int __devexit corgits_remove(struct platform_device *pdev)
-{
-       struct corgi_ts *corgi_ts = platform_get_drvdata(pdev);
-
-       free_irq(corgi_ts->irq_gpio, corgi_ts);
-       del_timer_sync(&corgi_ts->timer);
-       corgi_ts->machinfo->put_hsync();
-       input_unregister_device(corgi_ts->input);
-       kfree(corgi_ts);
-
-       return 0;
-}
-
-static struct platform_driver corgits_driver = {
-       .probe          = corgits_probe,
-       .remove         = __devexit_p(corgits_remove),
-       .suspend        = corgits_suspend,
-       .resume         = corgits_resume,
-       .driver         = {
-               .name   = "corgi-ts",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int __init corgits_init(void)
-{
-       return platform_driver_register(&corgits_driver);
-}
-
-static void __exit corgits_exit(void)
-{
-       platform_driver_unregister(&corgits_driver);
-}
-
-module_init(corgits_init);
-module_exit(corgits_exit);
-
-MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
-MODULE_DESCRIPTION("Corgi TouchScreen Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:corgi-ts");
index 204b8a1..75f8b73 100644 (file)
@@ -124,14 +124,25 @@ static irqreturn_t eeti_ts_isr(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static int eeti_ts_open(struct input_dev *dev)
+static void eeti_ts_start(struct eeti_ts_priv *priv)
 {
-       struct eeti_ts_priv *priv = input_get_drvdata(dev);
-
        enable_irq(priv->irq);
 
        /* Read the events once to arm the IRQ */
        eeti_ts_read(&priv->work);
+}
+
+static void eeti_ts_stop(struct eeti_ts_priv *priv)
+{
+       disable_irq(priv->irq);
+       cancel_work_sync(&priv->work);
+}
+
+static int eeti_ts_open(struct input_dev *dev)
+{
+       struct eeti_ts_priv *priv = input_get_drvdata(dev);
+
+       eeti_ts_start(priv);
 
        return 0;
 }
@@ -140,8 +151,7 @@ static void eeti_ts_close(struct input_dev *dev)
 {
        struct eeti_ts_priv *priv = input_get_drvdata(dev);
 
-       disable_irq(priv->irq);
-       cancel_work_sync(&priv->work);
+       eeti_ts_stop(priv);
 }
 
 static int __devinit eeti_ts_probe(struct i2c_client *client,
@@ -153,10 +163,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
        unsigned int irq_flags;
        int err = -ENOMEM;
 
-       /* In contrast to what's described in the datasheet, there seems
+       /*
+        * In contrast to what's described in the datasheet, there seems
         * to be no way of probing the presence of that device using I2C
         * commands. So we need to blindly believe it is there, and wait
-        * for interrupts to occur. */
+        * for interrupts to occur.
+        */
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
@@ -212,9 +224,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
                goto err2;
        }
 
-       /* Disable the irq for now. It will be enabled once the input device
-        * is opened. */
-       disable_irq(priv->irq);
+       /*
+        * Disable the device for now. It will be enabled once the
+        * input device is opened.
+        */
+       eeti_ts_stop(priv);
 
        device_init_wakeup(&client->dev, 0);
        return 0;
@@ -235,6 +249,12 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
 
        free_irq(priv->irq, priv);
+       /*
+        * eeti_ts_stop() leaves IRQ disabled. We need to re-enable it
+        * so that device still works if we reload the driver.
+        */
+       enable_irq(priv->irq);
+
        input_unregister_device(priv->input);
        i2c_set_clientdata(client, NULL);
        kfree(priv);
@@ -246,6 +266,14 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
 static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 {
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+       struct input_dev *input_dev = priv->input;
+
+       mutex_lock(&input_dev->mutex);
+
+       if (input_dev->users)
+               eeti_ts_stop(priv);
+
+       mutex_unlock(&input_dev->mutex);
 
        if (device_may_wakeup(&client->dev))
                enable_irq_wake(priv->irq);
@@ -256,10 +284,18 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
 static int eeti_ts_resume(struct i2c_client *client)
 {
        struct eeti_ts_priv *priv = i2c_get_clientdata(client);
+       struct input_dev *input_dev = priv->input;
 
        if (device_may_wakeup(&client->dev))
                disable_irq_wake(priv->irq);
 
+       mutex_lock(&input_dev->mutex);
+
+       if (input_dev->users)
+               eeti_ts_start(priv);
+
+       mutex_unlock(&input_dev->mutex);
+
        return 0;
 }
 #else
index 98a7d12..e0b7c83 100644 (file)
@@ -37,9 +37,7 @@
 
 #include <plat/adc.h>
 #include <plat/regs-adc.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/ts.h>
+#include <plat/ts.h>
 
 #define TSC_SLEEP  (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
 
@@ -57,6 +55,8 @@
                         S3C2410_ADCTSC_AUTO_PST | \
                         S3C2410_ADCTSC_XY_PST(0))
 
+#define FEAT_PEN_IRQ   (1 << 0)        /* HAS ADCCLRINTPNDNUP */
+
 /* Per-touchscreen data. */
 
 /**
@@ -71,6 +71,7 @@
  * @irq_tc: The interrupt number for pen up/down interrupt
  * @count: The number of samples collected.
  * @shift: The log2 of the maximum count to read in one go.
+ * @features: The features supported by the TSADC MOdule.
  */
 struct s3c2410ts {
        struct s3c_adc_client *client;
@@ -83,25 +84,11 @@ struct s3c2410ts {
        int irq_tc;
        int count;
        int shift;
+       int features;
 };
 
 static struct s3c2410ts ts;
 
-/**
- * s3c2410_ts_connect - configure gpio for s3c2410 systems
- *
- * Configure the GPIO for the S3C2410 system, where we have external FETs
- * connected to the device (later systems such as the S3C2440 integrate
- * these into the device).
-*/
-static inline void s3c2410_ts_connect(void)
-{
-       s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
-       s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
-}
-
 /**
  * get_down - return the down state of the pen
  * @data0: The data read from ADCDAT0 register.
@@ -188,6 +175,11 @@ static irqreturn_t stylus_irq(int irq, void *dev_id)
        else
                dev_info(ts.dev, "%s: count=%d\n", __func__, ts.count);
 
+       if (ts.features & FEAT_PEN_IRQ) {
+               /* Clear pen down/up interrupt */
+               writel(0x0, ts.io + S3C64XX_ADCCLRINTPNDNUP);
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -296,9 +288,9 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
                goto err_clk;
        }
 
-       /* Configure the touchscreen external FETs on the S3C2410 */
-       if (!platform_get_device_id(pdev)->driver_data)
-               s3c2410_ts_connect();
+       /* inititalise the gpio */
+       if (info->cfg_gpio)
+               info->cfg_gpio(to_platform_device(ts.dev));
 
        ts.client = s3c_adc_register(pdev, s3c24xx_ts_select,
                                     s3c24xx_ts_conversion, 1);
@@ -334,6 +326,7 @@ static int __devinit s3c2410ts_probe(struct platform_device *pdev)
        ts.input->id.version = 0x0102;
 
        ts.shift = info->oversampling_shift;
+       ts.features = platform_get_device_id(pdev)->driver_data;
 
        ret = request_irq(ts.irq_tc, stylus_irq, IRQF_DISABLED,
                          "s3c2410_ts_pen", ts.input);
@@ -420,15 +413,14 @@ static struct dev_pm_ops s3c_ts_pmops = {
 #endif
 
 static struct platform_device_id s3cts_driver_ids[] = {
-       { "s3c2410-ts", 0 },
-       { "s3c2440-ts", 1 },
+       { "s3c64xx-ts", FEAT_PEN_IRQ },
        { }
 };
 MODULE_DEVICE_TABLE(platform, s3cts_driver_ids);
 
 static struct platform_driver s3c_ts_driver = {
        .driver         = {
-               .name   = "s3c24xx-ts",
+               .name   = "samsung-ts",
                .owner  = THIS_MODULE,
 #ifdef CONFIG_PM
                .pm     = &s3c_ts_pmops,
index 9f49d90..c53e241 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 #include <linux/isdnif.h>
 #include <net/net_namespace.h>
+#include <linux/smp_lock.h>
 #include "isdn_divert.h"
 
 
@@ -177,9 +178,7 @@ isdn_divert_close(struct inode *ino, struct file *filep)
 /*********/
 /* IOCTL */
 /*********/
-static int
-isdn_divert_ioctl(struct inode *inode, struct file *file,
-                 uint cmd, ulong arg)
+static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg)
 {
        divert_ioctl dioctl;
        int i;
@@ -258,6 +257,17 @@ isdn_divert_ioctl(struct inode *inode, struct file *file,
        return copy_to_user((void __user *)arg, &dioctl, sizeof(dioctl)) ? -EFAULT : 0;
 }                              /* isdn_divert_ioctl */
 
+static long isdn_divert_ioctl(struct file *file, uint cmd, ulong arg)
+{
+       long ret;
+
+       lock_kernel();
+       ret = isdn_divert_ioctl_unlocked(file, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
 static const struct file_operations isdn_fops =
 {
        .owner          = THIS_MODULE,
@@ -265,7 +275,7 @@ static const struct file_operations isdn_fops =
        .read           = isdn_divert_read,
        .write          = isdn_divert_write,
        .poll           = isdn_divert_poll,
-       .ioctl          = isdn_divert_ioctl,
+       .unlocked_ioctl = isdn_divert_ioctl,
        .open           = isdn_divert_open,
        .release        = isdn_divert_close,                                      
 };
index 0be15c7..47a5ffe 100644 (file)
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index eb7e271..964a55f 100644 (file)
@@ -12,8 +12,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/slab.h>
-#include <linux/ctype.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/isdn/capilli.h>
index 0b39b38..f6f45f2 100644 (file)
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/slab.h>
 
 /* Version Information */
 #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
index 9ef5b04..05947f9 100644 (file)
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/usb.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ppp_defs.h>
index c99fb97..c22e5ac 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "gigaset.h"
 #include <linux/isdnif.h>
-#include <linux/slab.h>
 
 #define HW_HDR_LEN     2       /* Header size used to store ack info */
 
index f0dc6c9..c9f28dd 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "gigaset.h"
 #include <linux/gigaset_dev.h>
-#include <linux/tty.h>
 #include <linux/tty_flip.h>
 
 /*** our ioctls ***/
index b69f73a..b943efb 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 
 static ssize_t show_cidmode(struct device *dev,
                            struct device_attribute *attr, char *buf)
index 8b0afd2..e96c058 100644 (file)
  */
 
 #include "gigaset.h"
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/tty.h>
 #include <linux/completion.h>
-#include <linux/slab.h>
 
 /* Version Information */
 #define DRIVER_AUTHOR "Tilman Schmidt"
index 9430a2b..76dbb20 100644 (file)
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 07090f3..69c84a1 100644 (file)
@@ -178,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status)
 
        /* We set the status. */
        to_lgdev(vdev)->desc->status = status;
-       kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
+       hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0);
 }
 
 static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -229,7 +229,7 @@ static void lg_notify(struct virtqueue *vq)
         */
        struct lguest_vq_info *lvq = vq->priv;
 
-       kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
+       hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0);
 }
 
 /* An extern declaration inside a C file is bad form.  Don't do it. */
index fb2b7ef..b4eb675 100644 (file)
@@ -287,6 +287,18 @@ static int emulate_insn(struct lg_cpu *cpu)
        /* Decoding x86 instructions is icky. */
        insn = lgread(cpu, physaddr, u8);
 
+       /*
+        * Around 2.6.33, the kernel started using an emulation for the
+        * cmpxchg8b instruction in early boot on many configurations.  This
+        * code isn't paravirtualized, and it tries to disable interrupts.
+        * Ignore it, which will Mostly Work.
+        */
+       if (insn == 0xfa) {
+               /* "cli", or Clear Interrupt Enable instruction.  Skip it. */
+               cpu->regs->eip++;
+               return 1;
+       }
+
        /*
         * 0x66 is an "operand prefix".  It means it's using the upper 16 bits
         * of the eax register.
index 9712b2e..cefd63d 100644 (file)
@@ -2109,12 +2109,18 @@ repeat:
                if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */
                        /* .. if the array isn't clean, an 'even' event must also go
                         * to spares. */
-                       if ((mddev->events&1)==0)
+                       if ((mddev->events&1)==0) {
                                nospares = 0;
+                               sync_req = 2; /* force a second update to get the
+                                              * even/odd in sync */
+                       }
                } else {
                        /* otherwise an 'odd' event must go to spares */
-                       if ((mddev->events&1))
+                       if ((mddev->events&1)) {
                                nospares = 0;
+                               sync_req = 2; /* force a second update to get the
+                                              * even/odd in sync */
+                       }
                }
        }
 
index e3e9a36..15348c3 100644 (file)
@@ -1527,7 +1527,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
 
                clear_bit(R5_UPTODATE, &sh->dev[i].flags);
                atomic_inc(&rdev->read_errors);
-               if (conf->mddev->degraded)
+               if (conf->mddev->degraded >= conf->max_degraded)
                        printk_rl(KERN_WARNING
                                  "raid5:%s: read error not correctable "
                                  "(sector %llu on %s).\n",
@@ -1650,8 +1650,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                     int previous, int *dd_idx,
                                     struct stripe_head *sh)
 {
-       long stripe;
-       unsigned long chunk_number;
+       sector_t stripe, stripe2;
+       sector_t chunk_number;
        unsigned int chunk_offset;
        int pd_idx, qd_idx;
        int ddf_layout = 0;
@@ -1671,18 +1671,13 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
         */
        chunk_offset = sector_div(r_sector, sectors_per_chunk);
        chunk_number = r_sector;
-       BUG_ON(r_sector != chunk_number);
 
        /*
         * Compute the stripe number
         */
-       stripe = chunk_number / data_disks;
-
-       /*
-        * Compute the data disk and parity disk indexes inside the stripe
-        */
-       *dd_idx = chunk_number % data_disks;
-
+       stripe = chunk_number;
+       *dd_idx = sector_div(stripe, data_disks);
+       stripe2 = stripe;
        /*
         * Select the parity disk based on the user selected algorithm.
         */
@@ -1694,21 +1689,21 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
        case 5:
                switch (algorithm) {
                case ALGORITHM_LEFT_ASYMMETRIC:
-                       pd_idx = data_disks - stripe % raid_disks;
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        break;
                case ALGORITHM_RIGHT_ASYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        break;
                case ALGORITHM_LEFT_SYMMETRIC:
-                       pd_idx = data_disks - stripe % raid_disks;
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
                        break;
                case ALGORITHM_RIGHT_SYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
                        break;
                case ALGORITHM_PARITY_0:
@@ -1728,7 +1723,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
 
                switch (algorithm) {
                case ALGORITHM_LEFT_ASYMMETRIC:
-                       pd_idx = raid_disks - 1 - (stripe % raid_disks);
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1737,7 +1732,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                (*dd_idx) += 2; /* D D P Q D */
                        break;
                case ALGORITHM_RIGHT_ASYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1746,12 +1741,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                (*dd_idx) += 2; /* D D P Q D */
                        break;
                case ALGORITHM_LEFT_SYMMETRIC:
-                       pd_idx = raid_disks - 1 - (stripe % raid_disks);
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = (pd_idx + 1) % raid_disks;
                        *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
                        break;
                case ALGORITHM_RIGHT_SYMMETRIC:
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        qd_idx = (pd_idx + 1) % raid_disks;
                        *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
                        break;
@@ -1770,7 +1765,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                        /* Exactly the same as RIGHT_ASYMMETRIC, but or
                         * of blocks for computing Q is different.
                         */
-                       pd_idx = stripe % raid_disks;
+                       pd_idx = sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1785,7 +1780,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                         * D D D P Q  rather than
                         * Q D D D P
                         */
-                       pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+                       stripe2 += 1;
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = pd_idx + 1;
                        if (pd_idx == raid_disks-1) {
                                (*dd_idx)++;    /* Q D D D P */
@@ -1797,7 +1793,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
 
                case ALGORITHM_ROTATING_N_CONTINUE:
                        /* Same as left_symmetric but Q is before P */
-                       pd_idx = raid_disks - 1 - (stripe % raid_disks);
+                       pd_idx = raid_disks - 1 - sector_div(stripe2, raid_disks);
                        qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
                        *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
                        ddf_layout = 1;
@@ -1805,27 +1801,27 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
 
                case ALGORITHM_LEFT_ASYMMETRIC_6:
                        /* RAID5 left_asymmetric, with Q on last device */
-                       pd_idx = data_disks - stripe % (raid_disks-1);
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks-1);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        qd_idx = raid_disks - 1;
                        break;
 
                case ALGORITHM_RIGHT_ASYMMETRIC_6:
-                       pd_idx = stripe % (raid_disks-1);
+                       pd_idx = sector_div(stripe2, raid_disks-1);
                        if (*dd_idx >= pd_idx)
                                (*dd_idx)++;
                        qd_idx = raid_disks - 1;
                        break;
 
                case ALGORITHM_LEFT_SYMMETRIC_6:
-                       pd_idx = data_disks - stripe % (raid_disks-1);
+                       pd_idx = data_disks - sector_div(stripe2, raid_disks-1);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
                        qd_idx = raid_disks - 1;
                        break;
 
                case ALGORITHM_RIGHT_SYMMETRIC_6:
-                       pd_idx = stripe % (raid_disks-1);
+                       pd_idx = sector_div(stripe2, raid_disks-1);
                        *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
                        qd_idx = raid_disks - 1;
                        break;
@@ -1870,14 +1866,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
                                 : conf->algorithm;
        sector_t stripe;
        int chunk_offset;
-       int chunk_number, dummy1, dd_idx = i;
+       sector_t chunk_number;
+       int dummy1, dd_idx = i;
        sector_t r_sector;
        struct stripe_head sh2;
 
 
        chunk_offset = sector_div(new_sector, sectors_per_chunk);
        stripe = new_sector;
-       BUG_ON(new_sector != stripe);
 
        if (i == sh->pd_idx)
                return 0;
@@ -1970,7 +1966,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
        }
 
        chunk_number = stripe * data_disks + i;
-       r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
+       r_sector = chunk_number * sectors_per_chunk + chunk_offset;
 
        check = raid5_compute_sector(conf, r_sector,
                                     previous, &dummy1, &sh2);
index fd8e1f4..7364b96 100644 (file)
@@ -423,15 +423,14 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
        }
 }
 
-int saa7146_vv_devinit(struct saa7146_dev *dev)
-{
-       return v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
-}
-EXPORT_SYMBOL_GPL(saa7146_vv_devinit);
-
 int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
 {
        struct saa7146_vv *vv;
+       int err;
+
+       err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
+       if (err)
+               return err;
 
        vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
        if (vv == NULL) {
index 5ed7526..b8b2c55 100644 (file)
@@ -558,9 +558,11 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
        /* ok, accept it */
        vv->ov_fb = *fb;
        vv->ov_fmt = fmt;
-       if (0 == vv->ov_fb.fmt.bytesperline)
-               vv->ov_fb.fmt.bytesperline =
-                       vv->ov_fb.fmt.width * fmt->depth / 8;
+
+       if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
+               vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
+               DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
+       }
 
        mutex_unlock(&dev->lock);
        return 0;
index a3c07fe..9697280 100644 (file)
@@ -4470,6 +4470,10 @@ static int stv090x_setup(struct dvb_frontend *fe)
        if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
                goto err;
 
+       /* workaround for stuck DiSEqC output */
+       if (config->diseqc_envelope_mode)
+               stv090x_send_diseqc_burst(fe, SEC_MINI_A);
+
        return 0;
 err:
        dprintk(FE_ERROR, 1, "I/O error");
index 9fdf26c..1500210 100644 (file)
@@ -643,9 +643,6 @@ static void frontend_init(struct budget *budget)
                                        &budget->i2c_adap,
                                        &tt1600_isl6423_config);
 
-                       } else {
-                               dvb_frontend_detach(budget->dvb_frontend);
-                               budget->dvb_frontend = NULL;
                        }
                }
                break;
index f8fc865..9644cf7 100644 (file)
@@ -361,7 +361,7 @@ config VIDEO_SAA717X
 
 config VIDEO_SAA7191
        tristate "Philips SAA7191 video decoder"
-       depends on VIDEO_V4L1 && I2C
+       depends on VIDEO_V4L2 && I2C
        ---help---
          Support for the Philips SAA7191 video decoder.
 
@@ -756,7 +756,7 @@ source "drivers/media/video/saa7134/Kconfig"
 
 config VIDEO_MXB
        tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
-       depends on PCI && VIDEO_V4L1 && I2C
+       depends on PCI && VIDEO_V4L2 && I2C
        select VIDEO_SAA7146_VV
        select VIDEO_TUNER
        select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
index b88b617..c51c386 100644 (file)
@@ -160,8 +160,6 @@ obj-$(CONFIG_VIDEO_MX3)                     += mx3_camera.o
 obj-$(CONFIG_VIDEO_PXA27x)             += pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)      += sh_mobile_ceu_camera.o
 
-obj-$(CONFIG_ARCH_DAVINCI)             += davinci/
-
 obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
 obj-$(CONFIG_USB_VIDEO_CLASS)  += uvc/
index 7cf042f..398dbe7 100644 (file)
@@ -223,7 +223,6 @@ int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
        BUG_ON(!dev->hw_ops.get_frame_format);
        BUG_ON(!dev->hw_ops.get_pixel_format);
        BUG_ON(!dev->hw_ops.set_pixel_format);
-       BUG_ON(!dev->hw_ops.set_params);
        BUG_ON(!dev->hw_ops.set_image_window);
        BUG_ON(!dev->hw_ops.get_image_window);
        BUG_ON(!dev->hw_ops.get_line_length);
@@ -1689,11 +1688,12 @@ static long vpfe_param_handler(struct file *file, void *priv,
        struct vpfe_device *vpfe_dev = video_drvdata(file);
        int ret = 0;
 
-       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
+       v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
 
        if (vpfe_dev->started) {
                /* only allowed if streaming is not started */
-               v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n");
+               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                       "device already started\n");
                return -EBUSY;
        }
 
@@ -1705,16 +1705,23 @@ static long vpfe_param_handler(struct file *file, void *priv,
        case VPFE_CMD_S_CCDC_RAW_PARAMS:
                v4l2_warn(&vpfe_dev->v4l2_dev,
                          "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
-               ret = ccdc_dev->hw_ops.set_params(param);
-               if (ret) {
-                       v4l2_err(&vpfe_dev->v4l2_dev,
-                               "Error in setting parameters in CCDC\n");
-                       goto unlock_out;
-               }
-               if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) {
-                       v4l2_err(&vpfe_dev->v4l2_dev,
-                               "Invalid image format at CCDC\n");
-                       goto unlock_out;
+               if (ccdc_dev->hw_ops.set_params) {
+                       ret = ccdc_dev->hw_ops.set_params(param);
+                       if (ret) {
+                               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                                       "Error setting parameters in CCDC\n");
+                               goto unlock_out;
+                       }
+                       if (vpfe_get_ccdc_image_format(vpfe_dev,
+                                                      &vpfe_dev->fmt) < 0) {
+                               v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                                       "Invalid image format at CCDC\n");
+                               goto unlock_out;
+                       }
+               } else {
+                       ret = -EINVAL;
+                       v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+                               "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
                }
                break;
        default:
@@ -1830,7 +1837,7 @@ static __init int vpfe_probe(struct platform_device *pdev)
        if (NULL == ccdc_cfg) {
                v4l2_err(pdev->dev.driver,
                         "Memory allocation failed for ccdc_cfg\n");
-               goto probe_free_dev_mem;
+               goto probe_free_lock;
        }
 
        strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
@@ -1982,8 +1989,9 @@ probe_out_video_release:
 probe_out_release_irq:
        free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
 probe_free_ccdc_cfg_mem:
-       mutex_unlock(&ccdc_lock);
        kfree(ccdc_cfg);
+probe_free_lock:
+       mutex_unlock(&ccdc_lock);
 probe_free_dev_mem:
        kfree(vpfe_dev);
        return ret;
index 38a6e15..3dee3e5 100644 (file)
@@ -1427,7 +1427,7 @@ static int input_kthread(void *data)
        struct gspca_dev *gspca_dev = (struct gspca_dev *)data;
        struct sd *sd = (struct sd *) gspca_dev;
 
-       DECLARE_WAIT_QUEUE_HEAD(wait);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait);
        set_freezable();
        for (;;) {
                if (kthread_should_stop())
index 15b2eef..edf0fe1 100644 (file)
@@ -1513,7 +1513,6 @@ static const struct sd_desc sd_desc = {
 static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam},
        {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista},
-       {USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200},
        {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110},
        {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam},
        {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2},
index dc7f2b0..b9c80e2 100644 (file)
@@ -1053,6 +1053,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
        {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
        {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
+       {USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
        {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
        {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
        {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
index af73da3..14f179a 100644 (file)
@@ -524,8 +524,6 @@ static const __devinitdata struct usb_device_id device_table[] = {
        {USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
        /* QuickCam Messenger (new) */
        {USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
-       /* QuickCam Messenger (new) */
-       {USB_DEVICE(0x046D, 0x08DA), .driver_info = BRIDGE_ST6422 },
        {}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
index e620a3a..ad2c232 100644 (file)
@@ -356,9 +356,6 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
 
        DEB_EE((".\n"));
 
-       ret = saa7146_vv_devinit(dev);
-       if (ret)
-               return ret;
        hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
        if (NULL == hexium) {
                printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
index fe596a1..938a1f8 100644 (file)
@@ -216,10 +216,6 @@ static int hexium_probe(struct saa7146_dev *dev)
                return -EFAULT;
        }
 
-       err = saa7146_vv_devinit(dev);
-       if (err)
-               return err;
-
        hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
        if (NULL == hexium) {
                printk("hexium_orion: hexium_probe: not enough kernel memory.\n");
index 3c8ebfc..34a6601 100644 (file)
@@ -49,8 +49,6 @@
 /*
  * CSI registers
  */
-#define DMA_CCR(x)     (0x8c + ((x) << 6))     /* Control Registers */
-#define DMA_DIMR       0x08                    /* Interrupt mask Register */
 #define CSICR1         0x00                    /* CSI Control Register 1 */
 #define CSISR          0x08                    /* CSI Status Register */
 #define CSIRXR         0x10                    /* CSI RxFIFO Register */
@@ -784,7 +782,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
                               pcdev);
 
        imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
-                              IMX_DMA_MEMSIZE_32, DMA_REQ_CSI_R, 0);
+                              IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
        /* burst length : 16 words = 64 bytes */
        imx_dma_config_burstlen(pcdev->dma_chan, 0);
 
@@ -798,8 +796,8 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
        set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
                                                   &mx1_camera_sof_fiq_start);
 
-       regs.ARM_r8 = DMA_BASE + DMA_DIMR;
-       regs.ARM_r9 = DMA_BASE + DMA_CCR(pcdev->dma_chan);
+       regs.ARM_r8 = (long)MX1_DMA_DIMR;
+       regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
        regs.ARM_r10 = (long)pcdev->base + CSICR1;
        regs.ARM_fp = (long)pcdev->base + CSISR;
        regs.ARM_sp = 1 << pcdev->dma_chan;
index 9f01f14..ef0c817 100644 (file)
@@ -169,11 +169,7 @@ static struct saa7146_extension extension;
 static int mxb_probe(struct saa7146_dev *dev)
 {
        struct mxb *mxb = NULL;
-       int err;
 
-       err = saa7146_vv_devinit(dev);
-       if (err)
-               return err;
        mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
        if (mxb == NULL) {
                DEB_D(("not enough kernel memory.\n"));
@@ -699,14 +695,17 @@ static struct saa7146_ext_vv vv_data;
 /* this function only gets called when the probing was successful */
 static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
 {
-       struct mxb *mxb = (struct mxb *)dev->ext_priv;
+       struct mxb *mxb;
 
        DEB_EE(("dev:%p\n", dev));
 
-       /* checking for i2c-devices can be omitted here, because we
-          already did this in "mxb_vl42_probe" */
-
        saa7146_vv_init(dev, &vv_data);
+       if (mxb_probe(dev)) {
+               saa7146_vv_release(dev);
+               return -1;
+       }
+       mxb = (struct mxb *)dev->ext_priv;
+
        vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
        vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
        vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
@@ -726,6 +725,7 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data
        vv_data.ops.vidioc_default = vidioc_default;
        if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
                ERR(("cannot register capture v4l2 device. skipping.\n"));
+               saa7146_vv_release(dev);
                return -1;
        }
 
@@ -846,7 +846,6 @@ static struct saa7146_extension extension = {
        .pci_tbl        = &pci_tbl[0],
        .module         = THIS_MODULE,
 
-       .probe          = mxb_probe,
        .attach         = mxb_attach,
        .detach         = mxb_detach,
 
index b189fe6..ce76d95 100644 (file)
@@ -1405,7 +1405,7 @@ static int omap24xxcam_mmap_buffers(struct file *file,
        }
 
        size = 0;
-       for (i = first; i <= last; i++) {
+       for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) {
                struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
 
                for (j = 0; j < dma->sglen; j++) {
index 5ecc30d..04bf5c1 100644 (file)
@@ -609,12 +609,9 @@ static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
  */
 static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
 {
-       unsigned long cicr0, cifr;
+       unsigned long cicr0;
 
        dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
-       /* Reset the FIFOs */
-       cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
-       __raw_writel(cifr, pcdev->base + CIFR);
        /* Enable End-Of-Frame Interrupt */
        cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
        cicr0 &= ~CICR0_EOFM;
@@ -935,7 +932,7 @@ static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
 static irqreturn_t pxa_camera_irq(int irq, void *data)
 {
        struct pxa_camera_dev *pcdev = data;
-       unsigned long status, cicr0;
+       unsigned long status, cifr, cicr0;
        struct pxa_buffer *buf;
        struct videobuf_buffer *vb;
 
@@ -949,6 +946,10 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
        __raw_writel(status, pcdev->base + CISR);
 
        if (status & CISR_EOF) {
+               /* Reset the FIFOs */
+               cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
+               __raw_writel(cifr, pcdev->base + CIFR);
+
                pcdev->active = list_first_entry(&pcdev->capture,
                                           struct pxa_buffer, vb.queue);
                vb = &pcdev->active->vb;
index 6e16b39..1ad980f 100644 (file)
@@ -1633,7 +1633,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
        height = pix->height;
 
        pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt);
-       if (pix->bytesperline < 0)
+       if ((int)pix->bytesperline < 0)
                return pix->bytesperline;
        pix->sizeimage = height * pix->bytesperline;
 
index a3d5728..f2ab025 100644 (file)
@@ -349,6 +349,9 @@ int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
                goto disable;
        }
 
+       /* If an interrupt arrived late clean up after it */
+       try_wait_for_completion(&wm831x->auxadc_done);
+
        /* Ignore the result to allow us to soldier on without IRQ hookup */
        wait_for_completion_timeout(&wm831x->auxadc_done, msecs_to_jiffies(5));
 
index e400a3b..b580748 100644 (file)
@@ -363,6 +363,10 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
        reg |= 1 << channel | WM8350_AUXADC_POLL;
        wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
 
+       /* If a late IRQ left the completion signalled then consume
+        * the completion. */
+       try_wait_for_completion(&wm8350->auxadc_done);
+
        /* We ignore the result of the completion and just check for a
         * conversion result, allowing us to soldier on if the IRQ
         * infrastructure is not set up for the chip. */
index 2191c8d..0d0d625 100644 (file)
@@ -311,6 +311,22 @@ config TI_DAC7512
          This driver can also be built as a module. If so, the module
          will be calles ti_dac7512.
 
+config VMWARE_BALLOON
+       tristate "VMware Balloon Driver"
+       depends on X86
+       help
+         This is VMware physical memory management driver which acts
+         like a "balloon" that can be inflated to reclaim physical pages
+         by reserving them in the guest and invalidating them in the
+         monitor, freeing up the underlying machine pages so they can
+         be allocated to other guests. The balloon can also be deflated
+         to allow the guest to use more physical memory.
+
+         If unsure, say N.
+
+         To compile this driver as a module, choose M here: the
+         module will be called vmware_balloon.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
index 27c4843..7b6f7ee 100644 (file)
@@ -29,3 +29,4 @@ obj-$(CONFIG_C2PORT)          += c2port/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y                          += eeprom/
 obj-y                          += cb710/
+obj-$(CONFIG_VMWARE_BALLOON)   += vmware_balloon.o
diff --git a/drivers/misc/vmware_balloon.c b/drivers/misc/vmware_balloon.c
new file mode 100644 (file)
index 0000000..db9cd02
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * VMware Balloon driver.
+ *
+ * Copyright (C) 2000-2010, VMware, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License and no 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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.
+ *
+ * Maintained by: Dmitry Torokhov <dtor@vmware.com>
+ */
+
+/*
+ * This is VMware physical memory management driver for Linux. The driver
+ * acts like a "balloon" that can be inflated to reclaim physical pages by
+ * reserving them in the guest and invalidating them in the monitor,
+ * freeing up the underlying machine pages so they can be allocated to
+ * other guests.  The balloon can also be deflated to allow the guest to
+ * use more physical memory. Higher level policies can control the sizes
+ * of balloons in VMs in order to manage physical memory resources.
+ */
+
+//#define DEBUG
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <asm/hypervisor.h>
+
+MODULE_AUTHOR("VMware, Inc.");
+MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
+MODULE_VERSION("1.2.1.0-K");
+MODULE_ALIAS("dmi:*:svnVMware*:*");
+MODULE_ALIAS("vmware_vmmemctl");
+MODULE_LICENSE("GPL");
+
+/*
+ * Various constants controlling rate of inflaint/deflating balloon,
+ * measured in pages.
+ */
+
+/*
+ * Rate of allocating memory when there is no memory pressure
+ * (driver performs non-sleeping allocations).
+ */
+#define VMW_BALLOON_NOSLEEP_ALLOC_MAX  16384U
+
+/*
+ * Rates of memory allocaton when guest experiences memory pressure
+ * (driver performs sleeping allocations).
+ */
+#define VMW_BALLOON_RATE_ALLOC_MIN     512U
+#define VMW_BALLOON_RATE_ALLOC_MAX     2048U
+#define VMW_BALLOON_RATE_ALLOC_INC     16U
+
+/*
+ * Rates for releasing pages while deflating balloon.
+ */
+#define VMW_BALLOON_RATE_FREE_MIN      512U
+#define VMW_BALLOON_RATE_FREE_MAX      16384U
+#define VMW_BALLOON_RATE_FREE_INC      16U
+
+/*
+ * When guest is under memory pressure, use a reduced page allocation
+ * rate for next several cycles.
+ */
+#define VMW_BALLOON_SLOW_CYCLES                4
+
+/*
+ * Use __GFP_HIGHMEM to allow pages from HIGHMEM zone. We don't
+ * allow wait (__GFP_WAIT) for NOSLEEP page allocations. Use
+ * __GFP_NOWARN, to suppress page allocation failure warnings.
+ */
+#define VMW_PAGE_ALLOC_NOSLEEP         (__GFP_HIGHMEM|__GFP_NOWARN)
+
+/*
+ * Use GFP_HIGHUSER when executing in a separate kernel thread
+ * context and allocation can sleep.  This is less stressful to
+ * the guest memory system, since it allows the thread to block
+ * while memory is reclaimed, and won't take pages from emergency
+ * low-memory pools.
+ */
+#define VMW_PAGE_ALLOC_CANSLEEP                (GFP_HIGHUSER)
+
+/* Maximum number of page allocations without yielding processor */
+#define VMW_BALLOON_YIELD_THRESHOLD    1024
+
+
+/*
+ * Hypervisor communication port definitions.
+ */
+#define VMW_BALLOON_HV_PORT            0x5670
+#define VMW_BALLOON_HV_MAGIC           0x456c6d6f
+#define VMW_BALLOON_PROTOCOL_VERSION   2
+#define VMW_BALLOON_GUEST_ID           1       /* Linux */
+
+#define VMW_BALLOON_CMD_START          0
+#define VMW_BALLOON_CMD_GET_TARGET     1
+#define VMW_BALLOON_CMD_LOCK           2
+#define VMW_BALLOON_CMD_UNLOCK         3
+#define VMW_BALLOON_CMD_GUEST_ID       4
+
+/* error codes */
+#define VMW_BALLOON_SUCCESS            0
+#define VMW_BALLOON_FAILURE            -1
+#define VMW_BALLOON_ERROR_CMD_INVALID  1
+#define VMW_BALLOON_ERROR_PPN_INVALID  2
+#define VMW_BALLOON_ERROR_PPN_LOCKED   3
+#define VMW_BALLOON_ERROR_PPN_UNLOCKED 4
+#define VMW_BALLOON_ERROR_PPN_PINNED   5
+#define VMW_BALLOON_ERROR_PPN_NOTNEEDED        6
+#define VMW_BALLOON_ERROR_RESET                7
+#define VMW_BALLOON_ERROR_BUSY         8
+
+#define VMWARE_BALLOON_CMD(cmd, data, result)          \
+({                                                     \
+       unsigned long __stat, __dummy1, __dummy2;       \
+       __asm__ __volatile__ ("inl (%%dx)" :            \
+               "=a"(__stat),                           \
+               "=c"(__dummy1),                         \
+               "=d"(__dummy2),                         \
+               "=b"(result) :                          \
+               "0"(VMW_BALLOON_HV_MAGIC),              \
+               "1"(VMW_BALLOON_CMD_##cmd),             \
+               "2"(VMW_BALLOON_HV_PORT),               \
+               "3"(data) :                             \
+               "memory");                              \
+       result &= -1UL;                                 \
+       __stat & -1UL;                                  \
+})
+
+#ifdef CONFIG_DEBUG_FS
+struct vmballoon_stats {
+       unsigned int timer;
+
+       /* allocation statustics */
+       unsigned int alloc;
+       unsigned int alloc_fail;
+       unsigned int sleep_alloc;
+       unsigned int sleep_alloc_fail;
+       unsigned int refused_alloc;
+       unsigned int refused_free;
+       unsigned int free;
+
+       /* monitor operations */
+       unsigned int lock;
+       unsigned int lock_fail;
+       unsigned int unlock;
+       unsigned int unlock_fail;
+       unsigned int target;
+       unsigned int target_fail;
+       unsigned int start;
+       unsigned int start_fail;
+       unsigned int guest_type;
+       unsigned int guest_type_fail;
+};
+
+#define STATS_INC(stat) (stat)++
+#else
+#define STATS_INC(stat)
+#endif
+
+struct vmballoon {
+
+       /* list of reserved physical pages */
+       struct list_head pages;
+
+       /* transient list of non-balloonable pages */
+       struct list_head refused_pages;
+
+       /* balloon size in pages */
+       unsigned int size;
+       unsigned int target;
+
+       /* reset flag */
+       bool reset_required;
+
+       /* adjustment rates (pages per second) */
+       unsigned int rate_alloc;
+       unsigned int rate_free;
+
+       /* slowdown page allocations for next few cycles */
+       unsigned int slow_allocation_cycles;
+
+#ifdef CONFIG_DEBUG_FS
+       /* statistics */
+       struct vmballoon_stats stats;
+
+       /* debugfs file exporting statistics */
+       struct dentry *dbg_entry;
+#endif
+
+       struct sysinfo sysinfo;
+
+       struct delayed_work dwork;
+};
+
+static struct vmballoon balloon;
+static struct workqueue_struct *vmballoon_wq;
+
+/*
+ * Send "start" command to the host, communicating supported version
+ * of the protocol.
+ */
+static bool vmballoon_send_start(struct vmballoon *b)
+{
+       unsigned long status, dummy;
+
+       STATS_INC(b->stats.start);
+
+       status = VMWARE_BALLOON_CMD(START, VMW_BALLOON_PROTOCOL_VERSION, dummy);
+       if (status == VMW_BALLOON_SUCCESS)
+               return true;
+
+       pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+       STATS_INC(b->stats.start_fail);
+       return false;
+}
+
+static bool vmballoon_check_status(struct vmballoon *b, unsigned long status)
+{
+       switch (status) {
+       case VMW_BALLOON_SUCCESS:
+               return true;
+
+       case VMW_BALLOON_ERROR_RESET:
+               b->reset_required = true;
+               /* fall through */
+
+       default:
+               return false;
+       }
+}
+
+/*
+ * Communicate guest type to the host so that it can adjust ballooning
+ * algorithm to the one most appropriate for the guest. This command
+ * is normally issued after sending "start" command and is part of
+ * standard reset sequence.
+ */
+static bool vmballoon_send_guest_id(struct vmballoon *b)
+{
+       unsigned long status, dummy;
+
+       status = VMWARE_BALLOON_CMD(GUEST_ID, VMW_BALLOON_GUEST_ID, dummy);
+
+       STATS_INC(b->stats.guest_type);
+
+       if (vmballoon_check_status(b, status))
+               return true;
+
+       pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+       STATS_INC(b->stats.guest_type_fail);
+       return false;
+}
+
+/*
+ * Retrieve desired balloon size from the host.
+ */
+static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
+{
+       unsigned long status;
+       unsigned long target;
+       unsigned long limit;
+       u32 limit32;
+
+       /*
+        * si_meminfo() is cheap. Moreover, we want to provide dynamic
+        * max balloon size later. So let us call si_meminfo() every
+        * iteration.
+        */
+       si_meminfo(&b->sysinfo);
+       limit = b->sysinfo.totalram;
+
+       /* Ensure limit fits in 32-bits */
+       limit32 = (u32)limit;
+       if (limit != limit32)
+               return false;
+
+       /* update stats */
+       STATS_INC(b->stats.target);
+
+       status = VMWARE_BALLOON_CMD(GET_TARGET, limit, target);
+       if (vmballoon_check_status(b, status)) {
+               *new_target = target;
+               return true;
+       }
+
+       pr_debug("%s - failed, hv returns %ld\n", __func__, status);
+       STATS_INC(b->stats.target_fail);
+       return false;
+}
+
+/*
+ * Notify the host about allocated page so that host can use it without
+ * fear that guest will need it. Host may reject some pages, we need to
+ * check the return value and maybe submit a different page.
+ */
+static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn)
+{
+       unsigned long status, dummy;
+       u32 pfn32;
+
+       pfn32 = (u32)pfn;
+       if (pfn32 != pfn)
+               return false;
+
+       STATS_INC(b->stats.lock);
+
+       status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
+       if (vmballoon_check_status(b, status))
+               return true;
+
+       pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+       STATS_INC(b->stats.lock_fail);
+       return false;
+}
+
+/*
+ * Notify the host that guest intends to release given page back into
+ * the pool of available (to the guest) pages.
+ */
+static bool vmballoon_send_unlock_page(struct vmballoon *b, unsigned long pfn)
+{
+       unsigned long status, dummy;
+       u32 pfn32;
+
+       pfn32 = (u32)pfn;
+       if (pfn32 != pfn)
+               return false;
+
+       STATS_INC(b->stats.unlock);
+
+       status = VMWARE_BALLOON_CMD(UNLOCK, pfn, dummy);
+       if (vmballoon_check_status(b, status))
+               return true;
+
+       pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
+       STATS_INC(b->stats.unlock_fail);
+       return false;
+}
+
+/*
+ * Quickly release all pages allocated for the balloon. This function is
+ * called when host decides to "reset" balloon for one reason or another.
+ * Unlike normal "deflate" we do not (shall not) notify host of the pages
+ * being released.
+ */
+static void vmballoon_pop(struct vmballoon *b)
+{
+       struct page *page, *next;
+       unsigned int count = 0;
+
+       list_for_each_entry_safe(page, next, &b->pages, lru) {
+               list_del(&page->lru);
+               __free_page(page);
+               STATS_INC(b->stats.free);
+               b->size--;
+
+               if (++count >= b->rate_free) {
+                       count = 0;
+                       cond_resched();
+               }
+       }
+}
+
+/*
+ * Perform standard reset sequence by popping the balloon (in case it
+ * is not  empty) and then restarting protocol. This operation normally
+ * happens when host responds with VMW_BALLOON_ERROR_RESET to a command.
+ */
+static void vmballoon_reset(struct vmballoon *b)
+{
+       /* free all pages, skipping monitor unlock */
+       vmballoon_pop(b);
+
+       if (vmballoon_send_start(b)) {
+               b->reset_required = false;
+               if (!vmballoon_send_guest_id(b))
+                       pr_err("failed to send guest ID to the host\n");
+       }
+}
+
+/*
+ * Allocate (or reserve) a page for the balloon and notify the host.  If host
+ * refuses the page put it on "refuse" list and allocate another one until host
+ * is satisfied. "Refused" pages are released at the end of inflation cycle
+ * (when we allocate b->rate_alloc pages).
+ */
+static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
+{
+       struct page *page;
+       gfp_t flags;
+       bool locked = false;
+
+       do {
+               if (!can_sleep)
+                       STATS_INC(b->stats.alloc);
+               else
+                       STATS_INC(b->stats.sleep_alloc);
+
+               flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
+               page = alloc_page(flags);
+               if (!page) {
+                       if (!can_sleep)
+                               STATS_INC(b->stats.alloc_fail);
+                       else
+                               STATS_INC(b->stats.sleep_alloc_fail);
+                       return -ENOMEM;
+               }
+
+               /* inform monitor */
+               locked = vmballoon_send_lock_page(b, page_to_pfn(page));
+               if (!locked) {
+                       if (b->reset_required) {
+                               __free_page(page);
+                               return -EIO;
+                       }
+
+                       /* place on list of non-balloonable pages, retry allocation */
+                       list_add(&page->lru, &b->refused_pages);
+                       STATS_INC(b->stats.refused_alloc);
+               }
+       } while (!locked);
+
+       /* track allocated page */
+       list_add(&page->lru, &b->pages);
+
+       /* update balloon size */
+       b->size++;
+
+       return 0;
+}
+
+/*
+ * Release the page allocated for the balloon. Note that we first notify
+ * the host so it can make sure the page will be available for the guest
+ * to use, if needed.
+ */
+static int vmballoon_release_page(struct vmballoon *b, struct page *page)
+{
+       if (!vmballoon_send_unlock_page(b, page_to_pfn(page)))
+               return -EIO;
+
+       list_del(&page->lru);
+
+       /* deallocate page */
+       __free_page(page);
+       STATS_INC(b->stats.free);
+
+       /* update balloon size */
+       b->size--;
+
+       return 0;
+}
+
+/*
+ * Release pages that were allocated while attempting to inflate the
+ * balloon but were refused by the host for one reason or another.
+ */
+static void vmballoon_release_refused_pages(struct vmballoon *b)
+{
+       struct page *page, *next;
+
+       list_for_each_entry_safe(page, next, &b->refused_pages, lru) {
+               list_del(&page->lru);
+               __free_page(page);
+               STATS_INC(b->stats.refused_free);
+       }
+}
+
+/*
+ * Inflate the balloon towards its target size. Note that we try to limit
+ * the rate of allocation to make sure we are not choking the rest of the
+ * system.
+ */
+static void vmballoon_inflate(struct vmballoon *b)
+{
+       unsigned int goal;
+       unsigned int rate;
+       unsigned int i;
+       unsigned int allocations = 0;
+       int error = 0;
+       bool alloc_can_sleep = false;
+
+       pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+       /*
+        * First try NOSLEEP page allocations to inflate balloon.
+        *
+        * If we do not throttle nosleep allocations, we can drain all
+        * free pages in the guest quickly (if the balloon target is high).
+        * As a side-effect, draining free pages helps to inform (force)
+        * the guest to start swapping if balloon target is not met yet,
+        * which is a desired behavior. However, balloon driver can consume
+        * all available CPU cycles if too many pages are allocated in a
+        * second. Therefore, we throttle nosleep allocations even when
+        * the guest is not under memory pressure. OTOH, if we have already
+        * predicted that the guest is under memory pressure, then we
+        * slowdown page allocations considerably.
+        */
+
+       goal = b->target - b->size;
+       /*
+        * Start with no sleep allocation rate which may be higher
+        * than sleeping allocation rate.
+        */
+       rate = b->slow_allocation_cycles ?
+                       b->rate_alloc : VMW_BALLOON_NOSLEEP_ALLOC_MAX;
+
+       pr_debug("%s - goal: %d, no-sleep rate: %d, sleep rate: %d\n",
+                __func__, goal, rate, b->rate_alloc);
+
+       for (i = 0; i < goal; i++) {
+
+               error = vmballoon_reserve_page(b, alloc_can_sleep);
+               if (error) {
+                       if (error != -ENOMEM) {
+                               /*
+                                * Not a page allocation failure, stop this
+                                * cycle. Maybe we'll get new target from
+                                * the host soon.
+                                */
+                               break;
+                       }
+
+                       if (alloc_can_sleep) {
+                               /*
+                                * CANSLEEP page allocation failed, so guest
+                                * is under severe memory pressure. Quickly
+                                * decrease allocation rate.
+                                */
+                               b->rate_alloc = max(b->rate_alloc / 2,
+                                                   VMW_BALLOON_RATE_ALLOC_MIN);
+                               break;
+                       }
+
+                       /*
+                        * NOSLEEP page allocation failed, so the guest is
+                        * under memory pressure. Let us slow down page
+                        * allocations for next few cycles so that the guest
+                        * gets out of memory pressure. Also, if we already
+                        * allocated b->rate_alloc pages, let's pause,
+                        * otherwise switch to sleeping allocations.
+                        */
+                       b->slow_allocation_cycles = VMW_BALLOON_SLOW_CYCLES;
+
+                       if (i >= b->rate_alloc)
+                               break;
+
+                       alloc_can_sleep = true;
+                       /* Lower rate for sleeping allocations. */
+                       rate = b->rate_alloc;
+               }
+
+               if (++allocations > VMW_BALLOON_YIELD_THRESHOLD) {
+                       cond_resched();
+                       allocations = 0;
+               }
+
+               if (i >= rate) {
+                       /* We allocated enough pages, let's take a break. */
+                       break;
+               }
+       }
+
+       /*
+        * We reached our goal without failures so try increasing
+        * allocation rate.
+        */
+       if (error == 0 && i >= b->rate_alloc) {
+               unsigned int mult = i / b->rate_alloc;
+
+               b->rate_alloc =
+                       min(b->rate_alloc + mult * VMW_BALLOON_RATE_ALLOC_INC,
+                           VMW_BALLOON_RATE_ALLOC_MAX);
+       }
+
+       vmballoon_release_refused_pages(b);
+}
+
+/*
+ * Decrease the size of the balloon allowing guest to use more memory.
+ */
+static void vmballoon_deflate(struct vmballoon *b)
+{
+       struct page *page, *next;
+       unsigned int i = 0;
+       unsigned int goal;
+       int error;
+
+       pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
+
+       /* limit deallocation rate */
+       goal = min(b->size - b->target, b->rate_free);
+
+       pr_debug("%s - goal: %d, rate: %d\n", __func__, goal, b->rate_free);
+
+       /* free pages to reach target */
+       list_for_each_entry_safe(page, next, &b->pages, lru) {
+               error = vmballoon_release_page(b, page);
+               if (error) {
+                       /* quickly decrease rate in case of error */
+                       b->rate_free = max(b->rate_free / 2,
+                                          VMW_BALLOON_RATE_FREE_MIN);
+                       return;
+               }
+
+               if (++i >= goal)
+                       break;
+       }
+
+       /* slowly increase rate if there were no errors */
+       b->rate_free = min(b->rate_free + VMW_BALLOON_RATE_FREE_INC,
+                          VMW_BALLOON_RATE_FREE_MAX);
+}
+
+/*
+ * Balloon work function: reset protocol, if needed, get the new size and
+ * adjust balloon as needed. Repeat in 1 sec.
+ */
+static void vmballoon_work(struct work_struct *work)
+{
+       struct delayed_work *dwork = to_delayed_work(work);
+       struct vmballoon *b = container_of(dwork, struct vmballoon, dwork);
+       unsigned int target;
+
+       STATS_INC(b->stats.timer);
+
+       if (b->reset_required)
+               vmballoon_reset(b);
+
+       if (b->slow_allocation_cycles > 0)
+               b->slow_allocation_cycles--;
+
+       if (vmballoon_send_get_target(b, &target)) {
+               /* update target, adjust size */
+               b->target = target;
+
+               if (b->size < target)
+                       vmballoon_inflate(b);
+               else if (b->size > target)
+                       vmballoon_deflate(b);
+       }
+
+       queue_delayed_work(vmballoon_wq, dwork, round_jiffies_relative(HZ));
+}
+
+/*
+ * DEBUGFS Interface
+ */
+#ifdef CONFIG_DEBUG_FS
+
+static int vmballoon_debug_show(struct seq_file *f, void *offset)
+{
+       struct vmballoon *b = f->private;
+       struct vmballoon_stats *stats = &b->stats;
+
+       /* format size info */
+       seq_printf(f,
+                  "target:             %8d pages\n"
+                  "current:            %8d pages\n",
+                  b->target, b->size);
+
+       /* format rate info */
+       seq_printf(f,
+                  "rateNoSleepAlloc:   %8d pages/sec\n"
+                  "rateSleepAlloc:     %8d pages/sec\n"
+                  "rateFree:           %8d pages/sec\n",
+                  VMW_BALLOON_NOSLEEP_ALLOC_MAX,
+                  b->rate_alloc, b->rate_free);
+
+       seq_printf(f,
+                  "\n"
+                  "timer:              %8u\n"
+                  "start:              %8u (%4u failed)\n"
+                  "guestType:          %8u (%4u failed)\n"
+                  "lock:               %8u (%4u failed)\n"
+                  "unlock:             %8u (%4u failed)\n"
+                  "target:             %8u (%4u failed)\n"
+                  "primNoSleepAlloc:   %8u (%4u failed)\n"
+                  "primCanSleepAlloc:  %8u (%4u failed)\n"
+                  "primFree:           %8u\n"
+                  "errAlloc:           %8u\n"
+                  "errFree:            %8u\n",
+                  stats->timer,
+                  stats->start, stats->start_fail,
+                  stats->guest_type, stats->guest_type_fail,
+                  stats->lock,  stats->lock_fail,
+                  stats->unlock, stats->unlock_fail,
+                  stats->target, stats->target_fail,
+                  stats->alloc, stats->alloc_fail,
+                  stats->sleep_alloc, stats->sleep_alloc_fail,
+                  stats->free,
+                  stats->refused_alloc, stats->refused_free);
+
+       return 0;
+}
+
+static int vmballoon_debug_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, vmballoon_debug_show, inode->i_private);
+}
+
+static const struct file_operations vmballoon_debug_fops = {
+       .owner          = THIS_MODULE,
+       .open           = vmballoon_debug_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init vmballoon_debugfs_init(struct vmballoon *b)
+{
+       int error;
+
+       b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
+                                          &vmballoon_debug_fops);
+       if (IS_ERR(b->dbg_entry)) {
+               error = PTR_ERR(b->dbg_entry);
+               pr_err("failed to create debugfs entry, error: %d\n", error);
+               return error;
+       }
+
+       return 0;
+}
+
+static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
+{
+       debugfs_remove(b->dbg_entry);
+}
+
+#else
+
+static inline int vmballoon_debugfs_init(struct vmballoon *b)
+{
+       return 0;
+}
+
+static inline void vmballoon_debugfs_exit(struct vmballoon *b)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __init vmballoon_init(void)
+{
+       int error;
+
+       /*
+        * Check if we are running on VMware's hypervisor and bail out
+        * if we are not.
+        */
+       if (x86_hyper != &x86_hyper_vmware)
+               return -ENODEV;
+
+       vmballoon_wq = create_freezeable_workqueue("vmmemctl");
+       if (!vmballoon_wq) {
+               pr_err("failed to create workqueue\n");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&balloon.pages);
+       INIT_LIST_HEAD(&balloon.refused_pages);
+
+       /* initialize rates */
+       balloon.rate_alloc = VMW_BALLOON_RATE_ALLOC_MAX;
+       balloon.rate_free = VMW_BALLOON_RATE_FREE_MAX;
+
+       INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work);
+
+       /*
+        * Start balloon.
+        */
+       if (!vmballoon_send_start(&balloon)) {
+               pr_err("failed to send start command to the host\n");
+               error = -EIO;
+               goto fail;
+       }
+
+       if (!vmballoon_send_guest_id(&balloon)) {
+               pr_err("failed to send guest ID to the host\n");
+               error = -EIO;
+               goto fail;
+       }
+
+       error = vmballoon_debugfs_init(&balloon);
+       if (error)
+               goto fail;
+
+       queue_delayed_work(vmballoon_wq, &balloon.dwork, 0);
+
+       return 0;
+
+fail:
+       destroy_workqueue(vmballoon_wq);
+       return error;
+}
+module_init(vmballoon_init);
+
+static void __exit vmballoon_exit(void)
+{
+       cancel_delayed_work_sync(&balloon.dwork);
+       destroy_workqueue(vmballoon_wq);
+
+       vmballoon_debugfs_exit(&balloon);
+
+       /*
+        * Deallocate all reserved memory, and reset connection with monitor.
+        * Reset connection before deallocating memory to avoid potential for
+        * additional spurious resets from guest touching deallocated pages.
+        */
+       vmballoon_send_start(&balloon);
+       vmballoon_pop(&balloon);
+}
+module_exit(vmballoon_exit);
index a6dd7da..336d9f5 100644 (file)
@@ -314,8 +314,8 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
                        dmabuf = (unsigned *)tmpv;
                }
 
+               flush_kernel_dcache_page(sg_page(sg));
                kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
-               dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount);
                data->bytes_xfered += amount;
                if (size == 0)
                        break;
index 88be37d..fb279f4 100644 (file)
@@ -266,7 +266,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
                                "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
                                cmd->opcode, cmd->arg, cmd->flags,
                                cmd->resp[0], cmd->resp[1], cmd->resp[2],
-                               cmd->resp[2], cmd->error);
+                               cmd->resp[3], cmd->error);
                if (data)
                        seq_printf(s, "DATA %u / %u * %u flg %x err %d\n",
                                data->bytes_xfered, data->blocks,
@@ -276,7 +276,7 @@ static int atmci_req_show(struct seq_file *s, void *v)
                                "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n",
                                stop->opcode, stop->arg, stop->flags,
                                stop->resp[0], stop->resp[1], stop->resp[2],
-                               stop->resp[2], stop->error);
+                               stop->resp[3], stop->error);
        }
 
        spin_unlock_bh(&slot->host->lock);
@@ -569,9 +569,10 @@ static void atmci_dma_cleanup(struct atmel_mci *host)
 {
        struct mmc_data                 *data = host->data;
 
-       dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
-                    ((data->flags & MMC_DATA_WRITE)
-                     ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
+       if (data)
+               dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len,
+                            ((data->flags & MMC_DATA_WRITE)
+                             ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
 }
 
 static void atmci_stop_dma(struct atmel_mci *host)
@@ -1099,8 +1100,8 @@ static void atmci_command_complete(struct atmel_mci *host,
                        "command error: status=0x%08x\n", status);
 
                if (cmd->data) {
-                       host->data = NULL;
                        atmci_stop_dma(host);
+                       host->data = NULL;
                        mci_writel(host, IDR, MCI_NOTBUSY
                                        | MCI_TXRDY | MCI_RXRDY
                                        | ATMCI_DATA_ERROR_FLAGS);
@@ -1293,6 +1294,7 @@ static void atmci_tasklet_func(unsigned long priv)
                        } else {
                                data->bytes_xfered = data->blocks * data->blksz;
                                data->error = 0;
+                               mci_writel(host, IDR, ATMCI_DATA_ERROR_FLAGS);
                        }
 
                        if (!data->stop) {
@@ -1751,13 +1753,13 @@ static int __init atmci_probe(struct platform_device *pdev)
        ret = -ENODEV;
        if (pdata->slot[0].bus_width) {
                ret = atmci_init_slot(host, &pdata->slot[0],
-                               MCI_SDCSEL_SLOT_A, 0);
+                               0, MCI_SDCSEL_SLOT_A);
                if (!ret)
                        nr_slots++;
        }
        if (pdata->slot[1].bus_width) {
                ret = atmci_init_slot(host, &pdata->slot[1],
-                               MCI_SDCSEL_SLOT_B, 1);
+                               1, MCI_SDCSEL_SLOT_B);
                if (!ret)
                        nr_slots++;
        }
index 84c103a..ff115d9 100644 (file)
@@ -55,14 +55,16 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
                        host->cclk = host->mclk / (2 * (clk + 1));
                }
                if (host->hw_designer == AMBA_VENDOR_ST)
-                       clk |= MCI_FCEN; /* Bug fix in ST IP block */
+                       clk |= MCI_ST_FCEN; /* Bug fix in ST IP block */
                clk |= MCI_CLK_ENABLE;
                /* This hasn't proven to be worthwhile */
                /* clk |= MCI_CLK_PWRSAVE; */
        }
 
        if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
-               clk |= MCI_WIDE_BUS;
+               clk |= MCI_4BIT_BUS;
+       if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
+               clk |= MCI_ST_8BIT_BUS;
 
        writel(clk, host->base + MMCICLOCK);
 }
@@ -629,7 +631,18 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 
        mmc->ops = &mmci_ops;
        mmc->f_min = (host->mclk + 511) / 512;
-       mmc->f_max = min(host->mclk, fmax);
+       /*
+        * If the platform data supplies a maximum operating
+        * frequency, this takes precedence. Else, we fall back
+        * to using the module parameter, which has a (low)
+        * default value in case it is not specified. Either
+        * value must not exceed the clock rate into the block,
+        * of course.
+        */
+       if (plat->f_max)
+               mmc->f_max = min(host->mclk, plat->f_max);
+       else
+               mmc->f_max = min(host->mclk, fmax);
        dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 
 #ifdef CONFIG_REGULATOR
index 1ceb9a9..d77062e 100644 (file)
 #define MCI_CLK_ENABLE         (1 << 8)
 #define MCI_CLK_PWRSAVE                (1 << 9)
 #define MCI_CLK_BYPASS         (1 << 10)
-#define MCI_WIDE_BUS           (1 << 11)
+#define MCI_4BIT_BUS           (1 << 11)
+/* 8bit wide buses supported in ST Micro versions */
+#define MCI_ST_8BIT_BUS                (1 << 12)
 /* HW flow control on the ST Micro version */
-#define MCI_FCEN               (1 << 13)
+#define MCI_ST_FCEN            (1 << 13)
 
 #define MMCIARGUMENT           0x008
 #define MMCICOMMAND            0x00c
index 0ed4895..e4f00e7 100644 (file)
@@ -544,7 +544,7 @@ static irqreturn_t pxamci_detect_irq(int irq, void *devid)
 {
        struct pxamci_host *host = mmc_priv(devid);
 
-       mmc_detect_change(devid, host->pdata->detect_delay);
+       mmc_detect_change(devid, msecs_to_jiffies(host->pdata->detect_delay_ms));
        return IRQ_HANDLED;
 }
 
index 82d1e4d..4521b1e 100644 (file)
@@ -4,7 +4,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)              += mtd.o
-mtd-y                          := mtdcore.o mtdsuper.o mtdbdi.o
+mtd-y                          := mtdcore.o mtdsuper.o
 mtd-$(CONFIG_MTD_PARTITIONS)   += mtdpart.o
 
 obj-$(CONFIG_MTD_CONCAT)       += mtdconcat.o
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h
deleted file mode 100644 (file)
index c658fe7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Internal MTD definitions
- *
- * Copyright Â© 2006 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-/*
- * mtdbdi.c
- */
-extern struct backing_dev_info mtd_bdi_unmappable;
-extern struct backing_dev_info mtd_bdi_ro_mappable;
-extern struct backing_dev_info mtd_bdi_rw_mappable;
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
deleted file mode 100644 (file)
index 5ca5aed..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* MTD backing device capabilities
- *
- * Copyright Â© 2006 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/backing-dev.h>
-#include <linux/mtd/mtd.h>
-#include "internal.h"
-
-/*
- * backing device capabilities for non-mappable devices (such as NAND flash)
- * - permits private mappings, copies are taken of the data
- */
-struct backing_dev_info mtd_bdi_unmappable = {
-       .capabilities   = BDI_CAP_MAP_COPY,
-};
-
-/*
- * backing device capabilities for R/O mappable devices (such as ROM)
- * - permits private mappings, copies are taken of the data
- * - permits non-writable shared mappings
- */
-struct backing_dev_info mtd_bdi_ro_mappable = {
-       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
-                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
-};
-
-/*
- * backing device capabilities for writable mappable devices (such as RAM)
- * - permits private mappings, copies are taken of the data
- * - permits non-writable shared mappings
- */
-struct backing_dev_info mtd_bdi_rw_mappable = {
-       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
-                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
-                          BDI_CAP_WRITE_MAP),
-};
index 5b38b17..b177e75 100644 (file)
@@ -2,6 +2,9 @@
  * Core registration and callback routines for MTD
  * drivers and users.
  *
+ * bdi bits are:
+ * Copyright Â© 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
  */
 
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/mtd/compatmac.h>
 #include <linux/proc_fs.h>
+#include <linux/backing-dev.h>
 
 #include <linux/mtd/mtd.h>
-#include "internal.h"
 
 #include "mtdcore.h"
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+       .capabilities   = BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+       .capabilities   = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+                          BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+                          BDI_CAP_WRITE_MAP),
+};
 
 static int mtd_cls_suspend(struct device *dev, pm_message_t state);
 static int mtd_cls_resume(struct device *dev);
@@ -628,20 +659,55 @@ done:
 /*====================================================================*/
 /* Init code */
 
+static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
+{
+       int ret;
+
+       ret = bdi_init(bdi);
+       if (!ret)
+               ret = bdi_register(bdi, NULL, name);
+
+       if (ret)
+               bdi_destroy(bdi);
+
+       return ret;
+}
+
 static int __init init_mtd(void)
 {
        int ret;
+
        ret = class_register(&mtd_class);
+       if (ret)
+               goto err_reg;
+
+       ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap");
+       if (ret)
+               goto err_bdi1;
+
+       ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap");
+       if (ret)
+               goto err_bdi2;
+
+       ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap");
+       if (ret)
+               goto err_bdi3;
 
-       if (ret) {
-               pr_err("Error registering mtd class: %d\n", ret);
-               return ret;
-       }
 #ifdef CONFIG_PROC_FS
        if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
                proc_mtd->read_proc = mtd_read_proc;
 #endif /* CONFIG_PROC_FS */
        return 0;
+
+err_bdi3:
+       bdi_destroy(&mtd_bdi_ro_mappable);
+err_bdi2:
+       bdi_destroy(&mtd_bdi_unmappable);
+err_bdi1:
+       class_unregister(&mtd_class);
+err_reg:
+       pr_err("Error registering mtd class or bdi: %d\n", ret);
+       return ret;
 }
 
 static void __exit cleanup_mtd(void)
@@ -651,6 +717,9 @@ static void __exit cleanup_mtd(void)
                remove_proc_entry( "mtd", NULL);
 #endif /* CONFIG_PROC_FS */
        class_unregister(&mtd_class);
+       bdi_destroy(&mtd_bdi_unmappable);
+       bdi_destroy(&mtd_bdi_ro_mappable);
+       bdi_destroy(&mtd_bdi_rw_mappable);
 }
 
 module_init(init_mtd);
index af8b42e..7c00319 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/mtd/super.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
+#include <linux/slab.h>
 
 /*
  * compare superblocks to see if they're equivalent
@@ -44,6 +45,7 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
 
        sb->s_mtd = mtd;
        sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+       sb->s_bdi = mtd->backing_dev_info;
        return 0;
 }
 
index f59c074..d60fc57 100644 (file)
@@ -60,7 +60,13 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
        }
        buf64 = (uint64_t *)buf;
        while (i < len/8) {
-               uint64_t x;
+               /*
+                * Since GCC has no proper constraint (PR 43518)
+                * force x variable to r2/r3 registers as ldrd instruction
+                * requires first register to be even.
+                */
+               register uint64_t x asm ("r2");
+
                asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
                buf64[i++] = x;
        }
index a03d291..f0d23de 100644 (file)
@@ -1944,7 +1944,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                netif_dbg(tp, rx_status, dev, "%s() status %04x, size %04x, cur %04x\n",
                          __func__, rx_status, rx_size, cur_rx);
 #if RTL8139_DEBUG > 2
-               print_dump_hex(KERN_DEBUG, "Frame contents: ",
+               print_hex_dump(KERN_DEBUG, "Frame contents: ",
                               DUMP_PREFIX_OFFSET, 16, 1,
                               &rx_ring[ring_offset], 70, true);
 #endif
index a583b50..12b280a 100644 (file)
@@ -273,6 +273,7 @@ obj-$(CONFIG_USB_RTL8150)       += usb/
 obj-$(CONFIG_USB_HSO)          += usb/
 obj-$(CONFIG_USB_USBNET)        += usb/
 obj-$(CONFIG_USB_ZD1201)        += usb/
+obj-$(CONFIG_USB_IPHETH)        += usb/
 
 obj-y += wireless/
 obj-$(CONFIG_NET_TULIP) += tulip/
index ed5e974..a8f0512 100644 (file)
@@ -674,6 +674,7 @@ static struct zorro_device_id a2065_zorro_tbl[] __devinitdata = {
        { ZORRO_PROD_AMERISTAR_A2065 },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, a2065_zorro_tbl);
 
 static struct zorro_driver a2065_driver = {
        .name           = "a2065",
index fa1a235..4b30a46 100644 (file)
@@ -145,6 +145,7 @@ static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = {
     { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE },
     { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl);
 
 static struct zorro_driver ariadne_driver = {
     .name      = "ariadne",
index 6995169..cd17d09 100644 (file)
@@ -311,11 +311,6 @@ err:
                processed++;
        }
 
-       if (processed) {
-               wrw(ep, REG_RXDENQ, processed);
-               wrw(ep, REG_RXSTSENQ, processed);
-       }
-
        return processed;
 }
 
@@ -350,6 +345,11 @@ poll_some_more:
                        goto poll_some_more;
        }
 
+       if (rx) {
+               wrw(ep, REG_RXDENQ, rx);
+               wrw(ep, REG_RXSTSENQ, rx);
+       }
+
        return rx;
 }
 
index a257bab..ac90a38 100644 (file)
@@ -58,8 +58,8 @@
 #include "bnx2_fw.h"
 
 #define DRV_MODULE_NAME                "bnx2"
-#define DRV_MODULE_VERSION     "2.0.8"
-#define DRV_MODULE_RELDATE     "Feb 15, 2010"
+#define DRV_MODULE_VERSION     "2.0.9"
+#define DRV_MODULE_RELDATE     "April 27, 2010"
 #define FW_MIPS_FILE_06                "bnx2/bnx2-mips-06-5.0.0.j6.fw"
 #define FW_RV2P_FILE_06                "bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
 #define FW_MIPS_FILE_09                "bnx2/bnx2-mips-09-5.0.0.j9.fw"
@@ -651,9 +651,10 @@ bnx2_napi_enable(struct bnx2 *bp)
 }
 
 static void
-bnx2_netif_stop(struct bnx2 *bp)
+bnx2_netif_stop(struct bnx2 *bp, bool stop_cnic)
 {
-       bnx2_cnic_stop(bp);
+       if (stop_cnic)
+               bnx2_cnic_stop(bp);
        if (netif_running(bp->dev)) {
                int i;
 
@@ -671,14 +672,15 @@ bnx2_netif_stop(struct bnx2 *bp)
 }
 
 static void
-bnx2_netif_start(struct bnx2 *bp)
+bnx2_netif_start(struct bnx2 *bp, bool start_cnic)
 {
        if (atomic_dec_and_test(&bp->intr_sem)) {
                if (netif_running(bp->dev)) {
                        netif_tx_wake_all_queues(bp->dev);
                        bnx2_napi_enable(bp);
                        bnx2_enable_int(bp);
-                       bnx2_cnic_start(bp);
+                       if (start_cnic)
+                               bnx2_cnic_start(bp);
                }
        }
 }
@@ -4759,8 +4761,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                rc = bnx2_alloc_bad_rbuf(bp);
        }
 
-       if (bp->flags & BNX2_FLAG_USING_MSIX)
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
                bnx2_setup_msix_tbl(bp);
+               /* Prevent MSIX table reads and write from timing out */
+               REG_WR(bp, BNX2_MISC_ECO_HW_CTL,
+                       BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
+       }
 
        return rc;
 }
@@ -6273,12 +6279,12 @@ bnx2_reset_task(struct work_struct *work)
                return;
        }
 
-       bnx2_netif_stop(bp);
+       bnx2_netif_stop(bp, true);
 
        bnx2_init_nic(bp, 1);
 
        atomic_set(&bp->intr_sem, 1);
-       bnx2_netif_start(bp);
+       bnx2_netif_start(bp, true);
        rtnl_unlock();
 }
 
@@ -6320,7 +6326,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
        struct bnx2 *bp = netdev_priv(dev);
 
        if (netif_running(dev))
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, false);
 
        bp->vlgrp = vlgrp;
 
@@ -6331,7 +6337,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
        if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
                bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
 
-       bnx2_netif_start(bp);
+       bnx2_netif_start(bp, false);
 }
 #endif
 
@@ -7051,9 +7057,9 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
        bp->stats_ticks &= BNX2_HC_STATS_TICKS_HC_STAT_TICKS;
 
        if (netif_running(bp->dev)) {
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                bnx2_init_nic(bp, 0);
-               bnx2_netif_start(bp);
+               bnx2_netif_start(bp, true);
        }
 
        return 0;
@@ -7083,7 +7089,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
                /* Reset will erase chipset stats; save them */
                bnx2_save_stats(bp);
 
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
                bnx2_free_skbs(bp);
                bnx2_free_mem(bp);
@@ -7111,7 +7117,7 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
                        bnx2_setup_cnic_irq_info(bp);
                mutex_unlock(&bp->cnic_lock);
 #endif
-               bnx2_netif_start(bp);
+               bnx2_netif_start(bp, true);
        }
        return 0;
 }
@@ -7364,7 +7370,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
        if (etest->flags & ETH_TEST_FL_OFFLINE) {
                int i;
 
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG);
                bnx2_free_skbs(bp);
 
@@ -7383,7 +7389,7 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
                        bnx2_shutdown_chip(bp);
                else {
                        bnx2_init_nic(bp, 1);
-                       bnx2_netif_start(bp);
+                       bnx2_netif_start(bp, true);
                }
 
                /* wait for link up */
@@ -8377,7 +8383,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
                return 0;
 
        flush_scheduled_work();
-       bnx2_netif_stop(bp);
+       bnx2_netif_stop(bp, true);
        netif_device_detach(dev);
        del_timer_sync(&bp->timer);
        bnx2_shutdown_chip(bp);
@@ -8399,7 +8405,7 @@ bnx2_resume(struct pci_dev *pdev)
        bnx2_set_power_state(bp, PCI_D0);
        netif_device_attach(dev);
        bnx2_init_nic(bp, 1);
-       bnx2_netif_start(bp);
+       bnx2_netif_start(bp, true);
        return 0;
 }
 
@@ -8426,7 +8432,7 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
        }
 
        if (netif_running(dev)) {
-               bnx2_netif_stop(bp);
+               bnx2_netif_stop(bp, true);
                del_timer_sync(&bp->timer);
                bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
        }
@@ -8483,7 +8489,7 @@ static void bnx2_io_resume(struct pci_dev *pdev)
 
        rtnl_lock();
        if (netif_running(dev))
-               bnx2_netif_start(bp);
+               bnx2_netif_start(bp, true);
 
        netif_device_attach(dev);
        rtnl_unlock();
index 3345109..d800b59 100644 (file)
@@ -1006,7 +1006,7 @@ static int ems_usb_probe(struct usb_interface *intf,
 
        netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS);
        if (!netdev) {
-               dev_err(netdev->dev.parent, "Couldn't alloc candev\n");
+               dev_err(&intf->dev, "ems_usb: Couldn't alloc candev\n");
                return -ENOMEM;
        }
 
@@ -1036,20 +1036,20 @@ static int ems_usb_probe(struct usb_interface *intf,
 
        dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!dev->intr_urb) {
-               dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n");
+               dev_err(&intf->dev, "Couldn't alloc intr URB\n");
                goto cleanup_candev;
        }
 
        dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL);
        if (!dev->intr_in_buffer) {
-               dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n");
+               dev_err(&intf->dev, "Couldn't alloc Intr buffer\n");
                goto cleanup_intr_urb;
        }
 
        dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE +
                                     sizeof(struct ems_cpc_msg), GFP_KERNEL);
        if (!dev->tx_msg_buffer) {
-               dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n");
+               dev_err(&intf->dev, "Couldn't alloc Tx buffer\n");
                goto cleanup_intr_in_buffer;
        }
 
index 9781942..4b451a7 100644 (file)
@@ -2334,13 +2334,13 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
        struct cnic_local *cp = dev->cnic_priv;
        u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
 
-       prefetch(cp->status_blk.bnx2x);
-       prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+       if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+               prefetch(cp->status_blk.bnx2x);
+               prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
 
-       if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
                tasklet_schedule(&cp->cnic_irq_task);
-
-       cnic_chk_pkt_rings(cp);
+               cnic_chk_pkt_rings(cp);
+       }
 
        return 0;
 }
index 5248f9e..35cd367 100644 (file)
@@ -934,7 +934,7 @@ static struct cphy_ops xaui_direct_ops = {
 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
                            int phy_addr, const struct mdio_ops *mdio_ops)
 {
-       cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
+       cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
                  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
                  "10GBASE-CX4");
        return 0;
index aced6c5..e3f1b85 100644 (file)
@@ -439,7 +439,7 @@ static void free_irq_resources(struct adapter *adapter)
 static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
                              unsigned long n)
 {
-       int attempts = 5;
+       int attempts = 10;
 
        while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
                if (!--attempts)
index b997e57..7910803 100644 (file)
 #include <linux/ethtool.h>
 #include <linux/string.h>
 #include <linux/firmware.h>
+#include <linux/rtnetlink.h>
 #include <asm/unaligned.h>
 
 
@@ -2265,8 +2266,13 @@ static void e100_tx_timeout_task(struct work_struct *work)
 
        DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
                ioread8(&nic->csr->scb.status));
-       e100_down(netdev_priv(netdev));
-       e100_up(netdev_priv(netdev));
+
+       rtnl_lock();
+       if (netif_running(netdev)) {
+               e100_down(netdev_priv(netdev));
+               e100_up(netdev_priv(netdev));
+       }
+       rtnl_unlock();
 }
 
 static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
index 712ccc6..9015555 100644 (file)
@@ -336,7 +336,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        static int global_quad_port_a; /* global port a indication */
        struct pci_dev *pdev = adapter->pdev;
-       u16 eeprom_data = 0;
        int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1;
        s32 rc;
 
@@ -387,16 +386,15 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
                if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
                        adapter->flags &= ~FLAG_HAS_WOL;
                break;
-
        case e1000_82573:
+       case e1000_82574:
+       case e1000_82583:
+               /* Disable ASPM L0s due to hardware errata */
+               e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
+
                if (pdev->device == E1000_DEV_ID_82573L) {
-                       if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
-                                      &eeprom_data) < 0)
-                               break;
-                       if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
-                               adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
-                               adapter->max_hw_frame_size = DEFAULT_JUMBO;
-                       }
+                       adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
+                       adapter->max_hw_frame_size = DEFAULT_JUMBO;
                }
                break;
        default:
@@ -1792,6 +1790,7 @@ struct e1000_info e1000_82571_info = {
                                  | FLAG_RESET_OVERWRITES_LAA /* errata */
                                  | FLAG_TARC_SPEED_MODE_BIT /* errata */
                                  | FLAG_APME_CHECK_PORT_B,
+       .flags2                 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
        .pba                    = 38,
        .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
@@ -1809,6 +1808,7 @@ struct e1000_info e1000_82572_info = {
                                  | FLAG_RX_CSUM_ENABLED
                                  | FLAG_HAS_CTRLEXT_ON_LOAD
                                  | FLAG_TARC_SPEED_MODE_BIT, /* errata */
+       .flags2                 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */
        .pba                    = 38,
        .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
@@ -1820,13 +1820,11 @@ struct e1000_info e1000_82572_info = {
 struct e1000_info e1000_82573_info = {
        .mac                    = e1000_82573,
        .flags                  = FLAG_HAS_HW_VLAN_FILTER
-                                 | FLAG_HAS_JUMBO_FRAMES
                                  | FLAG_HAS_WOL
                                  | FLAG_APME_IN_CTRL3
                                  | FLAG_RX_CSUM_ENABLED
                                  | FLAG_HAS_SMART_POWER_DOWN
                                  | FLAG_HAS_AMT
-                                 | FLAG_HAS_ERT
                                  | FLAG_HAS_SWSM_ON_LOAD,
        .pba                    = 20,
        .max_hw_frame_size      = ETH_FRAME_LEN + ETH_FCS_LEN,
index 118bdf4..ee32b9b 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/io.h>
 #include <linux/netdevice.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 
 #include "hw.h"
 
@@ -374,7 +375,7 @@ struct e1000_adapter {
 struct e1000_info {
        enum e1000_mac_type     mac;
        unsigned int            flags;
-       unsigned int            flags2;
+       unsigned int            flags2;
        u32                     pba;
        u32                     max_hw_frame_size;
        s32                     (*get_variants)(struct e1000_adapter *);
@@ -421,6 +422,7 @@ struct e1000_info {
 #define FLAG2_CRC_STRIPPING               (1 << 0)
 #define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
 #define FLAG2_IS_DISCARDING               (1 << 2)
+#define FLAG2_DISABLE_ASPM_L1             (1 << 3)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -461,6 +463,7 @@ extern void e1000e_update_stats(struct e1000_adapter *adapter);
 extern bool e1000e_has_link(struct e1000_adapter *adapter);
 extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
 extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
+extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
 
 extern unsigned int copybreak;
 
index cfd09ce..dbf8178 100644 (file)
@@ -661,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
                                i = 0;
                }
 
+               if (i == tx_ring->next_to_use)
+                       break;
                eop = tx_ring->buffer_info[i].next_to_watch;
                eop_desc = E1000_TX_DESC(*tx_ring, eop);
        }
@@ -4281,6 +4283,14 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
                return -EINVAL;
        }
 
+       /* 82573 Errata 17 */
+       if (((adapter->hw.mac.type == e1000_82573) ||
+            (adapter->hw.mac.type == e1000_82574)) &&
+           (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
+               adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
+               e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
+       }
+
        while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
                msleep(1);
        /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
@@ -4603,29 +4613,42 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
        }
 }
 
-static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+#ifdef CONFIG_PCIEASPM
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+       pci_disable_link_state(pdev, state);
+}
+#else
+static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
 {
        int pos;
-       u16 val;
+       u16 reg16;
 
        /*
-        * 82573 workaround - disable L1 ASPM on mobile chipsets
-        *
-        * L1 ASPM on various mobile (ich7) chipsets do not behave properly
-        * resulting in lost data or garbage information on the pci-e link
-        * level. This could result in (false) bad EEPROM checksum errors,
-        * long ping times (up to 2s) or even a system freeze/hang.
-        *
-        * Unfortunately this feature saves about 1W power consumption when
-        * active.
+        * Both device and parent should have the same ASPM setting.
+        * Disable ASPM in downstream component first and then upstream.
         */
-       pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-       pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
-       if (val & 0x2) {
-               dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
-               val &= ~0x2;
-               pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
-       }
+       pos = pci_pcie_cap(pdev);
+       pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+       reg16 &= ~state;
+       pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
+
+       if (!pdev->bus->self)
+               return;
+
+       pos = pci_pcie_cap(pdev->bus->self);
+       pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
+       reg16 &= ~state;
+       pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
+}
+#endif
+void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+{
+       dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
+                (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
+                (state & PCIE_LINK_STATE_L1) ? "L1" : "");
+
+       __e1000e_disable_aspm(pdev, state);
 }
 
 #ifdef CONFIG_PM
@@ -4651,7 +4674,8 @@ static int e1000_resume(struct pci_dev *pdev)
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
        pci_save_state(pdev);
-       e1000e_disable_l1aspm(pdev);
+       if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+               e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
        err = pci_enable_device_mem(pdev);
        if (err) {
@@ -4793,7 +4817,8 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        int err;
        pci_ers_result_t result;
 
-       e1000e_disable_l1aspm(pdev);
+       if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+               e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
        err = pci_enable_device_mem(pdev);
        if (err) {
                dev_err(&pdev->dev,
@@ -4887,13 +4912,6 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
                dev_warn(&adapter->pdev->dev,
                         "Warning: detected DSPD enabled in EEPROM\n");
        }
-
-       ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
-       if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
-               /* ASPM enable */
-               dev_warn(&adapter->pdev->dev,
-                        "Warning: detected ASPM enabled in EEPROM\n");
-       }
 }
 
 static const struct net_device_ops e1000e_netdev_ops = {
@@ -4942,7 +4960,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        u16 eeprom_data = 0;
        u16 eeprom_apme_mask = E1000_EEPROM_APME;
 
-       e1000e_disable_l1aspm(pdev);
+       if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
+               e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
        err = pci_enable_device_mem(pdev);
        if (err)
index 9f98c1c..9b4e8f7 100644 (file)
@@ -1653,7 +1653,7 @@ fec_set_mac_address(struct net_device *dev, void *p)
                (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
                fep->hwp + FEC_ADDR_LOW);
        writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
-               fep + FEC_ADDR_HIGH);
+               fep->hwp + FEC_ADDR_HIGH);
        return 0;
 }
 
index 73b260c..5c98f7c 100644 (file)
@@ -5899,7 +5899,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        /* Limit the number of tx's outstanding for hw bug */
        if (id->driver_data & DEV_NEED_TX_LIMIT) {
                np->tx_limit = 1;
-               if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
+               if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) &&
                    pci_dev->revision >= 0xA2)
                        np->tx_limit = 0;
        }
index d5160ed..3acac5f 100644 (file)
@@ -205,8 +205,6 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
 static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np)
 {
        struct gfar __iomem *enet_regs;
-       u32 __iomem *ioremap_tbipa;
-       u64 addr, size;
 
        /*
         * This is mildly evil, but so is our hardware for doing this.
@@ -220,9 +218,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi
                return &enet_regs->tbipa;
        } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") ||
                        of_device_is_compatible(np, "fsl,etsec2-tbi")) {
-               addr = of_translate_address(np, of_get_address(np, 1, &size, NULL));
-               ioremap_tbipa = ioremap(addr, size);
-               return ioremap_tbipa;
+               return of_iomap(np, 1);
        } else
                return NULL;
 }
@@ -279,6 +275,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
        u32 __iomem *tbipa;
        struct mii_bus *new_bus;
        int tbiaddr = -1;
+       const u32 *addrp;
        u64 addr = 0, size = 0;
        int err = 0;
 
@@ -297,8 +294,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
        new_bus->priv = priv;
        fsl_pq_mdio_bus_name(new_bus->id, np);
 
+       addrp = of_get_address(np, 0, &size, NULL);
+       if (!addrp) {
+               err = -EINVAL;
+               goto err_free_bus;
+       }
+
        /* Set the PHY base address */
-       addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
+       addr = of_translate_address(np, addrp);
+       if (addr == OF_BAD_ADDR) {
+               err = -EINVAL;
+               goto err_free_bus;
+       }
+
        map = ioremap(addr, size);
        if (!map) {
                err = -ENOMEM;
index 080d1ce..5d3763f 100644 (file)
@@ -549,12 +549,8 @@ static int gfar_parse_group(struct device_node *np,
                struct gfar_private *priv, const char *model)
 {
        u32 *queue_mask;
-       u64 addr, size;
-
-       addr = of_translate_address(np,
-                       of_get_address(np, 0, &size, NULL));
-       priv->gfargrp[priv->num_grps].regs = ioremap(addr, size);
 
+       priv->gfargrp[priv->num_grps].regs = of_iomap(np, 0);
        if (!priv->gfargrp[priv->num_grps].regs)
                return -ENOMEM;
 
@@ -1515,9 +1511,9 @@ static void gfar_halt_nodisable(struct net_device *dev)
                tempval |= (DMACTRL_GRS | DMACTRL_GTS);
                gfar_write(&regs->dmactrl, tempval);
 
-               while (!(gfar_read(&regs->ievent) &
-                        (IEVENT_GRSC | IEVENT_GTSC)))
-                       cpu_relax();
+               spin_event_timeout(((gfar_read(&regs->ievent) &
+                        (IEVENT_GRSC | IEVENT_GTSC)) ==
+                        (IEVENT_GRSC | IEVENT_GTSC)), -1, 0);
        }
 }
 
@@ -1653,6 +1649,7 @@ static void free_skb_resources(struct gfar_private *priv)
                        sizeof(struct rxbd8) * priv->total_rx_ring_size,
                        priv->tx_queue[0]->tx_bd_base,
                        priv->tx_queue[0]->tx_bd_dma_base);
+       skb_queue_purge(&priv->rx_recycle);
 }
 
 void gfar_start(struct net_device *dev)
@@ -2092,7 +2089,6 @@ static int gfar_close(struct net_device *dev)
 
        disable_napi(priv);
 
-       skb_queue_purge(&priv->rx_recycle);
        cancel_work_sync(&priv->reset_task);
        stop_gfar(dev);
 
index 24724b4..07d8e5b 100644 (file)
@@ -71,6 +71,7 @@ static struct zorro_device_id hydra_zorro_tbl[] __devinitdata = {
     { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
     { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl);
 
 static struct zorro_driver hydra_driver = {
     .name      = "hydra",
index d313fae..7430384 100644 (file)
@@ -1814,6 +1814,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
                retval = 0;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* quad port adapters only support WoL on port A */
                if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
                        wol->supported = 0;
index 9b3c51a..c9baa2a 100644 (file)
@@ -1612,6 +1612,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                        adapter->eeprom_wol = 0;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* if quad port adapter, disable WoL on all but port A */
                if (global_quad_port_a != 0)
                        adapter->eeprom_wol = 0;
index b405a00..12fc0e7 100644 (file)
@@ -39,6 +39,8 @@
 #define IXGBE_82599_MC_TBL_SIZE   128
 #define IXGBE_82599_VFT_TBL_SIZE  128
 
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
@@ -69,8 +71,14 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
        if (hw->phy.multispeed_fiber) {
                /* Set up dual speed SFP+ support */
                mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+               mac->ops.disable_tx_laser =
+                                      &ixgbe_disable_tx_laser_multispeed_fiber;
+               mac->ops.enable_tx_laser =
+                                       &ixgbe_enable_tx_laser_multispeed_fiber;
                mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
        } else {
+               mac->ops.disable_tx_laser = NULL;
+               mac->ops.enable_tx_laser = NULL;
                mac->ops.flap_tx_laser = NULL;
                if ((mac->ops.get_media_type(hw) ==
                     ixgbe_media_type_backplane) &&
@@ -415,6 +423,44 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
        return status;
 }
 
+ /**
+  *  ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
+  *  @hw: pointer to hardware structure
+  *
+  *  The base drivers may require better control over SFP+ module
+  *  PHY states.  This includes selectively shutting down the Tx
+  *  laser on the PHY, effectively halting physical link.
+  **/
+void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+       u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+       /* Disable tx laser; allow 100us to go dark per spec */
+       esdp_reg |= IXGBE_ESDP_SDP3;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(100);
+}
+
+/**
+ *  ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
+ *  @hw: pointer to hardware structure
+ *
+ *  The base drivers may require better control over SFP+ module
+ *  PHY states.  This includes selectively turning on the Tx
+ *  laser on the PHY, effectively starting physical link.
+ **/
+void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
+{
+       u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+       /* Enable tx laser; allow 100ms to light up */
+       esdp_reg &= ~IXGBE_ESDP_SDP3;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+       IXGBE_WRITE_FLUSH(hw);
+       msleep(100);
+}
+
 /**
  *  ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
  *  @hw: pointer to hardware structure
@@ -429,23 +475,11 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
  **/
 void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 {
-       u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
-
        hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
 
        if (hw->mac.autotry_restart) {
-               /* Disable tx laser; allow 100us to go dark per spec */
-               esdp_reg |= IXGBE_ESDP_SDP3;
-               IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-               IXGBE_WRITE_FLUSH(hw);
-               udelay(100);
-
-               /* Enable tx laser; allow 100ms to light up */
-               esdp_reg &= ~IXGBE_ESDP_SDP3;
-               IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-               IXGBE_WRITE_FLUSH(hw);
-               msleep(100);
-
+               ixgbe_disable_tx_laser_multispeed_fiber(hw);
+               ixgbe_enable_tx_laser_multispeed_fiber(hw);
                hw->mac.autotry_restart = false;
        }
 }
index 8f677cb..6c00ee4 100644 (file)
@@ -2982,6 +2982,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
        else
                ixgbe_configure_msi_and_legacy(adapter);
 
+       /* enable the optics */
+       if (hw->phy.multispeed_fiber)
+               hw->mac.ops.enable_tx_laser(hw);
+
        clear_bit(__IXGBE_DOWN, &adapter->state);
        ixgbe_napi_enable_all(adapter);
 
@@ -3243,6 +3247,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        /* signal that we are down to the interrupt handler */
        set_bit(__IXGBE_DOWN, &adapter->state);
 
+       /* power down the optics */
+       if (hw->phy.multispeed_fiber)
+               hw->mac.ops.disable_tx_laser(hw);
+
        /* disable receive for all VFs and wait one second */
        if (adapter->num_vfs) {
                /* ping all the active vfs to let them know we are going down */
@@ -6253,6 +6261,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                goto err_eeprom;
        }
 
+       /* power down the optics */
+       if (hw->phy.multispeed_fiber)
+               hw->mac.ops.disable_tx_laser(hw);
+
        init_timer(&adapter->watchdog_timer);
        adapter->watchdog_timer.function = &ixgbe_watchdog;
        adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -6400,16 +6412,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
        del_timer_sync(&adapter->sfp_timer);
        cancel_work_sync(&adapter->watchdog_task);
        cancel_work_sync(&adapter->sfp_task);
-       if (adapter->hw.phy.multispeed_fiber) {
-               struct ixgbe_hw *hw = &adapter->hw;
-               /*
-                * Restart clause 37 autoneg, disable and re-enable
-                * the tx laser, to clear & alert the link partner
-                * that it needs to restart autotry
-                */
-               hw->mac.autotry_restart = true;
-               hw->mac.ops.flap_tx_laser(hw);
-       }
        cancel_work_sync(&adapter->multispeed_fiber_task);
        cancel_work_sync(&adapter->sfp_config_module_task);
        if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
index 4ec6dc1..534affc 100644 (file)
@@ -2398,6 +2398,8 @@ struct ixgbe_mac_operations {
        s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
 
        /* Link */
+       void (*disable_tx_laser)(struct ixgbe_hw *);
+       void (*enable_tx_laser)(struct ixgbe_hw *);
        void (*flap_tx_laser)(struct ixgbe_hw *);
        s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
        s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
index 13cc1ca..9e9f9b3 100644 (file)
@@ -722,12 +722,14 @@ static void ks8851_tx_work(struct work_struct *work)
                txb = skb_dequeue(&ks->txq);
                last = skb_queue_empty(&ks->txq);
 
-               ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
-               ks8851_wrpkt(ks, txb, last);
-               ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
-               ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
+               if (txb != NULL) {
+                       ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA);
+                       ks8851_wrpkt(ks, txb, last);
+                       ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
+                       ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
 
-               ks8851_done_tx(ks, txb);
+                       ks8851_done_tx(ks, txb);
+               }
        }
 
        mutex_unlock(&ks->lock);
index 4718877..ecde087 100644 (file)
@@ -1690,7 +1690,7 @@ myri10ge_set_pauseparam(struct net_device *netdev,
        if (pause->tx_pause != mgp->pause)
                return myri10ge_change_pause(mgp, pause->tx_pause);
        if (pause->rx_pause != mgp->pause)
-               return myri10ge_change_pause(mgp, pause->tx_pause);
+               return myri10ge_change_pause(mgp, pause->rx_pause);
        if (pause->autoneg != 0)
                return -EINVAL;
        return 0;
index 3d1d3a7..757f87b 100644 (file)
@@ -781,8 +781,13 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
                  inw(ioaddr + EL3_STATUS));
 
        spin_lock_irqsave(&lp->window_lock, flags);
+
+       dev->stats.tx_bytes += skb->len;
+
+       /* Put out the doubleword header... */
        outw(skb->len, ioaddr + TX_FIFO);
        outw(0, ioaddr + TX_FIFO);
+       /* ... and the packet rounded to a doubleword. */
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
 
        dev->trans_start = jiffies;
@@ -1021,8 +1026,6 @@ static void update_stats(struct net_device *dev)
        /* BadSSD */                               inb(ioaddr + 12);
        up                                       = inb(ioaddr + 13);
 
-       dev->stats.tx_bytes                     += tx + ((up & 0xf0) << 12);
-
        EL3WINDOW(1);
 }
 
index ff7eb91..ccc5537 100644 (file)
@@ -1608,9 +1608,12 @@ static void set_rx_mode(struct net_device *dev)
 {
     unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
-    u_int multicast_table[ 2 ] = { 0, };
+    unsigned char multicast_table[8];
     unsigned long flags;
     u_short rx_cfg_setting;
+    int i;
+
+    memset(multicast_table, 0, sizeof(multicast_table));
 
     if (dev->flags & IFF_PROMISC) {
        rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
@@ -1622,10 +1625,6 @@ static void set_rx_mode(struct net_device *dev)
 
            netdev_for_each_mc_addr(mc_addr, dev) {
                u_int position = ether_crc(6, mc_addr->dmi_addr);
-#ifndef final_version          /* Verify multicast address. */
-               if ((mc_addr->dmi_addr[0] & 1) == 0)
-                   continue;
-#endif
                multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
            }
        }
@@ -1635,8 +1634,8 @@ static void set_rx_mode(struct net_device *dev)
     /* Load MC table and Rx setting into the chip without interrupts. */
     spin_lock_irqsave(&smc->lock, flags);
     SMC_SELECT_BANK(3);
-    outl(multicast_table[0], ioaddr + MULTICAST0);
-    outl(multicast_table[1], ioaddr + MULTICAST4);
+    for (i = 0; i < 8; i++)
+       outb(multicast_table[i], ioaddr + MULTICAST0 + i);
     SMC_SELECT_BANK(0);
     outw(rx_cfg_setting, ioaddr + RCR);
     SMC_SELECT_BANK(2);
@@ -1805,23 +1804,30 @@ static void media_check(u_long arg)
     SMC_SELECT_BANK(1);
     media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1;
 
+    SMC_SELECT_BANK(saved_bank);
+    spin_unlock_irqrestore(&smc->lock, flags);
+
     /* Check for pending interrupt with watchdog flag set: with
        this, we can limp along even if the interrupt is blocked */
     if (smc->watchdog++ && ((i>>8) & i)) {
        if (!smc->fast_poll)
            printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+       local_irq_save(flags);
        smc_interrupt(dev->irq, dev);
+       local_irq_restore(flags);
        smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
        smc->fast_poll--;
        smc->media.expires = jiffies + HZ/100;
        add_timer(&smc->media);
-       SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irqrestore(&smc->lock, flags);
        return;
     }
 
+    spin_lock_irqsave(&smc->lock, flags);
+
+    saved_bank = inw(ioaddr + BANK_SELECT);
+
     if (smc->cfg & CFG_MII_SELECT) {
        if (smc->mii_if.phy_id < 0)
            goto reschedule;
@@ -1979,15 +1985,16 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        if (smc->cfg & CFG_MII_SELECT)
                ret = mii_ethtool_gset(&smc->mii_if, ecmd);
        else
                ret = smc_netdev_get_ecmd(dev, ecmd);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -1997,15 +2004,16 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        int ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        if (smc->cfg & CFG_MII_SELECT)
                ret = mii_ethtool_sset(&smc->mii_if, ecmd);
        else
                ret = smc_netdev_set_ecmd(dev, ecmd);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -2015,12 +2023,13 @@ static u32 smc_get_link(struct net_device *dev)
        unsigned int ioaddr = dev->base_addr;
        u16 saved_bank = inw(ioaddr + BANK_SELECT);
        u32 ret;
+       unsigned long flags;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        SMC_SELECT_BANK(3);
        ret = smc_link_ok(dev);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return ret;
 }
 
@@ -2057,16 +2066,17 @@ static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
        int rc = 0;
        u16 saved_bank;
        unsigned int ioaddr = dev->base_addr;
+       unsigned long flags;
 
        if (!netif_running(dev))
                return -EINVAL;
 
-       spin_lock_irq(&smc->lock);
+       spin_lock_irqsave(&smc->lock, flags);
        saved_bank = inw(ioaddr + BANK_SELECT);
        SMC_SELECT_BANK(3);
        rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL);
        SMC_SELECT_BANK(saved_bank);
-       spin_unlock_irq(&smc->lock);
+       spin_unlock_irqrestore(&smc->lock, flags);
        return rc;
 }
 
index fc5938b..a527e37 100644 (file)
@@ -88,6 +88,11 @@ config LSI_ET1011C_PHY
        ---help---
          Supports the LSI ET1011C PHY.
 
+config MICREL_PHY
+       tristate "Driver for Micrel PHYs"
+       ---help---
+         Supports the KSZ9021, VSC8201, KS8001 PHYs.
+
 config FIXED_PHY
        bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
        depends on PHYLIB=y
index 1342585..13bebab 100644 (file)
@@ -20,4 +20,5 @@ obj-$(CONFIG_MDIO_BITBANG)    += mdio-bitbang.o
 obj-$(CONFIG_MDIO_GPIO)                += mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)     += national.o
 obj-$(CONFIG_STE10XP)          += ste10Xp.o
+obj-$(CONFIG_MICREL_PHY)       += micrel.o
 obj-$(CONFIG_MDIO_OCTEON)      += mdio-octeon.o
index a872aea..f443d43 100644 (file)
@@ -88,6 +88,7 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
 static int __init octeon_mdiobus_probe(struct platform_device *pdev)
 {
        struct octeon_mdiobus *bus;
+       union cvmx_smix_en smi_en;
        int i;
        int err = -ENOENT;
 
@@ -103,6 +104,10 @@ static int __init octeon_mdiobus_probe(struct platform_device *pdev)
        if (!bus->mii_bus)
                goto err;
 
+       smi_en.u64 = 0;
+       smi_en.s.en = 1;
+       cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+
        /*
         * Standard Octeon evaluation boards don't support phy
         * interrupts, we need to poll.
@@ -133,17 +138,22 @@ err_register:
 
 err:
        devm_kfree(&pdev->dev, bus);
+       smi_en.u64 = 0;
+       cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
        return err;
 }
 
 static int __exit octeon_mdiobus_remove(struct platform_device *pdev)
 {
        struct octeon_mdiobus *bus;
+       union cvmx_smix_en smi_en;
 
        bus = dev_get_drvdata(&pdev->dev);
 
        mdiobus_unregister(bus->mii_bus);
        mdiobus_free(bus->mii_bus);
+       smi_en.u64 = 0;
+       cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
        return 0;
 }
 
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
new file mode 100644 (file)
index 0000000..e67691d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * drivers/net/phy/micrel.c
+ *
+ * Driver for Micrel PHYs
+ *
+ * Author: David J. Choi
+ *
+ * Copyright (c) 2010 Micrel, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Support : ksz9021 , vsc8201, ks8001
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define        PHY_ID_KSZ9021                  0x00221611
+#define        PHY_ID_VSC8201                  0x000FC413
+#define        PHY_ID_KS8001                   0x0022161A
+
+
+static int kszphy_config_init(struct phy_device *phydev)
+{
+       return 0;
+}
+
+
+static struct phy_driver ks8001_driver = {
+       .phy_id         = PHY_ID_KS8001,
+       .name           = "Micrel KS8001",
+       .phy_id_mask    = 0x00fffff0,
+       .features       = PHY_BASIC_FEATURES,
+       .flags          = PHY_POLL,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver vsc8201_driver = {
+       .phy_id         = PHY_ID_VSC8201,
+       .name           = "Micrel VSC8201",
+       .phy_id_mask    = 0x00fffff0,
+       .features       = PHY_BASIC_FEATURES,
+       .flags          = PHY_POLL,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver ksz9021_driver = {
+       .phy_id         = PHY_ID_KSZ9021,
+       .phy_id_mask    = 0x000fff10,
+       .name           = "Micrel KSZ9021 Gigabit PHY",
+       .features       = PHY_GBIT_FEATURES | SUPPORTED_Pause,
+       .flags          = PHY_POLL,
+       .config_init    = kszphy_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .driver         = { .owner = THIS_MODULE, },
+};
+
+static int __init ksphy_init(void)
+{
+       int ret;
+
+       ret = phy_driver_register(&ks8001_driver);
+       if (ret)
+               goto err1;
+       ret = phy_driver_register(&vsc8201_driver);
+       if (ret)
+               goto err2;
+
+       ret = phy_driver_register(&ksz9021_driver);
+       if (ret)
+               goto err3;
+       return 0;
+
+err3:
+       phy_driver_unregister(&vsc8201_driver);
+err2:
+       phy_driver_unregister(&ks8001_driver);
+err1:
+       return ret;
+}
+
+static void __exit ksphy_exit(void)
+{
+       phy_driver_unregister(&ks8001_driver);
+       phy_driver_unregister(&vsc8201_driver);
+       phy_driver_unregister(&ksz9021_driver);
+}
+
+module_init(ksphy_init);
+module_exit(ksphy_exit);
+
+MODULE_DESCRIPTION("Micrel PHY driver");
+MODULE_AUTHOR("David J. Choi");
+MODULE_LICENSE("GPL");
index 6e281bc..8518a2e 100644 (file)
@@ -405,6 +405,7 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        DECLARE_WAITQUEUE(wait, current);
        ssize_t ret;
        struct sk_buff *skb = NULL;
+       struct iovec iov;
 
        ret = count;
 
@@ -448,7 +449,9 @@ static ssize_t ppp_read(struct file *file, char __user *buf,
        if (skb->len > count)
                goto outf;
        ret = -EFAULT;
-       if (copy_to_user(buf, skb->data, skb->len))
+       iov.iov_base = buf;
+       iov.iov_len = count;
+       if (skb_copy_datagram_iovec(skb, 0, &iov, skb->len))
                goto outf;
        ret = skb->len;
 
@@ -1567,13 +1570,22 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        struct channel *pch = chan->ppp;
        int proto;
 
-       if (!pch || skb->len == 0) {
+       if (!pch) {
                kfree_skb(skb);
                return;
        }
 
-       proto = PPP_PROTO(skb);
        read_lock_bh(&pch->upl);
+       if (!pskb_may_pull(skb, 2)) {
+               kfree_skb(skb);
+               if (pch->ppp) {
+                       ++pch->ppp->dev->stats.rx_length_errors;
+                       ppp_receive_error(pch->ppp);
+               }
+               goto done;
+       }
+
+       proto = PPP_PROTO(skb);
        if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) {
                /* put it on the channel queue */
                skb_queue_tail(&pch->file.rq, skb);
@@ -1585,6 +1597,8 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
        } else {
                ppp_do_recv(pch->ppp, skb, pch);
        }
+
+done:
        read_unlock_bh(&pch->upl);
 }
 
@@ -1617,7 +1631,8 @@ ppp_input_error(struct ppp_channel *chan, int code)
 static void
 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
-       if (pskb_may_pull(skb, 2)) {
+       /* note: a 0-length skb is used as an error indication */
+       if (skb->len > 0) {
 #ifdef CONFIG_PPP_MULTILINK
                /* XXX do channel-level decompression here */
                if (PPP_PROTO(skb) == PPP_MP)
@@ -1625,15 +1640,10 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
                else
 #endif /* CONFIG_PPP_MULTILINK */
                        ppp_receive_nonmp_frame(ppp, skb);
-               return;
+       } else {
+               kfree_skb(skb);
+               ppp_receive_error(ppp);
        }
-
-       if (skb->len > 0)
-               /* note: a 0-length skb is used as an error indication */
-               ++ppp->dev->stats.rx_length_errors;
-
-       kfree_skb(skb);
-       ppp_receive_error(ppp);
 }
 
 static void
index a6ef266..e73ba45 100644 (file)
@@ -431,6 +431,9 @@ void qlcnic_set_multi(struct net_device *netdev)
        u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        u32 mode = VPORT_MISS_MODE_DROP;
 
+       if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+               return;
+
        qlcnic_nic_add_mac(adapter, adapter->mac_addr);
        qlcnic_nic_add_mac(adapter, bcast_addr);
 
index 43afdb6..0298d8c 100644 (file)
 #define RX_DESC_SIZE   (RX_DCNT * sizeof(struct r6040_descriptor))
 #define TX_DESC_SIZE   (TX_DCNT * sizeof(struct r6040_descriptor))
 #define MBCR_DEFAULT   0x012A  /* MAC Bus Control Register */
-#define MCAST_MAX      4       /* Max number multicast addresses to filter */
+#define MCAST_MAX      3       /* Max number multicast addresses to filter */
 
 /* Descriptor status */
 #define DSC_OWNER_MAC  0x8000  /* MAC is the owner of this descriptor */
@@ -982,9 +982,6 @@ static void r6040_multicast_list(struct net_device *dev)
                        crc >>= 26;
                        hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
                }
-               /* Write the index of the hash table */
-               for (i = 0; i < 4; i++)
-                       iowrite16(hash_table[i] << 14, ioaddr + MCR1);
                /* Fill the MAC hash tables with their values */
                iowrite16(hash_table[0], ioaddr + MAR0);
                iowrite16(hash_table[1], ioaddr + MAR1);
@@ -1000,9 +997,9 @@ static void r6040_multicast_list(struct net_device *dev)
                        iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
                        iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
                } else {
-                       iowrite16(0xffff, ioaddr + MID_0L + 8 * i);
-                       iowrite16(0xffff, ioaddr + MID_0M + 8 * i);
-                       iowrite16(0xffff, ioaddr + MID_0H + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
                }
                i++;
        }
index dbb1f5a..dd8106f 100644 (file)
@@ -1042,14 +1042,14 @@ static void rtl8169_vlan_rx_register(struct net_device *dev,
 }
 
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
-                              struct sk_buff *skb)
+                              struct sk_buff *skb, int polling)
 {
        u32 opts2 = le32_to_cpu(desc->opts2);
        struct vlan_group *vlgrp = tp->vlgrp;
        int ret;
 
        if (vlgrp && (opts2 & RxVlanTag)) {
-               vlan_hwaccel_receive_skb(skb, vlgrp, swab16(opts2 & 0xffff));
+               __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling);
                ret = 0;
        } else
                ret = -1;
@@ -1066,7 +1066,7 @@ static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
 }
 
 static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
-                              struct sk_buff *skb)
+                              struct sk_buff *skb, int polling)
 {
        return -1;
 }
@@ -2759,6 +2759,7 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
 {
        iounmap(ioaddr);
        pci_release_regions(pdev);
+       pci_clear_mwi(pdev);
        pci_disable_device(pdev);
        free_netdev(dev);
 }
@@ -2825,8 +2826,13 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
        spin_lock_irq(&tp->lock);
 
        RTL_W8(Cfg9346, Cfg9346_Unlock);
+
        RTL_W32(MAC4, high);
+       RTL_R32(MAC4);
+
        RTL_W32(MAC0, low);
+       RTL_R32(MAC0);
+
        RTL_W8(Cfg9346, Cfg9346_Lock);
 
        spin_unlock_irq(&tp->lock);
@@ -3014,9 +3020,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_free_dev_1;
        }
 
-       rc = pci_set_mwi(pdev);
-       if (rc < 0)
-               goto err_out_disable_2;
+       if (pci_set_mwi(pdev) < 0)
+               netif_info(tp, probe, dev, "Mem-Wr-Inval unavailable\n");
 
        /* make sure PCI base addr 1 is MMIO */
        if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
@@ -3024,7 +3029,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                          "region #%d not an MMIO resource, aborting\n",
                          region);
                rc = -ENODEV;
-               goto err_out_mwi_3;
+               goto err_out_mwi_2;
        }
 
        /* check for weird/broken PCI region reporting */
@@ -3032,13 +3037,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                netif_err(tp, probe, dev,
                          "Invalid PCI region size(s), aborting\n");
                rc = -ENODEV;
-               goto err_out_mwi_3;
+               goto err_out_mwi_2;
        }
 
        rc = pci_request_regions(pdev, MODULENAME);
        if (rc < 0) {
                netif_err(tp, probe, dev, "could not request regions\n");
-               goto err_out_mwi_3;
+               goto err_out_mwi_2;
        }
 
        tp->cp_cmd = PCIMulRW | RxChkSum;
@@ -3051,7 +3056,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc < 0) {
                        netif_err(tp, probe, dev, "DMA configuration failed\n");
-                       goto err_out_free_res_4;
+                       goto err_out_free_res_3;
                }
        }
 
@@ -3060,7 +3065,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!ioaddr) {
                netif_err(tp, probe, dev, "cannot remap MMIO, aborting\n");
                rc = -EIO;
-               goto err_out_free_res_4;
+               goto err_out_free_res_3;
        }
 
        tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
@@ -3102,7 +3107,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (i == ARRAY_SIZE(rtl_chip_info)) {
                dev_err(&pdev->dev,
                        "driver bug, MAC version not found in rtl_chip_info\n");
-               goto err_out_msi_5;
+               goto err_out_msi_4;
        }
        tp->chipset = i;
 
@@ -3167,7 +3172,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        rc = register_netdev(dev);
        if (rc < 0)
-               goto err_out_msi_5;
+               goto err_out_msi_4;
 
        pci_set_drvdata(pdev, dev);
 
@@ -3190,14 +3195,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 out:
        return rc;
 
-err_out_msi_5:
+err_out_msi_4:
        rtl_disable_msi(pdev, tp);
        iounmap(ioaddr);
-err_out_free_res_4:
+err_out_free_res_3:
        pci_release_regions(pdev);
-err_out_mwi_3:
+err_out_mwi_2:
        pci_clear_mwi(pdev);
-err_out_disable_2:
        pci_disable_device(pdev);
 err_out_free_dev_1:
        free_netdev(dev);
@@ -4441,12 +4445,20 @@ out:
        return done;
 }
 
+/*
+ * Warning : rtl8169_rx_interrupt() might be called :
+ * 1) from NAPI (softirq) context
+ *     (polling = 1 : we should call netif_receive_skb())
+ * 2) from process context (rtl8169_reset_task())
+ *     (polling = 0 : we must call netif_rx() instead)
+ */
 static int rtl8169_rx_interrupt(struct net_device *dev,
                                struct rtl8169_private *tp,
                                void __iomem *ioaddr, u32 budget)
 {
        unsigned int cur_rx, rx_left;
        unsigned int delta, count;
+       int polling = (budget != ~(u32)0) ? 1 : 0;
 
        cur_rx = tp->cur_rx;
        rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
@@ -4508,8 +4520,12 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                        skb_put(skb, pkt_size);
                        skb->protocol = eth_type_trans(skb, dev);
 
-                       if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
-                               netif_receive_skb(skb);
+                       if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) {
+                               if (likely(polling))
+                                       netif_receive_skb(skb);
+                               else
+                                       netif_rx(skb);
+                       }
 
                        dev->stats.rx_bytes += pkt_size;
                        dev->stats.rx_packets++;
index 9944e5d..04efc0c 100644 (file)
@@ -2353,17 +2353,36 @@ static int sbmac_init(struct platform_device *pldev, long long base)
 
        sc->mii_bus = mdiobus_alloc();
        if (sc->mii_bus == NULL) {
-               sbmac_uninitctx(sc);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto uninit_ctx;
        }
 
+       sc->mii_bus->name = sbmac_mdio_string;
+       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+       sc->mii_bus->priv = sc;
+       sc->mii_bus->read = sbmac_mii_read;
+       sc->mii_bus->write = sbmac_mii_write;
+       sc->mii_bus->irq = sc->phy_irq;
+       for (i = 0; i < PHY_MAX_ADDR; ++i)
+               sc->mii_bus->irq[i] = SBMAC_PHY_INT;
+
+       sc->mii_bus->parent = &pldev->dev;
+       /*
+        * Probe PHY address
+        */
+       err = mdiobus_register(sc->mii_bus);
+       if (err) {
+               printk(KERN_ERR "%s: unable to register MDIO bus\n",
+                      dev->name);
+               goto free_mdio;
+       }
+       dev_set_drvdata(&pldev->dev, sc->mii_bus);
+
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR "%s.%d: unable to register netdev\n",
                       sbmac_string, idx);
-               mdiobus_free(sc->mii_bus);
-               sbmac_uninitctx(sc);
-               return err;
+               goto unreg_mdio;
        }
 
        pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name);
@@ -2379,19 +2398,15 @@ static int sbmac_init(struct platform_device *pldev, long long base)
        pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n",
               dev->name, base, eaddr);
 
-       sc->mii_bus->name = sbmac_mdio_string;
-       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
-       sc->mii_bus->priv = sc;
-       sc->mii_bus->read = sbmac_mii_read;
-       sc->mii_bus->write = sbmac_mii_write;
-       sc->mii_bus->irq = sc->phy_irq;
-       for (i = 0; i < PHY_MAX_ADDR; ++i)
-               sc->mii_bus->irq[i] = SBMAC_PHY_INT;
-
-       sc->mii_bus->parent = &pldev->dev;
-       dev_set_drvdata(&pldev->dev, sc->mii_bus);
-
        return 0;
+unreg_mdio:
+       mdiobus_unregister(sc->mii_bus);
+       dev_set_drvdata(&pldev->dev, NULL);
+free_mdio:
+       mdiobus_free(sc->mii_bus);
+uninit_ctx:
+       sbmac_uninitctx(sc);
+       return err;
 }
 
 
@@ -2417,16 +2432,6 @@ static int sbmac_open(struct net_device *dev)
                goto out_err;
        }
 
-       /*
-        * Probe PHY address
-        */
-       err = mdiobus_register(sc->mii_bus);
-       if (err) {
-               printk(KERN_ERR "%s: unable to register MDIO bus\n",
-                      dev->name);
-               goto out_unirq;
-       }
-
        sc->sbm_speed = sbmac_speed_none;
        sc->sbm_duplex = sbmac_duplex_none;
        sc->sbm_fc = sbmac_fc_none;
@@ -2457,11 +2462,7 @@ static int sbmac_open(struct net_device *dev)
        return 0;
 
 out_unregister:
-       mdiobus_unregister(sc->mii_bus);
-
-out_unirq:
        free_irq(dev->irq, dev);
-
 out_err:
        return err;
 }
@@ -2650,9 +2651,6 @@ static int sbmac_close(struct net_device *dev)
 
        phy_disconnect(sc->phy_dev);
        sc->phy_dev = NULL;
-
-       mdiobus_unregister(sc->mii_bus);
-
        free_irq(dev->irq, dev);
 
        sbdma_emptyring(&(sc->sbm_txdma));
@@ -2760,6 +2758,7 @@ static int __exit sbmac_remove(struct platform_device *pldev)
 
        unregister_netdev(dev);
        sbmac_uninitctx(sc);
+       mdiobus_unregister(sc->mii_bus);
        mdiobus_free(sc->mii_bus);
        iounmap(sc->sbm_base);
        free_netdev(dev);
index 6486657..649a264 100644 (file)
@@ -1861,6 +1861,7 @@ out:
        }
 
        if (disabled) {
+               dev_close(efx->net_dev);
                EFX_ERR(efx, "has been disabled\n");
                efx->state = STATE_DISABLED;
        } else {
@@ -1884,8 +1885,7 @@ static void efx_reset_work(struct work_struct *data)
        }
 
        rtnl_lock();
-       if (efx_reset(efx, efx->reset_pending))
-               dev_close(efx->net_dev);
+       (void)efx_reset(efx, efx->reset_pending);
        rtnl_unlock();
 }
 
index d294d66..08278e7 100644 (file)
@@ -1320,7 +1320,9 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
 
        EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
 
-       falcon_probe_board(efx, board_rev);
+       rc = falcon_probe_board(efx, board_rev);
+       if (rc)
+               goto fail2;
 
        kfree(nvconfig);
        return 0;
index 5712fdd..c7a933a 100644 (file)
@@ -728,15 +728,7 @@ static const struct falcon_board_type board_types[] = {
        },
 };
 
-static const struct falcon_board_type falcon_dummy_board = {
-       .init           = efx_port_dummy_op_int,
-       .init_phy       = efx_port_dummy_op_void,
-       .fini           = efx_port_dummy_op_void,
-       .set_id_led     = efx_port_dummy_op_set_id_led,
-       .monitor        = efx_port_dummy_op_int,
-};
-
-void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
+int falcon_probe_board(struct efx_nic *efx, u16 revision_info)
 {
        struct falcon_board *board = falcon_board(efx);
        u8 type_id = FALCON_BOARD_TYPE(revision_info);
@@ -754,8 +746,9 @@ void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
                         (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
                         ? board->type->ref_model : board->type->gen_type,
                         'A' + board->major, board->minor);
+               return 0;
        } else {
                EFX_ERR(efx, "unknown board type %d\n", type_id);
-               board->type = &falcon_dummy_board;
+               return -ENODEV;
        }
 }
index 9351c03..3166baf 100644 (file)
@@ -156,7 +156,7 @@ extern struct efx_nic_type siena_a0_nic_type;
  **************************************************************************
  */
 
-extern void falcon_probe_board(struct efx_nic *efx, u16 revision_info);
+extern int falcon_probe_board(struct efx_nic *efx, u16 revision_info);
 
 /* TX data path */
 extern int efx_nic_probe_tx(struct efx_tx_queue *tx_queue);
index 38dcc42..e0c46f5 100644 (file)
@@ -456,8 +456,17 @@ static int siena_try_update_nic_stats(struct efx_nic *efx)
 
 static void siena_update_nic_stats(struct efx_nic *efx)
 {
-       while (siena_try_update_nic_stats(efx) == -EAGAIN)
-               cpu_relax();
+       int retry;
+
+       /* If we're unlucky enough to read statistics wduring the DMA, wait
+        * up to 10ms for it to finish (typically takes <500us) */
+       for (retry = 0; retry < 100; ++retry) {
+               if (siena_try_update_nic_stats(efx) == 0)
+                       return;
+               udelay(100);
+       }
+
+       /* Use the old values instead */
 }
 
 static void siena_start_nic_stats(struct efx_nic *efx)
index a214a16..4111a85 100644 (file)
@@ -1686,7 +1686,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
        }
        pr_info("done!\n");
 
-       if (!request_mem_region(res->start, (res->end - res->start),
+       if (!request_mem_region(res->start, resource_size(res),
                                pdev->name)) {
                pr_err("%s: ERROR: memory allocation failed"
                       "cannot get the I/O addr 0x%x\n",
@@ -1695,9 +1695,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
                goto out;
        }
 
-       addr = ioremap(res->start, (res->end - res->start));
+       addr = ioremap(res->start, resource_size(res));
        if (!addr) {
-               pr_err("%s: ERROR: memory mapping failed \n", __func__);
+               pr_err("%s: ERROR: memory mapping failed\n", __func__);
                ret = -ENOMEM;
                goto out;
        }
@@ -1775,7 +1775,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
 out:
        if (ret < 0) {
                platform_set_drvdata(pdev, NULL);
-               release_mem_region(res->start, (res->end - res->start));
+               release_mem_region(res->start, resource_size(res));
                if (addr != NULL)
                        iounmap(addr);
        }
@@ -1813,7 +1813,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
 
        iounmap((void *)ndev->base_addr);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, (res->end - res->start));
+       release_mem_region(res->start, resource_size(res));
 
        free_netdev(ndev);
 
index 22cf1c4..ecc41cf 100644 (file)
@@ -8633,6 +8633,7 @@ static int tg3_test_msi(struct tg3 *tp)
        pci_disable_msi(tp->pdev);
 
        tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+       tp->napi[0].irq_vec = tp->pdev->irq;
 
        err = tg3_request_irq(tp, 0);
        if (err)
index 96c39bd..4326520 100644 (file)
@@ -387,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
+       /* Orphan the skb - required as we might hang on to it
+        * for indefinite time. */
+       skb_orphan(skb);
+
        /* Enqueue packet */
        skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
        dev->trans_start = jiffies;
index ba56ce4..d7b7018 100644 (file)
@@ -385,4 +385,25 @@ config USB_CDC_PHONET
          cellular modem, as found on most Nokia handsets with the
          "PC suite" USB profile.
 
+config USB_IPHETH
+       tristate "Apple iPhone USB Ethernet driver"
+       default n
+       ---help---
+         Module used to share Internet connection (tethering) from your
+         iPhone (Original, 3G and 3GS) to your system.
+         Note that you need userspace libraries and programs that are needed
+         to pair your device with your system and that understand the iPhone
+         protocol.
+
+         For more information: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+
+config USB_SIERRA_NET
+       tristate "USB-to-WWAN Driver for Sierra Wireless modems"
+       depends on USB_USBNET
+       help
+         Choose this option if you have a Sierra Wireless USB-to-WWAN device.
+
+         To compile this driver as a module, choose M here: the
+         module will be called sierra_net.
+
 endmenu
index 82ea629..b13a279 100644 (file)
@@ -23,4 +23,6 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
 obj-$(CONFIG_USB_USBNET)       += usbnet.o
 obj-$(CONFIG_USB_NET_INT51X1)  += int51x1.o
 obj-$(CONFIG_USB_CDC_PHONET)   += cdc-phonet.o
+obj-$(CONFIG_USB_IPHETH)       += ipheth.o
+obj-$(CONFIG_USB_SIERRA_NET)   += sierra_net.o
 
index c8cdb7f..3547cf1 100644 (file)
@@ -431,6 +431,7 @@ static const struct driver_info mbm_info = {
        .bind =         cdc_bind,
        .unbind =       usbnet_cdc_unbind,
        .status =       cdc_status,
+       .manage_power = cdc_manage_power,
 };
 
 /*-------------------------------------------------------------------------*/
index 04b2810..5dfed92 100644 (file)
@@ -240,7 +240,7 @@ static int dm_write_shared_word(struct usbnet *dev, int phy, u8 reg, __le16 valu
                goto out;
 
        dm_write_reg(dev, DM_SHARED_ADDR, phy ? (reg | 0x40) : reg);
-       dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1c : 0x14);
+       dm_write_reg(dev, DM_SHARED_CTRL, phy ? 0x1a : 0x12);
 
        for (i = 0; i < DM_TIMEOUT; i++) {
                u8 tmp;
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c
new file mode 100644 (file)
index 0000000..418825d
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ * ipheth.c - Apple iPhone USB Ethernet driver
+ *
+ * Copyright (c) 2009 Diego Giagio <diego@giagio.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of GIAGIO.COM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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.
+ *
+ *
+ * Attention: iPhone device must be paired, otherwise it won't respond to our
+ * driver. For more info: http://giagio.com/wiki/moin.cgi/iPhoneEthernetDriver
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/usb.h>
+#include <linux/workqueue.h>
+
+#define USB_VENDOR_APPLE        0x05ac
+#define USB_PRODUCT_IPHONE      0x1290
+#define USB_PRODUCT_IPHONE_3G   0x1292
+#define USB_PRODUCT_IPHONE_3GS  0x1294
+
+#define IPHETH_USBINTF_CLASS    255
+#define IPHETH_USBINTF_SUBCLASS 253
+#define IPHETH_USBINTF_PROTO    1
+
+#define IPHETH_BUF_SIZE         1516
+#define IPHETH_TX_TIMEOUT       (5 * HZ)
+
+#define IPHETH_INTFNUM          2
+#define IPHETH_ALT_INTFNUM      1
+
+#define IPHETH_CTRL_ENDP        0x00
+#define IPHETH_CTRL_BUF_SIZE    0x40
+#define IPHETH_CTRL_TIMEOUT     (5 * HZ)
+
+#define IPHETH_CMD_GET_MACADDR   0x00
+#define IPHETH_CMD_CARRIER_CHECK 0x45
+
+#define IPHETH_CARRIER_CHECK_TIMEOUT round_jiffies_relative(1 * HZ)
+#define IPHETH_CARRIER_ON       0x04
+
+static struct usb_device_id ipheth_table[] = {
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3G,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
+       { USB_DEVICE_AND_INTERFACE_INFO(
+               USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS,
+               IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS,
+               IPHETH_USBINTF_PROTO) },
+       { }
+};
+MODULE_DEVICE_TABLE(usb, ipheth_table);
+
+struct ipheth_device {
+       struct usb_device *udev;
+       struct usb_interface *intf;
+       struct net_device *net;
+       struct sk_buff *tx_skb;
+       struct urb *tx_urb;
+       struct urb *rx_urb;
+       unsigned char *tx_buf;
+       unsigned char *rx_buf;
+       unsigned char *ctrl_buf;
+       u8 bulk_in;
+       u8 bulk_out;
+       struct delayed_work carrier_work;
+};
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags);
+
+static int ipheth_alloc_urbs(struct ipheth_device *iphone)
+{
+       struct urb *tx_urb = NULL;
+       struct urb *rx_urb = NULL;
+       u8 *tx_buf = NULL;
+       u8 *rx_buf = NULL;
+
+       tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (tx_urb == NULL)
+               goto error_nomem;
+
+       rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (rx_urb == NULL)
+               goto free_tx_urb;
+
+       tx_buf = usb_buffer_alloc(iphone->udev,
+                                 IPHETH_BUF_SIZE,
+                                 GFP_KERNEL,
+                                 &tx_urb->transfer_dma);
+       if (tx_buf == NULL)
+               goto free_rx_urb;
+
+       rx_buf = usb_buffer_alloc(iphone->udev,
+                                 IPHETH_BUF_SIZE,
+                                 GFP_KERNEL,
+                                 &rx_urb->transfer_dma);
+       if (rx_buf == NULL)
+               goto free_tx_buf;
+
+
+       iphone->tx_urb = tx_urb;
+       iphone->rx_urb = rx_urb;
+       iphone->tx_buf = tx_buf;
+       iphone->rx_buf = rx_buf;
+       return 0;
+
+free_tx_buf:
+       usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, tx_buf,
+                       tx_urb->transfer_dma);
+free_rx_urb:
+       usb_free_urb(rx_urb);
+free_tx_urb:
+       usb_free_urb(tx_urb);
+error_nomem:
+       return -ENOMEM;
+}
+
+static void ipheth_free_urbs(struct ipheth_device *iphone)
+{
+       usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf,
+                       iphone->rx_urb->transfer_dma);
+       usb_buffer_free(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf,
+                       iphone->tx_urb->transfer_dma);
+       usb_free_urb(iphone->rx_urb);
+       usb_free_urb(iphone->tx_urb);
+}
+
+static void ipheth_kill_urbs(struct ipheth_device *dev)
+{
+       usb_kill_urb(dev->tx_urb);
+       usb_kill_urb(dev->rx_urb);
+}
+
+static void ipheth_rcvbulk_callback(struct urb *urb)
+{
+       struct ipheth_device *dev;
+       struct sk_buff *skb;
+       int status;
+       char *buf;
+       int len;
+
+       dev = urb->context;
+       if (dev == NULL)
+               return;
+
+       status = urb->status;
+       switch (status) {
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ESHUTDOWN:
+               return;
+       case 0:
+               break;
+       default:
+               err("%s: urb status: %d", __func__, urb->status);
+               return;
+       }
+
+       len = urb->actual_length;
+       buf = urb->transfer_buffer;
+
+       skb = dev_alloc_skb(NET_IP_ALIGN + len);
+       if (!skb) {
+               err("%s: dev_alloc_skb: -ENOMEM", __func__);
+               dev->net->stats.rx_dropped++;
+               return;
+       }
+
+       skb_reserve(skb, NET_IP_ALIGN);
+       memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN);
+       skb->dev = dev->net;
+       skb->protocol = eth_type_trans(skb, dev->net);
+
+       dev->net->stats.rx_packets++;
+       dev->net->stats.rx_bytes += len;
+
+       netif_rx(skb);
+       ipheth_rx_submit(dev, GFP_ATOMIC);
+}
+
+static void ipheth_sndbulk_callback(struct urb *urb)
+{
+       struct ipheth_device *dev;
+
+       dev = urb->context;
+       if (dev == NULL)
+               return;
+
+       if (urb->status != 0 &&
+           urb->status != -ENOENT &&
+           urb->status != -ECONNRESET &&
+           urb->status != -ESHUTDOWN)
+               err("%s: urb status: %d", __func__, urb->status);
+
+       dev_kfree_skb_irq(dev->tx_skb);
+       netif_wake_queue(dev->net);
+}
+
+static int ipheth_carrier_set(struct ipheth_device *dev)
+{
+       struct usb_device *udev = dev->udev;
+       int retval;
+
+       retval = usb_control_msg(udev,
+                       usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+                       IPHETH_CMD_CARRIER_CHECK, /* request */
+                       0xc0, /* request type */
+                       0x00, /* value */
+                       0x02, /* index */
+                       dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
+                       IPHETH_CTRL_TIMEOUT);
+       if (retval < 0) {
+               err("%s: usb_control_msg: %d", __func__, retval);
+               return retval;
+       }
+
+       if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON)
+               netif_carrier_on(dev->net);
+       else
+               netif_carrier_off(dev->net);
+
+       return 0;
+}
+
+static void ipheth_carrier_check_work(struct work_struct *work)
+{
+       struct ipheth_device *dev = container_of(work, struct ipheth_device,
+                                                carrier_work.work);
+
+       ipheth_carrier_set(dev);
+       schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+}
+
+static int ipheth_get_macaddr(struct ipheth_device *dev)
+{
+       struct usb_device *udev = dev->udev;
+       struct net_device *net = dev->net;
+       int retval;
+
+       retval = usb_control_msg(udev,
+                                usb_rcvctrlpipe(udev, IPHETH_CTRL_ENDP),
+                                IPHETH_CMD_GET_MACADDR, /* request */
+                                0xc0, /* request type */
+                                0x00, /* value */
+                                0x02, /* index */
+                                dev->ctrl_buf,
+                                IPHETH_CTRL_BUF_SIZE,
+                                IPHETH_CTRL_TIMEOUT);
+       if (retval < 0) {
+               err("%s: usb_control_msg: %d", __func__, retval);
+       } else if (retval < ETH_ALEN) {
+               err("%s: usb_control_msg: short packet: %d bytes",
+                       __func__, retval);
+               retval = -EINVAL;
+       } else {
+               memcpy(net->dev_addr, dev->ctrl_buf, ETH_ALEN);
+               retval = 0;
+       }
+
+       return retval;
+}
+
+static int ipheth_rx_submit(struct ipheth_device *dev, gfp_t mem_flags)
+{
+       struct usb_device *udev = dev->udev;
+       int retval;
+
+       usb_fill_bulk_urb(dev->rx_urb, udev,
+                         usb_rcvbulkpipe(udev, dev->bulk_in),
+                         dev->rx_buf, IPHETH_BUF_SIZE,
+                         ipheth_rcvbulk_callback,
+                         dev);
+       dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       retval = usb_submit_urb(dev->rx_urb, mem_flags);
+       if (retval)
+               err("%s: usb_submit_urb: %d", __func__, retval);
+       return retval;
+}
+
+static int ipheth_open(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       struct usb_device *udev = dev->udev;
+       int retval = 0;
+
+       usb_set_interface(udev, IPHETH_INTFNUM, IPHETH_ALT_INTFNUM);
+
+       retval = ipheth_carrier_set(dev);
+       if (retval)
+               return retval;
+
+       retval = ipheth_rx_submit(dev, GFP_KERNEL);
+       if (retval)
+               return retval;
+
+       schedule_delayed_work(&dev->carrier_work, IPHETH_CARRIER_CHECK_TIMEOUT);
+       netif_start_queue(net);
+       return retval;
+}
+
+static int ipheth_close(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+
+       cancel_delayed_work_sync(&dev->carrier_work);
+       netif_stop_queue(net);
+       return 0;
+}
+
+static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       struct usb_device *udev = dev->udev;
+       int retval;
+
+       /* Paranoid */
+       if (skb->len > IPHETH_BUF_SIZE) {
+               WARN(1, "%s: skb too large: %d bytes", __func__, skb->len);
+               dev->net->stats.tx_dropped++;
+               dev_kfree_skb_irq(skb);
+               return NETDEV_TX_OK;
+       }
+
+       memcpy(dev->tx_buf, skb->data, skb->len);
+       if (skb->len < IPHETH_BUF_SIZE)
+               memset(dev->tx_buf + skb->len, 0, IPHETH_BUF_SIZE - skb->len);
+
+       usb_fill_bulk_urb(dev->tx_urb, udev,
+                         usb_sndbulkpipe(udev, dev->bulk_out),
+                         dev->tx_buf, IPHETH_BUF_SIZE,
+                         ipheth_sndbulk_callback,
+                         dev);
+       dev->tx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       retval = usb_submit_urb(dev->tx_urb, GFP_ATOMIC);
+       if (retval) {
+               err("%s: usb_submit_urb: %d", __func__, retval);
+               dev->net->stats.tx_errors++;
+               dev_kfree_skb_irq(skb);
+       } else {
+               dev->tx_skb = skb;
+
+               dev->net->stats.tx_packets++;
+               dev->net->stats.tx_bytes += skb->len;
+               netif_stop_queue(net);
+       }
+
+       return NETDEV_TX_OK;
+}
+
+static void ipheth_tx_timeout(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+
+       err("%s: TX timeout", __func__);
+       dev->net->stats.tx_errors++;
+       usb_unlink_urb(dev->tx_urb);
+}
+
+static struct net_device_stats *ipheth_stats(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       return &dev->net->stats;
+}
+
+static u32 ipheth_ethtool_op_get_link(struct net_device *net)
+{
+       struct ipheth_device *dev = netdev_priv(net);
+       return netif_carrier_ok(dev->net);
+}
+
+static struct ethtool_ops ops = {
+       .get_link = ipheth_ethtool_op_get_link
+};
+
+static const struct net_device_ops ipheth_netdev_ops = {
+       .ndo_open = &ipheth_open,
+       .ndo_stop = &ipheth_close,
+       .ndo_start_xmit = &ipheth_tx,
+       .ndo_tx_timeout = &ipheth_tx_timeout,
+       .ndo_get_stats = &ipheth_stats,
+};
+
+static struct device_type ipheth_type = {
+       .name   = "wwan",
+};
+
+static int ipheth_probe(struct usb_interface *intf,
+                       const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_host_interface *hintf;
+       struct usb_endpoint_descriptor *endp;
+       struct ipheth_device *dev;
+       struct net_device *netdev;
+       int i;
+       int retval;
+
+       netdev = alloc_etherdev(sizeof(struct ipheth_device));
+       if (!netdev)
+               return -ENOMEM;
+
+       netdev->netdev_ops = &ipheth_netdev_ops;
+       netdev->watchdog_timeo = IPHETH_TX_TIMEOUT;
+       strcpy(netdev->name, "wwan%d");
+
+       dev = netdev_priv(netdev);
+       dev->udev = udev;
+       dev->net = netdev;
+       dev->intf = intf;
+
+       /* Set up endpoints */
+       hintf = usb_altnum_to_altsetting(intf, IPHETH_ALT_INTFNUM);
+       if (hintf == NULL) {
+               retval = -ENODEV;
+               err("Unable to find alternate settings interface");
+               goto err_endpoints;
+       }
+
+       for (i = 0; i < hintf->desc.bNumEndpoints; i++) {
+               endp = &hintf->endpoint[i].desc;
+               if (usb_endpoint_is_bulk_in(endp))
+                       dev->bulk_in = endp->bEndpointAddress;
+               else if (usb_endpoint_is_bulk_out(endp))
+                       dev->bulk_out = endp->bEndpointAddress;
+       }
+       if (!(dev->bulk_in && dev->bulk_out)) {
+               retval = -ENODEV;
+               err("Unable to find endpoints");
+               goto err_endpoints;
+       }
+
+       dev->ctrl_buf = kmalloc(IPHETH_CTRL_BUF_SIZE, GFP_KERNEL);
+       if (dev->ctrl_buf == NULL) {
+               retval = -ENOMEM;
+               goto err_alloc_ctrl_buf;
+       }
+
+       retval = ipheth_get_macaddr(dev);
+       if (retval)
+               goto err_get_macaddr;
+
+       INIT_DELAYED_WORK(&dev->carrier_work, ipheth_carrier_check_work);
+
+       retval = ipheth_alloc_urbs(dev);
+       if (retval) {
+               err("error allocating urbs: %d", retval);
+               goto err_alloc_urbs;
+       }
+
+       usb_set_intfdata(intf, dev);
+
+       SET_NETDEV_DEV(netdev, &intf->dev);
+       SET_ETHTOOL_OPS(netdev, &ops);
+       SET_NETDEV_DEVTYPE(netdev, &ipheth_type);
+
+       retval = register_netdev(netdev);
+       if (retval) {
+               err("error registering netdev: %d", retval);
+               retval = -EIO;
+               goto err_register_netdev;
+       }
+
+       dev_info(&intf->dev, "Apple iPhone USB Ethernet device attached\n");
+       return 0;
+
+err_register_netdev:
+       ipheth_free_urbs(dev);
+err_alloc_urbs:
+err_get_macaddr:
+err_alloc_ctrl_buf:
+       kfree(dev->ctrl_buf);
+err_endpoints:
+       free_netdev(netdev);
+       return retval;
+}
+
+static void ipheth_disconnect(struct usb_interface *intf)
+{
+       struct ipheth_device *dev;
+
+       dev = usb_get_intfdata(intf);
+       if (dev != NULL) {
+               unregister_netdev(dev->net);
+               ipheth_kill_urbs(dev);
+               ipheth_free_urbs(dev);
+               kfree(dev->ctrl_buf);
+               free_netdev(dev->net);
+       }
+       usb_set_intfdata(intf, NULL);
+       dev_info(&intf->dev, "Apple iPhone USB Ethernet now disconnected\n");
+}
+
+static struct usb_driver ipheth_driver = {
+       .name =         "ipheth",
+       .probe =        ipheth_probe,
+       .disconnect =   ipheth_disconnect,
+       .id_table =     ipheth_table,
+};
+
+static int __init ipheth_init(void)
+{
+       int retval;
+
+       retval = usb_register(&ipheth_driver);
+       if (retval) {
+               err("usb_register failed: %d", retval);
+               return retval;
+       }
+       return 0;
+}
+
+static void __exit ipheth_exit(void)
+{
+       usb_deregister(&ipheth_driver);
+}
+
+module_init(ipheth_init);
+module_exit(ipheth_exit);
+
+MODULE_AUTHOR("Diego Giagio <diego@giagio.com>");
+MODULE_DESCRIPTION("Apple iPhone USB Ethernet driver");
+MODULE_LICENSE("Dual BSD/GPL");
index 52671ea..c4c334d 100644 (file)
@@ -145,6 +145,7 @@ static struct usb_device_id usb_klsi_table[] = {
        { USB_DEVICE(0x0707, 0x0100) }, /* SMC 2202USB */
        { USB_DEVICE(0x07aa, 0x0001) }, /* Correga K.K. */
        { USB_DEVICE(0x07b8, 0x4000) }, /* D-Link DU-E10 */
+       { USB_DEVICE(0x07c9, 0xb010) }, /* Allied Telesyn AT-USB10 USB Ethernet Adapter */
        { USB_DEVICE(0x0846, 0x1001) }, /* NetGear EA-101 */
        { USB_DEVICE(0x0846, 0x1002) }, /* NetGear EA-101 */
        { USB_DEVICE(0x085a, 0x0008) }, /* PortGear Ethernet Adapter */
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
new file mode 100644 (file)
index 0000000..f1942d6
--- /dev/null
@@ -0,0 +1,1004 @@
+/*
+ * USB-to-WWAN Driver for Sierra Wireless modems
+ *
+ * Copyright (C) 2008, 2009, 2010 Paxton Smith, Matthew Safar, Rory Filer
+ *                          <linux@sierrawireless.com>
+ *
+ * Portions of this based on the cdc_ether driver by David Brownell (2003-2005)
+ * and Ole Andre Vadla Ravnas (ActiveSync) (2006).
+ *
+ * IMPORTANT DISCLAIMER: This driver is not commercially supported by
+ * Sierra Wireless. Use at your own risk.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define DRIVER_VERSION "v.2.0"
+#define DRIVER_AUTHOR "Paxton Smith, Matthew Safar, Rory Filer"
+#define DRIVER_DESC "USB-to-WWAN Driver for Sierra Wireless modems"
+static const char driver_name[] = "sierra_net";
+
+/* if defined debug messages enabled */
+/*#define      DEBUG*/
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <asm/unaligned.h>
+#include <linux/usb/usbnet.h>
+
+#define SWI_USB_REQUEST_GET_FW_ATTR    0x06
+#define SWI_GET_FW_ATTR_MASK           0x08
+
+/* atomic counter partially included in MAC address to make sure 2 devices
+ * do not end up with the same MAC - concept breaks in case of > 255 ifaces
+ */
+static atomic_t iface_counter = ATOMIC_INIT(0);
+
+/*
+ * SYNC Timer Delay definition used to set the expiry time
+ */
+#define SIERRA_NET_SYNCDELAY (2*HZ)
+
+/* Max. MTU supported. The modem buffers are limited to 1500 */
+#define SIERRA_NET_MAX_SUPPORTED_MTU   1500
+
+/* The SIERRA_NET_USBCTL_BUF_LEN defines a buffer size allocated for control
+ * message reception ... and thus the max. received packet.
+ * (May be the cause for parse_hip returning -EINVAL)
+ */
+#define SIERRA_NET_USBCTL_BUF_LEN      1024
+
+/* list of interface numbers - used for constructing interface lists */
+struct sierra_net_iface_info {
+       const u32 infolen;      /* number of interface numbers on list */
+       const u8  *ifaceinfo;   /* pointer to the array holding the numbers */
+};
+
+struct sierra_net_info_data {
+       u16 rx_urb_size;
+       struct sierra_net_iface_info whitelist;
+};
+
+/* Private data structure */
+struct sierra_net_data {
+
+       u8 ethr_hdr_tmpl[ETH_HLEN]; /* ethernet header template for rx'd pkts */
+
+       u16 link_up;            /* air link up or down */
+       u8 tx_hdr_template[4];  /* part of HIP hdr for tx'd packets */
+
+       u8 sync_msg[4];         /* SYNC message */
+       u8 shdwn_msg[4];        /* Shutdown message */
+
+       /* Backpointer to the container */
+       struct usbnet *usbnet;
+
+       u8 ifnum;       /* interface number */
+
+/* Bit masks, must be a power of 2 */
+#define SIERRA_NET_EVENT_RESP_AVAIL    0x01
+#define SIERRA_NET_TIMER_EXPIRY        0x02
+       unsigned long kevent_flags;
+       struct work_struct sierra_net_kevent;
+       struct timer_list sync_timer; /* For retrying SYNC sequence */
+};
+
+struct param {
+       int is_present;
+       union {
+               void  *ptr;
+               u32    dword;
+               u16    word;
+               u8     byte;
+       };
+};
+
+/* HIP message type */
+#define SIERRA_NET_HIP_EXTENDEDID      0x7F
+#define SIERRA_NET_HIP_HSYNC_ID                0x60    /* Modem -> host */
+#define SIERRA_NET_HIP_RESTART_ID      0x62    /* Modem -> host */
+#define SIERRA_NET_HIP_MSYNC_ID                0x20    /* Host -> modem */
+#define SIERRA_NET_HIP_SHUTD_ID                0x26    /* Host -> modem */
+
+#define SIERRA_NET_HIP_EXT_IP_IN_ID   0x0202
+#define SIERRA_NET_HIP_EXT_IP_OUT_ID  0x0002
+
+/* 3G UMTS Link Sense Indication definitions */
+#define SIERRA_NET_HIP_LSI_UMTSID      0x78
+
+/* Reverse Channel Grant Indication HIP message */
+#define SIERRA_NET_HIP_RCGI            0x64
+
+/* LSI Protocol types */
+#define SIERRA_NET_PROTOCOL_UMTS      0x01
+/* LSI Coverage */
+#define SIERRA_NET_COVERAGE_NONE      0x00
+#define SIERRA_NET_COVERAGE_NOPACKET  0x01
+
+/* LSI Session */
+#define SIERRA_NET_SESSION_IDLE       0x00
+/* LSI Link types */
+#define SIERRA_NET_AS_LINK_TYPE_IPv4  0x00
+
+struct lsi_umts {
+       u8 protocol;
+       u8 unused1;
+       __be16 length;
+       /* eventually use a union for the rest - assume umts for now */
+       u8 coverage;
+       u8 unused2[41];
+       u8 session_state;
+       u8 unused3[33];
+       u8 link_type;
+       u8 pdp_addr_len; /* NW-supplied PDP address len */
+       u8 pdp_addr[16]; /* NW-supplied PDP address (bigendian)) */
+       u8 unused4[23];
+       u8 dns1_addr_len; /* NW-supplied 1st DNS address len (bigendian) */
+       u8 dns1_addr[16]; /* NW-supplied 1st DNS address */
+       u8 dns2_addr_len; /* NW-supplied 2nd DNS address len */
+       u8 dns2_addr[16]; /* NW-supplied 2nd DNS address (bigendian)*/
+       u8 wins1_addr_len; /* NW-supplied 1st Wins address len */
+       u8 wins1_addr[16]; /* NW-supplied 1st Wins address (bigendian)*/
+       u8 wins2_addr_len; /* NW-supplied 2nd Wins address len */
+       u8 wins2_addr[16]; /* NW-supplied 2nd Wins address (bigendian) */
+       u8 unused5[4];
+       u8 gw_addr_len; /* NW-supplied GW address len */
+       u8 gw_addr[16]; /* NW-supplied GW address (bigendian) */
+       u8 reserved[8];
+} __attribute__ ((packed));
+
+#define SIERRA_NET_LSI_COMMON_LEN      4
+#define SIERRA_NET_LSI_UMTS_LEN        (sizeof(struct lsi_umts))
+#define SIERRA_NET_LSI_UMTS_STATUS_LEN \
+       (SIERRA_NET_LSI_UMTS_LEN - SIERRA_NET_LSI_COMMON_LEN)
+
+/* Forward definitions */
+static void sierra_sync_timer(unsigned long syncdata);
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu);
+
+/* Our own net device operations structure */
+static const struct net_device_ops sierra_net_device_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = sierra_net_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
+/* get private data associated with passed in usbnet device */
+static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
+{
+       return (struct sierra_net_data *)dev->data[0];
+}
+
+/* set private data associated with passed in usbnet device */
+static inline void sierra_net_set_private(struct usbnet *dev,
+                       struct sierra_net_data *priv)
+{
+       dev->data[0] = (unsigned long)priv;
+}
+
+/* is packet IPv4 */
+static inline int is_ip(struct sk_buff *skb)
+{
+       return (skb->protocol == cpu_to_be16(ETH_P_IP));
+}
+
+/*
+ * check passed in packet and make sure that:
+ *  - it is linear (no scatter/gather)
+ *  - it is ethernet (mac_header properly set)
+ */
+static int check_ethip_packet(struct sk_buff *skb, struct usbnet *dev)
+{
+       skb_reset_mac_header(skb); /* ethernet header */
+
+       if (skb_is_nonlinear(skb)) {
+               netdev_err(dev->net, "Non linear buffer-dropping\n");
+               return 0;
+       }
+
+       if (!pskb_may_pull(skb, ETH_HLEN))
+               return 0;
+       skb->protocol = eth_hdr(skb)->h_proto;
+
+       return 1;
+}
+
+static const u8 *save16bit(struct param *p, const u8 *datap)
+{
+       p->is_present = 1;
+       p->word = get_unaligned_be16(datap);
+       return datap + sizeof(p->word);
+}
+
+static const u8 *save8bit(struct param *p, const u8 *datap)
+{
+       p->is_present = 1;
+       p->byte = *datap;
+       return datap + sizeof(p->byte);
+}
+
+/*----------------------------------------------------------------------------*
+ *                              BEGIN HIP                                     *
+ *----------------------------------------------------------------------------*/
+/* HIP header */
+#define SIERRA_NET_HIP_HDR_LEN 4
+/* Extended HIP header */
+#define SIERRA_NET_HIP_EXT_HDR_LEN 6
+
+struct hip_hdr {
+       int    hdrlen;
+       struct param payload_len;
+       struct param msgid;
+       struct param msgspecific;
+       struct param extmsgid;
+};
+
+static int parse_hip(const u8 *buf, const u32 buflen, struct hip_hdr *hh)
+{
+       const u8 *curp = buf;
+       int    padded;
+
+       if (buflen < SIERRA_NET_HIP_HDR_LEN)
+               return -EPROTO;
+
+       curp = save16bit(&hh->payload_len, curp);
+       curp = save8bit(&hh->msgid, curp);
+       curp = save8bit(&hh->msgspecific, curp);
+
+       padded = hh->msgid.byte & 0x80;
+       hh->msgid.byte &= 0x7F;                 /* 7 bits */
+
+       hh->extmsgid.is_present = (hh->msgid.byte == SIERRA_NET_HIP_EXTENDEDID);
+       if (hh->extmsgid.is_present) {
+               if (buflen < SIERRA_NET_HIP_EXT_HDR_LEN)
+                       return -EPROTO;
+
+               hh->payload_len.word &= 0x3FFF; /* 14 bits */
+
+               curp = save16bit(&hh->extmsgid, curp);
+               hh->extmsgid.word &= 0x03FF;    /* 10 bits */
+
+               hh->hdrlen = SIERRA_NET_HIP_EXT_HDR_LEN;
+       } else {
+               hh->payload_len.word &= 0x07FF; /* 11 bits */
+               hh->hdrlen = SIERRA_NET_HIP_HDR_LEN;
+       }
+
+       if (padded) {
+               hh->hdrlen++;
+               hh->payload_len.word--;
+       }
+
+       /* if real packet shorter than the claimed length */
+       if (buflen < (hh->hdrlen + hh->payload_len.word))
+               return -EINVAL;
+
+       return 0;
+}
+
+static void build_hip(u8 *buf, const u16 payloadlen,
+               struct sierra_net_data *priv)
+{
+       /* the following doesn't have the full functionality. We
+        * currently build only one kind of header, so it is faster this way
+        */
+       put_unaligned_be16(payloadlen, buf);
+       memcpy(buf+2, priv->tx_hdr_template, sizeof(priv->tx_hdr_template));
+}
+/*----------------------------------------------------------------------------*
+ *                              END HIP                                       *
+ *----------------------------------------------------------------------------*/
+
+static int sierra_net_send_cmd(struct usbnet *dev,
+               u8 *cmd, int cmdlen, const char * cmd_name)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+       int  status;
+
+       status = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+                       USB_CDC_SEND_ENCAPSULATED_COMMAND,
+                       USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE, 0,
+                       priv->ifnum, cmd, cmdlen, USB_CTRL_SET_TIMEOUT);
+
+       if (status != cmdlen && status != -ENODEV)
+               netdev_err(dev->net, "Submit %s failed %d\n", cmd_name, status);
+
+       return status;
+}
+
+static int sierra_net_send_sync(struct usbnet *dev)
+{
+       int  status;
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       status = sierra_net_send_cmd(dev, priv->sync_msg,
+                       sizeof(priv->sync_msg), "SYNC");
+
+       return status;
+}
+
+static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix)
+{
+       dev_dbg(&(priv->usbnet->udev->dev), "%s %d", __func__, ctx_ix);
+       priv->tx_hdr_template[0] = 0x3F;
+       priv->tx_hdr_template[1] = ctx_ix;
+       *((u16 *)&priv->tx_hdr_template[2]) =
+               cpu_to_be16(SIERRA_NET_HIP_EXT_IP_OUT_ID);
+}
+
+static inline int sierra_net_is_valid_addrlen(u8 len)
+{
+       return (len == sizeof(struct in_addr));
+}
+
+static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen)
+{
+       struct lsi_umts *lsi = (struct lsi_umts *)data;
+
+       if (datalen < sizeof(struct lsi_umts)) {
+               netdev_err(dev->net, "%s: Data length %d, exp %Zu\n",
+                               __func__, datalen,
+                               sizeof(struct lsi_umts));
+               return -1;
+       }
+
+       if (lsi->length != cpu_to_be16(SIERRA_NET_LSI_UMTS_STATUS_LEN)) {
+               netdev_err(dev->net, "%s: LSI_UMTS_STATUS_LEN %d, exp %u\n",
+                               __func__, be16_to_cpu(lsi->length),
+                               (u32)SIERRA_NET_LSI_UMTS_STATUS_LEN);
+               return -1;
+       }
+
+       /* Validate the protocol  - only support UMTS for now */
+       if (lsi->protocol != SIERRA_NET_PROTOCOL_UMTS) {
+               netdev_err(dev->net, "Protocol unsupported, 0x%02x\n",
+                       lsi->protocol);
+               return -1;
+       }
+
+       /* Validate the link type */
+       if (lsi->link_type != SIERRA_NET_AS_LINK_TYPE_IPv4) {
+               netdev_err(dev->net, "Link type unsupported: 0x%02x\n",
+                       lsi->link_type);
+               return -1;
+       }
+
+       /* Validate the coverage */
+       if (lsi->coverage == SIERRA_NET_COVERAGE_NONE
+          || lsi->coverage == SIERRA_NET_COVERAGE_NOPACKET) {
+               netdev_err(dev->net, "No coverage, 0x%02x\n", lsi->coverage);
+               return 0;
+       }
+
+       /* Validate the session state */
+       if (lsi->session_state == SIERRA_NET_SESSION_IDLE) {
+               netdev_err(dev->net, "Session idle, 0x%02x\n",
+                       lsi->session_state);
+               return 0;
+       }
+
+       /* Set link_sense true */
+       return 1;
+}
+
+static void sierra_net_handle_lsi(struct usbnet *dev, char *data,
+               struct hip_hdr  *hh)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+       int link_up;
+
+       link_up = sierra_net_parse_lsi(dev, data + hh->hdrlen,
+                                       hh->payload_len.word);
+       if (link_up < 0) {
+               netdev_err(dev->net, "Invalid LSI\n");
+               return;
+       }
+       if (link_up) {
+               sierra_net_set_ctx_index(priv, hh->msgspecific.byte);
+               priv->link_up = 1;
+               netif_carrier_on(dev->net);
+       } else {
+               priv->link_up = 0;
+               netif_carrier_off(dev->net);
+       }
+}
+
+static void sierra_net_dosync(struct usbnet *dev)
+{
+       int status;
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       /* tell modem we are ready */
+       status = sierra_net_send_sync(dev);
+       if (status < 0)
+               netdev_err(dev->net,
+                       "Send SYNC failed, status %d\n", status);
+       status = sierra_net_send_sync(dev);
+       if (status < 0)
+               netdev_err(dev->net,
+                       "Send SYNC failed, status %d\n", status);
+
+       /* Now, start a timer and make sure we get the Restart Indication */
+       priv->sync_timer.function = sierra_sync_timer;
+       priv->sync_timer.data = (unsigned long) dev;
+       priv->sync_timer.expires = jiffies + SIERRA_NET_SYNCDELAY;
+       add_timer(&priv->sync_timer);
+}
+
+static void sierra_net_kevent(struct work_struct *work)
+{
+       struct sierra_net_data *priv =
+               container_of(work, struct sierra_net_data, sierra_net_kevent);
+       struct usbnet *dev = priv->usbnet;
+       int  len;
+       int  err;
+       u8  *buf;
+       u8   ifnum;
+
+       if (test_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags)) {
+               clear_bit(SIERRA_NET_EVENT_RESP_AVAIL, &priv->kevent_flags);
+
+               /* Query the modem for the LSI message */
+               buf = kzalloc(SIERRA_NET_USBCTL_BUF_LEN, GFP_KERNEL);
+               if (!buf) {
+                       netdev_err(dev->net,
+                               "failed to allocate buf for LS msg\n");
+                       return;
+               }
+               ifnum = priv->ifnum;
+               len = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+                               USB_CDC_GET_ENCAPSULATED_RESPONSE,
+                               USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
+                               0, ifnum, buf, SIERRA_NET_USBCTL_BUF_LEN,
+                               USB_CTRL_SET_TIMEOUT);
+
+               if (len < 0) {
+                       netdev_err(dev->net,
+                               "usb_control_msg failed, status %d\n", len);
+               } else {
+                       struct hip_hdr  hh;
+
+                       dev_dbg(&dev->udev->dev, "%s: Received status message,"
+                               " %04x bytes", __func__, len);
+
+                       err = parse_hip(buf, len, &hh);
+                       if (err) {
+                               netdev_err(dev->net, "%s: Bad packet,"
+                                       " parse result %d\n", __func__, err);
+                               kfree(buf);
+                               return;
+                       }
+
+                       /* Validate packet length */
+                       if (len != hh.hdrlen + hh.payload_len.word) {
+                               netdev_err(dev->net, "%s: Bad packet, received"
+                                       " %d, expected %d\n",   __func__, len,
+                                       hh.hdrlen + hh.payload_len.word);
+                               kfree(buf);
+                               return;
+                       }
+
+                       /* Switch on received message types */
+                       switch (hh.msgid.byte) {
+                       case SIERRA_NET_HIP_LSI_UMTSID:
+                               dev_dbg(&dev->udev->dev, "LSI for ctx:%d",
+                                       hh.msgspecific.byte);
+                               sierra_net_handle_lsi(dev, buf, &hh);
+                               break;
+                       case SIERRA_NET_HIP_RESTART_ID:
+                               dev_dbg(&dev->udev->dev, "Restart reported: %d,"
+                                               " stopping sync timer",
+                                               hh.msgspecific.byte);
+                               /* Got sync resp - stop timer & clear mask */
+                               del_timer_sync(&priv->sync_timer);
+                               clear_bit(SIERRA_NET_TIMER_EXPIRY,
+                                         &priv->kevent_flags);
+                               break;
+                       case SIERRA_NET_HIP_HSYNC_ID:
+                               dev_dbg(&dev->udev->dev, "SYNC received");
+                               err = sierra_net_send_sync(dev);
+                               if (err < 0)
+                                       netdev_err(dev->net,
+                                               "Send SYNC failed %d\n", err);
+                               break;
+                       case SIERRA_NET_HIP_EXTENDEDID:
+                               netdev_err(dev->net, "Unrecognized HIP msg, "
+                                       "extmsgid 0x%04x\n", hh.extmsgid.word);
+                               break;
+                       case SIERRA_NET_HIP_RCGI:
+                               /* Ignored */
+                               break;
+                       default:
+                               netdev_err(dev->net, "Unrecognized HIP msg, "
+                                       "msgid 0x%02x\n", hh.msgid.byte);
+                               break;
+                       }
+               }
+               kfree(buf);
+       }
+       /* The sync timer bit might be set */
+       if (test_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags)) {
+               clear_bit(SIERRA_NET_TIMER_EXPIRY, &priv->kevent_flags);
+               dev_dbg(&dev->udev->dev, "Deferred sync timer expiry");
+               sierra_net_dosync(priv->usbnet);
+       }
+
+       if (priv->kevent_flags)
+               dev_dbg(&dev->udev->dev, "sierra_net_kevent done, "
+                       "kevent_flags = 0x%lx", priv->kevent_flags);
+}
+
+static void sierra_net_defer_kevent(struct usbnet *dev, int work)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       set_bit(work, &priv->kevent_flags);
+       schedule_work(&priv->sierra_net_kevent);
+}
+
+/*
+ * Sync Retransmit Timer Handler. On expiry, kick the work queue
+ */
+void sierra_sync_timer(unsigned long syncdata)
+{
+       struct usbnet *dev = (struct usbnet *)syncdata;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+       /* Kick the tasklet */
+       sierra_net_defer_kevent(dev, SIERRA_NET_TIMER_EXPIRY);
+}
+
+static void sierra_net_status(struct usbnet *dev, struct urb *urb)
+{
+       struct usb_cdc_notification *event;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       if (urb->actual_length < sizeof *event)
+               return;
+
+       /* Add cases to handle other standard notifications. */
+       event = urb->transfer_buffer;
+       switch (event->bNotificationType) {
+       case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+       case USB_CDC_NOTIFY_SPEED_CHANGE:
+               /* USB 305 sends those */
+               break;
+       case USB_CDC_NOTIFY_RESPONSE_AVAILABLE:
+               sierra_net_defer_kevent(dev, SIERRA_NET_EVENT_RESP_AVAIL);
+               break;
+       default:
+               netdev_err(dev->net, ": unexpected notification %02x!\n",
+                               event->bNotificationType);
+               break;
+       }
+}
+
+static void sierra_net_get_drvinfo(struct net_device *net,
+               struct ethtool_drvinfo *info)
+{
+       /* Inherit standard device info */
+       usbnet_get_drvinfo(net, info);
+       strncpy(info->driver, driver_name, sizeof info->driver);
+       strncpy(info->version, DRIVER_VERSION, sizeof info->version);
+}
+
+static u32 sierra_net_get_link(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       /* Report link is down whenever the interface is down */
+       return sierra_net_get_private(dev)->link_up && netif_running(net);
+}
+
+static struct ethtool_ops sierra_net_ethtool_ops = {
+       .get_drvinfo = sierra_net_get_drvinfo,
+       .get_link = sierra_net_get_link,
+       .get_msglevel = usbnet_get_msglevel,
+       .set_msglevel = usbnet_set_msglevel,
+       .get_settings = usbnet_get_settings,
+       .set_settings = usbnet_set_settings,
+       .nway_reset = usbnet_nway_reset,
+};
+
+/* MTU can not be more than 1500 bytes, enforce it. */
+static int sierra_net_change_mtu(struct net_device *net, int new_mtu)
+{
+       if (new_mtu > SIERRA_NET_MAX_SUPPORTED_MTU)
+               return -EINVAL;
+
+       return usbnet_change_mtu(net, new_mtu);
+}
+
+static int is_whitelisted(const u8 ifnum,
+                       const struct sierra_net_iface_info *whitelist)
+{
+       if (whitelist) {
+               const u8 *list = whitelist->ifaceinfo;
+               int i;
+
+               for (i = 0; i < whitelist->infolen; i++) {
+                       if (list[i] == ifnum)
+                               return 1;
+               }
+       }
+       return 0;
+}
+
+static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap)
+{
+       int result = 0;
+       u16 *attrdata;
+
+       attrdata = kmalloc(sizeof(*attrdata), GFP_KERNEL);
+       if (!attrdata)
+               return -ENOMEM;
+
+       result = usb_control_msg(
+                       dev->udev,
+                       usb_rcvctrlpipe(dev->udev, 0),
+                       /* _u8 vendor specific request */
+                       SWI_USB_REQUEST_GET_FW_ATTR,
+                       USB_DIR_IN | USB_TYPE_VENDOR,   /* __u8 request type */
+                       0x0000,         /* __u16 value not used */
+                       0x0000,         /* __u16 index  not used */
+                       attrdata,       /* char *data */
+                       sizeof(*attrdata),              /* __u16 size */
+                       USB_CTRL_SET_TIMEOUT);  /* int timeout */
+
+       if (result < 0) {
+               kfree(attrdata);
+               return -EIO;
+       }
+
+       *datap = *attrdata;
+
+       kfree(attrdata);
+       return result;
+}
+
+/*
+ * collects the bulk endpoints, the status endpoint.
+ */
+static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u8      ifacenum;
+       u8      numendpoints;
+       u16     fwattr = 0;
+       int     status;
+       struct ethhdr *eth;
+       struct sierra_net_data *priv;
+       static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
+               0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
+       static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
+               0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00};
+
+       struct sierra_net_info_data *data =
+                       (struct sierra_net_info_data *)dev->driver_info->data;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       ifacenum = intf->cur_altsetting->desc.bInterfaceNumber;
+       /* We only accept certain interfaces */
+       if (!is_whitelisted(ifacenum, &data->whitelist)) {
+               dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum);
+               return -ENODEV;
+       }
+       numendpoints = intf->cur_altsetting->desc.bNumEndpoints;
+       /* We have three endpoints, bulk in and out, and a status */
+       if (numendpoints != 3) {
+               dev_err(&dev->udev->dev, "Expected 3 endpoints, found: %d",
+                       numendpoints);
+               return -ENODEV;
+       }
+       /* Status endpoint set in usbnet_get_endpoints() */
+       dev->status = NULL;
+       status = usbnet_get_endpoints(dev, intf);
+       if (status < 0) {
+               dev_err(&dev->udev->dev, "Error in usbnet_get_endpoints (%d)",
+                       status);
+               return -ENODEV;
+       }
+       /* Initialize sierra private data */
+       priv = kzalloc(sizeof *priv, GFP_KERNEL);
+       if (!priv) {
+               dev_err(&dev->udev->dev, "No memory");
+               return -ENOMEM;
+       }
+
+       priv->usbnet = dev;
+       priv->ifnum = ifacenum;
+       dev->net->netdev_ops = &sierra_net_device_ops;
+
+       /* change MAC addr to include, ifacenum, and to be unique */
+       dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
+       dev->net->dev_addr[ETH_ALEN-1] = ifacenum;
+
+       /* we will have to manufacture ethernet headers, prepare template */
+       eth = (struct ethhdr *)priv->ethr_hdr_tmpl;
+       memcpy(&eth->h_dest, dev->net->dev_addr, ETH_ALEN);
+       eth->h_proto = cpu_to_be16(ETH_P_IP);
+
+       /* prepare shutdown message template */
+       memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg));
+       /* set context index initially to 0 - prepares tx hdr template */
+       sierra_net_set_ctx_index(priv, 0);
+
+       /* decrease the rx_urb_size and max_tx_size to 4k on USB 1.1 */
+       dev->rx_urb_size  = data->rx_urb_size;
+       if (dev->udev->speed != USB_SPEED_HIGH)
+               dev->rx_urb_size  = min_t(size_t, 4096, data->rx_urb_size);
+
+       dev->net->hard_header_len += SIERRA_NET_HIP_EXT_HDR_LEN;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+
+       /* Set up the netdev */
+       dev->net->flags |= IFF_NOARP;
+       dev->net->ethtool_ops = &sierra_net_ethtool_ops;
+       netif_carrier_off(dev->net);
+
+       sierra_net_set_private(dev, priv);
+
+       priv->kevent_flags = 0;
+
+       /* Use the shared workqueue */
+       INIT_WORK(&priv->sierra_net_kevent, sierra_net_kevent);
+
+       /* Only need to do this once */
+       init_timer(&priv->sync_timer);
+
+       /* verify fw attributes */
+       status = sierra_net_get_fw_attr(dev, &fwattr);
+       dev_dbg(&dev->udev->dev, "Fw attr: %x\n", fwattr);
+
+       /* test whether firmware supports DHCP */
+       if (!(status == sizeof(fwattr) && (fwattr & SWI_GET_FW_ATTR_MASK))) {
+               /* found incompatible firmware version */
+               dev_err(&dev->udev->dev, "Incompatible driver and firmware"
+                       " versions\n");
+               kfree(priv);
+               return -ENODEV;
+       }
+       /* prepare sync message from template */
+       memcpy(priv->sync_msg, sync_tmplate, sizeof(priv->sync_msg));
+
+       /* initiate the sync sequence */
+       sierra_net_dosync(dev);
+
+       return 0;
+}
+
+static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int status;
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       /* Kill the timer then flush the work queue */
+       del_timer_sync(&priv->sync_timer);
+
+       flush_scheduled_work();
+
+       /* tell modem we are going away */
+       status = sierra_net_send_cmd(dev, priv->shdwn_msg,
+                       sizeof(priv->shdwn_msg), "Shutdown");
+       if (status < 0)
+               netdev_err(dev->net,
+                       "usb_control_msg failed, status %d\n", status);
+
+       sierra_net_set_private(dev, NULL);
+
+       kfree(priv);
+}
+
+static struct sk_buff *sierra_net_skb_clone(struct usbnet *dev,
+               struct sk_buff *skb, int len)
+{
+       struct sk_buff *new_skb;
+
+       /* clone skb */
+       new_skb = skb_clone(skb, GFP_ATOMIC);
+
+       /* remove len bytes from original */
+       skb_pull(skb, len);
+
+       /* trim next packet to it's length */
+       if (new_skb) {
+               skb_trim(new_skb, len);
+       } else {
+               if (netif_msg_rx_err(dev))
+                       netdev_err(dev->net, "failed to get skb\n");
+               dev->net->stats.rx_dropped++;
+       }
+
+       return new_skb;
+}
+
+/* ---------------------------- Receive data path ----------------------*/
+static int sierra_net_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       int err;
+       struct hip_hdr  hh;
+       struct sk_buff *new_skb;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+
+       /* could contain multiple packets */
+       while (likely(skb->len)) {
+               err = parse_hip(skb->data, skb->len, &hh);
+               if (err) {
+                       if (netif_msg_rx_err(dev))
+                               netdev_err(dev->net, "Invalid HIP header %d\n",
+                                       err);
+                       /* dev->net->stats.rx_errors incremented by caller */
+                       dev->net->stats.rx_length_errors++;
+                       return 0;
+               }
+
+               /* Validate Extended HIP header */
+               if (!hh.extmsgid.is_present
+                   || hh.extmsgid.word != SIERRA_NET_HIP_EXT_IP_IN_ID) {
+                       if (netif_msg_rx_err(dev))
+                               netdev_err(dev->net, "HIP/ETH: Invalid pkt\n");
+
+                       dev->net->stats.rx_frame_errors++;
+                       /* dev->net->stats.rx_errors incremented by caller */;
+                       return 0;
+               }
+
+               skb_pull(skb, hh.hdrlen);
+
+               /* We are going to accept this packet, prepare it */
+               memcpy(skb->data, sierra_net_get_private(dev)->ethr_hdr_tmpl,
+                       ETH_HLEN);
+
+               /* Last packet in batch handled by usbnet */
+               if (hh.payload_len.word == skb->len)
+                       return 1;
+
+               new_skb = sierra_net_skb_clone(dev, skb, hh.payload_len.word);
+               if (new_skb)
+                       usbnet_skb_return(dev, new_skb);
+
+       } /* while */
+
+       return 0;
+}
+
+/* ---------------------------- Transmit data path ----------------------*/
+struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+               gfp_t flags)
+{
+       struct sierra_net_data *priv = sierra_net_get_private(dev);
+       u16 len;
+       bool need_tail;
+
+       dev_dbg(&dev->udev->dev, "%s", __func__);
+       if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
+               /* enough head room as is? */
+               if (SIERRA_NET_HIP_EXT_HDR_LEN <= skb_headroom(skb)) {
+                       /* Save the Eth/IP length and set up HIP hdr */
+                       len = skb->len;
+                       skb_push(skb, SIERRA_NET_HIP_EXT_HDR_LEN);
+                       /* Handle ZLP issue */
+                       need_tail = ((len + SIERRA_NET_HIP_EXT_HDR_LEN)
+                               % dev->maxpacket == 0);
+                       if (need_tail) {
+                               if (unlikely(skb_tailroom(skb) == 0)) {
+                                       netdev_err(dev->net, "tx_fixup:"
+                                               "no room for packet\n");
+                                       dev_kfree_skb_any(skb);
+                                       return NULL;
+                               } else {
+                                       skb->data[skb->len] = 0;
+                                       __skb_put(skb, 1);
+                                       len = len + 1;
+                               }
+                       }
+                       build_hip(skb->data, len, priv);
+                       return skb;
+               } else {
+                       /*
+                        * compensate in the future if necessary
+                        */
+                       netdev_err(dev->net, "tx_fixup: no room for HIP\n");
+               } /* headroom */
+       }
+
+       if (!priv->link_up)
+               dev->net->stats.tx_carrier_errors++;
+
+       /* tx_dropped incremented by usbnet */
+
+       /* filter the packet out, release it  */
+       dev_kfree_skb_any(skb);
+       return NULL;
+}
+
+static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 };
+static const struct sierra_net_info_data sierra_net_info_data_68A3 = {
+       .rx_urb_size = 8 * 1024,
+       .whitelist = {
+               .infolen = ARRAY_SIZE(sierra_net_ifnum_list),
+               .ifaceinfo = sierra_net_ifnum_list
+       }
+};
+
+static const struct driver_info sierra_net_info_68A3 = {
+       .description = "Sierra Wireless USB-to-WWAN Modem",
+       .flags = FLAG_WWAN | FLAG_SEND_ZLP,
+       .bind = sierra_net_bind,
+       .unbind = sierra_net_unbind,
+       .status = sierra_net_status,
+       .rx_fixup = sierra_net_rx_fixup,
+       .tx_fixup = sierra_net_tx_fixup,
+       .data = (unsigned long)&sierra_net_info_data_68A3,
+};
+
+static const struct usb_device_id products[] = {
+       {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */
+       .driver_info = (unsigned long) &sierra_net_info_68A3},
+
+       {}, /* last item */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+/* We are based on usbnet, so let it handle the USB driver specifics */
+static struct usb_driver sierra_net_driver = {
+       .name = "sierra_net",
+       .id_table = products,
+       .probe = usbnet_probe,
+       .disconnect = usbnet_disconnect,
+       .suspend = usbnet_suspend,
+       .resume = usbnet_resume,
+       .no_dynamic_id = 1,
+};
+
+static int __init sierra_net_init(void)
+{
+       BUILD_BUG_ON(FIELD_SIZEOF(struct usbnet, data)
+                               < sizeof(struct cdc_state));
+
+       return usb_register(&sierra_net_driver);
+}
+
+static void __exit sierra_net_exit(void)
+{
+       usb_deregister(&sierra_net_driver);
+}
+
+module_exit(sierra_net_exit);
+module_init(sierra_net_init);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
index f9f0730..5ec542d 100644 (file)
@@ -187,7 +187,6 @@ tx_drop:
        return NETDEV_TX_OK;
 
 rx_drop:
-       kfree_skb(skb);
        rcv_stats->rx_dropped++;
        return NETDEV_TX_OK;
 }
index 6fb783c..b0577dd 100644 (file)
@@ -327,6 +327,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
        struct scatterlist sg[2];
        int err;
 
+       sg_init_table(sg, 2);
        skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
        if (unlikely(!skb))
                return -ENOMEM;
@@ -352,6 +353,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
        char *p;
        int i, err, offset;
 
+       sg_init_table(sg, MAX_SKB_FRAGS + 2);
        /* page in sg[MAX_SKB_FRAGS + 1] is list tail */
        for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
                first = get_a_page(vi, gfp);
index b9b9d6b..941f053 100644 (file)
@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device *dev)
        ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL);
 }
 
+static void ppp_close(struct net_device *dev)
+{
+       ppp_tx_flush();
+}
+
 static struct hdlc_proto proto = {
        .start          = ppp_start,
        .stop           = ppp_stop,
+       .close          = ppp_close,
        .type_trans     = ppp_type_trans,
        .ioctl          = ppp_ioctl,
        .netif_rx       = ppp_rx,
index 99a6da4..e1c2fca 100644 (file)
@@ -727,12 +727,16 @@ static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
 {
        struct device *parent = aru->udev->dev.parent;
 
+       complete(&aru->firmware_loading_complete);
+
        /* unbind anything failed */
        if (parent)
                down(&parent->sem);
        device_release_driver(&aru->udev->dev);
        if (parent)
                up(&parent->sem);
+
+       usb_put_dev(aru->udev);
 }
 
 static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
@@ -761,6 +765,8 @@ static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
        if (err)
                goto err_unrx;
 
+       complete(&aru->firmware_loading_complete);
+       usb_put_dev(aru->udev);
        return;
 
  err_unrx:
@@ -858,6 +864,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
        init_usb_anchor(&aru->tx_pending);
        init_usb_anchor(&aru->tx_submitted);
        init_completion(&aru->cmd_wait);
+       init_completion(&aru->firmware_loading_complete);
        spin_lock_init(&aru->tx_urb_lock);
 
        aru->tx_pending_urbs = 0;
@@ -877,6 +884,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
        if (err)
                goto err_freehw;
 
+       usb_get_dev(aru->udev);
        return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
                                       &aru->udev->dev, GFP_KERNEL, aru,
                                       ar9170_usb_firmware_step2);
@@ -896,6 +904,9 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
                return;
 
        aru->common.state = AR9170_IDLE;
+
+       wait_for_completion(&aru->firmware_loading_complete);
+
        ar9170_unregister(&aru->common);
        ar9170_usb_cancel_urbs(aru);
 
index a2ce3b1..919b060 100644 (file)
@@ -71,6 +71,7 @@ struct ar9170_usb {
        unsigned int tx_pending_urbs;
 
        struct completion cmd_wait;
+       struct completion firmware_loading_complete;
        int readlen;
        u8 *readbuf;
 
index 67ca4e5..115e1ae 100644 (file)
@@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
                ath9k_set_wiphy_idle(aphy, idle);
 
-               if (!idle && all_wiphys_idle)
-                       enable_radio = true;
+               enable_radio = (!idle && all_wiphys_idle);
 
                /*
                 * After we unlock here its possible another wiphy
index 83c52a6..8972166 100644 (file)
@@ -2015,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                        IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+                       if (qc)
+                               iwl_free_tfds_in_queue(priv, sta_id,
+                                                      tid, freed);
 
                        if (priv->mac80211_registered &&
                            (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2041,14 +2043,17 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                                   tx_resp->failure_frame);
 
                freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-               iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+               if (qc && likely(sta_id != IWL_INVALID_STATION))
+                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+               else if (sta_id == IWL_INVALID_STATION)
+                       IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
 
                if (priv->mac80211_registered &&
                    (iwl_queue_space(&txq->q) > txq->q.low_mark))
                        iwl_wake_queue(priv, txq_id);
        }
-
-       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+       if (qc && likely(sta_id != IWL_INVALID_STATION))
+               iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
index c4844ad..92b3e64 100644 (file)
@@ -259,7 +259,7 @@ static struct iwl_lib_ops iwl6000_lib = {
                        EEPROM_5000_REG_BAND_3_CHANNELS,
                        EEPROM_5000_REG_BAND_4_CHANNELS,
                        EEPROM_5000_REG_BAND_5_CHANNELS,
-                       EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+                       EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_5000_REG_BAND_52_HT40_CHANNELS
                },
                .verify_signature  = iwlcore_eeprom_verify_signature,
@@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6050_lib = {
                        EEPROM_5000_REG_BAND_3_CHANNELS,
                        EEPROM_5000_REG_BAND_4_CHANNELS,
                        EEPROM_5000_REG_BAND_5_CHANNELS,
-                       EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+                       EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
                        EEPROM_5000_REG_BAND_52_HT40_CHANNELS
                },
                .verify_signature  = iwlcore_eeprom_verify_signature,
index 35f819a..1460116 100644 (file)
@@ -346,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
               !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
 }
 
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+       if (tbl->expected_tpt)
+               return tbl->expected_tpt[rs_index];
+       return 0;
+}
+
 /**
  * rs_collect_tx_data - Update the success/failure sliding window
  *
@@ -353,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
  * at this rate.  window->data contains the bitmask of successful
  * packets.
  */
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
-                             int scale_index, s32 tpt, int attempts,
-                             int successes)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+                             int scale_index, int attempts, int successes)
 {
        struct iwl_rate_scale_data *window = NULL;
        static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
-       s32 fail_count;
+       s32 fail_count, tpt;
 
        if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
                return -EINVAL;
 
        /* Select window for current tx bit rate */
-       window = &(windows[scale_index]);
+       window = &(tbl->win[scale_index]);
+
+       /* Get expected throughput */
+       tpt = get_expected_tpt(tbl, scale_index);
 
        /*
         * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -739,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
        return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
                (a->is_SGI == b->is_SGI);
 }
-/*
- * Static function to get the expected throughput from an iwl_scale_tbl_info
- * that wraps a NULL pointer check
- */
-static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
-{
-       if (tbl->expected_tpt)
-               return tbl->expected_tpt[rs_index];
-       return 0;
-}
 
 /*
  * mac80211 sends us Tx status
@@ -765,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct iwl_rate_scale_data *window = NULL;
        enum mac80211_rate_control_flags mac_flags;
        u32 tx_rate;
        struct iwl_scale_tbl_info tbl_type;
-       struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
-       s32 tpt = 0;
+       struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
 
        IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
@@ -853,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
                return;
        }
-       window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
 
        /*
         * Updating the frame history depends on whether packets were
@@ -866,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
                rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
                                &rs_index);
-               tpt = get_expected_tpt(curr_tbl, rs_index);
-               rs_collect_tx_data(window, rs_index, tpt,
+               rs_collect_tx_data(curr_tbl, rs_index,
                                   info->status.ampdu_ack_len,
                                   info->status.ampdu_ack_map);
 
@@ -897,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                         * table as active/search.
                         */
                        if (table_type_matches(&tbl_type, curr_tbl))
-                               tpt = get_expected_tpt(curr_tbl, rs_index);
+                               tmp_tbl = curr_tbl;
                        else if (table_type_matches(&tbl_type, other_tbl))
-                               tpt = get_expected_tpt(other_tbl, rs_index);
+                               tmp_tbl = other_tbl;
                        else
                                continue;
-
-                       /* Constants mean 1 transmission, 0 successes */
-                       if (i < retries)
-                               rs_collect_tx_data(window, rs_index, tpt, 1,
-                                               0);
-                       else
-                               rs_collect_tx_data(window, rs_index, tpt, 1,
-                                               legacy_success);
+                       rs_collect_tx_data(tmp_tbl, rs_index, 1,
+                                          i < retries ? 0 : legacy_success);
                }
 
                /* Update success/fail counts if not searching for new mode */
index 8b8e3e1..bdff565 100644 (file)
@@ -3331,6 +3331,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
+       cancel_work_sync(&priv->start_internal_scan);
        cancel_delayed_work(&priv->alive_start);
        cancel_work_sync(&priv->beacon_update);
        del_timer_sync(&priv->statistics_periodic);
index de3b3f4..8b516c5 100644 (file)
@@ -808,6 +808,18 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
                }
        }
 
+       /*
+        * The above algorithm sometimes fails when the ucode
+        * reports 0 for all chains. It's not clear why that
+        * happens to start with, but it is then causing trouble
+        * because this can make us enable more chains than the
+        * hardware really has.
+        *
+        * To be safe, simply mask out any chains that we know
+        * are not on the device.
+        */
+       active_chains &= priv->hw_params.valid_rx_ant;
+
        num_tx_chains = 0;
        for (i = 0; i < NUM_RX_CHAINS; i++) {
                /* loops on all the bits of
index 6383d9f..f4e59ae 100644 (file)
@@ -2621,7 +2621,9 @@ struct iwl_ssid_ie {
 #define PROBE_OPTION_MAX_3945          4
 #define PROBE_OPTION_MAX               20
 #define TX_CMD_LIFE_TIME_INFINITE      cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH                        cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH_DISABLED       0
+#define IWL_GOOD_CRC_TH_DEFAULT                cpu_to_le16(1)
+#define IWL_GOOD_CRC_TH_NEVER          cpu_to_le16(0xffff)
 #define IWL_MAX_SCAN_SIZE 1024
 #define IWL_MAX_CMD_SIZE 4096
 #define IWL_MAX_PROBE_REQUEST          200
index db050b8..049b652 100644 (file)
@@ -308,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* Allocate and init all Tx and Command queues */
-       ret = iwl_txq_ctx_reset(priv);
-       if (ret)
-               return ret;
+       /* Allocate or reset and init all Tx and Command queues */
+       if (!priv->txq) {
+               ret = iwl_txq_ctx_alloc(priv);
+               if (ret)
+                       return ret;
+       } else
+               iwl_txq_ctx_reset(priv);
 
        set_bit(STATUS_INIT, &priv->status);
 
@@ -3355,7 +3358,6 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
         */
        IWL_DEBUG_INFO(priv, "perform radio reset.\n");
        iwl_internal_short_hw_scan(priv);
-       return;
 }
 
 
index 4ef7739..36940a9 100644 (file)
@@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 /*****************************************************
 * TX
 ******************************************************/
-int iwl_txq_ctx_reset(struct iwl_priv *priv);
+int iwl_txq_ctx_alloc(struct iwl_priv *priv);
+void iwl_txq_ctx_reset(struct iwl_priv *priv);
 void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
                                 struct iwl_tx_queue *txq,
@@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                      int slots_num, u32 txq_id);
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                       int slots_num, u32 txq_id);
 void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
 int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
 int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
@@ -503,7 +506,7 @@ void iwl_init_scan_params(struct iwl_priv *priv);
 int iwl_scan_cancel(struct iwl_priv *priv);
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-int iwl_internal_short_hw_scan(struct iwl_priv *priv);
+void iwl_internal_short_hw_scan(struct iwl_priv *priv);
 int iwl_force_reset(struct iwl_priv *priv, int mode);
 u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
                       const u8 *ie, int ie_len, int left);
index 6054c5f..ef1720a 100644 (file)
@@ -1296,6 +1296,7 @@ struct iwl_priv {
        struct work_struct tt_work;
        struct work_struct ct_enter;
        struct work_struct ct_exit;
+       struct work_struct start_internal_scan;
 
        struct tasklet_struct irq_tasklet;
 
index 4e1ba82..8171c70 100644 (file)
@@ -203,6 +203,10 @@ struct iwl_eeprom_enhanced_txpwr {
 #define EEPROM_5000_REG_BAND_52_HT40_CHANNELS  ((0x92)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 22  bytes */
 
+/* 6000 regulatory - indirect access */
+#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS  ((0x80)\
+               | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 14  bytes */
+
 /* 6000 and up regulatory tx power - indirect access */
 /* max. elements per section */
 #define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS    (8)
index 9ab0e41..741e65e 100644 (file)
@@ -470,6 +470,8 @@ EXPORT_SYMBOL(iwl_init_scan_params);
 
 static int iwl_scan_initiate(struct iwl_priv *priv)
 {
+       WARN_ON(!mutex_is_locked(&priv->mutex));
+
        IWL_DEBUG_INFO(priv, "Starting scan...\n");
        set_bit(STATUS_SCANNING, &priv->status);
        priv->is_internal_short_scan = false;
@@ -547,24 +549,31 @@ EXPORT_SYMBOL(iwl_mac_hw_scan);
  * internal short scan, this function should only been called while associated.
  * It will reset and tune the radio to prevent possible RF related problem
  */
-int iwl_internal_short_hw_scan(struct iwl_priv *priv)
+void iwl_internal_short_hw_scan(struct iwl_priv *priv)
 {
-       int ret = 0;
+       queue_work(priv->workqueue, &priv->start_internal_scan);
+}
+
+static void iwl_bg_start_internal_scan(struct work_struct *work)
+{
+       struct iwl_priv *priv =
+               container_of(work, struct iwl_priv, start_internal_scan);
+
+       mutex_lock(&priv->mutex);
 
        if (!iwl_is_ready_rf(priv)) {
-               ret = -EIO;
                IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
-               goto out;
+               goto unlock;
        }
+
        if (test_bit(STATUS_SCANNING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
-               ret = -EAGAIN;
-               goto out;
+               goto unlock;
        }
+
        if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
                IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
-               ret = -EAGAIN;
-               goto out;
+               goto unlock;
        }
 
        priv->scan_bands = 0;
@@ -577,9 +586,8 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv)
        set_bit(STATUS_SCANNING, &priv->status);
        priv->is_internal_short_scan = true;
        queue_work(priv->workqueue, &priv->request_scan);
-
-out:
-       return ret;
+ unlock:
+       mutex_unlock(&priv->mutex);
 }
 EXPORT_SYMBOL(iwl_internal_short_hw_scan);
 
@@ -805,16 +813,29 @@ static void iwl_bg_request_scan(struct work_struct *data)
                        rate = IWL_RATE_1M_PLCP;
                        rate_flags = RATE_MCS_CCK_MSK;
                }
-               scan->good_CRC_th = 0;
+               scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;
        } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                band = IEEE80211_BAND_5GHZ;
                rate = IWL_RATE_6M_PLCP;
                /*
-                * If active scaning is requested but a certain channel
-                * is marked passive, we can do active scanning if we
-                * detect transmissions.
+                * If active scanning is requested but a certain channel is
+                * marked passive, we can do active scanning if we detect
+                * transmissions.
+                *
+                * There is an issue with some firmware versions that triggers
+                * a sysassert on a "good CRC threshold" of zero (== disabled),
+                * on a radar channel even though this means that we should NOT
+                * send probes.
+                *
+                * The "good CRC threshold" is the number of frames that we
+                * need to receive during our dwell time on a channel before
+                * sending out probes -- setting this to a huge value will
+                * mean we never reach it, but at the same time work around
+                * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+                * here instead of IWL_GOOD_CRC_TH_DISABLED.
                 */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                               IWL_GOOD_CRC_TH_NEVER;
 
                /* Force use of chains B and C (0x6) for scan Rx for 4965
                 * Avoid A (0x1) because of its off-channel reception on A-band.
@@ -965,6 +986,7 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
        INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
        INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
        INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+       INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
        INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
 }
 EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
index f0b7e6c..8dd0c03 100644 (file)
@@ -194,10 +194,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
        struct iwl_queue *q = &txq->q;
        struct device *dev = &priv->pci_dev->dev;
        int i;
+       bool huge = false;
 
        if (q->n_bd == 0)
                return;
 
+       for (; q->read_ptr != q->write_ptr;
+            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+               /* we have no way to tell if it is a huge cmd ATM */
+               i = get_cmd_index(q, q->read_ptr, 0);
+
+               if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+                       huge = true;
+                       continue;
+               }
+
+               pci_unmap_single(priv->pci_dev,
+                                pci_unmap_addr(&txq->meta[i], mapping),
+                                pci_unmap_len(&txq->meta[i], len),
+                                PCI_DMA_BIDIRECTIONAL);
+       }
+       if (huge) {
+               i = q->n_window;
+               pci_unmap_single(priv->pci_dev,
+                                pci_unmap_addr(&txq->meta[i], mapping),
+                                pci_unmap_len(&txq->meta[i], len),
+                                PCI_DMA_BIDIRECTIONAL);
+       }
+
        /* De-alloc array of command/tx buffers */
        for (i = 0; i <= TFD_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
@@ -410,6 +434,26 @@ out_free_arrays:
 }
 EXPORT_SYMBOL(iwl_tx_queue_init);
 
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                       int slots_num, u32 txq_id)
+{
+       int actual_slots = slots_num;
+
+       if (txq_id == IWL_CMD_QUEUE_NUM)
+               actual_slots++;
+
+       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+
+       txq->need_update = 0;
+
+       /* Initialize queue's high/low-water marks, and head/tail indexes */
+       iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+       /* Tell device where to find queue */
+       priv->cfg->ops->lib->txq_init(priv, txq);
+}
+EXPORT_SYMBOL(iwl_tx_queue_reset);
+
 /**
  * iwl_hw_txq_ctx_free - Free TXQ Context
  *
@@ -421,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 
        /* Tx queues */
        if (priv->txq) {
-               for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
-                    txq_id++)
+               for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
                        if (txq_id == IWL_CMD_QUEUE_NUM)
                                iwl_cmd_queue_free(priv);
                        else
@@ -438,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
 /**
- * iwl_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialize them again
+ * iwl_txq_ctx_alloc - allocate TX queue context
+ * Allocate all Tx DMA structures and initialize them
  *
  * @param priv
  * @return error code
  */
-int iwl_txq_ctx_reset(struct iwl_priv *priv)
+int iwl_txq_ctx_alloc(struct iwl_priv *priv)
 {
-       int ret = 0;
+       int ret;
        int txq_id, slots_num;
        unsigned long flags;
 
@@ -504,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        return ret;
 }
 
+void iwl_txq_ctx_reset(struct iwl_priv *priv)
+{
+       int txq_id, slots_num;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Turn off all Tx DMA fifos */
+       priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+       /* Tell NIC where to find the "keep warm" buffer */
+       iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* Alloc and init all Tx queues, including the command queue (#4) */
+       for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
+               slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
+                           TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+               iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
+       }
+}
+
 /**
- * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ * iwl_txq_ctx_stop - Stop all Tx DMA channels
  */
 void iwl_txq_ctx_stop(struct iwl_priv *priv)
 {
@@ -525,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
                                    1000);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* Deallocate memory for all Tx queues */
-       iwl_hw_txq_ctx_free(priv);
 }
 EXPORT_SYMBOL(iwl_txq_ctx_stop);
 
@@ -1050,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        spin_lock_irqsave(&priv->hcmd_lock, flags);
 
+       /* If this is a huge cmd, mark the huge flag also on the meta.flags
+        * of the _original_ cmd. This is used for DMA mapping clean up.
+        */
+       if (cmd->flags & CMD_SIZE_HUGE) {
+               idx = get_cmd_index(q, q->write_ptr, 0);
+               txq->meta[idx].flags = CMD_SIZE_HUGE;
+       }
+
        idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
        out_cmd = txq->cmd[idx];
        out_meta = &txq->meta[idx];
@@ -1227,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
        struct iwl_device_cmd *cmd;
        struct iwl_cmd_meta *meta;
+       struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
@@ -1240,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                return;
        }
 
-       cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
-       cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-       meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
+       /* If this is a huge cmd, clear the huge flag on the meta.flags
+        * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
+        * the DMA buffer for the scan (huge) command.
+        */
+       if (huge) {
+               cmd_index = get_cmd_index(&txq->q, index, 0);
+               txq->meta[cmd_index].flags = 0;
+       }
+       cmd_index = get_cmd_index(&txq->q, index, huge);
+       cmd = txq->cmd[cmd_index];
+       meta = &txq->meta[cmd_index];
 
        pci_unmap_single(priv->pci_dev,
                         pci_unmap_addr(meta, mapping),
@@ -1264,6 +1344,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                               get_cmd_string(cmd->hdr.cmd));
                wake_up_interruptible(&priv->wait_command_queue);
        }
+       meta->flags = 0;
 }
 EXPORT_SYMBOL(iwl_tx_cmd_complete);
 
index b55e4f3..b74a56c 100644 (file)
@@ -2967,7 +2967,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                 * is marked passive, we can do active scanning if we
                 * detect transmissions.
                 */
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                               IWL_GOOD_CRC_TH_DISABLED;
                band = IEEE80211_BAND_5GHZ;
        } else {
                IWL_WARN(priv, "Invalid scan band count\n");
index 269fda3..c24067f 100644 (file)
@@ -246,7 +246,7 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
        u32 idx, i;
 
        i = (*index) % ring_limit;
-       (*index) = idx = le32_to_cpu(ring_control->device_idx[1]);
+       (*index) = idx = le32_to_cpu(ring_control->device_idx[ring_index]);
        idx %= ring_limit;
 
        while (i != idx) {
index 81c753a..9548cbb 100644 (file)
@@ -102,6 +102,7 @@ static struct zorro_device_id zorro8390_zorro_tbl[] __devinitdata = {
     { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, },
     { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl);
 
 static struct zorro_driver zorro8390_driver = {
     .name      = "zorro8390",
index 18ecae4..b474833 100644 (file)
@@ -69,7 +69,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
                }
 
                phy = get_phy_device(mdio, be32_to_cpup(addr));
-               if (!phy) {
+               if (!phy || IS_ERR(phy)) {
                        dev_err(&mdio->dev, "error probing PHY at address %i\n",
                                *addr);
                        continue;
index 166b67e..219f79e 100644 (file)
 
 #define OP_BUFFER_FLAGS        0
 
-/*
- * Read and write access is using spin locking. Thus, writing to the
- * buffer by NMI handler (x86) could occur also during critical
- * sections when reading the buffer. To avoid this, there are 2
- * buffers for independent read and write access. Read access is in
- * process context only, write access only in the NMI handler. If the
- * read buffer runs empty, both buffers are swapped atomically. There
- * is potentially a small window during swapping where the buffers are
- * disabled and samples could be lost.
- *
- * Using 2 buffers is a little bit overhead, but the solution is clear
- * and does not require changes in the ring buffer implementation. It
- * can be changed to a single buffer solution when the ring buffer
- * access is implemented as non-locking atomic code.
- */
-static struct ring_buffer *op_ring_buffer_read;
-static struct ring_buffer *op_ring_buffer_write;
+static struct ring_buffer *op_ring_buffer;
 DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer);
 
 static void wq_sync_buffer(struct work_struct *work);
@@ -68,12 +52,9 @@ void oprofile_cpu_buffer_inc_smpl_lost(void)
 
 void free_cpu_buffers(void)
 {
-       if (op_ring_buffer_read)
-               ring_buffer_free(op_ring_buffer_read);
-       op_ring_buffer_read = NULL;
-       if (op_ring_buffer_write)
-               ring_buffer_free(op_ring_buffer_write);
-       op_ring_buffer_write = NULL;
+       if (op_ring_buffer)
+               ring_buffer_free(op_ring_buffer);
+       op_ring_buffer = NULL;
 }
 
 #define RB_EVENT_HDR_SIZE 4
@@ -86,11 +67,8 @@ int alloc_cpu_buffers(void)
        unsigned long byte_size = buffer_size * (sizeof(struct op_sample) +
                                                 RB_EVENT_HDR_SIZE);
 
-       op_ring_buffer_read = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
-       if (!op_ring_buffer_read)
-               goto fail;
-       op_ring_buffer_write = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
-       if (!op_ring_buffer_write)
+       op_ring_buffer = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS);
+       if (!op_ring_buffer)
                goto fail;
 
        for_each_possible_cpu(i) {
@@ -162,16 +140,11 @@ struct op_sample
 *op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size)
 {
        entry->event = ring_buffer_lock_reserve
-               (op_ring_buffer_write, sizeof(struct op_sample) +
+               (op_ring_buffer, sizeof(struct op_sample) +
                 size * sizeof(entry->sample->data[0]));
-       if (entry->event)
-               entry->sample = ring_buffer_event_data(entry->event);
-       else
-               entry->sample = NULL;
-
-       if (!entry->sample)
+       if (!entry->event)
                return NULL;
-
+       entry->sample = ring_buffer_event_data(entry->event);
        entry->size = size;
        entry->data = entry->sample->data;
 
@@ -180,25 +153,16 @@ struct op_sample
 
 int op_cpu_buffer_write_commit(struct op_entry *entry)
 {
-       return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
+       return ring_buffer_unlock_commit(op_ring_buffer, entry->event);
 }
 
 struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
 {
        struct ring_buffer_event *e;
-       e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
-       if (e)
-               goto event;
-       if (ring_buffer_swap_cpu(op_ring_buffer_read,
-                                op_ring_buffer_write,
-                                cpu))
+       e = ring_buffer_consume(op_ring_buffer, cpu, NULL, NULL);
+       if (!e)
                return NULL;
-       e = ring_buffer_consume(op_ring_buffer_read, cpu, NULL);
-       if (e)
-               goto event;
-       return NULL;
 
-event:
        entry->event = e;
        entry->sample = ring_buffer_event_data(e);
        entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample))
@@ -209,8 +173,7 @@ event:
 
 unsigned long op_cpu_buffer_entries(int cpu)
 {
-       return ring_buffer_entries_cpu(op_ring_buffer_read, cpu)
-               + ring_buffer_entries_cpu(op_ring_buffer_write, cpu);
+       return ring_buffer_entries_cpu(op_ring_buffer, cpu);
 }
 
 static int
@@ -356,8 +319,16 @@ void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
 
 void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
 {
-       int is_kernel = !user_mode(regs);
-       unsigned long pc = profile_pc(regs);
+       int is_kernel;
+       unsigned long pc;
+
+       if (likely(regs)) {
+               is_kernel = !user_mode(regs);
+               pc = profile_pc(regs);
+       } else {
+               is_kernel = 0;    /* This value will not be used */
+               pc = ESCAPE_CODE; /* as this causes an early return. */
+       }
 
        __oprofile_add_ext_sample(pc, regs, event, is_kernel);
 }
index dc8a042..b336cd9 100644 (file)
@@ -253,22 +253,26 @@ static int __init oprofile_init(void)
        int err;
 
        err = oprofile_arch_init(&oprofile_ops);
-
        if (err < 0 || timer) {
                printk(KERN_INFO "oprofile: using timer interrupt.\n");
-               oprofile_timer_init(&oprofile_ops);
+               err = oprofile_timer_init(&oprofile_ops);
+               if (err)
+                       goto out_arch;
        }
-
        err = oprofilefs_register();
        if (err)
-               oprofile_arch_exit();
+               goto out_arch;
+       return 0;
 
+out_arch:
+       oprofile_arch_exit();
        return err;
 }
 
 
 static void __exit oprofile_exit(void)
 {
+       oprofile_timer_exit();
        oprofilefs_unregister();
        oprofile_arch_exit();
 }
index cb92f5c..47e12cb 100644 (file)
@@ -34,7 +34,8 @@ struct super_block;
 struct dentry;
 
 void oprofile_create_files(struct super_block *sb, struct dentry *root);
-void oprofile_timer_init(struct oprofile_operations *ops);
+int oprofile_timer_init(struct oprofile_operations *ops);
+void oprofile_timer_exit(void);
 
 int oprofile_set_backtrace(unsigned long depth);
 int oprofile_set_timeout(unsigned long time);
index 333f915..dc0ae4d 100644 (file)
 #include <linux/oprofile.h>
 #include <linux/profile.h>
 #include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/hrtimer.h>
+#include <asm/irq_regs.h>
 #include <asm/ptrace.h>
 
 #include "oprof.h"
 
-static int timer_notify(struct pt_regs *regs)
+static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer);
+
+static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer)
+{
+       oprofile_add_sample(get_irq_regs(), 0);
+       hrtimer_forward_now(hrtimer, ns_to_ktime(TICK_NSEC));
+       return HRTIMER_RESTART;
+}
+
+static void __oprofile_hrtimer_start(void *unused)
+{
+       struct hrtimer *hrtimer = &__get_cpu_var(oprofile_hrtimer);
+
+       hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       hrtimer->function = oprofile_hrtimer_notify;
+
+       hrtimer_start(hrtimer, ns_to_ktime(TICK_NSEC),
+                     HRTIMER_MODE_REL_PINNED);
+}
+
+static int oprofile_hrtimer_start(void)
 {
-       oprofile_add_sample(regs, 0);
+       on_each_cpu(__oprofile_hrtimer_start, NULL, 1);
        return 0;
 }
 
-static int timer_start(void)
+static void __oprofile_hrtimer_stop(int cpu)
 {
-       return register_timer_hook(timer_notify);
+       struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu);
+
+       hrtimer_cancel(hrtimer);
 }
 
+static void oprofile_hrtimer_stop(void)
+{
+       int cpu;
+
+       for_each_online_cpu(cpu)
+               __oprofile_hrtimer_stop(cpu);
+}
 
-static void timer_stop(void)
+static int __cpuinit oprofile_cpu_notify(struct notifier_block *self,
+                                        unsigned long action, void *hcpu)
 {
-       unregister_timer_hook(timer_notify);
+       long cpu = (long) hcpu;
+
+       switch (action) {
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               smp_call_function_single(cpu, __oprofile_hrtimer_start,
+                                        NULL, 1);
+               break;
+       case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
+               __oprofile_hrtimer_stop(cpu);
+               break;
+       }
+       return NOTIFY_OK;
 }
 
+static struct notifier_block __refdata oprofile_cpu_notifier = {
+       .notifier_call = oprofile_cpu_notify,
+};
 
-void __init oprofile_timer_init(struct oprofile_operations *ops)
+int __init oprofile_timer_init(struct oprofile_operations *ops)
 {
+       int rc;
+
+       rc = register_hotcpu_notifier(&oprofile_cpu_notifier);
+       if (rc)
+               return rc;
        ops->create_files = NULL;
        ops->setup = NULL;
        ops->shutdown = NULL;
-       ops->start = timer_start;
-       ops->stop = timer_stop;
+       ops->start = oprofile_hrtimer_start;
+       ops->stop = oprofile_hrtimer_stop;
        ops->cpu_type = "timer";
+       return 0;
+}
+
+void __exit oprofile_timer_exit(void)
+{
+       unregister_hotcpu_notifier(&oprofile_cpu_notifier);
 }
index 4e3e038..0830347 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <linux/vmalloc.h>
 
 #include <asm/pci-bridge.h>
 #include <linux/mutex.h>
@@ -430,6 +431,8 @@ int dlpar_remove_slot(char *drc_name)
                        rc = dlpar_remove_pci_slot(drc_name, dn);
                        break;
        }
+       vm_unmap_aliases();
+
        printk(KERN_INFO "%s: slot %s removed\n", DLPAR_MODULE_NAME, drc_name);
 exit:
        mutex_unlock(&rpadlpar_mutex);
index 7197022..ef7411c 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci_hotplug.h>
 #include <linux/smp.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 #include <asm/eeh.h>       /* for eeh_add_device() */
 #include <asm/rtas.h>          /* rtas_call */
 #include <asm/pci-bridge.h>    /* for pci_controller */
@@ -418,6 +419,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
                return -EINVAL;
 
        pcibios_remove_pci_devices(slot->bus);
+       vm_unmap_aliases();
+
        slot->state = NOT_CONFIGURED;
        return 0;
 }
index 4173125..371dc56 100644 (file)
@@ -3626,14 +3626,15 @@ static void intel_iommu_detach_device(struct iommu_domain *domain,
        domain_remove_one_dev_info(dmar_domain, pdev);
 }
 
-static int intel_iommu_map_range(struct iommu_domain *domain,
-                                unsigned long iova, phys_addr_t hpa,
-                                size_t size, int iommu_prot)
+static int intel_iommu_map(struct iommu_domain *domain,
+                          unsigned long iova, phys_addr_t hpa,
+                          int gfp_order, int iommu_prot)
 {
        struct dmar_domain *dmar_domain = domain->priv;
        u64 max_addr;
        int addr_width;
        int prot = 0;
+       size_t size;
        int ret;
 
        if (iommu_prot & IOMMU_READ)
@@ -3643,6 +3644,7 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
        if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
                prot |= DMA_PTE_SNP;
 
+       size     = PAGE_SIZE << gfp_order;
        max_addr = iova + size;
        if (dmar_domain->max_addr < max_addr) {
                int min_agaw;
@@ -3669,19 +3671,19 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
        return ret;
 }
 
-static void intel_iommu_unmap_range(struct iommu_domain *domain,
-                                   unsigned long iova, size_t size)
+static int intel_iommu_unmap(struct iommu_domain *domain,
+                            unsigned long iova, int gfp_order)
 {
        struct dmar_domain *dmar_domain = domain->priv;
-
-       if (!size)
-               return;
+       size_t size = PAGE_SIZE << gfp_order;
 
        dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
                            (iova + size - 1) >> VTD_PAGE_SHIFT);
 
        if (dmar_domain->max_addr == iova + size)
                dmar_domain->max_addr = iova;
+
+       return gfp_order;
 }
 
 static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -3714,8 +3716,8 @@ static struct iommu_ops intel_iommu_ops = {
        .domain_destroy = intel_iommu_domain_destroy,
        .attach_dev     = intel_iommu_attach_device,
        .detach_dev     = intel_iommu_detach_device,
-       .map            = intel_iommu_map_range,
-       .unmap          = intel_iommu_unmap_range,
+       .map            = intel_iommu_map,
+       .unmap          = intel_iommu_unmap,
        .iova_to_phys   = intel_iommu_iova_to_phys,
        .domain_has_cap = intel_iommu_domain_has_cap,
 };
index 5ea587e..3749912 100644 (file)
@@ -679,7 +679,7 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
  */
 int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
 {
-       return state > PCI_D0 ?
+       return state >= PCI_D0 ?
                        pci_platform_power_transition(dev, state) : -EINVAL;
 }
 EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
@@ -716,10 +716,6 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                 */
                return 0;
 
-       /* Check if we're already there */
-       if (dev->current_state == state)
-               return 0;
-
        __pci_start_power_transition(dev, state);
 
        /* This device is quirked not to be put into D3, so
index aa495ad..7a711ee 100644 (file)
@@ -244,11 +244,17 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
 
        /* Assert Secondary Bus Reset */
        pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &p2p_ctrl);
-       p2p_ctrl |= PCI_CB_BRIDGE_CTL_CB_RESET;
+       p2p_ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
 
+       /*
+        * we should send hot reset message for 2ms to allow it time to
+        * propogate to all downstream ports
+        */
+       msleep(2);
+
        /* De-assert Secondary Bus Reset */
-       p2p_ctrl &= ~PCI_CB_BRIDGE_CTL_CB_RESET;
+       p2p_ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL, p2p_ctrl);
 
        /*
index 882bd8d..c82548a 100644 (file)
@@ -174,19 +174,14 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
        pci_read_config_dword(dev, pos, &sz);
        pci_write_config_dword(dev, pos, l);
 
-       if (!sz)
-               goto fail;      /* BAR not implemented */
-
        /*
         * All bits set in sz means the device isn't working properly.
-        * If it's a memory BAR or a ROM, bit 0 must be clear; if it's
-        * an io BAR, bit 1 must be clear.
+        * If the BAR isn't implemented, all bits must be 0.  If it's a
+        * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
+        * 1 must be clear.
         */
-       if (sz == 0xffffffff) {
-               dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n",
-                       pos, sz);
+       if (!sz || sz == 0xffffffff)
                goto fail;
-       }
 
        /*
         * I don't know how l can have all bits set.  Copied from old code.
@@ -249,17 +244,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                                   pos, res);
                }
        } else {
-               u32 size = pci_size(l, sz, mask);
+               sz = pci_size(l, sz, mask);
 
-               if (!size) {
-                       dev_err(&dev->dev, "reg %x: invalid size "
-                               "(l %#x sz %#x mask %#x); broken device?",
-                               pos, l, sz, mask);
+               if (!sz)
                        goto fail;
-               }
 
                res->start = l;
-               res->end = l + size;
+               res->end = l + sz;
 
                dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
        }
index 4fe36d2..19b1113 100644 (file)
@@ -838,65 +838,11 @@ static void pci_bus_dump_resources(struct pci_bus *bus)
        }
 }
 
-static int __init pci_bus_get_depth(struct pci_bus *bus)
-{
-       int depth = 0;
-       struct pci_dev *dev;
-
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               int ret;
-               struct pci_bus *b = dev->subordinate;
-               if (!b)
-                       continue;
-
-               ret = pci_bus_get_depth(b);
-               if (ret + 1 > depth)
-                       depth = ret + 1;
-       }
-
-       return depth;
-}
-static int __init pci_get_max_depth(void)
-{
-       int depth = 0;
-       struct pci_bus *bus;
-
-       list_for_each_entry(bus, &pci_root_buses, node) {
-               int ret;
-
-               ret = pci_bus_get_depth(bus);
-               if (ret > depth)
-                       depth = ret;
-       }
-
-       return depth;
-}
-
-/*
- * first try will not touch pci bridge res
- * second  and later try will clear small leaf bridge res
- * will stop till to the max  deepth if can not find good one
- */
 void __init
 pci_assign_unassigned_resources(void)
 {
        struct pci_bus *bus;
-       int tried_times = 0;
-       enum release_type rel_type = leaf_only;
-       struct resource_list_x head, *list;
-       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
-                                 IORESOURCE_PREFETCH;
-       unsigned long failed_type;
-       int max_depth = pci_get_max_depth();
-       int pci_try_num;
 
-       head.next = NULL;
-
-       pci_try_num = max_depth + 1;
-       printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
-                max_depth, pci_try_num);
-
-again:
        /* Depth first, calculate sizes and alignments of all
           subordinate buses. */
        list_for_each_entry(bus, &pci_root_buses, node) {
@@ -904,65 +850,9 @@ again:
        }
        /* Depth last, allocate resources and update the hardware. */
        list_for_each_entry(bus, &pci_root_buses, node) {
-               __pci_bus_assign_resources(bus, &head);
-       }
-       tried_times++;
-
-       /* any device complain? */
-       if (!head.next)
-               goto enable_and_dump;
-       failed_type = 0;
-       for (list = head.next; list;) {
-               failed_type |= list->flags;
-               list = list->next;
-       }
-       /*
-        * io port are tight, don't try extra
-        * or if reach the limit, don't want to try more
-        */
-       failed_type &= type_mask;
-       if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
-               free_failed_list(&head);
-               goto enable_and_dump;
-       }
-
-       printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
-                        tried_times + 1);
-
-       /* third times and later will not check if it is leaf */
-       if ((tried_times + 1) > 2)
-               rel_type = whole_subtree;
-
-       /*
-        * Try to release leaf bridge's resources that doesn't fit resource of
-        * child device under that bridge
-        */
-       for (list = head.next; list;) {
-               bus = list->dev->bus;
-               pci_bus_release_bridge_resources(bus, list->flags & type_mask,
-                                                 rel_type);
-               list = list->next;
-       }
-       /* restore size and flags */
-       for (list = head.next; list;) {
-               struct resource *res = list->res;
-
-               res->start = list->start;
-               res->end = list->end;
-               res->flags = list->flags;
-               if (list->dev->subordinate)
-                       res->flags = 0;
-
-               list = list->next;
-       }
-       free_failed_list(&head);
-
-       goto again;
-
-enable_and_dump:
-       /* Depth last, update the hardware. */
-       list_for_each_entry(bus, &pci_root_buses, node)
+               pci_bus_assign_resources(bus);
                pci_enable_bridges(bus);
+       }
 
        /* dump the resource on buses */
        list_for_each_entry(bus, &pci_root_buses, node) {
index d189e47..a44733d 100644 (file)
@@ -234,7 +234,8 @@ config PCMCIA_PXA2XX
        depends on ARM && ARCH_PXA && PCMCIA
        depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
                    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
-                   || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2)
+                   || ARCOM_PCMCIA || ARCH_PXA_ESERIES || MACH_STARGATE2 \
+                   || MACH_VPAC270)
        select PCMCIA_SOC_COMMON
        help
          Say Y here to include support for the PXA2xx PCMCIA controller
index 381b031..4dae361 100644 (file)
@@ -66,6 +66,7 @@ pxa2xx-obj-$(CONFIG_MACH_PALMTC)              += pxa2xx_palmtc.o
 pxa2xx-obj-$(CONFIG_MACH_PALMLD)               += pxa2xx_palmld.o
 pxa2xx-obj-$(CONFIG_MACH_E740)                 += pxa2xx_e740.o
 pxa2xx-obj-$(CONFIG_MACH_STARGATE2)            += pxa2xx_stargate2.o
+pxa2xx-obj-$(CONFIG_MACH_VPAC270)              += pxa2xx_vpac270.o
 
 obj-$(CONFIG_PCMCIA_PXA2XX)                    += pxa2xx_base.o $(pxa2xx-obj-y)
 
index f230f65..854959c 100644 (file)
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
        if (!s)
                return -EINVAL;
 
+       if (s->functions) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
        /* We do not want to validate the CIS cache... */
        mutex_lock(&s->ops_mutex);
        destroy_cis_cache(s);
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
                count = 0;
        else {
                struct pcmcia_socket *s;
-               unsigned int chains;
+               unsigned int chains = 1;
 
                if (off + count > size)
                        count = size - off;
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
 
                if (!(s->state & SOCKET_PRESENT))
                        return -ENODEV;
-               if (pccard_validate_cis(s, &chains))
+               if (!s->functions && pccard_validate_cis(s, &chains))
                        return -EIO;
                if (!chains)
                        return -ENODATA;
index 75ed866..c338375 100644 (file)
@@ -671,20 +671,22 @@ static int pccardd(void *__skt)
                                socket_remove(skt);
                        if (sysfs_events & PCMCIA_UEVENT_INSERT)
                                socket_insert(skt);
-                       if ((sysfs_events & PCMCIA_UEVENT_RESUME) &&
-                               !(skt->state & SOCKET_CARDBUS)) {
-                               ret = socket_resume(skt);
-                               if (!ret && skt->callback)
-                                       skt->callback->resume(skt);
-                       }
                        if ((sysfs_events & PCMCIA_UEVENT_SUSPEND) &&
                                !(skt->state & SOCKET_CARDBUS)) {
                                if (skt->callback)
                                        ret = skt->callback->suspend(skt);
                                else
                                        ret = 0;
-                               if (!ret)
+                               if (!ret) {
                                        socket_suspend(skt);
+                                       msleep(100);
+                               }
+                       }
+                       if ((sysfs_events & PCMCIA_UEVENT_RESUME) &&
+                               !(skt->state & SOCKET_CARDBUS)) {
+                               ret = socket_resume(skt);
+                               if (!ret && skt->callback)
+                                       skt->callback->resume(skt);
                        }
                        if ((sysfs_events & PCMCIA_UEVENT_REQUERY) &&
                                !(skt->state & SOCKET_CARDBUS)) {
index 6206408..0f4cc3f 100644 (file)
@@ -146,7 +146,6 @@ static irqreturn_t db1200_pcmcia_cdirq(int irq, void *data)
 static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
 {
        int ret;
-       unsigned long flags;
 
        if (sock->stschg_irq != -1) {
                ret = request_irq(sock->stschg_irq, db1000_pcmcia_stschgirq,
@@ -162,8 +161,6 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
         * active one disabled.
         */
        if (sock->board_type == BOARD_TYPE_DB1200) {
-               local_irq_save(flags);
-
                ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
                                  IRQF_DISABLED, "pcmcia_insert", sock);
                if (ret)
@@ -173,17 +170,14 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
                                  IRQF_DISABLED, "pcmcia_eject", sock);
                if (ret) {
                        free_irq(sock->insert_irq, sock);
-                       local_irq_restore(flags);
                        goto out1;
                }
 
-               /* disable the currently active one */
+               /* enable the currently silent one */
                if (db1200_card_inserted(sock))
-                       disable_irq_nosync(sock->insert_irq);
+                       enable_irq(sock->eject_irq);
                else
-                       disable_irq_nosync(sock->eject_irq);
-
-               local_irq_restore(flags);
+                       enable_irq(sock->insert_irq);
        } else {
                /* all other (older) Db1x00 boards use a GPIO to show
                 * card detection status:  use both-edge triggers.
index cb6036d..041eee4 100644 (file)
@@ -335,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
 
                mutex_lock(&s->ops_mutex);
                list_del(&p_dev->socket_device_list);
-               p_dev->_removed = 1;
                mutex_unlock(&s->ops_mutex);
 
                dev_dbg(&p_dev->dev, "unregistering device\n");
@@ -654,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data)
 
 static void pcmcia_requery(struct pcmcia_socket *s)
 {
-       int present, has_pfc;
-
-       mutex_lock(&s->ops_mutex);
-       present = s->pcmcia_state.present;
-       mutex_unlock(&s->ops_mutex);
-
-       if (!present)
-               return;
+       int has_pfc;
 
        if (s->functions == 0) {
                pcmcia_card_add(s);
@@ -687,12 +679,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
                        new_funcs = mfc.nfn;
                else
                        new_funcs = 1;
-               if (old_funcs > new_funcs) {
+               if (old_funcs != new_funcs) {
+                       /* we need to re-start */
                        pcmcia_card_remove(s, NULL);
                        pcmcia_card_add(s);
-               } else if (new_funcs > old_funcs) {
-                       s->functions = new_funcs;
-                       pcmcia_device_add(s, 1);
                }
        }
 
@@ -728,6 +718,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
        struct pcmcia_socket *s = dev->socket;
        const struct firmware *fw;
        int ret = -ENOMEM;
+       cistpl_longlink_mfc_t mfc;
+       int old_funcs, new_funcs = 1;
 
        if (!filename)
                return -EINVAL;
@@ -750,6 +742,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
                        goto release;
                }
 
+               /* we need to re-start if the number of functions changed */
+               old_funcs = s->functions;
+               if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+                                       &mfc))
+                       new_funcs = mfc.nfn;
+
+               if (old_funcs != new_funcs)
+                       ret = -EBUSY;
 
                /* update information */
                pcmcia_device_query(dev);
@@ -820,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
-               if (dev->device_no != did->device_no)
-                       return 0;
+               dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
                mutex_lock(&dev->socket->ops_mutex);
                dev->socket->pcmcia_state.has_pfc = 1;
                mutex_unlock(&dev->socket->ops_mutex);
+               if (dev->device_no != did->device_no)
+                       return 0;
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
@@ -835,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
 
                /* if this is a pseudo-multi-function device,
                 * we need explicit matches */
-               if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
+               if (dev->socket->pcmcia_state.has_pfc)
                        return 0;
                if (dev->device_no)
                        return 0;
@@ -858,10 +859,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
                dev_dbg(&dev->dev, "device needs a fake CIS\n");
                if (!dev->socket->fake_cis)
-                       pcmcia_load_firmware(dev, did->cisfile);
-
-               if (!dev->socket->fake_cis)
-                       return 0;
+                       if (pcmcia_load_firmware(dev, did->cisfile))
+                               return 0;
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
@@ -1254,9 +1253,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 
        switch (event) {
        case CS_EVENT_CARD_REMOVAL:
-               mutex_lock(&s->ops_mutex);
-               s->pcmcia_state.present = 0;
-               mutex_unlock(&s->ops_mutex);
+               atomic_set(&skt->present, 0);
                pcmcia_card_remove(skt, NULL);
                handle_event(skt, event);
                mutex_lock(&s->ops_mutex);
@@ -1265,9 +1262,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
                break;
 
        case CS_EVENT_CARD_INSERTION:
+               atomic_set(&skt->present, 1);
                mutex_lock(&s->ops_mutex);
                s->pcmcia_state.has_pfc = 0;
-               s->pcmcia_state.present = 1;
                destroy_cis_cache(s); /* to be on the safe side... */
                mutex_unlock(&s->ops_mutex);
                pcmcia_card_add(skt);
@@ -1286,6 +1283,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
                        destroy_cis_cache(skt);
                        kfree(skt->fake_cis);
                        skt->fake_cis = NULL;
+                       s->functions = 0;
                        mutex_unlock(&s->ops_mutex);
                        /* now, add the new card */
                        ds_event(skt, CS_EVENT_CARD_INSERTION,
@@ -1307,7 +1305,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
     return 0;
 } /* ds_event */
 
-
+/*
+ * NOTE: This is racy. There's no guarantee the card will still be
+ * physically present, even if the call to this function returns
+ * non-NULL. Furthermore, the device driver most likely is unbound
+ * almost immediately, so the timeframe where pcmcia_dev_present
+ * returns NULL is probably really really small.
+ */
 struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
 {
        struct pcmcia_device *p_dev;
@@ -1317,22 +1321,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
        if (!p_dev)
                return NULL;
 
-       mutex_lock(&p_dev->socket->ops_mutex);
-       if (!p_dev->socket->pcmcia_state.present)
-               goto out;
-
-       if (p_dev->socket->pcmcia_state.dead)
-               goto out;
-
-       if (p_dev->_removed)
-               goto out;
-
-       if (p_dev->suspended)
-               goto out;
+       if (atomic_read(&p_dev->socket->present) != 0)
+               ret = p_dev;
 
-       ret = p_dev;
- out:
-       mutex_unlock(&p_dev->socket->ops_mutex);
        pcmcia_put_dev(p_dev);
        return ret;
 }
@@ -1382,6 +1373,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
                return ret;
        }
 
+       atomic_set(&socket->present, 0);
+
        return 0;
 }
 
@@ -1393,10 +1386,6 @@ static void pcmcia_bus_remove_socket(struct device *dev,
        if (!socket)
                return;
 
-       mutex_lock(&socket->ops_mutex);
-       socket->pcmcia_state.dead = 1;
-       mutex_unlock(&socket->ops_mutex);
-
        pccard_register_pcmcia(socket, NULL);
 
        /* unregister any unbound devices */
index 104e73d..7631faa 100644 (file)
@@ -711,7 +711,7 @@ static int ds_open(struct inode *inode, struct file *file)
            warning_printed = 1;
     }
 
-    if (s->pcmcia_state.present)
+    if (atomic_read(&s->present))
        queue_event(user, CS_EVENT_CARD_INSERTION);
 out:
     unlock_kernel();
@@ -770,9 +770,6 @@ static ssize_t ds_read(struct file *file, char __user *buf,
        return -EIO;
 
     s = user->socket;
-    if (s->pcmcia_state.dead)
-       return -EIO;
-
     ret = wait_event_interruptible(s->queue, !queue_empty(user));
     if (ret == 0)
        ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
@@ -838,8 +835,6 @@ static int ds_ioctl(struct inode *inode, struct file *file,
        return -EIO;
 
     s = user->socket;
-    if (s->pcmcia_state.dead)
-       return -EIO;
 
     size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
     if (size > sizeof(ds_ioctl_arg_t))
index caec1de..7c3d03b 100644 (file)
@@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        else
                printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
 
-#ifdef CONFIG_PCMCIA_PROBE
-
-       if (s->irq.AssignedIRQ != 0) {
-               /* If the interrupt is already assigned, it must be the same */
+       /* If the interrupt is already assigned, it must be the same */
+       if (s->irq.AssignedIRQ != 0)
                irq = s->irq.AssignedIRQ;
-       } else {
+
+#ifdef CONFIG_PCMCIA_PROBE
+       if (!irq) {
                int try;
                u32 mask = s->irq_mask;
                void *data = p_dev; /* something unique to this device */
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c
new file mode 100644 (file)
index 0000000..55627ec
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * linux/drivers/pcmcia/pxa2xx_vpac270.c
+ *
+ * Driver for Voipac PXA270 PCMCIA and CF sockets
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <mach/vpac270.h>
+
+#include "soc_common.h"
+
+static struct pcmcia_irqs cd_irqs[] = {
+       {
+               .sock = 0,
+               .irq  = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD),
+               .str  = "PCMCIA CD"
+       },
+       {
+               .sock = 1,
+               .irq  = IRQ_GPIO(GPIO17_VPAC270_CF_CD),
+               .str  = "CF CD"
+       },
+};
+
+static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+{
+       int ret;
+
+       if (skt->nr == 0) {
+               ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD");
+               if (ret)
+                       goto err1;
+               ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD);
+               if (ret)
+                       goto err2;
+
+               ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY");
+               if (ret)
+                       goto err2;
+               ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY);
+               if (ret)
+                       goto err3;
+
+               ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN");
+               if (ret)
+                       goto err3;
+               ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0);
+               if (ret)
+                       goto err4;
+
+               ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET");
+               if (ret)
+                       goto err4;
+               ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0);
+               if (ret)
+                       goto err5;
+
+               skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
+
+               return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
+
+err5:
+               gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
+err4:
+               gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
+err3:
+               gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
+err2:
+               gpio_free(GPIO84_VPAC270_PCMCIA_CD);
+err1:
+               return ret;
+
+       } else {
+               ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD");
+               if (ret)
+                       goto err6;
+               ret = gpio_direction_input(GPIO17_VPAC270_CF_CD);
+               if (ret)
+                       goto err7;
+
+               ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY");
+               if (ret)
+                       goto err7;
+               ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY);
+               if (ret)
+                       goto err8;
+
+               ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET");
+               if (ret)
+                       goto err8;
+               ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0);
+               if (ret)
+                       goto err9;
+
+               skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
+
+               return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
+
+err9:
+               gpio_free(GPIO16_VPAC270_CF_RESET);
+err8:
+               gpio_free(GPIO12_VPAC270_CF_RDY);
+err7:
+               gpio_free(GPIO17_VPAC270_CF_CD);
+err6:
+               return ret;
+
+       }
+}
+
+static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+{
+       gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
+       gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
+       gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
+       gpio_free(GPIO84_VPAC270_PCMCIA_CD);
+       gpio_free(GPIO16_VPAC270_CF_RESET);
+       gpio_free(GPIO12_VPAC270_CF_RDY);
+       gpio_free(GPIO17_VPAC270_CF_CD);
+}
+
+static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
+                                       struct pcmcia_state *state)
+{
+       if (skt->nr == 0) {
+               state->detect = !gpio_get_value(GPIO84_VPAC270_PCMCIA_CD);
+               state->ready  = !!gpio_get_value(GPIO35_VPAC270_PCMCIA_RDY);
+       } else {
+               state->detect = !gpio_get_value(GPIO17_VPAC270_CF_CD);
+               state->ready  = !!gpio_get_value(GPIO12_VPAC270_CF_RDY);
+       }
+       state->bvd1   = 1;
+       state->bvd2   = 1;
+       state->wrprot = 0;
+       state->vs_3v  = 1;
+       state->vs_Xv  = 0;
+}
+
+static int
+vpac270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
+                               const socket_state_t *state)
+{
+       if (skt->nr == 0) {
+               gpio_set_value(GPIO11_VPAC270_PCMCIA_RESET,
+                       (state->flags & SS_RESET));
+               gpio_set_value(GPIO107_VPAC270_PCMCIA_PPEN,
+                       !(state->Vcc == 33 || state->Vcc == 50));
+       } else {
+               gpio_set_value(GPIO16_VPAC270_CF_RESET,
+                       (state->flags & SS_RESET));
+       }
+
+       return 0;
+}
+
+static void vpac270_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
+{
+}
+
+static void vpac270_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+{
+}
+
+static struct pcmcia_low_level vpac270_pcmcia_ops = {
+       .owner                  = THIS_MODULE,
+
+       .first                  = 0,
+       .nr                     = 2,
+
+       .hw_init                = vpac270_pcmcia_hw_init,
+       .hw_shutdown            = vpac270_pcmcia_hw_shutdown,
+
+       .socket_state           = vpac270_pcmcia_socket_state,
+       .configure_socket       = vpac270_pcmcia_configure_socket,
+
+       .socket_init            = vpac270_pcmcia_socket_init,
+       .socket_suspend         = vpac270_pcmcia_socket_suspend,
+};
+
+static struct platform_device *vpac270_pcmcia_device;
+
+static int __init vpac270_pcmcia_init(void)
+{
+       int ret;
+
+       if (!machine_is_vpac270())
+               return -ENODEV;
+
+       vpac270_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
+       if (!vpac270_pcmcia_device)
+               return -ENOMEM;
+
+       ret = platform_device_add_data(vpac270_pcmcia_device,
+               &vpac270_pcmcia_ops, sizeof(vpac270_pcmcia_ops));
+
+       if (!ret)
+               ret = platform_device_add(vpac270_pcmcia_device);
+
+       if (ret)
+               platform_device_put(vpac270_pcmcia_device);
+
+       return ret;
+}
+
+static void __exit vpac270_pcmcia_exit(void)
+{
+       platform_device_unregister(vpac270_pcmcia_device);
+}
+
+module_init(vpac270_pcmcia_init);
+module_exit(vpac270_pcmcia_exit);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("PCMCIA support for Voipac PXA270");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
+MODULE_LICENSE("GPL");
index 559069a..a6eb7b5 100644 (file)
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
                return;
        }
        for (i = base, most = 0; i < base+num; i += 8) {
-               res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+               res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
                if (!res)
                        continue;
                hole = inb(i);
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
 
        bad = any = 0;
        for (i = base; i < base+num; i += 8) {
-               res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
-               if (!res)
+               res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+               if (!res) {
+                       if (!any)
+                               printk(" excluding");
+                       if (!bad)
+                               bad = any = i;
                        continue;
+               }
                for (j = 0; j < 8; j++)
                        if (inb(i+j) != most)
                                break;
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
        }
        if (bad) {
                if ((num > 16) && (bad == base) && (i == base+num)) {
+                       sub_interval(&s_data->io_db, bad, i-bad);
                        printk(" nothing: probe failed.\n");
                        return;
                } else {
@@ -804,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 {
        struct socket_data *data = s->resource_data;
-       unsigned long size = end - start + 1;
+       unsigned long size;
        int ret = 0;
 
 #if defined(CONFIG_X86)
@@ -814,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
                start = 0x100;
 #endif
 
+       size = end - start + 1;
+
        if (end < start)
                return -EINVAL;
 
index 7bec458..6c3320d 100644 (file)
@@ -390,6 +390,7 @@ config EEEPC_WMI
        depends on ACPI_WMI
        depends on INPUT
        depends on EXPERIMENTAL
+       select INPUT_SPARSEKMAP
        ---help---
          Say Y here if you want to support WMI-based hotkeys on Eee PC laptops.
 
index 52262b0..efe8f63 100644 (file)
@@ -79,15 +79,15 @@ static uint wapf = 1;
 module_param(wapf, uint, 0644);
 MODULE_PARM_DESC(wapf, "WAPF value");
 
-static uint wlan_status = 1;
-static uint bluetooth_status = 1;
+static int wlan_status = 1;
+static int bluetooth_status = 1;
 
-module_param(wlan_status, uint, 0644);
+module_param(wlan_status, int, 0644);
 MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot "
                 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
                 "default is 1");
 
-module_param(bluetooth_status, uint, 0644);
+module_param(bluetooth_status, int, 0644);
 MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot "
                 "(0 = disabled, 1 = enabled, -1 = don't do anything). "
                 "default is 1");
index 6ba6c30..66f53c3 100644 (file)
@@ -217,6 +217,7 @@ static void dell_wmi_notify(u32 value, void *context)
                if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
                        printk(KERN_INFO "dell-wmi: Received unknown WMI event"
                                         " (0x%x)\n", buffer_entry[1]);
+                       kfree(obj);
                        return;
                }
 
@@ -234,7 +235,7 @@ static void dell_wmi_notify(u32 value, void *context)
                            key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
                        /* Don't report brightness notifications that will also
                         * come via ACPI */
-                       return;
+                       ;
                } else {
                        input_report_key(dell_wmi_input_dev, key->keycode, 1);
                        input_sync(dell_wmi_input_dev);
index 54a0157..0306174 100644 (file)
@@ -169,7 +169,6 @@ struct eeepc_laptop {
        struct backlight_device *backlight_device;
 
        struct input_dev *inputdev;
-       struct key_entry *keymap;
 
        struct rfkill *wlan_rfkill;
        struct rfkill *bluetooth_rfkill;
@@ -1204,8 +1203,8 @@ static int eeepc_input_init(struct eeepc_laptop *eeepc)
 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
 {
        if (eeepc->inputdev) {
+               sparse_keymap_free(eeepc->inputdev);
                input_unregister_device(eeepc->inputdev);
-               kfree(eeepc->keymap);
        }
 }
 
index 9f88226..b227eb4 100644 (file)
@@ -23,6 +23,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#define        EEEPC_WMI_FILE  "eeepc-wmi"
+
 MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
 MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
 MODULE_LICENSE("GPL");
 
 #define EEEPC_WMI_EVENT_GUID   "ABBC0F72-8EA1-11D1-00A0-C90629100000"
+#define EEEPC_WMI_MGMT_GUID    "97845ED0-4E6D-11DE-8A39-0800200C9A66"
 
 MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
+MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
 
 #define NOTIFY_BRNUP_MIN       0x11
 #define NOTIFY_BRNUP_MAX       0x1f
 #define NOTIFY_BRNDOWN_MIN     0x20
 #define NOTIFY_BRNDOWN_MAX     0x2e
 
+#define EEEPC_WMI_METHODID_DEVS        0x53564544
+#define EEEPC_WMI_METHODID_DSTS        0x53544344
+
+#define EEEPC_WMI_DEVID_BACKLIGHT      0x00050012
+
 static const struct key_entry eeepc_wmi_keymap[] = {
        /* Sleep already handled via generic ACPI code */
        { KE_KEY, 0x5d, { KEY_WLAN } },
@@ -58,18 +72,198 @@ static const struct key_entry eeepc_wmi_keymap[] = {
        { KE_END, 0},
 };
 
-static struct input_dev *eeepc_wmi_input_dev;
+struct bios_args {
+       u32     dev_id;
+       u32     ctrl_param;
+};
+
+struct eeepc_wmi {
+       struct input_dev *inputdev;
+       struct backlight_device *backlight_device;
+};
+
+static struct platform_device *platform_device;
+
+static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
+{
+       int err;
+
+       eeepc->inputdev = input_allocate_device();
+       if (!eeepc->inputdev)
+               return -ENOMEM;
+
+       eeepc->inputdev->name = "Eee PC WMI hotkeys";
+       eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
+       eeepc->inputdev->id.bustype = BUS_HOST;
+       eeepc->inputdev->dev.parent = &platform_device->dev;
+
+       err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
+       if (err)
+               goto err_free_dev;
+
+       err = input_register_device(eeepc->inputdev);
+       if (err)
+               goto err_free_keymap;
+
+       return 0;
+
+err_free_keymap:
+       sparse_keymap_free(eeepc->inputdev);
+err_free_dev:
+       input_free_device(eeepc->inputdev);
+       return err;
+}
+
+static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
+{
+       if (eeepc->inputdev) {
+               sparse_keymap_free(eeepc->inputdev);
+               input_unregister_device(eeepc->inputdev);
+       }
+
+       eeepc->inputdev = NULL;
+}
+
+static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *ctrl_param)
+{
+       struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
+       struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *obj;
+       acpi_status status;
+       u32 tmp;
+
+       status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+                       1, EEEPC_WMI_METHODID_DSTS, &input, &output);
+
+       if (ACPI_FAILURE(status))
+               return status;
+
+       obj = (union acpi_object *)output.pointer;
+       if (obj && obj->type == ACPI_TYPE_INTEGER)
+               tmp = (u32)obj->integer.value;
+       else
+               tmp = 0;
+
+       if (ctrl_param)
+               *ctrl_param = tmp;
+
+       kfree(obj);
+
+       return status;
+
+}
+
+static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param)
+{
+       struct bios_args args = {
+               .dev_id = dev_id,
+               .ctrl_param = ctrl_param,
+       };
+       struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+       acpi_status status;
+
+       status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
+                       1, EEEPC_WMI_METHODID_DEVS, &input, NULL);
+
+       return status;
+}
+
+static int read_brightness(struct backlight_device *bd)
+{
+       static u32 ctrl_param;
+       acpi_status status;
+
+       status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &ctrl_param);
+
+       if (ACPI_FAILURE(status))
+               return -1;
+       else
+               return ctrl_param & 0xFF;
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+
+       static u32 ctrl_param;
+       acpi_status status;
+
+       ctrl_param = bd->props.brightness;
+
+       status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT, ctrl_param);
+
+       if (ACPI_FAILURE(status))
+               return -1;
+       else
+               return 0;
+}
+
+static const struct backlight_ops eeepc_wmi_bl_ops = {
+       .get_brightness = read_brightness,
+       .update_status = update_bl_status,
+};
+
+static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
+{
+       struct backlight_device *bd = eeepc->backlight_device;
+       int old = bd->props.brightness;
+       int new;
+
+       if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+               new = code - NOTIFY_BRNUP_MIN + 1;
+       else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
+               new = code - NOTIFY_BRNDOWN_MIN;
+
+       bd->props.brightness = new;
+       backlight_update_status(bd);
+       backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
+
+       return old;
+}
+
+static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
+{
+       struct backlight_device *bd;
+       struct backlight_properties props;
+
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
+       bd = backlight_device_register(EEEPC_WMI_FILE,
+                                      &platform_device->dev, eeepc,
+                                      &eeepc_wmi_bl_ops, &props);
+       if (IS_ERR(bd)) {
+               pr_err("Could not register backlight device\n");
+               return PTR_ERR(bd);
+       }
+
+       eeepc->backlight_device = bd;
+
+       bd->props.brightness = read_brightness(bd);
+       bd->props.power = FB_BLANK_UNBLANK;
+       backlight_update_status(bd);
+
+       return 0;
+}
+
+static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
+{
+       if (eeepc->backlight_device)
+               backlight_device_unregister(eeepc->backlight_device);
+
+       eeepc->backlight_device = NULL;
+}
 
 static void eeepc_wmi_notify(u32 value, void *context)
 {
+       struct eeepc_wmi *eeepc = context;
        struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *obj;
        acpi_status status;
        int code;
+       int orig_code;
 
        status = wmi_get_event_data(value, &response);
        if (status != AE_OK) {
-               pr_err("EEEPC WMI: bad event status 0x%x\n", status);
+               pr_err("bad event status 0x%x\n", status);
                return;
        }
 
@@ -77,81 +271,142 @@ static void eeepc_wmi_notify(u32 value, void *context)
 
        if (obj && obj->type == ACPI_TYPE_INTEGER) {
                code = obj->integer.value;
+               orig_code = code;
 
                if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
                        code = NOTIFY_BRNUP_MIN;
-               else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
+               else if (code >= NOTIFY_BRNDOWN_MIN &&
+                        code <= NOTIFY_BRNDOWN_MAX)
                        code = NOTIFY_BRNDOWN_MIN;
 
-               if (!sparse_keymap_report_event(eeepc_wmi_input_dev,
+               if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
+                       if (!acpi_video_backlight_support())
+                               eeepc_wmi_backlight_notify(eeepc, orig_code);
+               }
+
+               if (!sparse_keymap_report_event(eeepc->inputdev,
                                                code, 1, true))
-                       pr_info("EEEPC WMI: Unknown key %x pressed\n", code);
+                       pr_info("Unknown key %x pressed\n", code);
        }
 
        kfree(obj);
 }
 
-static int eeepc_wmi_input_setup(void)
+static int __devinit eeepc_wmi_platform_probe(struct platform_device *device)
 {
+       struct eeepc_wmi *eeepc;
        int err;
+       acpi_status status;
 
-       eeepc_wmi_input_dev = input_allocate_device();
-       if (!eeepc_wmi_input_dev)
-               return -ENOMEM;
-
-       eeepc_wmi_input_dev->name = "Eee PC WMI hotkeys";
-       eeepc_wmi_input_dev->phys = "wmi/input0";
-       eeepc_wmi_input_dev->id.bustype = BUS_HOST;
+       eeepc = platform_get_drvdata(device);
 
-       err = sparse_keymap_setup(eeepc_wmi_input_dev, eeepc_wmi_keymap, NULL);
+       err = eeepc_wmi_input_init(eeepc);
        if (err)
-               goto err_free_dev;
+               goto error_input;
 
-       err = input_register_device(eeepc_wmi_input_dev);
-       if (err)
-               goto err_free_keymap;
+       if (!acpi_video_backlight_support()) {
+               err = eeepc_wmi_backlight_init(eeepc);
+               if (err)
+                       goto error_backlight;
+       } else
+               pr_info("Backlight controlled by ACPI video driver\n");
+
+       status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
+                                       eeepc_wmi_notify, eeepc);
+       if (ACPI_FAILURE(status)) {
+               pr_err("Unable to register notify handler - %d\n",
+                       status);
+               err = -ENODEV;
+               goto error_wmi;
+       }
 
        return 0;
 
-err_free_keymap:
-       sparse_keymap_free(eeepc_wmi_input_dev);
-err_free_dev:
-       input_free_device(eeepc_wmi_input_dev);
+error_wmi:
+       eeepc_wmi_backlight_exit(eeepc);
+error_backlight:
+       eeepc_wmi_input_exit(eeepc);
+error_input:
        return err;
 }
 
+static int __devexit eeepc_wmi_platform_remove(struct platform_device *device)
+{
+       struct eeepc_wmi *eeepc;
+
+       eeepc = platform_get_drvdata(device);
+       wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
+       eeepc_wmi_backlight_exit(eeepc);
+       eeepc_wmi_input_exit(eeepc);
+
+       return 0;
+}
+
+static struct platform_driver platform_driver = {
+       .driver = {
+               .name = EEEPC_WMI_FILE,
+               .owner = THIS_MODULE,
+       },
+       .probe = eeepc_wmi_platform_probe,
+       .remove = __devexit_p(eeepc_wmi_platform_remove),
+};
+
 static int __init eeepc_wmi_init(void)
 {
+       struct eeepc_wmi *eeepc;
        int err;
-       acpi_status status;
 
-       if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID)) {
-               pr_warning("EEEPC WMI: No known WMI GUID found\n");
+       if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
+           !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
+               pr_warning("No known WMI GUID found\n");
                return -ENODEV;
        }
 
-       err = eeepc_wmi_input_setup();
-       if (err)
-               return err;
+       eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
+       if (!eeepc)
+               return -ENOMEM;
 
-       status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
-                                       eeepc_wmi_notify, NULL);
-       if (ACPI_FAILURE(status)) {
-               sparse_keymap_free(eeepc_wmi_input_dev);
-               input_unregister_device(eeepc_wmi_input_dev);
-               pr_err("EEEPC WMI: Unable to register notify handler - %d\n",
-                       status);
-               return -ENODEV;
+       platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
+       if (!platform_device) {
+               pr_warning("Unable to allocate platform device\n");
+               err = -ENOMEM;
+               goto fail_platform;
+       }
+
+       err = platform_device_add(platform_device);
+       if (err) {
+               pr_warning("Unable to add platform device\n");
+               goto put_dev;
+       }
+
+       platform_set_drvdata(platform_device, eeepc);
+
+       err = platform_driver_register(&platform_driver);
+       if (err) {
+               pr_warning("Unable to register platform driver\n");
+               goto del_dev;
        }
 
        return 0;
+
+del_dev:
+       platform_device_del(platform_device);
+put_dev:
+       platform_device_put(platform_device);
+fail_platform:
+       kfree(eeepc);
+
+       return err;
 }
 
 static void __exit eeepc_wmi_exit(void)
 {
-       wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
-       sparse_keymap_free(eeepc_wmi_input_dev);
-       input_unregister_device(eeepc_wmi_input_dev);
+       struct eeepc_wmi *eeepc;
+
+       eeepc = platform_get_drvdata(platform_device);
+       platform_driver_unregister(&platform_driver);
+       platform_device_unregister(platform_device);
+       kfree(eeepc);
 }
 
 module_init(eeepc_wmi_init);
index 35bb44a..100e4d9 100644 (file)
@@ -274,26 +274,6 @@ static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
        pnp_add_bus_resource(dev, start, end);
 }
 
-static u64 addr_space_length(struct pnp_dev *dev, u64 min, u64 max, u64 len)
-{
-       u64 max_len;
-
-       max_len = max - min + 1;
-       if (len <= max_len)
-               return len;
-
-       /*
-        * Per 6.4.3.5, _LEN cannot exceed _MAX - _MIN + 1, but some BIOSes
-        * don't do this correctly, e.g.,
-        * https://bugzilla.kernel.org/show_bug.cgi?id=15480
-        */
-       dev_info(&dev->dev,
-                "resource length %#llx doesn't fit in %#llx-%#llx, trimming\n",
-                (unsigned long long) len, (unsigned long long) min,
-                (unsigned long long) max);
-       return max_len;
-}
-
 static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
                                                  struct acpi_resource *res)
 {
@@ -309,7 +289,8 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
                return;
        }
 
-       len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
+       /* Windows apparently computes length rather than using _LEN */
+       len = p->maximum - p->minimum + 1;
        window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
 
        if (p->resource_type == ACPI_MEMORY_RANGE)
@@ -330,7 +311,8 @@ static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
        int window;
        u64 len;
 
-       len = addr_space_length(dev, p->minimum, p->maximum, p->address_length);
+       /* Windows apparently computes length rather than using _LEN */
+       len = p->maximum - p->minimum + 1;
        window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
 
        if (p->resource_type == ACPI_MEMORY_RANGE)
index 2e54e6a..e3446ab 100644 (file)
@@ -211,6 +211,8 @@ int pnp_check_port(struct pnp_dev *dev, struct resource *res)
                        if (tres->flags & IORESOURCE_IO) {
                                if (cannot_compare(tres->flags))
                                        continue;
+                               if (tres->flags & IORESOURCE_WINDOW)
+                                       continue;
                                tport = &tres->start;
                                tend = &tres->end;
                                if (ranged_conflict(port, end, tport, tend))
@@ -271,6 +273,8 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
                        if (tres->flags & IORESOURCE_MEM) {
                                if (cannot_compare(tres->flags))
                                        continue;
+                               if (tres->flags & IORESOURCE_WINDOW)
+                                       continue;
                                taddr = &tres->start;
                                tend = &tres->end;
                                if (ranged_conflict(addr, end, taddr, tend))
index b6218f1..552cad8 100644 (file)
@@ -109,7 +109,7 @@ static int max8925_is_enabled(struct regulator_dev *rdev)
        struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
        int ret;
 
-       ret = max8925_reg_read(info->i2c, info->vol_reg);
+       ret = max8925_reg_read(info->i2c, info->enable_reg);
        if (ret < 0)
                return ret;
 
index a681f5e..ad036dd 100644 (file)
@@ -618,9 +618,12 @@ static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
                dev_get_platdata(&pdev->dev);
        int i;
 
+       platform_set_drvdata(pdev, NULL);
+
        for (i = 0; i < pdata->num_regulators; i++)
                regulator_unregister(priv->regulators[i]);
 
+       kfree(priv);
        return 0;
 }
 
index 6a13037..50ac047 100644 (file)
@@ -620,6 +620,16 @@ config RTC_DRV_NUC900
 
 comment "on-CPU RTC drivers"
 
+config RTC_DRV_DAVINCI
+       tristate "TI DaVinci RTC"
+       depends on ARCH_DAVINCI_DM365
+       help
+         If you say yes here you get support for the RTC on the
+         DaVinci platforms (DM365).
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-davinci.
+
 config RTC_DRV_OMAP
        tristate "TI OMAP1"
        depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX
index 44ef194..245311a 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_RTC_DRV_BQ32K)   += rtc-bq32k.o
 obj-$(CONFIG_RTC_DRV_BQ4802)   += rtc-bq4802.o
 obj-$(CONFIG_RTC_DRV_CMOS)     += rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_COH901331)        += rtc-coh901331.o
+obj-$(CONFIG_RTC_DRV_DAVINCI)  += rtc-davinci.o
 obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o
 obj-$(CONFIG_RTC_DRV_DS1216)   += rtc-ds1216.o
 obj-$(CONFIG_RTC_DRV_DS1286)   += rtc-ds1286.o
diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c
new file mode 100644 (file)
index 0000000..92a8f6c
--- /dev/null
@@ -0,0 +1,673 @@
+/*
+ * DaVinci Power Management and Real Time Clock Driver for TI platforms
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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/module.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+/*
+ * The DaVinci RTC is a simple RTC with the following
+ * Sec: 0 - 59 : BCD count
+ * Min: 0 - 59 : BCD count
+ * Hour: 0 - 23 : BCD count
+ * Day: 0 - 0x7FFF(32767) : Binary count ( Over 89 years )
+ */
+
+/* PRTC interface registers */
+#define DAVINCI_PRTCIF_PID             0x00
+#define PRTCIF_CTLR                    0x04
+#define PRTCIF_LDATA                   0x08
+#define PRTCIF_UDATA                   0x0C
+#define PRTCIF_INTEN                   0x10
+#define PRTCIF_INTFLG                  0x14
+
+/* PRTCIF_CTLR bit fields */
+#define PRTCIF_CTLR_BUSY               BIT(31)
+#define PRTCIF_CTLR_SIZE               BIT(25)
+#define PRTCIF_CTLR_DIR                        BIT(24)
+#define PRTCIF_CTLR_BENU_MSB           BIT(23)
+#define PRTCIF_CTLR_BENU_3RD_BYTE      BIT(22)
+#define PRTCIF_CTLR_BENU_2ND_BYTE      BIT(21)
+#define PRTCIF_CTLR_BENU_LSB           BIT(20)
+#define PRTCIF_CTLR_BENU_MASK          (0x00F00000)
+#define PRTCIF_CTLR_BENL_MSB           BIT(19)
+#define PRTCIF_CTLR_BENL_3RD_BYTE      BIT(18)
+#define PRTCIF_CTLR_BENL_2ND_BYTE      BIT(17)
+#define PRTCIF_CTLR_BENL_LSB           BIT(16)
+#define PRTCIF_CTLR_BENL_MASK          (0x000F0000)
+
+/* PRTCIF_INTEN bit fields */
+#define PRTCIF_INTEN_RTCSS             BIT(1)
+#define PRTCIF_INTEN_RTCIF             BIT(0)
+#define PRTCIF_INTEN_MASK              (PRTCIF_INTEN_RTCSS \
+                                       | PRTCIF_INTEN_RTCIF)
+
+/* PRTCIF_INTFLG bit fields */
+#define PRTCIF_INTFLG_RTCSS            BIT(1)
+#define PRTCIF_INTFLG_RTCIF            BIT(0)
+#define PRTCIF_INTFLG_MASK             (PRTCIF_INTFLG_RTCSS \
+                                       | PRTCIF_INTFLG_RTCIF)
+
+/* PRTC subsystem registers */
+#define PRTCSS_RTC_INTC_EXTENA1                (0x0C)
+#define PRTCSS_RTC_CTRL                        (0x10)
+#define PRTCSS_RTC_WDT                 (0x11)
+#define PRTCSS_RTC_TMR0                        (0x12)
+#define PRTCSS_RTC_TMR1                        (0x13)
+#define PRTCSS_RTC_CCTRL               (0x14)
+#define PRTCSS_RTC_SEC                 (0x15)
+#define PRTCSS_RTC_MIN                 (0x16)
+#define PRTCSS_RTC_HOUR                        (0x17)
+#define PRTCSS_RTC_DAY0                        (0x18)
+#define PRTCSS_RTC_DAY1                        (0x19)
+#define PRTCSS_RTC_AMIN                        (0x1A)
+#define PRTCSS_RTC_AHOUR               (0x1B)
+#define PRTCSS_RTC_ADAY0               (0x1C)
+#define PRTCSS_RTC_ADAY1               (0x1D)
+#define PRTCSS_RTC_CLKC_CNT            (0x20)
+
+/* PRTCSS_RTC_INTC_EXTENA1 */
+#define PRTCSS_RTC_INTC_EXTENA1_MASK   (0x07)
+
+/* PRTCSS_RTC_CTRL bit fields */
+#define PRTCSS_RTC_CTRL_WDTBUS         BIT(7)
+#define PRTCSS_RTC_CTRL_WEN            BIT(6)
+#define PRTCSS_RTC_CTRL_WDRT           BIT(5)
+#define PRTCSS_RTC_CTRL_WDTFLG         BIT(4)
+#define PRTCSS_RTC_CTRL_TE             BIT(3)
+#define PRTCSS_RTC_CTRL_TIEN           BIT(2)
+#define PRTCSS_RTC_CTRL_TMRFLG         BIT(1)
+#define PRTCSS_RTC_CTRL_TMMD           BIT(0)
+
+/* PRTCSS_RTC_CCTRL bit fields */
+#define PRTCSS_RTC_CCTRL_CALBUSY       BIT(7)
+#define PRTCSS_RTC_CCTRL_DAEN          BIT(5)
+#define PRTCSS_RTC_CCTRL_HAEN          BIT(4)
+#define PRTCSS_RTC_CCTRL_MAEN          BIT(3)
+#define PRTCSS_RTC_CCTRL_ALMFLG                BIT(2)
+#define PRTCSS_RTC_CCTRL_AIEN          BIT(1)
+#define PRTCSS_RTC_CCTRL_CAEN          BIT(0)
+
+static DEFINE_SPINLOCK(davinci_rtc_lock);
+
+struct davinci_rtc {
+       struct rtc_device               *rtc;
+       void __iomem                    *base;
+       resource_size_t                 pbase;
+       size_t                          base_size;
+       int                             irq;
+};
+
+static inline void rtcif_write(struct davinci_rtc *davinci_rtc,
+                              u32 val, u32 addr)
+{
+       writel(val, davinci_rtc->base + addr);
+}
+
+static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr)
+{
+       return readl(davinci_rtc->base + addr);
+}
+
+static inline void rtcif_wait(struct davinci_rtc *davinci_rtc)
+{
+       while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY)
+               cpu_relax();
+}
+
+static inline void rtcss_write(struct davinci_rtc *davinci_rtc,
+                              unsigned long val, u8 addr)
+{
+       rtcif_wait(davinci_rtc);
+
+       rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR);
+       rtcif_write(davinci_rtc, val, PRTCIF_LDATA);
+
+       rtcif_wait(davinci_rtc);
+}
+
+static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr)
+{
+       rtcif_wait(davinci_rtc);
+
+       rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr,
+                   PRTCIF_CTLR);
+
+       rtcif_wait(davinci_rtc);
+
+       return rtcif_read(davinci_rtc, PRTCIF_LDATA);
+}
+
+static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc)
+{
+       while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
+              PRTCSS_RTC_CCTRL_CALBUSY)
+               cpu_relax();
+}
+
+static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev)
+{
+       struct davinci_rtc *davinci_rtc = class_dev;
+       unsigned long events = 0;
+       u32 irq_flg;
+       u8 alm_irq, tmr_irq;
+       u8 rtc_ctrl, rtc_cctrl;
+       int ret = IRQ_NONE;
+
+       irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) &
+                 PRTCIF_INTFLG_RTCSS;
+
+       alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
+                 PRTCSS_RTC_CCTRL_ALMFLG;
+
+       tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) &
+                 PRTCSS_RTC_CTRL_TMRFLG;
+
+       if (irq_flg) {
+               if (alm_irq) {
+                       events |= RTC_IRQF | RTC_AF;
+                       rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
+                       rtc_cctrl |=  PRTCSS_RTC_CCTRL_ALMFLG;
+                       rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
+               } else if (tmr_irq) {
+                       events |= RTC_IRQF | RTC_PF;
+                       rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
+                       rtc_ctrl |=  PRTCSS_RTC_CTRL_TMRFLG;
+                       rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
+               }
+
+               rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS,
+                                   PRTCIF_INTFLG);
+               rtc_update_irq(davinci_rtc->rtc, 1, events);
+
+               ret = IRQ_HANDLED;
+       }
+
+       return ret;
+}
+
+static int
+davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       u8 rtc_ctrl;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
+
+       switch (cmd) {
+       case RTC_WIE_ON:
+               rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG;
+               break;
+       case RTC_WIE_OFF:
+               rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
+               break;
+       case RTC_UIE_OFF:
+       case RTC_UIE_ON:
+               ret = -ENOTTY;
+               break;
+       default:
+               ret = -ENOIOCTLCMD;
+       }
+
+       rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       return ret;
+}
+
+static int convertfromdays(u16 days, struct rtc_time *tm)
+{
+       int tmp_days, year, mon;
+
+       for (year = 2000;; year++) {
+               tmp_days = rtc_year_days(1, 12, year);
+               if (days >= tmp_days)
+                       days -= tmp_days;
+               else {
+                       for (mon = 0;; mon++) {
+                               tmp_days = rtc_month_days(mon, year);
+                               if (days >= tmp_days) {
+                                       days -= tmp_days;
+                               } else {
+                                       tm->tm_year = year - 1900;
+                                       tm->tm_mon = mon;
+                                       tm->tm_mday = days + 1;
+                                       break;
+                               }
+                       }
+                       break;
+               }
+       }
+       return 0;
+}
+
+static int convert2days(u16 *days, struct rtc_time *tm)
+{
+       int i;
+       *days = 0;
+
+       /* epoch == 1900 */
+       if (tm->tm_year < 100 || tm->tm_year > 199)
+               return -EINVAL;
+
+       for (i = 2000; i < 1900 + tm->tm_year; i++)
+               *days += rtc_year_days(1, 12, i);
+
+       *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year);
+
+       return 0;
+}
+
+static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       u16 days = 0;
+       u8 day0, day1;
+       unsigned long flags;
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC));
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN));
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR));
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       days |= day1;
+       days <<= 8;
+       days |= day0;
+
+       if (convertfromdays(days, tm) < 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       u16 days;
+       u8 rtc_cctrl;
+       unsigned long flags;
+
+       if (convert2days(&days, tm) < 0)
+               return -EINVAL;
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1);
+
+       rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
+       rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN;
+       rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       return 0;
+}
+
+static int davinci_rtc_alarm_irq_enable(struct device *dev,
+                                       unsigned int enabled)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       unsigned long flags;
+       u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       if (enabled)
+               rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN |
+                            PRTCSS_RTC_CCTRL_HAEN |
+                            PRTCSS_RTC_CCTRL_MAEN |
+                            PRTCSS_RTC_CCTRL_ALMFLG |
+                            PRTCSS_RTC_CCTRL_AIEN;
+       else
+               rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN;
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       return 0;
+}
+
+static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       u16 days = 0;
+       u8 day0, day1;
+       unsigned long flags;
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN));
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR));
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+       days |= day1;
+       days <<= 8;
+       days |= day0;
+
+       if (convertfromdays(days, &alm->time) < 0)
+               return -EINVAL;
+
+       alm->pending = !!(rtcss_read(davinci_rtc,
+                         PRTCSS_RTC_CCTRL) &
+                       PRTCSS_RTC_CCTRL_AIEN);
+       alm->enabled = alm->pending && device_may_wakeup(dev);
+
+       return 0;
+}
+
+static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       unsigned long flags;
+       u16 days;
+
+       if (alm->time.tm_mday <= 0 && alm->time.tm_mon < 0
+           && alm->time.tm_year < 0) {
+               struct rtc_time tm;
+               unsigned long now, then;
+
+               davinci_rtc_read_time(dev, &tm);
+               rtc_tm_to_time(&tm, &now);
+
+               alm->time.tm_mday = tm.tm_mday;
+               alm->time.tm_mon = tm.tm_mon;
+               alm->time.tm_year = tm.tm_year;
+               rtc_tm_to_time(&alm->time, &then);
+
+               if (then < now) {
+                       rtc_time_to_tm(now + 24 * 60 * 60, &tm);
+                       alm->time.tm_mday = tm.tm_mday;
+                       alm->time.tm_mon = tm.tm_mon;
+                       alm->time.tm_year = tm.tm_year;
+               }
+       }
+
+       if (convert2days(&days, &alm->time) < 0)
+               return -EINVAL;
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0);
+
+       davinci_rtcss_calendar_wait(davinci_rtc);
+       rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       return 0;
+}
+
+static int davinci_rtc_irq_set_state(struct device *dev, int enabled)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       unsigned long flags;
+       u8 rtc_ctrl;
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
+
+       if (enabled) {
+               while (rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL)
+                      & PRTCSS_RTC_CTRL_WDTBUS)
+                       cpu_relax();
+
+               rtc_ctrl |= PRTCSS_RTC_CTRL_TE;
+               rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
+
+               rtcss_write(davinci_rtc, 0x0, PRTCSS_RTC_CLKC_CNT);
+
+               rtc_ctrl |= PRTCSS_RTC_CTRL_TIEN |
+                           PRTCSS_RTC_CTRL_TMMD |
+                           PRTCSS_RTC_CTRL_TMRFLG;
+       } else
+               rtc_ctrl &= ~PRTCSS_RTC_CTRL_TIEN;
+
+       rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       return 0;
+}
+
+static int davinci_rtc_irq_set_freq(struct device *dev, int freq)
+{
+       struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
+       unsigned long flags;
+       u16 tmr_counter = (0x8000 >> (ffs(freq) - 1));
+
+       spin_lock_irqsave(&davinci_rtc_lock, flags);
+
+       rtcss_write(davinci_rtc, tmr_counter & 0xFF, PRTCSS_RTC_TMR0);
+       rtcss_write(davinci_rtc, (tmr_counter & 0xFF00) >> 8, PRTCSS_RTC_TMR1);
+
+       spin_unlock_irqrestore(&davinci_rtc_lock, flags);
+
+       return 0;
+}
+
+static struct rtc_class_ops davinci_rtc_ops = {
+       .ioctl                  = davinci_rtc_ioctl,
+       .read_time              = davinci_rtc_read_time,
+       .set_time               = davinci_rtc_set_time,
+       .alarm_irq_enable       = davinci_rtc_alarm_irq_enable,
+       .read_alarm             = davinci_rtc_read_alarm,
+       .set_alarm              = davinci_rtc_set_alarm,
+       .irq_set_state          = davinci_rtc_irq_set_state,
+       .irq_set_freq           = davinci_rtc_irq_set_freq,
+};
+
+static int __init davinci_rtc_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct davinci_rtc *davinci_rtc;
+       struct resource *res, *mem;
+       int ret = 0;
+
+       davinci_rtc = kzalloc(sizeof(struct davinci_rtc), GFP_KERNEL);
+       if (!davinci_rtc) {
+               dev_dbg(dev, "could not allocate memory for private data\n");
+               return -ENOMEM;
+       }
+
+       davinci_rtc->irq = platform_get_irq(pdev, 0);
+       if (davinci_rtc->irq < 0) {
+               dev_err(dev, "no RTC irq\n");
+               ret = davinci_rtc->irq;
+               goto fail1;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(dev, "no mem resource\n");
+               ret = -EINVAL;
+               goto fail1;
+       }
+
+       davinci_rtc->pbase = res->start;
+       davinci_rtc->base_size = resource_size(res);
+
+       mem = request_mem_region(davinci_rtc->pbase, davinci_rtc->base_size,
+                                pdev->name);
+       if (!mem) {
+               dev_err(dev, "RTC registers at %08x are not free\n",
+                       davinci_rtc->pbase);
+               ret = -EBUSY;
+               goto fail1;
+       }
+
+       davinci_rtc->base = ioremap(davinci_rtc->pbase, davinci_rtc->base_size);
+       if (!davinci_rtc->base) {
+               dev_err(dev, "unable to ioremap MEM resource\n");
+               ret = -ENOMEM;
+               goto fail2;
+       }
+
+       davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+                                   &davinci_rtc_ops, THIS_MODULE);
+       if (IS_ERR(davinci_rtc->rtc)) {
+               dev_err(dev, "unable to register RTC device, err %ld\n",
+                               PTR_ERR(davinci_rtc->rtc));
+               goto fail3;
+       }
+
+       rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
+       rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
+       rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1);
+
+       rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL);
+       rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
+
+       ret = request_irq(davinci_rtc->irq, davinci_rtc_interrupt,
+                         IRQF_DISABLED, "davinci_rtc", davinci_rtc);
+       if (ret < 0) {
+               dev_err(dev, "unable to register davinci RTC interrupt\n");
+               goto fail4;
+       }
+
+       /* Enable interrupts */
+       rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN);
+       rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK,
+                           PRTCSS_RTC_INTC_EXTENA1);
+
+       rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL);
+
+       platform_set_drvdata(pdev, davinci_rtc);
+
+       device_init_wakeup(&pdev->dev, 0);
+
+       return 0;
+
+fail4:
+       rtc_device_unregister(davinci_rtc->rtc);
+fail3:
+       iounmap(davinci_rtc->base);
+fail2:
+       release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size);
+fail1:
+       kfree(davinci_rtc);
+
+       return ret;
+}
+
+static int __devexit davinci_rtc_remove(struct platform_device *pdev)
+{
+       struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
+
+       device_init_wakeup(&pdev->dev, 0);
+
+       rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
+
+       free_irq(davinci_rtc->irq, davinci_rtc);
+
+       rtc_device_unregister(davinci_rtc->rtc);
+
+       iounmap(davinci_rtc->base);
+       release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size);
+
+       platform_set_drvdata(pdev, NULL);
+
+       kfree(davinci_rtc);
+
+       return 0;
+}
+
+static struct platform_driver davinci_rtc_driver = {
+       .probe          = davinci_rtc_probe,
+       .remove         = __devexit_p(davinci_rtc_remove),
+       .driver         = {
+               .name = "rtc_davinci",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init rtc_init(void)
+{
+       return platform_driver_probe(&davinci_rtc_driver, davinci_rtc_probe);
+}
+module_init(rtc_init);
+
+static void __exit rtc_exit(void)
+{
+       platform_driver_unregister(&davinci_rtc_driver);
+}
+module_exit(rtc_exit);
+
+MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>");
+MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
+MODULE_LICENSE("GPL");
index bbea90b..0e86247 100644 (file)
@@ -37,6 +37,9 @@
  */
 #define DASD_CHANQ_MAX_SIZE 4
 
+#define DASD_SLEEPON_START_TAG (void *) 1
+#define DASD_SLEEPON_END_TAG   (void *) 2
+
 /*
  * SECTION: exported variables of dasd.c
  */
@@ -62,6 +65,7 @@ static void dasd_device_tasklet(struct dasd_device *);
 static void dasd_block_tasklet(struct dasd_block *);
 static void do_kick_device(struct work_struct *);
 static void do_restore_device(struct work_struct *);
+static void do_reload_device(struct work_struct *);
 static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
 static void dasd_device_timeout(unsigned long);
 static void dasd_block_timeout(unsigned long);
@@ -112,6 +116,7 @@ struct dasd_device *dasd_alloc_device(void)
        device->timer.data = (unsigned long) device;
        INIT_WORK(&device->kick_work, do_kick_device);
        INIT_WORK(&device->restore_device, do_restore_device);
+       INIT_WORK(&device->reload_device, do_reload_device);
        device->state = DASD_STATE_NEW;
        device->target = DASD_STATE_NEW;
        mutex_init(&device->state_mutex);
@@ -517,6 +522,26 @@ void dasd_kick_device(struct dasd_device *device)
        schedule_work(&device->kick_work);
 }
 
+/*
+ * dasd_reload_device will schedule a call do do_reload_device to the kernel
+ * event daemon.
+ */
+static void do_reload_device(struct work_struct *work)
+{
+       struct dasd_device *device = container_of(work, struct dasd_device,
+                                                 reload_device);
+       device->discipline->reload(device);
+       dasd_put_device(device);
+}
+
+void dasd_reload_device(struct dasd_device *device)
+{
+       dasd_get_device(device);
+       /* queue call to dasd_reload_device to the kernel event daemon. */
+       schedule_work(&device->reload_device);
+}
+EXPORT_SYMBOL(dasd_reload_device);
+
 /*
  * dasd_restore_device will schedule a call do do_restore_device to the kernel
  * event daemon.
@@ -1472,7 +1497,10 @@ void dasd_add_request_tail(struct dasd_ccw_req *cqr)
  */
 static void dasd_wakeup_cb(struct dasd_ccw_req *cqr, void *data)
 {
-       wake_up((wait_queue_head_t *) data);
+       spin_lock_irq(get_ccwdev_lock(cqr->startdev->cdev));
+       cqr->callback_data = DASD_SLEEPON_END_TAG;
+       spin_unlock_irq(get_ccwdev_lock(cqr->startdev->cdev));
+       wake_up(&generic_waitq);
 }
 
 static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
@@ -1482,10 +1510,7 @@ static inline int _wait_for_wakeup(struct dasd_ccw_req *cqr)
 
        device = cqr->startdev;
        spin_lock_irq(get_ccwdev_lock(device->cdev));
-       rc = ((cqr->status == DASD_CQR_DONE ||
-              cqr->status == DASD_CQR_NEED_ERP ||
-              cqr->status == DASD_CQR_TERMINATED) &&
-             list_empty(&cqr->devlist));
+       rc = (cqr->callback_data == DASD_SLEEPON_END_TAG);
        spin_unlock_irq(get_ccwdev_lock(device->cdev));
        return rc;
 }
@@ -1573,7 +1598,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
                        wait_event(generic_waitq, !(device->stopped));
 
                cqr->callback = dasd_wakeup_cb;
-               cqr->callback_data = (void *) &generic_waitq;
+               cqr->callback_data = DASD_SLEEPON_START_TAG;
                dasd_add_request_tail(cqr);
                if (interruptible) {
                        rc = wait_event_interruptible(
@@ -1652,7 +1677,7 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
        }
 
        cqr->callback = dasd_wakeup_cb;
-       cqr->callback_data = (void *) &generic_waitq;
+       cqr->callback_data = DASD_SLEEPON_START_TAG;
        cqr->status = DASD_CQR_QUEUED;
        list_add(&cqr->devlist, &device->ccw_queue);
 
@@ -1899,7 +1924,8 @@ restart:
                /*  Process requests that may be recovered */
                if (cqr->status == DASD_CQR_NEED_ERP) {
                        erp_fn = base->discipline->erp_action(cqr);
-                       erp_fn(cqr);
+                       if (IS_ERR(erp_fn(cqr)))
+                               continue;
                        goto restart;
                }
 
index 6927e75..85bfd87 100644 (file)
@@ -1418,9 +1418,29 @@ static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
                                                struct dasd_ccw_req *erp)
 {
        struct dasd_ccw_req *cqr = erp->refers;
+       char *sense;
 
        if (cqr->block &&
            (cqr->block->base != cqr->startdev)) {
+
+               sense = dasd_get_sense(&erp->refers->irb);
+               /*
+                * dynamic pav may have changed base alias mapping
+                */
+               if (!test_bit(DASD_FLAG_OFFLINE, &cqr->startdev->flags) && sense
+                   && (sense[0] == 0x10) && (sense[7] == 0x0F)
+                   && (sense[8] == 0x67)) {
+                       /*
+                        * remove device from alias handling to prevent new
+                        * requests from being scheduled on the
+                        * wrong alias device
+                        */
+                       dasd_alias_remove_device(cqr->startdev);
+
+                       /* schedule worker to reload device */
+                       dasd_reload_device(cqr->startdev);
+               }
+
                if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
                        DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
                                    "ERP on alias device for request %p,"
@@ -2309,7 +2329,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
                                      cqr->retries);
                        dasd_block_set_timer(device->block, (HZ << 3));
                 }
-               return cqr;
+               return erp;
        }
 
        ccw = cqr->cpaddr;
@@ -2372,6 +2392,9 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
        /* add erp and initialize with default TIC */
        erp = dasd_3990_erp_add_erp(cqr);
 
+       if (IS_ERR(erp))
+               return erp;
+
        /* inspect sense, determine specific ERP if possible */
        if (erp != cqr) {
 
@@ -2711,6 +2734,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
        if (erp == NULL) {
                /* no matching erp found - set up erp */
                erp = dasd_3990_erp_additional_erp(cqr);
+               if (IS_ERR(erp))
+                       return erp;
        } else {
                /* matching erp found - set all leading erp's to DONE */
                erp = dasd_3990_erp_handle_match_erp(cqr, erp);
index 8c48142..4155805 100644 (file)
@@ -190,20 +190,21 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
        struct alias_server *server, *newserver;
        struct alias_lcu *lcu, *newlcu;
        int is_lcu_known;
-       struct dasd_uid *uid;
+       struct dasd_uid uid;
 
        private = (struct dasd_eckd_private *) device->private;
-       uid = &private->uid;
+
+       device->discipline->get_uid(device, &uid);
        spin_lock_irqsave(&aliastree.lock, flags);
        is_lcu_known = 1;
-       server = _find_server(uid);
+       server = _find_server(&uid);
        if (!server) {
                spin_unlock_irqrestore(&aliastree.lock, flags);
-               newserver = _allocate_server(uid);
+               newserver = _allocate_server(&uid);
                if (IS_ERR(newserver))
                        return PTR_ERR(newserver);
                spin_lock_irqsave(&aliastree.lock, flags);
-               server = _find_server(uid);
+               server = _find_server(&uid);
                if (!server) {
                        list_add(&newserver->server, &aliastree.serverlist);
                        server = newserver;
@@ -214,14 +215,14 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
                }
        }
 
-       lcu = _find_lcu(server, uid);
+       lcu = _find_lcu(server, &uid);
        if (!lcu) {
                spin_unlock_irqrestore(&aliastree.lock, flags);
-               newlcu = _allocate_lcu(uid);
+               newlcu = _allocate_lcu(&uid);
                if (IS_ERR(newlcu))
                        return PTR_ERR(newlcu);
                spin_lock_irqsave(&aliastree.lock, flags);
-               lcu = _find_lcu(server, uid);
+               lcu = _find_lcu(server, &uid);
                if (!lcu) {
                        list_add(&newlcu->lcu, &server->lculist);
                        lcu = newlcu;
@@ -256,20 +257,20 @@ void dasd_alias_lcu_setup_complete(struct dasd_device *device)
        unsigned long flags;
        struct alias_server *server;
        struct alias_lcu *lcu;
-       struct dasd_uid *uid;
+       struct dasd_uid uid;
 
        private = (struct dasd_eckd_private *) device->private;
-       uid = &private->uid;
+       device->discipline->get_uid(device, &uid);
        lcu = NULL;
        spin_lock_irqsave(&aliastree.lock, flags);
-       server = _find_server(uid);
+       server = _find_server(&uid);
        if (server)
-               lcu = _find_lcu(server, uid);
+               lcu = _find_lcu(server, &uid);
        spin_unlock_irqrestore(&aliastree.lock, flags);
        if (!lcu) {
                DBF_EVENT_DEVID(DBF_ERR, device->cdev,
                                "could not find lcu for %04x %02x",
-                               uid->ssid, uid->real_unit_addr);
+                               uid.ssid, uid.real_unit_addr);
                WARN_ON(1);
                return;
        }
@@ -282,20 +283,20 @@ void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
        unsigned long flags;
        struct alias_server *server;
        struct alias_lcu *lcu;
-       struct dasd_uid *uid;
+       struct dasd_uid uid;
 
        private = (struct dasd_eckd_private *) device->private;
-       uid = &private->uid;
+       device->discipline->get_uid(device, &uid);
        lcu = NULL;
        spin_lock_irqsave(&aliastree.lock, flags);
-       server = _find_server(uid);
+       server = _find_server(&uid);
        if (server)
-               lcu = _find_lcu(server, uid);
+               lcu = _find_lcu(server, &uid);
        spin_unlock_irqrestore(&aliastree.lock, flags);
        if (!lcu) {
                DBF_EVENT_DEVID(DBF_ERR, device->cdev,
                                "could not find lcu for %04x %02x",
-                               uid->ssid, uid->real_unit_addr);
+                               uid.ssid, uid.real_unit_addr);
                WARN_ON(1);
                return;
        }
@@ -314,9 +315,11 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
        struct alias_lcu *lcu;
        struct alias_server *server;
        int was_pending;
+       struct dasd_uid uid;
 
        private = (struct dasd_eckd_private *) device->private;
        lcu = private->lcu;
+       device->discipline->get_uid(device, &uid);
        spin_lock_irqsave(&lcu->lock, flags);
        list_del_init(&device->alias_list);
        /* make sure that the workers don't use this device */
@@ -353,7 +356,7 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
                        _schedule_lcu_update(lcu, NULL);
                spin_unlock(&lcu->lock);
        }
-       server = _find_server(&private->uid);
+       server = _find_server(&uid);
        if (server && list_empty(&server->lculist)) {
                list_del(&server->server);
                _free_server(server);
@@ -366,19 +369,30 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
  * in the lcu is up to date and will update the device uid before
  * adding it to a pav group.
  */
+
 static int _add_device_to_lcu(struct alias_lcu *lcu,
-                             struct dasd_device *device)
+                             struct dasd_device *device,
+                             struct dasd_device *pos)
 {
 
        struct dasd_eckd_private *private;
        struct alias_pav_group *group;
-       struct dasd_uid *uid;
+       struct dasd_uid uid;
+       unsigned long flags;
 
        private = (struct dasd_eckd_private *) device->private;
-       uid = &private->uid;
-       uid->type = lcu->uac->unit[uid->real_unit_addr].ua_type;
-       uid->base_unit_addr = lcu->uac->unit[uid->real_unit_addr].base_ua;
-       dasd_set_uid(device->cdev, &private->uid);
+
+       /* only lock if not already locked */
+       if (device != pos)
+               spin_lock_irqsave_nested(get_ccwdev_lock(device->cdev), flags,
+                                        CDEV_NESTED_SECOND);
+       private->uid.type = lcu->uac->unit[private->uid.real_unit_addr].ua_type;
+       private->uid.base_unit_addr =
+               lcu->uac->unit[private->uid.real_unit_addr].base_ua;
+       uid = private->uid;
+
+       if (device != pos)
+               spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
 
        /* if we have no PAV anyway, we don't need to bother with PAV groups */
        if (lcu->pav == NO_PAV) {
@@ -386,25 +400,25 @@ static int _add_device_to_lcu(struct alias_lcu *lcu,
                return 0;
        }
 
-       group = _find_group(lcu, uid);
+       group = _find_group(lcu, &uid);
        if (!group) {
                group = kzalloc(sizeof(*group), GFP_ATOMIC);
                if (!group)
                        return -ENOMEM;
-               memcpy(group->uid.vendor, uid->vendor, sizeof(uid->vendor));
-               memcpy(group->uid.serial, uid->serial, sizeof(uid->serial));
-               group->uid.ssid = uid->ssid;
-               if (uid->type == UA_BASE_DEVICE)
-                       group->uid.base_unit_addr = uid->real_unit_addr;
+               memcpy(group->uid.vendor, uid.vendor, sizeof(uid.vendor));
+               memcpy(group->uid.serial, uid.serial, sizeof(uid.serial));
+               group->uid.ssid = uid.ssid;
+               if (uid.type == UA_BASE_DEVICE)
+                       group->uid.base_unit_addr = uid.real_unit_addr;
                else
-                       group->uid.base_unit_addr = uid->base_unit_addr;
-               memcpy(group->uid.vduit, uid->vduit, sizeof(uid->vduit));
+                       group->uid.base_unit_addr = uid.base_unit_addr;
+               memcpy(group->uid.vduit, uid.vduit, sizeof(uid.vduit));
                INIT_LIST_HEAD(&group->group);
                INIT_LIST_HEAD(&group->baselist);
                INIT_LIST_HEAD(&group->aliaslist);
                list_add(&group->group, &lcu->grouplist);
        }
-       if (uid->type == UA_BASE_DEVICE)
+       if (uid.type == UA_BASE_DEVICE)
                list_move(&device->alias_list, &group->baselist);
        else
                list_move(&device->alias_list, &group->aliaslist);
@@ -525,7 +539,10 @@ static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu)
        if (rc)
                return rc;
 
-       spin_lock_irqsave(&lcu->lock, flags);
+       /* need to take cdev lock before lcu lock */
+       spin_lock_irqsave_nested(get_ccwdev_lock(refdev->cdev), flags,
+                                CDEV_NESTED_FIRST);
+       spin_lock(&lcu->lock);
        lcu->pav = NO_PAV;
        for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) {
                switch (lcu->uac->unit[i].ua_type) {
@@ -542,9 +559,10 @@ static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu)
 
        list_for_each_entry_safe(device, tempdev, &lcu->active_devices,
                                 alias_list) {
-               _add_device_to_lcu(lcu, device);
+               _add_device_to_lcu(lcu, device, refdev);
        }
-       spin_unlock_irqrestore(&lcu->lock, flags);
+       spin_unlock(&lcu->lock);
+       spin_unlock_irqrestore(get_ccwdev_lock(refdev->cdev), flags);
        return 0;
 }
 
@@ -628,9 +646,12 @@ int dasd_alias_add_device(struct dasd_device *device)
        private = (struct dasd_eckd_private *) device->private;
        lcu = private->lcu;
        rc = 0;
-       spin_lock_irqsave(&lcu->lock, flags);
+
+       /* need to take cdev lock before lcu lock */
+       spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+       spin_lock(&lcu->lock);
        if (!(lcu->flags & UPDATE_PENDING)) {
-               rc = _add_device_to_lcu(lcu, device);
+               rc = _add_device_to_lcu(lcu, device, device);
                if (rc)
                        lcu->flags |= UPDATE_PENDING;
        }
@@ -638,10 +659,19 @@ int dasd_alias_add_device(struct dasd_device *device)
                list_move(&device->alias_list, &lcu->active_devices);
                _schedule_lcu_update(lcu, device);
        }
-       spin_unlock_irqrestore(&lcu->lock, flags);
+       spin_unlock(&lcu->lock);
+       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
        return rc;
 }
 
+int dasd_alias_update_add_device(struct dasd_device *device)
+{
+       struct dasd_eckd_private *private;
+       private = (struct dasd_eckd_private *) device->private;
+       private->lcu->flags |= UPDATE_PENDING;
+       return dasd_alias_add_device(device);
+}
+
 int dasd_alias_remove_device(struct dasd_device *device)
 {
        struct dasd_eckd_private *private;
@@ -740,19 +770,30 @@ static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu)
        struct alias_pav_group *pavgroup;
        struct dasd_device *device;
        struct dasd_eckd_private *private;
+       unsigned long flags;
 
        /* active and inactive list can contain alias as well as base devices */
        list_for_each_entry(device, &lcu->active_devices, alias_list) {
                private = (struct dasd_eckd_private *) device->private;
-               if (private->uid.type != UA_BASE_DEVICE)
+               spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+               if (private->uid.type != UA_BASE_DEVICE) {
+                       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
+                                              flags);
                        continue;
+               }
+               spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
                dasd_schedule_block_bh(device->block);
                dasd_schedule_device_bh(device);
        }
        list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
                private = (struct dasd_eckd_private *) device->private;
-               if (private->uid.type != UA_BASE_DEVICE)
+               spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+               if (private->uid.type != UA_BASE_DEVICE) {
+                       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
+                                              flags);
                        continue;
+               }
+               spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
                dasd_schedule_block_bh(device->block);
                dasd_schedule_device_bh(device);
        }
index eff9c81..34d51dd 100644 (file)
@@ -49,7 +49,6 @@ struct dasd_devmap {
         unsigned int devindex;
         unsigned short features;
        struct dasd_device *device;
-       struct dasd_uid uid;
 };
 
 /*
@@ -936,42 +935,46 @@ dasd_device_status_show(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
 
-static ssize_t
-dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t dasd_alias_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
 {
-       struct dasd_devmap *devmap;
-       int alias;
+       struct dasd_device *device;
+       struct dasd_uid uid;
 
-       devmap = dasd_find_busid(dev_name(dev));
-       spin_lock(&dasd_devmap_lock);
-       if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
-               spin_unlock(&dasd_devmap_lock);
+       device = dasd_device_from_cdev(to_ccwdev(dev));
+       if (IS_ERR(device))
                return sprintf(buf, "0\n");
+
+       if (device->discipline && device->discipline->get_uid &&
+           !device->discipline->get_uid(device, &uid)) {
+               if (uid.type == UA_BASE_PAV_ALIAS ||
+                   uid.type == UA_HYPER_PAV_ALIAS)
+                       return sprintf(buf, "1\n");
        }
-       if (devmap->uid.type == UA_BASE_PAV_ALIAS ||
-           devmap->uid.type == UA_HYPER_PAV_ALIAS)
-               alias = 1;
-       else
-               alias = 0;
-       spin_unlock(&dasd_devmap_lock);
-       return sprintf(buf, alias ? "1\n" : "0\n");
+       dasd_put_device(device);
+
+       return sprintf(buf, "0\n");
 }
 
 static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
 
-static ssize_t
-dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t dasd_vendor_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
-       struct dasd_devmap *devmap;
+       struct dasd_device *device;
+       struct dasd_uid uid;
        char *vendor;
 
-       devmap = dasd_find_busid(dev_name(dev));
-       spin_lock(&dasd_devmap_lock);
-       if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
-               vendor = devmap->uid.vendor;
-       else
-               vendor = "";
-       spin_unlock(&dasd_devmap_lock);
+       device = dasd_device_from_cdev(to_ccwdev(dev));
+       vendor = "";
+       if (IS_ERR(device))
+               return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
+
+       if (device->discipline && device->discipline->get_uid &&
+           !device->discipline->get_uid(device, &uid))
+                       vendor = uid.vendor;
+
+       dasd_put_device(device);
 
        return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
 }
@@ -985,48 +988,51 @@ static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);
 static ssize_t
 dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct dasd_devmap *devmap;
+       struct dasd_device *device;
+       struct dasd_uid uid;
        char uid_string[UID_STRLEN];
        char ua_string[3];
-       struct dasd_uid *uid;
 
-       devmap = dasd_find_busid(dev_name(dev));
-       spin_lock(&dasd_devmap_lock);
-       if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
-               spin_unlock(&dasd_devmap_lock);
-               return sprintf(buf, "\n");
-       }
-       uid = &devmap->uid;
-       switch (uid->type) {
-       case UA_BASE_DEVICE:
-               sprintf(ua_string, "%02x", uid->real_unit_addr);
-               break;
-       case UA_BASE_PAV_ALIAS:
-               sprintf(ua_string, "%02x", uid->base_unit_addr);
-               break;
-       case UA_HYPER_PAV_ALIAS:
-               sprintf(ua_string, "xx");
-               break;
-       default:
-               /* should not happen, treat like base device */
-               sprintf(ua_string, "%02x", uid->real_unit_addr);
-               break;
+       device = dasd_device_from_cdev(to_ccwdev(dev));
+       uid_string[0] = 0;
+       if (IS_ERR(device))
+               return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
+
+       if (device->discipline && device->discipline->get_uid &&
+           !device->discipline->get_uid(device, &uid)) {
+               switch (uid.type) {
+               case UA_BASE_DEVICE:
+                       snprintf(ua_string, sizeof(ua_string), "%02x",
+                                uid.real_unit_addr);
+                       break;
+               case UA_BASE_PAV_ALIAS:
+                       snprintf(ua_string, sizeof(ua_string), "%02x",
+                                uid.base_unit_addr);
+                       break;
+               case UA_HYPER_PAV_ALIAS:
+                       snprintf(ua_string, sizeof(ua_string), "xx");
+                       break;
+               default:
+                       /* should not happen, treat like base device */
+                       snprintf(ua_string, sizeof(ua_string), "%02x",
+                                uid.real_unit_addr);
+                       break;
+               }
+
+               if (strlen(uid.vduit) > 0)
+                       snprintf(uid_string, sizeof(uid_string),
+                                "%s.%s.%04x.%s.%s",
+                                uid.vendor, uid.serial, uid.ssid, ua_string,
+                                uid.vduit);
+               else
+                       snprintf(uid_string, sizeof(uid_string),
+                                "%s.%s.%04x.%s",
+                                uid.vendor, uid.serial, uid.ssid, ua_string);
        }
-       if (strlen(uid->vduit) > 0)
-               snprintf(uid_string, sizeof(uid_string),
-                        "%s.%s.%04x.%s.%s",
-                        uid->vendor, uid->serial,
-                        uid->ssid, ua_string,
-                        uid->vduit);
-       else
-               snprintf(uid_string, sizeof(uid_string),
-                        "%s.%s.%04x.%s",
-                        uid->vendor, uid->serial,
-                        uid->ssid, ua_string);
-       spin_unlock(&dasd_devmap_lock);
+       dasd_put_device(device);
+
        return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
 }
-
 static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
 
 /*
@@ -1093,50 +1099,6 @@ static struct attribute_group dasd_attr_group = {
        .attrs = dasd_attrs,
 };
 
-/*
- * Return copy of the device unique identifier.
- */
-int
-dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
-{
-       struct dasd_devmap *devmap;
-
-       devmap = dasd_find_busid(dev_name(&cdev->dev));
-       if (IS_ERR(devmap))
-               return PTR_ERR(devmap);
-       spin_lock(&dasd_devmap_lock);
-       *uid = devmap->uid;
-       spin_unlock(&dasd_devmap_lock);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(dasd_get_uid);
-
-/*
- * Register the given device unique identifier into devmap struct.
- * In addition check if the related storage server subsystem ID is already
- * contained in the dasd_server_ssid_list. If subsystem ID is not contained,
- * create new entry.
- * Return 0 if server was already in serverlist,
- *       1 if the server was added successful
- *      <0 in case of error.
- */
-int
-dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
-{
-       struct dasd_devmap *devmap;
-
-       devmap = dasd_find_busid(dev_name(&cdev->dev));
-       if (IS_ERR(devmap))
-               return PTR_ERR(devmap);
-
-       spin_lock(&dasd_devmap_lock);
-       devmap->uid = *uid;
-       spin_unlock(&dasd_devmap_lock);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(dasd_set_uid);
-
 /*
  * Return value of the specified feature.
  */
index 0cb2331..5b1cd8d 100644 (file)
@@ -692,18 +692,20 @@ dasd_eckd_cdl_reclen(int recid)
 /*
  * Generate device unique id that specifies the physical device.
  */
-static int dasd_eckd_generate_uid(struct dasd_device *device,
-                                 struct dasd_uid *uid)
+static int dasd_eckd_generate_uid(struct dasd_device *device)
 {
        struct dasd_eckd_private *private;
+       struct dasd_uid *uid;
        int count;
+       unsigned long flags;
 
        private = (struct dasd_eckd_private *) device->private;
        if (!private)
                return -ENODEV;
        if (!private->ned || !private->gneq)
                return -ENODEV;
-
+       uid = &private->uid;
+       spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
        memset(uid, 0, sizeof(struct dasd_uid));
        memcpy(uid->vendor, private->ned->HDA_manufacturer,
               sizeof(uid->vendor) - 1);
@@ -726,9 +728,25 @@ static int dasd_eckd_generate_uid(struct dasd_device *device,
                                private->vdsneq->uit[count]);
                }
        }
+       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
        return 0;
 }
 
+static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)
+{
+       struct dasd_eckd_private *private;
+       unsigned long flags;
+
+       if (device->private) {
+               private = (struct dasd_eckd_private *)device->private;
+               spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+               *uid = private->uid;
+               spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+               return 0;
+       }
+       return -EINVAL;
+}
+
 static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
                                                    void *rcd_buffer,
                                                    struct ciw *ciw, __u8 lpm)
@@ -1088,6 +1106,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
 {
        struct dasd_eckd_private *private;
        struct dasd_block *block;
+       struct dasd_uid temp_uid;
        int is_known, rc;
        int readonly;
 
@@ -1124,13 +1143,13 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
        if (rc)
                goto out_err1;
 
-       /* Generate device unique id and register in devmap */
-       rc = dasd_eckd_generate_uid(device, &private->uid);
+       /* Generate device unique id */
+       rc = dasd_eckd_generate_uid(device);
        if (rc)
                goto out_err1;
-       dasd_set_uid(device->cdev, &private->uid);
 
-       if (private->uid.type == UA_BASE_DEVICE) {
+       dasd_eckd_get_uid(device, &temp_uid);
+       if (temp_uid.type == UA_BASE_DEVICE) {
                block = dasd_alloc_block();
                if (IS_ERR(block)) {
                        DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
@@ -1451,6 +1470,7 @@ static int dasd_eckd_ready_to_online(struct dasd_device *device)
 
 static int dasd_eckd_online_to_ready(struct dasd_device *device)
 {
+       cancel_work_sync(&device->reload_device);
        return dasd_alias_remove_device(device);
 };
 
@@ -1709,10 +1729,27 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
 {
        char mask;
        char *sense = NULL;
+       struct dasd_eckd_private *private;
 
+       private = (struct dasd_eckd_private *) device->private;
        /* first of all check for state change pending interrupt */
        mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
        if ((scsw_dstat(&irb->scsw) & mask) == mask) {
+               /* for alias only and not in offline processing*/
+               if (!device->block && private->lcu &&
+                   !test_bit(DASD_FLAG_OFFLINE, &device->flags)) {
+                       /*
+                        * the state change could be caused by an alias
+                        * reassignment remove device from alias handling
+                        * to prevent new requests from being scheduled on
+                        * the wrong alias device
+                        */
+                       dasd_alias_remove_device(device);
+
+                       /* schedule worker to reload device */
+                       dasd_reload_device(device);
+               }
+
                dasd_generic_handle_state_change(device);
                return;
        }
@@ -3259,7 +3296,7 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
                dasd_eckd_dump_sense_ccw(device, req, irb);
 }
 
-int dasd_eckd_pm_freeze(struct dasd_device *device)
+static int dasd_eckd_pm_freeze(struct dasd_device *device)
 {
        /*
         * the device should be disconnected from our LCU structure
@@ -3272,7 +3309,7 @@ int dasd_eckd_pm_freeze(struct dasd_device *device)
        return 0;
 }
 
-int dasd_eckd_restore_device(struct dasd_device *device)
+static int dasd_eckd_restore_device(struct dasd_device *device)
 {
        struct dasd_eckd_private *private;
        struct dasd_eckd_characteristics temp_rdc_data;
@@ -3287,15 +3324,16 @@ int dasd_eckd_restore_device(struct dasd_device *device)
        if (rc)
                goto out_err;
 
-       /* Generate device unique id and register in devmap */
-       rc = dasd_eckd_generate_uid(device, &private->uid);
-       dasd_get_uid(device->cdev, &temp_uid);
+       dasd_eckd_get_uid(device, &temp_uid);
+       /* Generate device unique id */
+       rc = dasd_eckd_generate_uid(device);
+       spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
        if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
                dev_err(&device->cdev->dev, "The UID of the DASD has "
                        "changed\n");
+       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
        if (rc)
                goto out_err;
-       dasd_set_uid(device->cdev, &private->uid);
 
        /* register lcu with alias handling, enable PAV if this is a new lcu */
        is_known = dasd_alias_make_device_known_to_lcu(device);
@@ -3336,6 +3374,56 @@ out_err:
        return -1;
 }
 
+static int dasd_eckd_reload_device(struct dasd_device *device)
+{
+       struct dasd_eckd_private *private;
+       int rc, old_base;
+       char print_uid[60];
+       struct dasd_uid uid;
+       unsigned long flags;
+
+       private = (struct dasd_eckd_private *) device->private;
+
+       spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+       old_base = private->uid.base_unit_addr;
+       spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
+
+       /* Read Configuration Data */
+       rc = dasd_eckd_read_conf(device);
+       if (rc)
+               goto out_err;
+
+       rc = dasd_eckd_generate_uid(device);
+       if (rc)
+               goto out_err;
+       /*
+        * update unit address configuration and
+        * add device to alias management
+        */
+       dasd_alias_update_add_device(device);
+
+       dasd_eckd_get_uid(device, &uid);
+
+       if (old_base != uid.base_unit_addr) {
+               if (strlen(uid.vduit) > 0)
+                       snprintf(print_uid, sizeof(print_uid),
+                                "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial,
+                                uid.ssid, uid.base_unit_addr, uid.vduit);
+               else
+                       snprintf(print_uid, sizeof(print_uid),
+                                "%s.%s.%04x.%02x", uid.vendor, uid.serial,
+                                uid.ssid, uid.base_unit_addr);
+
+               dev_info(&device->cdev->dev,
+                        "An Alias device was reassigned to a new base device "
+                        "with UID: %s\n", print_uid);
+       }
+       return 0;
+
+out_err:
+       return -1;
+}
+
 static struct ccw_driver dasd_eckd_driver = {
        .name        = "dasd-eckd",
        .owner       = THIS_MODULE,
@@ -3389,6 +3477,8 @@ static struct dasd_discipline dasd_eckd_discipline = {
        .ioctl = dasd_eckd_ioctl,
        .freeze = dasd_eckd_pm_freeze,
        .restore = dasd_eckd_restore_device,
+       .reload = dasd_eckd_reload_device,
+       .get_uid = dasd_eckd_get_uid,
 };
 
 static int __init
index 864d53c..dd6385a 100644 (file)
@@ -426,7 +426,6 @@ struct alias_pav_group {
        struct dasd_device *next;
 };
 
-
 struct dasd_eckd_private {
        struct dasd_eckd_characteristics rdc_data;
        u8 *conf_data;
@@ -463,4 +462,5 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *);
 void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *);
 void dasd_alias_lcu_setup_complete(struct dasd_device *);
 void dasd_alias_wait_for_lcu_setup(struct dasd_device *);
+int dasd_alias_update_add_device(struct dasd_device *);
 #endif                         /* DASD_ECKD_H */
index a91d4a9..32fac18 100644 (file)
@@ -81,6 +81,10 @@ struct dasd_block;
 #define DASD_SIM_MSG_TO_OP 0x03
 #define DASD_SIM_LOG 0x0C
 
+/* lock class for nested cdev lock */
+#define CDEV_NESTED_FIRST 1
+#define CDEV_NESTED_SECOND 2
+
 /*
  * SECTION: MACROs for klogd and s390 debug feature (dbf)
  */
@@ -228,6 +232,24 @@ struct dasd_ccw_req {
 /* Signature for error recovery functions. */
 typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
 
+/*
+ * Unique identifier for dasd device.
+ */
+#define UA_NOT_CONFIGURED  0x00
+#define UA_BASE_DEVICE    0x01
+#define UA_BASE_PAV_ALIAS  0x02
+#define UA_HYPER_PAV_ALIAS 0x03
+
+struct dasd_uid {
+       __u8 type;
+       char vendor[4];
+       char serial[15];
+       __u16 ssid;
+       __u8 real_unit_addr;
+       __u8 base_unit_addr;
+       char vduit[33];
+};
+
 /*
  * the struct dasd_discipline is
  * sth like a table of virtual functions, if you think of dasd_eckd
@@ -312,28 +334,15 @@ struct dasd_discipline {
        /* suspend/resume functions */
        int (*freeze) (struct dasd_device *);
        int (*restore) (struct dasd_device *);
-};
 
-extern struct dasd_discipline *dasd_diag_discipline_pointer;
-
-/*
- * Unique identifier for dasd device.
- */
-#define UA_NOT_CONFIGURED  0x00
-#define UA_BASE_DEVICE    0x01
-#define UA_BASE_PAV_ALIAS  0x02
-#define UA_HYPER_PAV_ALIAS 0x03
+       /* reload device after state change */
+       int (*reload) (struct dasd_device *);
 
-struct dasd_uid {
-       __u8 type;
-       char vendor[4];
-       char serial[15];
-       __u16 ssid;
-       __u8 real_unit_addr;
-       __u8 base_unit_addr;
-       char vduit[33];
+       int (*get_uid) (struct dasd_device *, struct dasd_uid *);
 };
 
+extern struct dasd_discipline *dasd_diag_discipline_pointer;
+
 /*
  * Notification numbers for extended error reporting notifications:
  * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's
@@ -386,6 +395,7 @@ struct dasd_device {
         struct tasklet_struct tasklet;
        struct work_struct kick_work;
        struct work_struct restore_device;
+       struct work_struct reload_device;
        struct timer_list timer;
 
        debug_info_t *debug_area;
@@ -582,6 +592,7 @@ void dasd_enable_device(struct dasd_device *);
 void dasd_set_target_state(struct dasd_device *, int);
 void dasd_kick_device(struct dasd_device *);
 void dasd_restore_device(struct dasd_device *);
+void dasd_reload_device(struct dasd_device *);
 
 void dasd_add_request_head(struct dasd_ccw_req *);
 void dasd_add_request_tail(struct dasd_ccw_req *);
@@ -629,8 +640,6 @@ void dasd_devmap_exit(void);
 struct dasd_device *dasd_create_device(struct ccw_device *);
 void dasd_delete_device(struct dasd_device *);
 
-int dasd_get_uid(struct ccw_device *, struct dasd_uid *);
-int dasd_set_uid(struct ccw_device *, struct dasd_uid *);
 int dasd_get_feature(struct ccw_device *, int);
 int dasd_set_feature(struct ccw_device *, int, int);
 
index 4e34d36..40834f1 100644 (file)
@@ -148,13 +148,12 @@ config VMLOGRDR
          This driver depends on the IUCV support driver.
 
 config VMCP
-       tristate "Support for the z/VM CP interface (VM only)"
+       bool "Support for the z/VM CP interface"
        depends on S390
        help
          Select this option if you want to be able to interact with the control
          program on z/VM
 
-
 config MONREADER
        tristate "API for reading z/VM monitor service records"
        depends on IUCV
index 0eabcca..857dfcb 100644 (file)
@@ -484,6 +484,7 @@ fs3270_open(struct inode *inode, struct file *filp)
                raw3270_del_view(&fp->view);
                goto out;
        }
+       nonseekable_open(inode, filp);
        filp->private_data = fp;
 out:
        mutex_unlock(&fs3270_mutex);
index cb6bffe..18d9a49 100644 (file)
@@ -49,7 +49,7 @@ static unsigned char ret_diacr[NR_DEAD] = {
 struct kbd_data *
 kbd_alloc(void) {
        struct kbd_data *kbd;
-       int i, len;
+       int i;
 
        kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL);
        if (!kbd)
@@ -59,12 +59,11 @@ kbd_alloc(void) {
                goto out_kbd;
        for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
                if (key_maps[i]) {
-                       kbd->key_maps[i] =
-                               kmalloc(sizeof(u_short)*NR_KEYS, GFP_KERNEL);
+                       kbd->key_maps[i] = kmemdup(key_maps[i],
+                                                  sizeof(u_short) * NR_KEYS,
+                                                  GFP_KERNEL);
                        if (!kbd->key_maps[i])
                                goto out_maps;
-                       memcpy(kbd->key_maps[i], key_maps[i],
-                              sizeof(u_short)*NR_KEYS);
                }
        }
        kbd->func_table = kzalloc(sizeof(func_table), GFP_KERNEL);
@@ -72,23 +71,21 @@ kbd_alloc(void) {
                goto out_maps;
        for (i = 0; i < ARRAY_SIZE(func_table); i++) {
                if (func_table[i]) {
-                       len = strlen(func_table[i]) + 1;
-                       kbd->func_table[i] = kmalloc(len, GFP_KERNEL);
+                       kbd->func_table[i] = kstrdup(func_table[i],
+                                                    GFP_KERNEL);
                        if (!kbd->func_table[i])
                                goto out_func;
-                       memcpy(kbd->func_table[i], func_table[i], len);
                }
        }
        kbd->fn_handler =
                kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL);
        if (!kbd->fn_handler)
                goto out_func;
-       kbd->accent_table =
-               kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL);
+       kbd->accent_table = kmemdup(accent_table,
+                                   sizeof(struct kbdiacruc) * MAX_DIACR,
+                                   GFP_KERNEL);
        if (!kbd->accent_table)
                goto out_fn_handler;
-       memcpy(kbd->accent_table, accent_table,
-              sizeof(struct kbdiacruc)*MAX_DIACR);
        kbd->accent_table_size = accent_table_size;
        return kbd;
 
index 5bb59d3..04e532e 100644 (file)
@@ -1,24 +1,20 @@
 /*
- * Copyright IBM Corp. 2004,2007
+ * Copyright IBM Corp. 2004,2010
  * Interface implementation for communication with the z/VM control program
- * Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
  *
+ * Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
  *
  * z/VMs CP offers the possibility to issue commands via the diagnose code 8
  * this driver implements a character device that issues these commands and
  * returns the answer of CP.
-
+ *
  * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS
  */
 
-#define KMSG_COMPONENT "vmcp"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
-#include <linux/module.h>
 #include <linux/slab.h>
 #include <asm/compat.h>
 #include <asm/cpcmd.h>
 #include <asm/uaccess.h>
 #include "vmcp.h"
 
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Christian Borntraeger <borntraeger@de.ibm.com>");
-MODULE_DESCRIPTION("z/VM CP interface");
-
 static debug_info_t *vmcp_debug;
 
 static int vmcp_open(struct inode *inode, struct file *file)
@@ -197,11 +189,8 @@ static int __init vmcp_init(void)
 {
        int ret;
 
-       if (!MACHINE_IS_VM) {
-               pr_warning("The z/VM CP interface device driver cannot be "
-                          "loaded without z/VM\n");
-               return -ENODEV;
-       }
+       if (!MACHINE_IS_VM)
+               return 0;
 
        vmcp_debug = debug_register("vmcp", 1, 1, 240);
        if (!vmcp_debug)
@@ -214,19 +203,8 @@ static int __init vmcp_init(void)
        }
 
        ret = misc_register(&vmcp_dev);
-       if (ret) {
+       if (ret)
                debug_unregister(vmcp_debug);
-               return ret;
-       }
-
-       return 0;
-}
-
-static void __exit vmcp_exit(void)
-{
-       misc_deregister(&vmcp_dev);
-       debug_unregister(vmcp_debug);
+       return ret;
 }
-
-module_init(vmcp_init);
-module_exit(vmcp_exit);
+device_initcall(vmcp_init);
index 18daf16..f5ea338 100644 (file)
@@ -445,7 +445,7 @@ static int zcore_memmap_open(struct inode *inode, struct file *filp)
        }
        kfree(chunk_array);
        filp->private_data = buf;
-       return 0;
+       return nonseekable_open(inode, filp);
 }
 
 static int zcore_memmap_release(struct inode *inode, struct file *filp)
@@ -473,7 +473,7 @@ static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
 
 static int zcore_reipl_open(struct inode *inode, struct file *filp)
 {
-       return 0;
+       return nonseekable_open(inode, filp);
 }
 
 static int zcore_reipl_release(struct inode *inode, struct file *filp)
@@ -638,11 +638,7 @@ static int __init zcore_reipl_init(void)
                rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
        else
                rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
-       if (rc) {
-               free_page((unsigned long) ipl_block);
-               return rc;
-       }
-       if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
+       if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
            ipib_info.checksum) {
                TRACE("Checksum does not match\n");
                free_page((unsigned long) ipl_block);
index 4038f5b..ce7cb87 100644 (file)
@@ -29,6 +29,7 @@
 #include "chsc.h"
 
 static void *sei_page;
+static DEFINE_SPINLOCK(sda_lock);
 
 /**
  * chsc_error_from_response() - convert a chsc response to an error
@@ -832,11 +833,10 @@ void __init chsc_free_sei_area(void)
        kfree(sei_page);
 }
 
-int __init
-chsc_enable_facility(int operation_code)
+int chsc_enable_facility(int operation_code)
 {
        int ret;
-       struct {
+       static struct {
                struct chsc_header request;
                u8 reserved1:4;
                u8 format:4;
@@ -849,33 +849,32 @@ chsc_enable_facility(int operation_code)
                u32 reserved5:4;
                u32 format2:4;
                u32 reserved6:24;
-       } __attribute__ ((packed)) *sda_area;
+       } __attribute__ ((packed, aligned(4096))) sda_area;
 
-       sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
-       if (!sda_area)
-               return -ENOMEM;
-       sda_area->request.length = 0x0400;
-       sda_area->request.code = 0x0031;
-       sda_area->operation_code = operation_code;
+       spin_lock(&sda_lock);
+       memset(&sda_area, 0, sizeof(sda_area));
+       sda_area.request.length = 0x0400;
+       sda_area.request.code = 0x0031;
+       sda_area.operation_code = operation_code;
 
-       ret = chsc(sda_area);
+       ret = chsc(&sda_area);
        if (ret > 0) {
                ret = (ret == 3) ? -ENODEV : -EBUSY;
                goto out;
        }
 
-       switch (sda_area->response.code) {
+       switch (sda_area.response.code) {
        case 0x0101:
                ret = -EOPNOTSUPP;
                break;
        default:
-               ret = chsc_error_from_response(sda_area->response.code);
+               ret = chsc_error_from_response(sda_area.response.code);
        }
        if (ret != 0)
                CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
-                             operation_code, sda_area->response.code);
+                             operation_code, sda_area.response.code);
  out:
-       free_page((unsigned long)sda_area);
+       spin_unlock(&sda_lock);
        return ret;
 }
 
index 404f630..a83877c 100644 (file)
@@ -124,7 +124,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
         * since we don't have a way to clear the subchannel and
         * cannot disable it with a request running.
         */
-       cc = stsch(sch->schid, &schib);
+       cc = stsch_err(sch->schid, &schib);
        if (!cc && scsw_stctl(&schib.scsw))
                return -EAGAIN;
        return 0;
@@ -803,6 +803,7 @@ static long chsc_ioctl(struct file *filp, unsigned int cmd,
 
 static const struct file_operations chsc_fops = {
        .owner = THIS_MODULE,
+       .open = nonseekable_open,
        .unlocked_ioctl = chsc_ioctl,
        .compat_ioctl = chsc_ioctl,
 };
index f736cdc..f4e6cf3 100644 (file)
@@ -361,7 +361,7 @@ int cio_commit_config(struct subchannel *sch)
        struct schib schib;
        int ccode, retry, ret = 0;
 
-       if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+       if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
                return -ENODEV;
 
        for (retry = 0; retry < 5; retry++) {
@@ -372,7 +372,7 @@ int cio_commit_config(struct subchannel *sch)
                        return ccode;
                switch (ccode) {
                case 0: /* successful */
-                       if (stsch(sch->schid, &schib) ||
+                       if (stsch_err(sch->schid, &schib) ||
                            !css_sch_is_valid(&schib))
                                return -ENODEV;
                        if (cio_check_config(sch, &schib)) {
@@ -404,7 +404,7 @@ int cio_update_schib(struct subchannel *sch)
 {
        struct schib schib;
 
-       if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
+       if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
                return -ENODEV;
 
        memcpy(&sch->schib, &schib, sizeof(schib));
@@ -616,7 +616,8 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
        struct pt_regs *old_regs;
 
        old_regs = set_irq_regs(regs);
-       s390_idle_check();
+       s390_idle_check(regs, S390_lowcore.int_clock,
+                       S390_lowcore.async_enter_timer);
        irq_enter();
        __get_cpu_var(s390_idle).nohz_delay = 1;
        if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
@@ -771,7 +772,7 @@ cio_get_console_sch_no(void)
        if (console_irq != -1) {
                /* VM provided us with the irq number of the console. */
                schid.sch_no = console_irq;
-               if (stsch(schid, &console_subchannel.schib) != 0 ||
+               if (stsch_err(schid, &console_subchannel.schib) != 0 ||
                    (console_subchannel.schib.pmcw.st != SUBCHANNEL_TYPE_IO) ||
                    !console_subchannel.schib.pmcw.dnv)
                        return -1;
@@ -863,10 +864,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
        cc = 0;
        for (retry=0;retry<3;retry++) {
                schib->pmcw.ena = 0;
-               cc = msch(schid, schib);
+               cc = msch_err(schid, schib);
                if (cc)
                        return (cc==3?-ENODEV:-EBUSY);
-               if (stsch(schid, schib) || !css_sch_is_valid(schib))
+               if (stsch_err(schid, schib) || !css_sch_is_valid(schib))
                        return -ENODEV;
                if (!schib->pmcw.ena)
                        return 0;
@@ -913,7 +914,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)
 
        pgm_check_occured = 0;
        s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
-       rc = stsch(schid, addr);
+       rc = stsch_err(schid, addr);
        s390_base_pgm_handler_fn = NULL;
 
        /* The program check handler could have changed pgm_check_occured. */
@@ -950,7 +951,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
                        /* No default clear strategy */
                        break;
                }
-               stsch(schid, &schib);
+               stsch_err(schid, &schib);
                __disable_subchannel_easy(schid, &schib);
        }
 out:
@@ -1086,7 +1087,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
        schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
        if (!schid.one)
                return -ENODEV;
-       if (stsch(schid, &schib))
+       if (stsch_err(schid, &schib))
                return -ENODEV;
        if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
                return -ENODEV;
index 2769da5..ac94ac7 100644 (file)
@@ -648,6 +648,8 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
 static void __init
 css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
 {
+       struct cpuid cpu_id;
+
        if (css_general_characteristics.mcss) {
                css->global_pgid.pgid_high.ext_cssid.version = 0x80;
                css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
@@ -658,8 +660,9 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
                css->global_pgid.pgid_high.cpu_addr = 0;
 #endif
        }
-       css->global_pgid.cpu_id = S390_lowcore.cpu_id.ident;
-       css->global_pgid.cpu_model = S390_lowcore.cpu_id.machine;
+       get_cpu_id(&cpu_id);
+       css->global_pgid.cpu_id = cpu_id.ident;
+       css->global_pgid.cpu_model = cpu_id.machine;
        css->global_pgid.tod_high = tod_high;
 
 }
@@ -870,15 +873,10 @@ static int __init css_bus_init(void)
 
        /* Try to enable MSS. */
        ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
-       switch (ret) {
-       case 0: /* Success. */
-               max_ssid = __MAX_SSID;
-               break;
-       case -ENOMEM:
-               goto out;
-       default:
+       if (ret)
                max_ssid = 0;
-       }
+       else /* Success. */
+               max_ssid = __MAX_SSID;
 
        ret = slow_subchannel_init();
        if (ret)
@@ -1048,6 +1046,11 @@ static int __init channel_subsystem_init_sync(void)
 }
 subsys_initcall_sync(channel_subsystem_init_sync);
 
+void channel_subsystem_reinit(void)
+{
+       chsc_enable_facility(CHSC_SDA_OC_MSS);
+}
+
 #ifdef CONFIG_PROC_FS
 static ssize_t cio_settle_write(struct file *file, const char __user *buf,
                                size_t count, loff_t *ppos)
@@ -1062,6 +1065,7 @@ static ssize_t cio_settle_write(struct file *file, const char __user *buf,
 }
 
 static const struct file_operations cio_settle_proc_fops = {
+       .open = nonseekable_open,
        .write = cio_settle_write,
 };
 
index c56ab94..c9b8526 100644 (file)
@@ -45,7 +45,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
        sch = to_subchannel(cdev->dev.parent);
        private = to_io_private(sch);
        orb = &private->orb;
-       cc = stsch(sch->schid, &schib);
+       cc = stsch_err(sch->schid, &schib);
 
        printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
               "device information:\n", get_clock());
index 48aa064..f0037ee 100644 (file)
@@ -13,8 +13,8 @@
 #include <asm/debug.h>
 #include "chsc.h"
 
-#define QDIO_BUSY_BIT_PATIENCE         100     /* 100 microseconds */
-#define QDIO_INPUT_THRESHOLD           500     /* 500 microseconds */
+#define QDIO_BUSY_BIT_PATIENCE         (100 << 12)     /* 100 microseconds */
+#define QDIO_INPUT_THRESHOLD           (500 << 12)     /* 500 microseconds */
 
 /*
  * if an asynchronous HiperSockets queue runs full, the 10 seconds timer wait
@@ -296,10 +296,8 @@ struct qdio_q {
        struct qdio_irq *irq_ptr;
        struct sl *sl;
        /*
-        * Warning: Leave this member at the end so it won't be cleared in
-        * qdio_fill_qs. A page is allocated under this pointer and used for
-        * slib and sl. slib is 2048 bytes big and sl points to offset
-        * PAGE_SIZE / 2.
+        * A page is allocated under this pointer and used for slib and sl.
+        * slib is 2048 bytes big and sl points to offset PAGE_SIZE / 2.
         */
        struct slib *slib;
 } __attribute__ ((aligned(256)));
@@ -372,11 +370,6 @@ static inline int multicast_outbound(struct qdio_q *q)
               (q->nr == q->irq_ptr->nr_output_qs - 1);
 }
 
-static inline unsigned long long get_usecs(void)
-{
-       return monotonic_clock() >> 12;
-}
-
 #define pci_out_supported(q) \
        (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)
 #define is_qebsm(q)                    (q->irq_ptr->sch_token != 0)
index 88be7b9..00520f9 100644 (file)
@@ -336,10 +336,10 @@ again:
                WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2);
 
                if (!start_time) {
-                       start_time = get_usecs();
+                       start_time = get_clock();
                        goto again;
                }
-               if ((get_usecs() - start_time) < QDIO_BUSY_BIT_PATIENCE)
+               if ((get_clock() - start_time) < QDIO_BUSY_BIT_PATIENCE)
                        goto again;
        }
        return cc;
@@ -536,7 +536,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q)
        if ((bufnr != q->last_move) || q->qdio_error) {
                q->last_move = bufnr;
                if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
-                       q->u.in.timestamp = get_usecs();
+                       q->u.in.timestamp = get_clock();
                return 1;
        } else
                return 0;
@@ -567,7 +567,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
         * At this point we know, that inbound first_to_check
         * has (probably) not moved (see qdio_inbound_processing).
         */
-       if (get_usecs() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
+       if (get_clock() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%02x",
                              q->first_to_check);
                return 1;
@@ -606,7 +606,7 @@ static void qdio_kick_handler(struct qdio_q *q)
 static void __qdio_inbound_processing(struct qdio_q *q)
 {
        qperf_inc(q, tasklet_inbound);
-again:
+
        if (!qdio_inbound_q_moved(q))
                return;
 
@@ -615,7 +615,10 @@ again:
        if (!qdio_inbound_q_done(q)) {
                /* means poll time is not yet over */
                qperf_inc(q, tasklet_inbound_resched);
-               goto again;
+               if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) {
+                       tasklet_schedule(&q->tasklet);
+                       return;
+               }
        }
 
        qdio_stop_polling(q);
@@ -625,7 +628,8 @@ again:
         */
        if (!qdio_inbound_q_done(q)) {
                qperf_inc(q, tasklet_inbound_resched2);
-               goto again;
+               if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+                       tasklet_schedule(&q->tasklet);
        }
 }
 
@@ -955,6 +959,9 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
                return;
        }
 
+       if (irq_ptr->perf_stat_enabled)
+               irq_ptr->perf_stat.qdio_int++;
+
        if (IS_ERR(irb)) {
                switch (PTR_ERR(irb)) {
                case -EIO:
@@ -1016,30 +1023,6 @@ int qdio_get_ssqd_desc(struct ccw_device *cdev,
 }
 EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
 
-/**
- * qdio_cleanup - shutdown queues and free data structures
- * @cdev: associated ccw device
- * @how: use halt or clear to shutdown
- *
- * This function calls qdio_shutdown() for @cdev with method @how.
- * and qdio_free(). The qdio_free() return value is ignored since
- * !irq_ptr is already checked.
- */
-int qdio_cleanup(struct ccw_device *cdev, int how)
-{
-       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
-       int rc;
-
-       if (!irq_ptr)
-               return -ENODEV;
-
-       rc = qdio_shutdown(cdev, how);
-
-       qdio_free(cdev);
-       return rc;
-}
-EXPORT_SYMBOL_GPL(qdio_cleanup);
-
 static void qdio_shutdown_queues(struct ccw_device *cdev)
 {
        struct qdio_irq *irq_ptr = cdev->private->qdio_data;
@@ -1156,28 +1139,6 @@ int qdio_free(struct ccw_device *cdev)
 }
 EXPORT_SYMBOL_GPL(qdio_free);
 
-/**
- * qdio_initialize - allocate and establish queues for a qdio subchannel
- * @init_data: initialization data
- *
- * This function first allocates queues via qdio_allocate() and on success
- * establishes them via qdio_establish().
- */
-int qdio_initialize(struct qdio_initialize *init_data)
-{
-       int rc;
-
-       rc = qdio_allocate(init_data);
-       if (rc)
-               return rc;
-
-       rc = qdio_establish(init_data);
-       if (rc)
-               qdio_free(init_data->cdev);
-       return rc;
-}
-EXPORT_SYMBOL_GPL(qdio_initialize);
-
 /**
  * qdio_allocate - allocate qdio queues and associated data
  * @init_data: initialization data
index 7f4a754..6326b67 100644 (file)
@@ -106,10 +106,12 @@ int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, int nr_output_qs
 static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
                              qdio_handler_t *handler, int i)
 {
-       /* must be cleared by every qdio_establish */
-       memset(q, 0, ((char *)&q->slib) - ((char *)q));
-       memset(q->slib, 0, PAGE_SIZE);
+       struct slib *slib = q->slib;
 
+       /* queue must be cleared for qdio_establish */
+       memset(q, 0, sizeof(*q));
+       memset(slib, 0, PAGE_SIZE);
+       q->slib = slib;
        q->irq_ptr = irq_ptr;
        q->mask = 1 << (31 - i);
        q->nr = i;
index ce5f891..8daf1b9 100644 (file)
@@ -95,7 +95,7 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
        for_each_input_queue(irq_ptr, q, i)
                list_add_rcu(&q->entry, &tiq_list);
        mutex_unlock(&tiq_list_lock);
-       xchg(irq_ptr->dsci, 1);
+       xchg(irq_ptr->dsci, 1 << 7);
 }
 
 void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
@@ -173,7 +173,7 @@ static void tiqdio_thinint_handler(void *ind, void *drv_data)
 
                /* prevent racing */
                if (*tiqdio_alsi)
-                       xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 1);
+                       xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 1 << 7);
        }
 }
 
index 304caf5..41e0aae 100644 (file)
@@ -302,7 +302,7 @@ static ssize_t zcrypt_write(struct file *filp, const char __user *buf,
 static int zcrypt_open(struct inode *inode, struct file *filp)
 {
        atomic_inc(&zcrypt_open_count);
-       return 0;
+       return nonseekable_open(inode, filp);
 }
 
 /**
index 3ba738b..28f7134 100644 (file)
@@ -1292,13 +1292,14 @@ int qeth_qdio_clear_card(struct qeth_card *card, int use_halt)
                QETH_QDIO_CLEANING)) {
        case QETH_QDIO_ESTABLISHED:
                if (card->info.type == QETH_CARD_TYPE_IQD)
-                       rc = qdio_cleanup(CARD_DDEV(card),
+                       rc = qdio_shutdown(CARD_DDEV(card),
                                QDIO_FLAG_CLEANUP_USING_HALT);
                else
-                       rc = qdio_cleanup(CARD_DDEV(card),
+                       rc = qdio_shutdown(CARD_DDEV(card),
                                QDIO_FLAG_CLEANUP_USING_CLEAR);
                if (rc)
                        QETH_DBF_TEXT_(TRACE, 3, "1err%d", rc);
+               qdio_free(CARD_DDEV(card));
                atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
                break;
        case QETH_QDIO_CLEANING:
@@ -3810,10 +3811,18 @@ static int qeth_qdio_establish(struct qeth_card *card)
 
        if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
                QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
-               rc = qdio_initialize(&init_data);
-               if (rc)
+               rc = qdio_allocate(&init_data);
+               if (rc) {
+                       atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
+                       goto out;
+               }
+               rc = qdio_establish(&init_data);
+               if (rc) {
                        atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
+                       qdio_free(CARD_DDEV(card));
+               }
        }
+out:
        kfree(out_sbal_ptrs);
        kfree(in_sbal_ptrs);
        kfree(qib_param_field);
index 25d9e0a..1a2db0a 100644 (file)
@@ -254,6 +254,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
 }
 
 static const struct file_operations zfcp_cfdc_fops = {
+       .open = nonseekable_open,
        .unlocked_ioctl = zfcp_cfdc_dev_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = zfcp_cfdc_dev_ioctl
index 1856489..b3b1d2f 100644 (file)
@@ -2105,7 +2105,8 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
        blktrc.inb_usage = req->qdio_req.qdio_inb_usage;
        blktrc.outb_usage = req->qdio_req.qdio_outb_usage;
 
-       if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+       if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
+           !(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
                blktrc.flags |= ZFCP_BLK_LAT_VALID;
                blktrc.channel_lat = lat_in->channel_lat * ticks;
                blktrc.fabric_lat = lat_in->fabric_lat * ticks;
@@ -2157,9 +2158,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
        fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
        zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
 
-       zfcp_fsf_req_trace(req, scpnt);
-
 skip_fsfstatus:
+       zfcp_fsf_req_trace(req, scpnt);
        zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
 
        scpnt->host_scribble = NULL;
index 19f255b..d3b62eb 100644 (file)
@@ -105,9 +105,9 @@ static ssize_t
 flash_read(struct file * file, char __user * buf,
           size_t count, loff_t *ppos)
 {
-       unsigned long p = file->f_pos;
+       loff_t p = *ppos;
        int i;
-       
+
        if (count > flash.read_size - p)
                count = flash.read_size - p;
 
@@ -118,7 +118,7 @@ flash_read(struct file * file, char __user * buf,
                buf++;
        }
 
-       file->f_pos += count;
+       *ppos += count;
        return count;
 }
 
index 9201afe..7f87979 100644 (file)
@@ -4724,6 +4724,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
        asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
                                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+       if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) {
+               warn_code = -ENOMEM;
+               goto err_dma_map;
+       }
        phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
        AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
                                 (uchar *)&phy_addr, 1);
@@ -4739,14 +4743,23 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
        AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
        if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
                asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
-               return warn_code;
+               warn_code = UW_ERR;
+               goto err_mcode_start;
        }
        if (AscStartChip(iop_base) != 1) {
                asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
-               return warn_code;
+               warn_code = UW_ERR;
+               goto err_mcode_start;
        }
 
        return warn_code;
+
+err_mcode_start:
+       dma_unmap_single(board->dev, asc_dvc->overrun_dma,
+                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+err_dma_map:
+       asc_dvc->overrun_dma = 0;
+       return warn_code;
 }
 
 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
@@ -4802,6 +4815,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
        }
        release_firmware(fw);
        warn_code |= AscInitMicroCodeVar(asc_dvc);
+       if (!asc_dvc->overrun_dma)
+               return warn_code;
        asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
        AscEnableInterrupt(iop_base);
        return warn_code;
@@ -7978,9 +7993,10 @@ static int advansys_reset(struct scsi_cmnd *scp)
                status = AscInitAsc1000Driver(asc_dvc);
 
                /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
-               if (asc_dvc->err_code) {
+               if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
                        scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
-                                   "0x%x\n", asc_dvc->err_code);
+                                   "0x%x, status: 0x%x\n", asc_dvc->err_code,
+                                   status);
                        ret = FAILED;
                } else if (status) {
                        scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
@@ -12311,7 +12327,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
                if (!asc_dvc_varp->overrun_buf) {
                        ret = -ENOMEM;
-                       goto err_free_wide_mem;
+                       goto err_free_irq;
                }
                warn_code = AscInitAsc1000Driver(asc_dvc_varp);
 
@@ -12320,30 +12336,36 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
                                        "warn 0x%x, error 0x%x\n",
                                        asc_dvc_varp->init_state, warn_code,
                                        asc_dvc_varp->err_code);
-                       if (asc_dvc_varp->err_code) {
+                       if (!asc_dvc_varp->overrun_dma) {
                                ret = -ENODEV;
-                               kfree(asc_dvc_varp->overrun_buf);
+                               goto err_free_mem;
                        }
                }
        } else {
-               if (advansys_wide_init_chip(shost))
+               if (advansys_wide_init_chip(shost)) {
                        ret = -ENODEV;
+                       goto err_free_mem;
+               }
        }
 
-       if (ret)
-               goto err_free_wide_mem;
-
        ASC_DBG_PRT_SCSI_HOST(2, shost);
 
        ret = scsi_add_host(shost, boardp->dev);
        if (ret)
-               goto err_free_wide_mem;
+               goto err_free_mem;
 
        scsi_scan_host(shost);
        return 0;
 
- err_free_wide_mem:
-       advansys_wide_free_mem(boardp);
+ err_free_mem:
+       if (ASC_NARROW_BOARD(boardp)) {
+               if (asc_dvc_varp->overrun_dma)
+                       dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
+                                        ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
+               kfree(asc_dvc_varp->overrun_buf);
+       } else
+               advansys_wide_free_mem(boardp);
+ err_free_irq:
        free_irq(boardp->irq, shost);
  err_free_dma:
 #ifdef CONFIG_ISA
index 72617b6..e641922 100644 (file)
@@ -169,6 +169,7 @@ unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
                SE_DEBUG(DBG_LVL_1,
                         "Failed to allocate memory for"
                         "mgmt_invalidate_icds \n");
+               spin_unlock(&ctrl->mbox_lock);
                return -1;
        }
        nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
index 6cf9dc3..6b624e7 100644 (file)
@@ -362,6 +362,7 @@ struct bnx2i_hba {
        u32 num_ccell;
 
        int ofld_conns_active;
+       wait_queue_head_t eh_wait;
 
        int max_active_conns;
        struct iscsi_cid_queue cid_que;
@@ -381,6 +382,7 @@ struct bnx2i_hba {
        spinlock_t lock;        /* protects hba structure access */
        struct mutex net_dev_lock;/* sync net device access */
 
+       int hba_shutdown_tmo;
        /*
         * PCI related info.
         */
index 6d8172e..5d9296c 100644 (file)
@@ -177,11 +177,22 @@ void bnx2i_stop(void *handle)
        struct bnx2i_hba *hba = handle;
 
        /* check if cleanup happened in GOING_DOWN context */
-       clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
        if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
                                &hba->adapter_state))
                iscsi_host_for_each_session(hba->shost,
                                            bnx2i_drop_session);
+
+       /* Wait for all endpoints to be torn down, Chip will be reset once
+        *  control returns to network driver. So it is required to cleanup and
+        * release all connection resources before returning from this routine.
+        */
+       wait_event_interruptible_timeout(hba->eh_wait,
+                                        (hba->ofld_conns_active == 0),
+                                        hba->hba_shutdown_tmo);
+       /* This flag should be cleared last so that ep_disconnect() gracefully
+        * cleans up connection context
+        */
+       clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 }
 
 /**
index f2e9b18..fa68ab3 100644 (file)
@@ -820,6 +820,11 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic)
 
        spin_lock_init(&hba->lock);
        mutex_init(&hba->net_dev_lock);
+       init_waitqueue_head(&hba->eh_wait);
+       if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
+               hba->hba_shutdown_tmo = 240 * HZ;
+       else    /* 5706/5708/5709 */
+               hba->hba_shutdown_tmo = 30 * HZ;
 
        if (iscsi_host_add(shost, &hba->pcidev->dev))
                goto free_dump_mem;
@@ -1658,8 +1663,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
                 */
                hba = bnx2i_check_route(dst_addr);
 
-       if (!hba) {
-               rc = -ENOMEM;
+       if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+               rc = -EINVAL;
                goto check_busy;
        }
 
@@ -1804,7 +1809,7 @@ static int bnx2i_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
                                               (bnx2i_ep->state ==
                                                EP_STATE_CONNECT_COMPL)),
                                              msecs_to_jiffies(timeout_ms));
-       if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED))
+       if (bnx2i_ep->state == EP_STATE_OFLD_FAILED)
                rc = -1;
 
        if (rc > 0)
@@ -1957,6 +1962,8 @@ return_bnx2i_ep:
 
        if (!hba->ofld_conns_active)
                bnx2i_unreg_dev_all();
+
+       wake_up_interruptible(&hba->eh_wait);
 }
 
 
index 4967643..0435d04 100644 (file)
@@ -188,7 +188,8 @@ MODULE_DEVICE_TABLE(pci,dptids);
 static int adpt_detect(struct scsi_host_template* sht)
 {
        struct pci_dev *pDev = NULL;
-       adpt_hba* pHba;
+       adpt_hba *pHba;
+       adpt_hba *next;
 
        PINFO("Detecting Adaptec I2O RAID controllers...\n");
 
@@ -206,7 +207,8 @@ static int adpt_detect(struct scsi_host_template* sht)
        }
 
        /* In INIT state, Activate IOPs */
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
                // Activate does get status , init outbound, and get hrt
                if (adpt_i2o_activate_hba(pHba) < 0) {
                        adpt_i2o_delete_hba(pHba);
@@ -243,7 +245,8 @@ rebuild_sys_tab:
        PDEBUG("HBA's in OPERATIONAL state\n");
 
        printk("dpti: If you have a lot of devices this could take a few minutes.\n");
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
                printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
                if (adpt_i2o_lct_get(pHba) < 0){
                        adpt_i2o_delete_hba(pHba);
@@ -263,7 +266,8 @@ rebuild_sys_tab:
                adpt_sysfs_class = NULL;
        }
 
-       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+       for (pHba = hba_chain; pHba; pHba = next) {
+               next = pHba->next;
                if (adpt_scsi_host_alloc(pHba, sht) < 0){
                        adpt_i2o_delete_hba(pHba);
                        continue;
@@ -1229,11 +1233,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
                }
        }
        pci_dev_put(pHba->pDev);
-       kfree(pHba);
-
        if (adpt_sysfs_class)
                device_destroy(adpt_sysfs_class,
                                MKDEV(DPTI_I2O_MAJOR, pHba->unit));
+       kfree(pHba);
 
        if(hba_count <= 0){
                unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
index ff5ec5a..88bad0e 100644 (file)
@@ -323,16 +323,6 @@ static void set_srp_direction(struct scsi_cmnd *cmd,
                srp_cmd->buf_fmt = fmt;
 }
 
-static void unmap_sg_list(int num_entries,
-               struct device *dev,
-               struct srp_direct_buf *md)
-{
-       int i;
-
-       for (i = 0; i < num_entries; ++i)
-               dma_unmap_single(dev, md[i].va, md[i].len, DMA_BIDIRECTIONAL);
-}
-
 /**
  * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format
  * @cmd:       srp_cmd whose additional_data member will be unmapped
@@ -350,24 +340,9 @@ static void unmap_cmd_data(struct srp_cmd *cmd,
 
        if (out_fmt == SRP_NO_DATA_DESC && in_fmt == SRP_NO_DATA_DESC)
                return;
-       else if (out_fmt == SRP_DATA_DESC_DIRECT ||
-                in_fmt == SRP_DATA_DESC_DIRECT) {
-               struct srp_direct_buf *data =
-                       (struct srp_direct_buf *) cmd->add_data;
-               dma_unmap_single(dev, data->va, data->len, DMA_BIDIRECTIONAL);
-       } else {
-               struct srp_indirect_buf *indirect =
-                       (struct srp_indirect_buf *) cmd->add_data;
-               int num_mapped = indirect->table_desc.len /
-                       sizeof(struct srp_direct_buf);
 
-               if (num_mapped <= MAX_INDIRECT_BUFS) {
-                       unmap_sg_list(num_mapped, dev, &indirect->desc_list[0]);
-                       return;
-               }
-
-               unmap_sg_list(num_mapped, dev, evt_struct->ext_list);
-       }
+       if (evt_struct->cmnd)
+               scsi_dma_unmap(evt_struct->cmnd);
 }
 
 static int map_sg_list(struct scsi_cmnd *cmd, int nseg,
index 0ee725c..02143af 100644 (file)
@@ -599,7 +599,7 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
        set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
        write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
 
-       if (sock->sk->sk_sleep && waitqueue_active(sock->sk->sk_sleep)) {
+       if (sock->sk->sk_sleep) {
                sock->sk->sk_err = EIO;
                wake_up_interruptible(sock->sk->sk_sleep);
        }
index 6d5ae44..633e090 100644 (file)
@@ -471,12 +471,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
 
        WARN_ON(hdrlength >= 256);
        hdr->hlength = hdrlength & 0xFF;
+       hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
 
        if (session->tt->init_task && session->tt->init_task(task))
                return -EIO;
 
        task->state = ISCSI_TASK_RUNNING;
-       hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
        session->cmdsn++;
 
        conn->scsicmd_pdus_cnt++;
index b00efd1..88f7446 100644 (file)
@@ -395,11 +395,15 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
 void sas_ata_task_abort(struct sas_task *task)
 {
        struct ata_queued_cmd *qc = task->uldd_task;
+       struct request_queue *q = qc->scsicmd->device->request_queue;
        struct completion *waiting;
+       unsigned long flags;
 
        /* Bounce SCSI-initiated commands to the SCSI EH */
        if (qc->scsicmd) {
+               spin_lock_irqsave(q->queue_lock, flags);
                blk_abort_request(qc->scsicmd->request);
+               spin_unlock_irqrestore(q->queue_lock, flags);
                scsi_schedule_eh(qc->scsicmd->device->host);
                return;
        }
index 2660e1b..8228350 100644 (file)
@@ -1030,6 +1030,8 @@ int __sas_task_abort(struct sas_task *task)
 void sas_task_abort(struct sas_task *task)
 {
        struct scsi_cmnd *sc = task->uldd_task;
+       struct request_queue *q = sc->device->request_queue;
+       unsigned long flags;
 
        /* Escape for libsas internal commands */
        if (!sc) {
@@ -1044,7 +1046,9 @@ void sas_task_abort(struct sas_task *task)
                return;
        }
 
+       spin_lock_irqsave(q->queue_lock, flags);
        blk_abort_request(sc->request);
+       spin_unlock_irqrestore(q->queue_lock, flags);
        scsi_schedule_eh(sc->device->host);
 }
 
index ec37238..d62b3e4 100644 (file)
@@ -433,7 +433,7 @@ lpfc_bsg_rport_els_cmp(struct lpfc_hba *phba,
        dd_data = cmdiocbq->context1;
        /* normal completion and timeout crossed paths, already done */
        if (!dd_data) {
-               spin_unlock_irqrestore(&phba->hbalock, flags);
+               spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
                return;
        }
 
@@ -1196,7 +1196,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
        dd_data = cmdiocbq->context1;
        /* normal completion and timeout crossed paths, already done */
        if (!dd_data) {
-               spin_unlock_irqrestore(&phba->hbalock, flags);
+               spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
                return;
        }
 
index 359e9a7..1c7ef55 100644 (file)
@@ -2393,6 +2393,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
        return 0;
 
 done:
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
        if (bsg_job->request->msgcode == FC_BSG_HST_CT)
                kfree(sp->fcport);
        kfree(sp->ctx);
index 09d6d4b..caeb7d1 100644 (file)
@@ -467,7 +467,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
        if (conn_err_detail)
                *conn_err_detail = mbox_sts[5];
        if (tcp_source_port_num)
-               *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
+               *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
        if (connection_id)
                *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
        status = QLA_SUCCESS;
index 3e10c30..3a5bfd1 100644 (file)
@@ -957,7 +957,8 @@ static int resp_start_stop(struct scsi_cmnd * scp,
 static sector_t get_sdebug_capacity(void)
 {
        if (scsi_debug_virtual_gb > 0)
-               return 2048 * 1024 * (sector_t)scsi_debug_virtual_gb;
+               return (sector_t)scsi_debug_virtual_gb *
+                       (1073741824 / scsi_debug_sector_size);
        else
                return sdebug_store_sectors;
 }
index d45c69c..7ad53fa 100644 (file)
@@ -302,7 +302,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
                if (scmd->device->allow_restart &&
                    (sshdr.asc == 0x04) && (sshdr.ascq == 0x02))
                        return FAILED;
-               return SUCCESS;
+
+               if (blk_barrier_rq(scmd->request))
+                       /*
+                        * barrier requests should always retry on UA
+                        * otherwise block will get a spurious error
+                        */
+                       return NEEDS_RETRY;
+               else
+                       /*
+                        * for normal (non barrier) commands, pass the
+                        * UA upwards for a determination in the
+                        * completion functions
+                        */
+                       return SUCCESS;
 
                /* these three are not supported */
        case COPY_ABORTED:
index 8b827f3..de6c603 100644 (file)
@@ -1040,6 +1040,7 @@ static void sd_prepare_flush(struct request_queue *q, struct request *rq)
 {
        rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->timeout = SD_TIMEOUT;
+       rq->retries = SD_MAX_RETRIES;
        rq->cmd[0] = SYNCHRONIZE_CACHE;
        rq->cmd_len = 10;
 }
index d0b7d2f..333580b 100644 (file)
@@ -1587,7 +1587,7 @@ static int wd7000_host_reset(struct scsi_cmnd *SCpnt)
 {
        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
-       spin_unlock_irq(SCpnt->device->host->host_lock);
+       spin_lock_irq(SCpnt->device->host->host_lock);
 
        if (wd7000_adapter_reset(host) < 0) {
                spin_unlock_irq(SCpnt->device->host->host_lock);
index 105449c..e17764d 100644 (file)
@@ -69,6 +69,7 @@ static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = {
        },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, zorro7xx_zorro_tbl);
 
 static int __devinit zorro7xx_init_one(struct zorro_dev *z,
                                       const struct zorro_device_id *ent)
index 24485cc..4822cb5 100644 (file)
@@ -348,6 +348,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
        {       "FUJ02E6",              0       },
        /* Fujitsu Wacom 2FGT Tablet PC device */
        {       "FUJ02E7",              0       },
+       /* Fujitsu Wacom 1FGT Tablet PC device */
+       {       "FUJ02E9",              0       },
        /*
         * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
         * disguise)
index f55c494..302836a 100644 (file)
@@ -518,12 +518,13 @@ config SERIAL_S3C2412
          Serial port support for the Samsung S3C2412 and S3C2413 SoC
 
 config SERIAL_S3C2440
-       tristate "Samsung S3C2440/S3C2442 Serial port support"
-       depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
+       tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
+       depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
        default y if CPU_S3C2440
        default y if CPU_S3C2442
+       select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
        help
-         Serial port support for the Samsung S3C2440 and S3C2442 SoC
+         Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
 
 config SERIAL_S3C24A0
        tristate "Samsung S3C24A0 Serial port support"
@@ -533,21 +534,13 @@ config SERIAL_S3C24A0
          Serial port support for the Samsung S3C24A0 SoC
 
 config SERIAL_S3C6400
-       tristate "Samsung S3C6400/S3C6410/S5P6440 Seria port support"
-       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440)
+       tristate "Samsung S3C6400/S3C6410/S5P6440/S5PC100 Serial port support"
+       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5PC100)
        select SERIAL_SAMSUNG_UARTS_4
        default y
        help
-         Serial port support for the Samsung S3C6400, S3C6410 and S5P6440
-         SoCs
-
-config SERIAL_S5PC100
-       tristate "Samsung S5PC100 Serial port support"
-       depends on SERIAL_SAMSUNG && CPU_S5PC100
-       select SERIAL_SAMSUNG_UARTS_4
-       default y
-       help
-         Serial port support for the Samsung S5PC100 SoCs
+         Serial port support for the Samsung S3C6400, S3C6410, S5P6440
+         and S5PC100 SoCs
 
 config SERIAL_S5PV210
        tristate "Samsung S5PV210 Serial port support"
index 6aa4723..328f107 100644 (file)
@@ -44,7 +44,6 @@ obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
 obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
 obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
 obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
-obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
 obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
 obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
index 2c9bf9b..eed3c2d 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/atmel_pdc.h>
 #include <linux/atmel_serial.h>
+#include <linux/uaccess.h>
 
 #include <asm/io.h>
 
@@ -59,6 +60,9 @@
 
 #include <linux/serial_core.h>
 
+static void atmel_start_rx(struct uart_port *port);
+static void atmel_stop_rx(struct uart_port *port);
+
 #ifdef CONFIG_SERIAL_ATMEL_TTYAT
 
 /* Use device name ttyAT, major 204 and minor 154-169.  This is necessary if we
@@ -93,6 +97,7 @@
 #define UART_GET_BRGR(port)    __raw_readl((port)->membase + ATMEL_US_BRGR)
 #define UART_PUT_BRGR(port,v)  __raw_writel(v, (port)->membase + ATMEL_US_BRGR)
 #define UART_PUT_RTOR(port,v)  __raw_writel(v, (port)->membase + ATMEL_US_RTOR)
+#define UART_PUT_TTGR(port, v) __raw_writel(v, (port)->membase + ATMEL_US_TTGR)
 
  /* PDC registers */
 #define UART_PUT_PTCR(port,v)  __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
@@ -147,6 +152,9 @@ struct atmel_uart_port {
        unsigned int            irq_status_prev;
 
        struct circ_buf         rx_ring;
+
+       struct serial_rs485     rs485;          /* rs485 settings */
+       unsigned int            tx_done_mask;
 };
 
 static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
@@ -187,6 +195,46 @@ static bool atmel_use_dma_tx(struct uart_port *port)
 }
 #endif
 
+/* Enable or disable the rs485 support */
+void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
+{
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+       unsigned int mode;
+
+       spin_lock(&port->lock);
+
+       /* Disable interrupts */
+       UART_PUT_IDR(port, atmel_port->tx_done_mask);
+
+       mode = UART_GET_MR(port);
+
+       /* Resetting serial mode to RS232 (0x0) */
+       mode &= ~ATMEL_US_USMODE;
+
+       atmel_port->rs485 = *rs485conf;
+
+       if (rs485conf->flags & SER_RS485_ENABLED) {
+               dev_dbg(port->dev, "Setting UART to RS485\n");
+               atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
+               UART_PUT_TTGR(port, rs485conf->delay_rts_before_send);
+               mode |= ATMEL_US_USMODE_RS485;
+       } else {
+               dev_dbg(port->dev, "Setting UART to RS232\n");
+               if (atmel_use_dma_tx(port))
+                       atmel_port->tx_done_mask = ATMEL_US_ENDTX |
+                               ATMEL_US_TXBUFE;
+               else
+                       atmel_port->tx_done_mask = ATMEL_US_TXRDY;
+       }
+       UART_PUT_MR(port, mode);
+
+       /* Enable interrupts */
+       UART_PUT_IER(port, atmel_port->tx_done_mask);
+
+       spin_unlock(&port->lock);
+
+}
+
 /*
  * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
  */
@@ -202,6 +250,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
 {
        unsigned int control = 0;
        unsigned int mode;
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
 #ifdef CONFIG_ARCH_AT91RM9200
        if (cpu_is_at91rm9200()) {
@@ -236,6 +285,17 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
                mode |= ATMEL_US_CHMODE_LOC_LOOP;
        else
                mode |= ATMEL_US_CHMODE_NORMAL;
+
+       /* Resetting serial mode to RS232 (0x0) */
+       mode &= ~ATMEL_US_USMODE;
+
+       if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+               dev_dbg(port->dev, "Setting UART to RS485\n");
+               UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
+               mode |= ATMEL_US_USMODE_RS485;
+       } else {
+               dev_dbg(port->dev, "Setting UART to RS232\n");
+       }
        UART_PUT_MR(port, mode);
 }
 
@@ -268,12 +328,17 @@ static u_int atmel_get_mctrl(struct uart_port *port)
  */
 static void atmel_stop_tx(struct uart_port *port)
 {
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
        if (atmel_use_dma_tx(port)) {
                /* disable PDC transmit */
                UART_PUT_PTCR(port, ATMEL_PDC_TXTDIS);
-               UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
-       } else
-               UART_PUT_IDR(port, ATMEL_US_TXRDY);
+       }
+       /* Disable interrupts */
+       UART_PUT_IDR(port, atmel_port->tx_done_mask);
+
+       if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+               atmel_start_rx(port);
 }
 
 /*
@@ -281,17 +346,39 @@ static void atmel_stop_tx(struct uart_port *port)
  */
 static void atmel_start_tx(struct uart_port *port)
 {
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+
        if (atmel_use_dma_tx(port)) {
                if (UART_GET_PTSR(port) & ATMEL_PDC_TXTEN)
                        /* The transmitter is already running.  Yes, we
                           really need this.*/
                        return;
 
-               UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+               if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+                       atmel_stop_rx(port);
+
                /* re-enable PDC transmit */
                UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
-       } else
-               UART_PUT_IER(port, ATMEL_US_TXRDY);
+       }
+       /* Enable interrupts */
+       UART_PUT_IER(port, atmel_port->tx_done_mask);
+}
+
+/*
+ * start receiving - port is in process of being opened.
+ */
+static void atmel_start_rx(struct uart_port *port)
+{
+       UART_PUT_CR(port, ATMEL_US_RSTSTA);  /* reset status and receiver */
+
+       if (atmel_use_dma_rx(port)) {
+               /* enable PDC controller */
+               UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
+                       port->read_status_mask);
+               UART_PUT_PTCR(port, ATMEL_PDC_RXTEN);
+       } else {
+               UART_PUT_IER(port, ATMEL_US_RXRDY);
+       }
 }
 
 /*
@@ -302,9 +389,11 @@ static void atmel_stop_rx(struct uart_port *port)
        if (atmel_use_dma_rx(port)) {
                /* disable PDC receive */
                UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS);
-               UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
-       } else
+               UART_PUT_IDR(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT |
+                       port->read_status_mask);
+       } else {
                UART_PUT_IDR(port, ATMEL_US_RXRDY);
+       }
 }
 
 /*
@@ -428,8 +517,9 @@ static void atmel_rx_chars(struct uart_port *port)
 static void atmel_tx_chars(struct uart_port *port)
 {
        struct circ_buf *xmit = &port->state->xmit;
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) {
+       if (port->x_char && UART_GET_CSR(port) & atmel_port->tx_done_mask) {
                UART_PUT_CHAR(port, port->x_char);
                port->icount.tx++;
                port->x_char = 0;
@@ -437,7 +527,7 @@ static void atmel_tx_chars(struct uart_port *port)
        if (uart_circ_empty(xmit) || uart_tx_stopped(port))
                return;
 
-       while (UART_GET_CSR(port) & ATMEL_US_TXRDY) {
+       while (UART_GET_CSR(port) & atmel_port->tx_done_mask) {
                UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
                port->icount.tx++;
@@ -449,7 +539,8 @@ static void atmel_tx_chars(struct uart_port *port)
                uart_write_wakeup(port);
 
        if (!uart_circ_empty(xmit))
-               UART_PUT_IER(port, ATMEL_US_TXRDY);
+               /* Enable interrupts */
+               UART_PUT_IER(port, atmel_port->tx_done_mask);
 }
 
 /*
@@ -501,18 +592,10 @@ atmel_handle_transmit(struct uart_port *port, unsigned int pending)
 {
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       if (atmel_use_dma_tx(port)) {
-               /* PDC transmit */
-               if (pending & (ATMEL_US_ENDTX | ATMEL_US_TXBUFE)) {
-                       UART_PUT_IDR(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
-                       tasklet_schedule(&atmel_port->tasklet);
-               }
-       } else {
-               /* Interrupt transmit */
-               if (pending & ATMEL_US_TXRDY) {
-                       UART_PUT_IDR(port, ATMEL_US_TXRDY);
-                       tasklet_schedule(&atmel_port->tasklet);
-               }
+       if (pending & atmel_port->tx_done_mask) {
+               /* Either PDC or interrupt transmission */
+               UART_PUT_IDR(port, atmel_port->tx_done_mask);
+               tasklet_schedule(&atmel_port->tasklet);
        }
 }
 
@@ -590,9 +673,15 @@ static void atmel_tx_dma(struct uart_port *port)
 
                UART_PUT_TPR(port, pdc->dma_addr + xmit->tail);
                UART_PUT_TCR(port, count);
-               /* re-enable PDC transmit and interrupts */
+               /* re-enable PDC transmit */
                UART_PUT_PTCR(port, ATMEL_PDC_TXTEN);
-               UART_PUT_IER(port, ATMEL_US_ENDTX | ATMEL_US_TXBUFE);
+               /* Enable interrupts */
+               UART_PUT_IER(port, atmel_port->tx_done_mask);
+       } else {
+               if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+                       /* DMA done, stop TX, start RX for RS485 */
+                       atmel_start_rx(port);
+               }
        }
 
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -1017,6 +1106,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
 {
        unsigned long flags;
        unsigned int mode, imr, quot, baud;
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
        /* Get current mode register */
        mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
@@ -1115,6 +1205,17 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
        /* disable receiver and transmitter */
        UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS);
 
+       /* Resetting serial mode to RS232 (0x0) */
+       mode &= ~ATMEL_US_USMODE;
+
+       if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
+               dev_dbg(port->dev, "Setting UART to RS485\n");
+               UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_before_send);
+               mode |= ATMEL_US_USMODE_RS485;
+       } else {
+               dev_dbg(port->dev, "Setting UART to RS232\n");
+       }
+
        /* set the parity, stop bits and data size */
        UART_PUT_MR(port, mode);
 
@@ -1231,6 +1332,35 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch)
 }
 #endif
 
+static int
+atmel_ioctl(struct uart_port *port, unsigned int cmd, unsigned long arg)
+{
+       struct serial_rs485 rs485conf;
+
+       switch (cmd) {
+       case TIOCSRS485:
+               if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg,
+                                       sizeof(rs485conf)))
+                       return -EFAULT;
+
+               atmel_config_rs485(port, &rs485conf);
+               break;
+
+       case TIOCGRS485:
+               if (copy_to_user((struct serial_rs485 *) arg,
+                                       &(to_atmel_uart_port(port)->rs485),
+                                       sizeof(rs485conf)))
+                       return -EFAULT;
+               break;
+
+       default:
+               return -ENOIOCTLCMD;
+       }
+       return 0;
+}
+
+
+
 static struct uart_ops atmel_pops = {
        .tx_empty       = atmel_tx_empty,
        .set_mctrl      = atmel_set_mctrl,
@@ -1250,6 +1380,7 @@ static struct uart_ops atmel_pops = {
        .config_port    = atmel_config_port,
        .verify_port    = atmel_verify_port,
        .pm             = atmel_serial_pm,
+       .ioctl          = atmel_ioctl,
 #ifdef CONFIG_CONSOLE_POLL
        .poll_get_char  = atmel_poll_get_char,
        .poll_put_char  = atmel_poll_put_char,
@@ -1265,13 +1396,12 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
        struct uart_port *port = &atmel_port->uart;
        struct atmel_uart_data *data = pdev->dev.platform_data;
 
-       port->iotype    = UPIO_MEM;
-       port->flags     = UPF_BOOT_AUTOCONF;
-       port->ops       = &atmel_pops;
-       port->fifosize  = 1;
-       port->line      = pdev->id;
-       port->dev       = &pdev->dev;
-
+       port->iotype            = UPIO_MEM;
+       port->flags             = UPF_BOOT_AUTOCONF;
+       port->ops               = &atmel_pops;
+       port->fifosize          = 1;
+       port->line              = pdev->id;
+       port->dev               = &pdev->dev;
        port->mapbase   = pdev->resource[0].start;
        port->irq       = pdev->resource[1].start;
 
@@ -1299,8 +1429,16 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port,
 
        atmel_port->use_dma_rx = data->use_dma_rx;
        atmel_port->use_dma_tx = data->use_dma_tx;
-       if (atmel_use_dma_tx(port))
+       atmel_port->rs485       = data->rs485;
+       /* Use TXEMPTY for interrupt when rs485 else TXRDY or ENDTX|TXBUFE */
+       if (atmel_port->rs485.flags & SER_RS485_ENABLED)
+               atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
+       else if (atmel_use_dma_tx(port)) {
                port->fifosize = PDC_BUFFER_SIZE;
+               atmel_port->tx_done_mask = ATMEL_US_ENDTX | ATMEL_US_TXBUFE;
+       } else {
+               atmel_port->tx_done_mask = ATMEL_US_TXRDY;
+       }
 }
 
 /*
@@ -1334,6 +1472,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch)
 static void atmel_console_write(struct console *co, const char *s, u_int count)
 {
        struct uart_port *port = &atmel_ports[co->index].uart;
+       struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
        unsigned int status, imr;
        unsigned int pdc_tx;
 
@@ -1341,7 +1480,7 @@ static void atmel_console_write(struct console *co, const char *s, u_int count)
         * First, save IMR and then disable interrupts
         */
        imr = UART_GET_IMR(port);
-       UART_PUT_IDR(port, ATMEL_US_RXRDY | ATMEL_US_TXRDY);
+       UART_PUT_IDR(port, ATMEL_US_RXRDY | atmel_port->tx_done_mask);
 
        /* Store PDC transmit status and disable it */
        pdc_tx = UART_GET_PTSR(port) & ATMEL_PDC_TXTEN;
index 4315b23..eacb588 100644 (file)
 #define  MX2_UCR3_RXDMUXSEL     (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
 #define  UCR3_INVT      (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN      (1<<0)  /* Preset registers enable */
-#define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
+#define  UCR4_CTSTL_SHF  10      /* CTS trigger level shift */
+#define  UCR4_CTSTL_MASK 0x3F    /* CTS trigger is 6 bits wide */
 #define  UCR4_INVR      (1<<9)  /* Inverted infrared reception */
 #define  UCR4_ENIRI     (1<<8)  /* Serial infrared interrupt enable */
 #define  UCR4_WKEN      (1<<7)  /* Wake interrupt enable */
@@ -591,6 +592,9 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
        return 0;
 }
 
+/* half the RX buffer size */
+#define CTSTL 16
+
 static int imx_startup(struct uart_port *port)
 {
        struct imx_port *sport = (struct imx_port *)port;
@@ -607,6 +611,10 @@ static int imx_startup(struct uart_port *port)
        if (USE_IRDA(sport))
                temp |= UCR4_IRSC;
 
+       /* set the trigger level for CTS */
+       temp &= ~(UCR4_CTSTL_MASK<<  UCR4_CTSTL_SHF);
+       temp |= CTSTL<<  UCR4_CTSTL_SHF;
+
        writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
 
        if (USE_IRDA(sport)) {
index 7bb5fee..b5aaef9 100644 (file)
@@ -263,6 +263,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        spin_lock_irqsave(&port->lock, flags);
+       uart_update_timeout(port, termios->c_cflag, baud);
        writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
        writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
        writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
@@ -379,6 +380,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data)
 static void mcf_config_port(struct uart_port *port, int flags)
 {
        port->type = PORT_MCF;
+       port->fifosize = MCFUART_TXFIFOSIZE;
 
        /* Clear mask, so no surprise interrupts. */
        writeb(0, port->membase + MCFUART_UIMR);
@@ -424,7 +426,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
 /*
  *     Define the basic serial functions we support.
  */
-static struct uart_ops mcf_uart_ops = {
+static const struct uart_ops mcf_uart_ops = {
        .tx_empty       = mcf_tx_empty,
        .get_mctrl      = mcf_get_mctrl,
        .set_mctrl      = mcf_set_mctrl,
@@ -443,7 +445,7 @@ static struct uart_ops mcf_uart_ops = {
        .verify_port    = mcf_verify_port,
 };
 
-static struct mcf_uart mcf_ports[3];
+static struct mcf_uart mcf_ports[4];
 
 #define        MCF_MAXPORTS    ARRAY_SIZE(mcf_ports)
 
index 3119fdd..02469c3 100644 (file)
  * kind, whether express or implied.
  */
 
-/* Platform device Usage :
- *
- * Since PSCs can have multiple function, the correct driver for each one
- * is selected by calling mpc52xx_match_psc_function(...). The function
- * handled by this driver is "uart".
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- *
- * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
- * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
- * fpr the console code : without this 1:1 mapping, at early boot time, when we
- * are parsing the kernel args console=ttyPSC?, we wouldn't know which PSC it
- * will be mapped to.
- */
-
-/* OF Platform device Usage :
- *
- * This driver is only used for PSCs configured in uart mode.  The device
- * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible
- * list.
- *
- * By default, PSC devices are enumerated in the order they are found.  However
- * a particular PSC number can be forces by adding 'device_no = <port#>'
- * to the device node.
- *
- * The driver init all necessary registers to place the PSC in uart mode without
- * DCD. However, the pin multiplexing aren't changed and should be set either
- * by the bootloader or in the platform init code.
- */
-
 #undef DEBUG
 
 #include <linux/device.h>
@@ -1500,7 +1467,7 @@ mpc52xx_uart_init(void)
        /*
         * Map the PSC FIFO Controller and init if on MPC512x.
         */
-       if (psc_ops->fifoc_init) {
+       if (psc_ops && psc_ops->fifoc_init) {
                ret = psc_ops->fifoc_init();
                if (ret)
                        return ret;
index 4eaa043..700e108 100644 (file)
@@ -752,8 +752,10 @@ static void pmz_break_ctl(struct uart_port *port, int break_state)
                uap->curregs[R5] = new_reg;
 
                /* NOTE: Not subject to 'transmitter active' rule. */
-               if (ZS_IS_ASLEEP(uap))
+               if (ZS_IS_ASLEEP(uap)) {
+                       spin_unlock_irqrestore(&port->lock, flags);
                        return;
+               }
                write_zsreg(uap, R5, uap->curregs[R5]);
        }
 
index 175d202..8cfa5b1 100644 (file)
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
  * manfid 0x0160, 0x0104
  * This card appears to have a 14.7456MHz clock.
  */
+/* Generic Modem: MD55x (GPRS/EDGE) have
+ * Elan VPU16551 UART with 14.7456MHz oscillator
+ * manfid 0x015D, 0x4C45
+ */
 static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
 {
        port->uartclk = 14745600;
@@ -195,6 +199,11 @@ static const struct serial_quirk quirks[] = {
                .prodid = 0x0104,
                .multi  = -1,
                .setup  = quirk_setup_brainboxes_0104,
+       }, {
+               .manfid = 0x015D,
+               .prodid = 0x4C45,
+               .multi  = -1,
+               .setup  = quirk_setup_brainboxes_0104,
        }, {
                .manfid = MANFID_IBM,
                .prodid = ~0,
index 2e71bbc..b196202 100644 (file)
@@ -650,6 +650,7 @@ static struct console ks8695_console = {
 
 static int __init ks8695_console_init(void)
 {
+       add_preferred_console(SERIAL_KS8695_DEVNAME, 0, NULL);
        register_console(&ks8695_console);
        return 0;
 }
index 8eb094c..8d993c4 100644 (file)
@@ -83,16 +83,16 @@ struct sci_port {
 
        /* Interface clock */
        struct clk              *iclk;
-       /* Data clock */
-       struct clk              *dclk;
+       /* Function clock */
+       struct clk              *fclk;
 
        struct list_head        node;
        struct dma_chan                 *chan_tx;
        struct dma_chan                 *chan_rx;
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
        struct device                   *dma_dev;
-       enum sh_dmae_slave_chan_id      slave_tx;
-       enum sh_dmae_slave_chan_id      slave_rx;
+       unsigned int                    slave_tx;
+       unsigned int                    slave_rx;
        struct dma_async_tx_descriptor  *desc_tx;
        struct dma_async_tx_descriptor  *desc_rx[2];
        dma_cookie_t                    cookie_tx;
@@ -107,6 +107,7 @@ struct sci_port {
        struct work_struct              work_tx;
        struct work_struct              work_rx;
        struct timer_list               rx_timer;
+       unsigned int                    rx_timeout;
 #endif
 };
 
@@ -674,22 +675,22 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
        struct sci_port *s = to_sci_port(port);
 
        if (s->chan_rx) {
-               unsigned long tout;
                u16 scr = sci_in(port, SCSCR);
                u16 ssr = sci_in(port, SCxSR);
 
                /* Disable future Rx interrupts */
-               sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE);
+               if (port->type == PORT_SCIFA) {
+                       disable_irq_nosync(irq);
+                       scr |= 0x4000;
+               } else {
+                       scr &= ~SCI_CTRL_FLAGS_RIE;
+               }
+               sci_out(port, SCSCR, scr);
                /* Clear current interrupt */
                sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
-               /* Calculate delay for 1.5 DMA buffers */
-               tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
-                       port->fifosize / 2;
-               dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n",
-                       tout * 1000 / HZ);
-               if (tout < 2)
-                       tout = 2;
-               mod_timer(&s->rx_timer, jiffies + tout);
+               dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
+                       jiffies, s->rx_timeout);
+               mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
 
                return IRQ_HANDLED;
        }
@@ -799,7 +800,7 @@ static int sci_notifier(struct notifier_block *self,
            (phase == CPUFREQ_RESUMECHANGE)) {
                spin_lock_irqsave(&priv->lock, flags);
                list_for_each_entry(sci_port, &priv->ports, node)
-                       sci_port->port.uartclk = clk_get_rate(sci_port->dclk);
+                       sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
                spin_unlock_irqrestore(&priv->lock, flags);
        }
 
@@ -810,21 +811,17 @@ static void sci_clk_enable(struct uart_port *port)
 {
        struct sci_port *sci_port = to_sci_port(port);
 
-       clk_enable(sci_port->dclk);
-       sci_port->port.uartclk = clk_get_rate(sci_port->dclk);
-
-       if (sci_port->iclk)
-               clk_enable(sci_port->iclk);
+       clk_enable(sci_port->iclk);
+       sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
+       clk_enable(sci_port->fclk);
 }
 
 static void sci_clk_disable(struct uart_port *port)
 {
        struct sci_port *sci_port = to_sci_port(port);
 
-       if (sci_port->iclk)
-               clk_disable(sci_port->iclk);
-
-       clk_disable(sci_port->dclk);
+       clk_disable(sci_port->fclk);
+       clk_disable(sci_port->iclk);
 }
 
 static int sci_request_irq(struct sci_port *port)
@@ -913,22 +910,26 @@ static void sci_dma_tx_complete(void *arg)
 
        spin_lock_irqsave(&port->lock, flags);
 
-       xmit->tail += s->sg_tx.length;
+       xmit->tail += sg_dma_len(&s->sg_tx);
        xmit->tail &= UART_XMIT_SIZE - 1;
 
-       port->icount.tx += s->sg_tx.length;
+       port->icount.tx += sg_dma_len(&s->sg_tx);
 
        async_tx_ack(s->desc_tx);
        s->cookie_tx = -EINVAL;
        s->desc_tx = NULL;
 
-       spin_unlock_irqrestore(&port->lock, flags);
-
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
 
-       if (uart_circ_chars_pending(xmit))
+       if (!uart_circ_empty(xmit)) {
                schedule_work(&s->work_tx);
+       } else if (port->type == PORT_SCIFA) {
+               u16 ctrl = sci_in(port, SCSCR);
+               sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
+       }
+
+       spin_unlock_irqrestore(&port->lock, flags);
 }
 
 /* Locking: called with port lock held */
@@ -972,13 +973,13 @@ static void sci_dma_rx_complete(void *arg)
        unsigned long flags;
        int count;
 
-       dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+       dev_dbg(port->dev, "%s(%d) active #%d\n", __func__, port->line, s->active_rx);
 
        spin_lock_irqsave(&port->lock, flags);
 
        count = sci_dma_rx_push(s, tty, s->buf_len_rx);
 
-       mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5));
+       mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
 
        spin_unlock_irqrestore(&port->lock, flags);
 
@@ -1050,6 +1051,8 @@ static void sci_submit_rx(struct sci_port *s)
                        sci_rx_dma_release(s, true);
                        return;
                }
+               dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
+                       s->cookie_rx[i], i);
        }
 
        s->active_rx = s->cookie_rx[0];
@@ -1107,10 +1110,10 @@ static void work_fn_rx(struct work_struct *work)
                return;
        }
 
-       dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__,
-               s->cookie_rx[new], new);
-
        s->active_rx = s->cookie_rx[!new];
+
+       dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", __func__,
+               s->cookie_rx[new], new, s->active_rx);
 }
 
 static void work_fn_tx(struct work_struct *work)
@@ -1131,14 +1134,13 @@ static void work_fn_tx(struct work_struct *work)
         */
        spin_lock_irq(&port->lock);
        sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
-       sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
+       sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
                sg->offset;
-       sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
+       sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
                CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
-       sg->dma_length = sg->length;
        spin_unlock_irq(&port->lock);
 
-       BUG_ON(!sg->length);
+       BUG_ON(!sg_dma_len(sg));
 
        desc = chan->device->device_prep_slave_sg(chan,
                        sg, s->sg_len_tx, DMA_TO_DEVICE,
@@ -1173,23 +1175,28 @@ static void work_fn_tx(struct work_struct *work)
 
 static void sci_start_tx(struct uart_port *port)
 {
+       struct sci_port *s = to_sci_port(port);
        unsigned short ctrl;
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
-       struct sci_port *s = to_sci_port(port);
-
-       if (s->chan_tx) {
-               if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0)
-                       schedule_work(&s->work_tx);
-
-               return;
+       if (port->type == PORT_SCIFA) {
+               u16 new, scr = sci_in(port, SCSCR);
+               if (s->chan_tx)
+                       new = scr | 0x8000;
+               else
+                       new = scr & ~0x8000;
+               if (new != scr)
+                       sci_out(port, SCSCR, new);
        }
+       if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
+           s->cookie_tx < 0)
+               schedule_work(&s->work_tx);
 #endif
-
-       /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
-       ctrl = sci_in(port, SCSCR);
-       ctrl |= SCI_CTRL_FLAGS_TIE;
-       sci_out(port, SCSCR, ctrl);
+       if (!s->chan_tx || port->type == PORT_SCIFA) {
+               /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
+               ctrl = sci_in(port, SCSCR);
+               sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
+       }
 }
 
 static void sci_stop_tx(struct uart_port *port)
@@ -1198,6 +1205,8 @@ static void sci_stop_tx(struct uart_port *port)
 
        /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
        ctrl = sci_in(port, SCSCR);
+       if (port->type == PORT_SCIFA)
+               ctrl &= ~0x8000;
        ctrl &= ~SCI_CTRL_FLAGS_TIE;
        sci_out(port, SCSCR, ctrl);
 }
@@ -1208,6 +1217,8 @@ static void sci_start_rx(struct uart_port *port)
 
        /* Set RIE (Receive Interrupt Enable) bit in SCSCR */
        ctrl |= sci_in(port, SCSCR);
+       if (port->type == PORT_SCIFA)
+               ctrl &= ~0x4000;
        sci_out(port, SCSCR, ctrl);
 }
 
@@ -1217,6 +1228,8 @@ static void sci_stop_rx(struct uart_port *port)
 
        /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
        ctrl = sci_in(port, SCSCR);
+       if (port->type == PORT_SCIFA)
+               ctrl &= ~0x4000;
        ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
        sci_out(port, SCSCR, ctrl);
 }
@@ -1251,8 +1264,12 @@ static void rx_timer_fn(unsigned long arg)
 {
        struct sci_port *s = (struct sci_port *)arg;
        struct uart_port *port = &s->port;
-
        u16 scr = sci_in(port, SCSCR);
+
+       if (port->type == PORT_SCIFA) {
+               scr &= ~0x4000;
+               enable_irq(s->irqs[1]);
+       }
        sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE);
        dev_dbg(port->dev, "DMA Rx timed out\n");
        schedule_work(&s->work_rx);
@@ -1339,8 +1356,7 @@ static void sci_request_dma(struct uart_port *port)
                        sg_init_table(sg, 1);
                        sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
                                    (int)buf[i] & ~PAGE_MASK);
-                       sg->dma_address = dma[i];
-                       sg->dma_length = sg->length;
+                       sg_dma_address(sg) = dma[i];
                }
 
                INIT_WORK(&s->work_rx, work_fn_rx);
@@ -1403,8 +1419,12 @@ static void sci_shutdown(struct uart_port *port)
 static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
                            struct ktermios *old)
 {
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+       struct sci_port *s = to_sci_port(port);
+#endif
        unsigned int status, baud, smr_val, max_baud;
        int t = -1;
+       u16 scfcr = 0;
 
        /*
         * earlyprintk comes here early on with port->uartclk set to zero.
@@ -1427,7 +1447,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
        sci_out(port, SCSCR, 0x00);     /* TE=0, RE=0, CKE1=0 */
 
        if (port->type != PORT_SCI)
-               sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
+               sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST);
 
        smr_val = sci_in(port, SCSMR) & 3;
        if ((termios->c_cflag & CSIZE) == CS7)
@@ -1458,10 +1478,32 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        sci_init_pins(port, termios->c_cflag);
-       sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0);
+       sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0));
 
        sci_out(port, SCSCR, SCSCR_INIT(port));
 
+#ifdef CONFIG_SERIAL_SH_SCI_DMA
+       /*
+        * Calculate delay for 1.5 DMA buffers: see
+        * drivers/serial/serial_core.c::uart_update_timeout(). With 10 bits
+        * (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
+        * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
+        * Then below we calculate 3 jiffies (12ms) for 1.5 DMA buffers (3 FIFO
+        * sizes), but it has been found out experimentally, that this is not
+        * enough: the driver too often needlessly runs on a DMA timeout. 20ms
+        * as a minimum seem to work perfectly.
+        */
+       if (s->chan_rx) {
+               s->rx_timeout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
+                       port->fifosize / 2;
+               dev_dbg(port->dev,
+                       "DMA Rx t-out %ums, tty t-out %u jiffies\n",
+                       s->rx_timeout * 1000 / HZ, port->timeout);
+               if (s->rx_timeout < msecs_to_jiffies(20))
+                       s->rx_timeout = msecs_to_jiffies(20);
+       }
+#endif
+
        if ((termios->c_cflag & CREAD) != 0)
                sci_start_rx(port);
 }
@@ -1553,10 +1595,10 @@ static struct uart_ops sci_uart_ops = {
 #endif
 };
 
-static void __devinit sci_init_single(struct platform_device *dev,
-                                     struct sci_port *sci_port,
-                                     unsigned int index,
-                                     struct plat_sci_port *p)
+static int __devinit sci_init_single(struct platform_device *dev,
+                                    struct sci_port *sci_port,
+                                    unsigned int index,
+                                    struct plat_sci_port *p)
 {
        struct uart_port *port = &sci_port->port;
 
@@ -1577,8 +1619,23 @@ static void __devinit sci_init_single(struct platform_device *dev,
        }
 
        if (dev) {
-               sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL;
-               sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
+               sci_port->iclk = clk_get(&dev->dev, "sci_ick");
+               if (IS_ERR(sci_port->iclk)) {
+                       sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
+                       if (IS_ERR(sci_port->iclk)) {
+                               dev_err(&dev->dev, "can't get iclk\n");
+                               return PTR_ERR(sci_port->iclk);
+                       }
+               }
+
+               /*
+                * The function clock is optional, ignore it if we can't
+                * find it.
+                */
+               sci_port->fclk = clk_get(&dev->dev, "sci_fck");
+               if (IS_ERR(sci_port->fclk))
+                       sci_port->fclk = NULL;
+
                sci_port->enable = sci_clk_enable;
                sci_port->disable = sci_clk_disable;
                port->dev = &dev->dev;
@@ -1605,6 +1662,7 @@ static void __devinit sci_init_single(struct platform_device *dev,
 #endif
 
        memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
+       return 0;
 }
 
 #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
@@ -1754,8 +1812,11 @@ static int sci_remove(struct platform_device *dev)
        cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER);
 
        spin_lock_irqsave(&priv->lock, flags);
-       list_for_each_entry(p, &priv->ports, node)
+       list_for_each_entry(p, &priv->ports, node) {
                uart_remove_one_port(&sci_uart_driver, &p->port);
+               clk_put(p->iclk);
+               clk_put(p->fclk);
+       }
        spin_unlock_irqrestore(&priv->lock, flags);
 
        kfree(priv);
@@ -1781,7 +1842,9 @@ static int __devinit sci_probe_single(struct platform_device *dev,
                return 0;
        }
 
-       sci_init_single(dev, sciport, index, p);
+       ret = sci_init_single(dev, sciport, index, p);
+       if (ret)
+               return ret;
 
        ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
        if (ret)
diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig
new file mode 100644 (file)
index 0000000..a54de0b
--- /dev/null
@@ -0,0 +1,24 @@
+config INTC_USERIMASK
+       bool "Userspace interrupt masking support"
+       depends on ARCH_SHMOBILE || (SUPERH && CPU_SH4A)
+       help
+         This enables support for hardware-assisted userspace hardirq
+         masking.
+
+         SH-4A and newer interrupt blocks all support a special shadowed
+         page with all non-masking registers obscured when mapped in to
+         userspace. This is primarily for use by userspace device
+         drivers that are using special priority levels.
+
+         If in doubt, say N.
+
+config INTC_BALANCING
+       bool "Hardware IRQ balancing support"
+       depends on SMP && SUPERH && CPU_SUBTYPE_SH7786
+       help
+         This enables support for IRQ auto-distribution mode on SH-X3
+         SMP parts. All of the balancing and CPU wakeup decisions are
+         taken care of automatically by hardware for distributed
+         vectors.
+
+         If in doubt, say N.
index 4956bf1..78bb512 100644 (file)
@@ -4,4 +4,6 @@
 obj-$(CONFIG_SUPERHYWAY)       += superhyway/
 obj-$(CONFIG_MAPLE)            += maple/
 obj-$(CONFIG_GENERIC_GPIO)     += pfc.o
+obj-$(CONFIG_SUPERH)           += clk.o
+obj-$(CONFIG_SH_CLK_CPG)       += clk-cpg.o
 obj-y                          += intc.o
diff --git a/drivers/sh/clk-cpg.c b/drivers/sh/clk-cpg.c
new file mode 100644 (file)
index 0000000..f5c80ba
--- /dev/null
@@ -0,0 +1,298 @@
+#include <linux/clk.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+
+static int sh_clk_mstp32_enable(struct clk *clk)
+{
+       __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
+                    clk->enable_reg);
+       return 0;
+}
+
+static void sh_clk_mstp32_disable(struct clk *clk)
+{
+       __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
+                    clk->enable_reg);
+}
+
+static struct clk_ops sh_clk_mstp32_clk_ops = {
+       .enable         = sh_clk_mstp32_enable,
+       .disable        = sh_clk_mstp32_disable,
+       .recalc         = followparent_recalc,
+};
+
+int __init sh_clk_mstp32_register(struct clk *clks, int nr)
+{
+       struct clk *clkp;
+       int ret = 0;
+       int k;
+
+       for (k = 0; !ret && (k < nr); k++) {
+               clkp = clks + k;
+               clkp->ops = &sh_clk_mstp32_clk_ops;
+               ret |= clk_register(clkp);
+       }
+
+       return ret;
+}
+
+static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
+{
+       return clk_rate_table_round(clk, clk->freq_table, rate);
+}
+
+static int sh_clk_div6_divisors[64] = {
+       1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+       33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+       49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
+};
+
+static struct clk_div_mult_table sh_clk_div6_table = {
+       .divisors = sh_clk_div6_divisors,
+       .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
+};
+
+static unsigned long sh_clk_div6_recalc(struct clk *clk)
+{
+       struct clk_div_mult_table *table = &sh_clk_div6_table;
+       unsigned int idx;
+
+       clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+                            table, NULL);
+
+       idx = __raw_readl(clk->enable_reg) & 0x003f;
+
+       return clk->freq_table[idx].frequency;
+}
+
+static int sh_clk_div6_set_rate(struct clk *clk,
+                               unsigned long rate, int algo_id)
+{
+       unsigned long value;
+       int idx;
+
+       idx = clk_rate_table_find(clk, clk->freq_table, rate);
+       if (idx < 0)
+               return idx;
+
+       value = __raw_readl(clk->enable_reg);
+       value &= ~0x3f;
+       value |= idx;
+       __raw_writel(value, clk->enable_reg);
+       return 0;
+}
+
+static int sh_clk_div6_enable(struct clk *clk)
+{
+       unsigned long value;
+       int ret;
+
+       ret = sh_clk_div6_set_rate(clk, clk->rate, 0);
+       if (ret == 0) {
+               value = __raw_readl(clk->enable_reg);
+               value &= ~0x100; /* clear stop bit to enable clock */
+               __raw_writel(value, clk->enable_reg);
+       }
+       return ret;
+}
+
+static void sh_clk_div6_disable(struct clk *clk)
+{
+       unsigned long value;
+
+       value = __raw_readl(clk->enable_reg);
+       value |= 0x100; /* stop clock */
+       value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
+       __raw_writel(value, clk->enable_reg);
+}
+
+static struct clk_ops sh_clk_div6_clk_ops = {
+       .recalc         = sh_clk_div6_recalc,
+       .round_rate     = sh_clk_div_round_rate,
+       .set_rate       = sh_clk_div6_set_rate,
+       .enable         = sh_clk_div6_enable,
+       .disable        = sh_clk_div6_disable,
+};
+
+int __init sh_clk_div6_register(struct clk *clks, int nr)
+{
+       struct clk *clkp;
+       void *freq_table;
+       int nr_divs = sh_clk_div6_table.nr_divisors;
+       int freq_table_size = sizeof(struct cpufreq_frequency_table);
+       int ret = 0;
+       int k;
+
+       freq_table_size *= (nr_divs + 1);
+       freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
+       if (!freq_table) {
+               pr_err("sh_clk_div6_register: unable to alloc memory\n");
+               return -ENOMEM;
+       }
+
+       for (k = 0; !ret && (k < nr); k++) {
+               clkp = clks + k;
+
+               clkp->ops = &sh_clk_div6_clk_ops;
+               clkp->id = -1;
+               clkp->freq_table = freq_table + (k * freq_table_size);
+               clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
+
+               ret = clk_register(clkp);
+       }
+
+       return ret;
+}
+
+static unsigned long sh_clk_div4_recalc(struct clk *clk)
+{
+       struct clk_div4_table *d4t = clk->priv;
+       struct clk_div_mult_table *table = d4t->div_mult_table;
+       unsigned int idx;
+
+       clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+                            table, &clk->arch_flags);
+
+       idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
+
+       return clk->freq_table[idx].frequency;
+}
+
+static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
+{
+       struct clk_div4_table *d4t = clk->priv;
+       struct clk_div_mult_table *table = d4t->div_mult_table;
+       u32 value;
+       int ret;
+
+       /* we really need a better way to determine parent index, but for
+        * now assume internal parent comes with CLK_ENABLE_ON_INIT set,
+        * no CLK_ENABLE_ON_INIT means external clock...
+        */
+
+       if (parent->flags & CLK_ENABLE_ON_INIT)
+               value = __raw_readl(clk->enable_reg) & ~(1 << 7);
+       else
+               value = __raw_readl(clk->enable_reg) | (1 << 7);
+
+       ret = clk_reparent(clk, parent);
+       if (ret < 0)
+               return ret;
+
+       __raw_writel(value, clk->enable_reg);
+
+       /* Rebiuld the frequency table */
+       clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
+                            table, &clk->arch_flags);
+
+       return 0;
+}
+
+static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate, int algo_id)
+{
+       struct clk_div4_table *d4t = clk->priv;
+       unsigned long value;
+       int idx = clk_rate_table_find(clk, clk->freq_table, rate);
+       if (idx < 0)
+               return idx;
+
+       value = __raw_readl(clk->enable_reg);
+       value &= ~(0xf << clk->enable_bit);
+       value |= (idx << clk->enable_bit);
+       __raw_writel(value, clk->enable_reg);
+
+       if (d4t->kick)
+               d4t->kick(clk);
+
+       return 0;
+}
+
+static int sh_clk_div4_enable(struct clk *clk)
+{
+       __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
+       return 0;
+}
+
+static void sh_clk_div4_disable(struct clk *clk)
+{
+       __raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
+}
+
+static struct clk_ops sh_clk_div4_clk_ops = {
+       .recalc         = sh_clk_div4_recalc,
+       .set_rate       = sh_clk_div4_set_rate,
+       .round_rate     = sh_clk_div_round_rate,
+};
+
+static struct clk_ops sh_clk_div4_enable_clk_ops = {
+       .recalc         = sh_clk_div4_recalc,
+       .set_rate       = sh_clk_div4_set_rate,
+       .round_rate     = sh_clk_div_round_rate,
+       .enable         = sh_clk_div4_enable,
+       .disable        = sh_clk_div4_disable,
+};
+
+static struct clk_ops sh_clk_div4_reparent_clk_ops = {
+       .recalc         = sh_clk_div4_recalc,
+       .set_rate       = sh_clk_div4_set_rate,
+       .round_rate     = sh_clk_div_round_rate,
+       .enable         = sh_clk_div4_enable,
+       .disable        = sh_clk_div4_disable,
+       .set_parent     = sh_clk_div4_set_parent,
+};
+
+static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
+                       struct clk_div4_table *table, struct clk_ops *ops)
+{
+       struct clk *clkp;
+       void *freq_table;
+       int nr_divs = table->div_mult_table->nr_divisors;
+       int freq_table_size = sizeof(struct cpufreq_frequency_table);
+       int ret = 0;
+       int k;
+
+       freq_table_size *= (nr_divs + 1);
+       freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
+       if (!freq_table) {
+               pr_err("sh_clk_div4_register: unable to alloc memory\n");
+               return -ENOMEM;
+       }
+
+       for (k = 0; !ret && (k < nr); k++) {
+               clkp = clks + k;
+
+               clkp->ops = ops;
+               clkp->id = -1;
+               clkp->priv = table;
+
+               clkp->freq_table = freq_table + (k * freq_table_size);
+               clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
+
+               ret = clk_register(clkp);
+       }
+
+       return ret;
+}
+
+int __init sh_clk_div4_register(struct clk *clks, int nr,
+                               struct clk_div4_table *table)
+{
+       return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
+}
+
+int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
+                               struct clk_div4_table *table)
+{
+       return sh_clk_div4_register_ops(clks, nr, table,
+                                       &sh_clk_div4_enable_clk_ops);
+}
+
+int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
+                               struct clk_div4_table *table)
+{
+       return sh_clk_div4_register_ops(clks, nr, table,
+                                       &sh_clk_div4_reparent_clk_ops);
+}
diff --git a/drivers/sh/clk.c b/drivers/sh/clk.c
new file mode 100644 (file)
index 0000000..5d84ada
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * drivers/sh/clk.c - SuperH clock framework
+ *
+ *  Copyright (C) 2005 - 2009  Paul Mundt
+ *
+ * This clock framework is derived from the OMAP version by:
+ *
+ *     Copyright (C) 2004 - 2008 Nokia Corporation
+ *     Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ *  Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/sysdev.h>
+#include <linux/seq_file.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/sh_clk.h>
+
+static LIST_HEAD(clock_list);
+static DEFINE_SPINLOCK(clock_lock);
+static DEFINE_MUTEX(clock_list_sem);
+
+void clk_rate_table_build(struct clk *clk,
+                         struct cpufreq_frequency_table *freq_table,
+                         int nr_freqs,
+                         struct clk_div_mult_table *src_table,
+                         unsigned long *bitmap)
+{
+       unsigned long mult, div;
+       unsigned long freq;
+       int i;
+
+       for (i = 0; i < nr_freqs; i++) {
+               div = 1;
+               mult = 1;
+
+               if (src_table->divisors && i < src_table->nr_divisors)
+                       div = src_table->divisors[i];
+
+               if (src_table->multipliers && i < src_table->nr_multipliers)
+                       mult = src_table->multipliers[i];
+
+               if (!div || !mult || (bitmap && !test_bit(i, bitmap)))
+                       freq = CPUFREQ_ENTRY_INVALID;
+               else
+                       freq = clk->parent->rate * mult / div;
+
+               freq_table[i].index = i;
+               freq_table[i].frequency = freq;
+       }
+
+       /* Termination entry */
+       freq_table[i].index = i;
+       freq_table[i].frequency = CPUFREQ_TABLE_END;
+}
+
+long clk_rate_table_round(struct clk *clk,
+                         struct cpufreq_frequency_table *freq_table,
+                         unsigned long rate)
+{
+       unsigned long rate_error, rate_error_prev = ~0UL;
+       unsigned long rate_best_fit = rate;
+       unsigned long highest, lowest;
+       int i;
+
+       highest = lowest = 0;
+
+       for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               unsigned long freq = freq_table[i].frequency;
+
+               if (freq == CPUFREQ_ENTRY_INVALID)
+                       continue;
+
+               if (freq > highest)
+                       highest = freq;
+               if (freq < lowest)
+                       lowest = freq;
+
+               rate_error = abs(freq - rate);
+               if (rate_error < rate_error_prev) {
+                       rate_best_fit = freq;
+                       rate_error_prev = rate_error;
+               }
+
+               if (rate_error == 0)
+                       break;
+       }
+
+       if (rate >= highest)
+               rate_best_fit = highest;
+       if (rate <= lowest)
+               rate_best_fit = lowest;
+
+       return rate_best_fit;
+}
+
+int clk_rate_table_find(struct clk *clk,
+                       struct cpufreq_frequency_table *freq_table,
+                       unsigned long rate)
+{
+       int i;
+
+       for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+               unsigned long freq = freq_table[i].frequency;
+
+               if (freq == CPUFREQ_ENTRY_INVALID)
+                       continue;
+
+               if (freq == rate)
+                       return i;
+       }
+
+       return -ENOENT;
+}
+
+/* Used for clocks that always have same value as the parent clock */
+unsigned long followparent_recalc(struct clk *clk)
+{
+       return clk->parent ? clk->parent->rate : 0;
+}
+
+int clk_reparent(struct clk *child, struct clk *parent)
+{
+       list_del_init(&child->sibling);
+       if (parent)
+               list_add(&child->sibling, &parent->children);
+       child->parent = parent;
+
+       /* now do the debugfs renaming to reattach the child
+          to the proper parent */
+
+       return 0;
+}
+
+/* Propagate rate to children */
+void propagate_rate(struct clk *tclk)
+{
+       struct clk *clkp;
+
+       list_for_each_entry(clkp, &tclk->children, sibling) {
+               if (clkp->ops && clkp->ops->recalc)
+                       clkp->rate = clkp->ops->recalc(clkp);
+
+               propagate_rate(clkp);
+       }
+}
+
+static void __clk_disable(struct clk *clk)
+{
+       if (WARN(!clk->usecount, "Trying to disable clock %s with 0 usecount\n",
+                clk->name))
+               return;
+
+       if (!(--clk->usecount)) {
+               if (likely(clk->ops && clk->ops->disable))
+                       clk->ops->disable(clk);
+               if (likely(clk->parent))
+                       __clk_disable(clk->parent);
+       }
+}
+
+void clk_disable(struct clk *clk)
+{
+       unsigned long flags;
+
+       if (!clk)
+               return;
+
+       spin_lock_irqsave(&clock_lock, flags);
+       __clk_disable(clk);
+       spin_unlock_irqrestore(&clock_lock, flags);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+static int __clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (clk->usecount++ == 0) {
+               if (clk->parent) {
+                       ret = __clk_enable(clk->parent);
+                       if (unlikely(ret))
+                               goto err;
+               }
+
+               if (clk->ops && clk->ops->enable) {
+                       ret = clk->ops->enable(clk);
+                       if (ret) {
+                               if (clk->parent)
+                                       __clk_disable(clk->parent);
+                               goto err;
+                       }
+               }
+       }
+
+       return ret;
+err:
+       clk->usecount--;
+       return ret;
+}
+
+int clk_enable(struct clk *clk)
+{
+       unsigned long flags;
+       int ret;
+
+       if (!clk)
+               return -EINVAL;
+
+       spin_lock_irqsave(&clock_lock, flags);
+       ret = __clk_enable(clk);
+       spin_unlock_irqrestore(&clock_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+static LIST_HEAD(root_clks);
+
+/**
+ * recalculate_root_clocks - recalculate and propagate all root clocks
+ *
+ * Recalculates all root clocks (clocks with no parent), which if the
+ * clock's .recalc is set correctly, should also propagate their rates.
+ * Called at init.
+ */
+void recalculate_root_clocks(void)
+{
+       struct clk *clkp;
+
+       list_for_each_entry(clkp, &root_clks, sibling) {
+               if (clkp->ops && clkp->ops->recalc)
+                       clkp->rate = clkp->ops->recalc(clkp);
+               propagate_rate(clkp);
+       }
+}
+
+int clk_register(struct clk *clk)
+{
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       /*
+        * trap out already registered clocks
+        */
+       if (clk->node.next || clk->node.prev)
+               return 0;
+
+       mutex_lock(&clock_list_sem);
+
+       INIT_LIST_HEAD(&clk->children);
+       clk->usecount = 0;
+
+       if (clk->parent)
+               list_add(&clk->sibling, &clk->parent->children);
+       else
+               list_add(&clk->sibling, &root_clks);
+
+       list_add(&clk->node, &clock_list);
+       if (clk->ops && clk->ops->init)
+               clk->ops->init(clk);
+       mutex_unlock(&clock_list_sem);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+       mutex_lock(&clock_list_sem);
+       list_del(&clk->sibling);
+       list_del(&clk->node);
+       mutex_unlock(&clock_list_sem);
+}
+EXPORT_SYMBOL_GPL(clk_unregister);
+
+void clk_enable_init_clocks(void)
+{
+       struct clk *clkp;
+
+       list_for_each_entry(clkp, &clock_list, node)
+               if (clkp->flags & CLK_ENABLE_ON_INIT)
+                       clk_enable(clkp);
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       return clk_set_rate_ex(clk, rate, 0);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
+{
+       int ret = -EOPNOTSUPP;
+       unsigned long flags;
+
+       spin_lock_irqsave(&clock_lock, flags);
+
+       if (likely(clk->ops && clk->ops->set_rate)) {
+               ret = clk->ops->set_rate(clk, rate, algo_id);
+               if (ret != 0)
+                       goto out_unlock;
+       } else {
+               clk->rate = rate;
+               ret = 0;
+       }
+
+       if (clk->ops && clk->ops->recalc)
+               clk->rate = clk->ops->recalc(clk);
+
+       propagate_rate(clk);
+
+out_unlock:
+       spin_unlock_irqrestore(&clock_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       unsigned long flags;
+       int ret = -EINVAL;
+
+       if (!parent || !clk)
+               return ret;
+       if (clk->parent == parent)
+               return 0;
+
+       spin_lock_irqsave(&clock_lock, flags);
+       if (clk->usecount == 0) {
+               if (clk->ops->set_parent)
+                       ret = clk->ops->set_parent(clk, parent);
+               else
+                       ret = clk_reparent(clk, parent);
+
+               if (ret == 0) {
+                       pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
+                                clk->name, clk->parent->name, clk->rate);
+                       if (clk->ops->recalc)
+                               clk->rate = clk->ops->recalc(clk);
+                       propagate_rate(clk);
+               }
+       } else
+               ret = -EBUSY;
+       spin_unlock_irqrestore(&clock_lock, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (likely(clk->ops && clk->ops->round_rate)) {
+               unsigned long flags, rounded;
+
+               spin_lock_irqsave(&clock_lock, flags);
+               rounded = clk->ops->round_rate(clk, rate);
+               spin_unlock_irqrestore(&clock_lock, flags);
+
+               return rounded;
+       }
+
+       return clk_get_rate(clk);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+#ifdef CONFIG_PM
+static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
+{
+       static pm_message_t prev_state;
+       struct clk *clkp;
+
+       switch (state.event) {
+       case PM_EVENT_ON:
+               /* Resumeing from hibernation */
+               if (prev_state.event != PM_EVENT_FREEZE)
+                       break;
+
+               list_for_each_entry(clkp, &clock_list, node) {
+                       if (likely(clkp->ops)) {
+                               unsigned long rate = clkp->rate;
+
+                               if (likely(clkp->ops->set_parent))
+                                       clkp->ops->set_parent(clkp,
+                                               clkp->parent);
+                               if (likely(clkp->ops->set_rate))
+                                       clkp->ops->set_rate(clkp,
+                                               rate, NO_CHANGE);
+                               else if (likely(clkp->ops->recalc))
+                                       clkp->rate = clkp->ops->recalc(clkp);
+                       }
+               }
+               break;
+       case PM_EVENT_FREEZE:
+               break;
+       case PM_EVENT_SUSPEND:
+               break;
+       }
+
+       prev_state = state;
+       return 0;
+}
+
+static int clks_sysdev_resume(struct sys_device *dev)
+{
+       return clks_sysdev_suspend(dev, PMSG_ON);
+}
+
+static struct sysdev_class clks_sysdev_class = {
+       .name = "clks",
+};
+
+static struct sysdev_driver clks_sysdev_driver = {
+       .suspend = clks_sysdev_suspend,
+       .resume = clks_sysdev_resume,
+};
+
+static struct sys_device clks_sysdev_dev = {
+       .cls = &clks_sysdev_class,
+};
+
+static int __init clk_sysdev_init(void)
+{
+       sysdev_class_register(&clks_sysdev_class);
+       sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
+       sysdev_register(&clks_sysdev_dev);
+
+       return 0;
+}
+subsys_initcall(clk_sysdev_init);
+#endif
+
+/*
+ *     debugfs support to trace clock tree hierarchy and attributes
+ */
+static struct dentry *clk_debugfs_root;
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+       int err;
+       struct dentry *d, *child, *child_tmp;
+       struct clk *pa = c->parent;
+       char s[255];
+       char *p = s;
+
+       p += sprintf(p, "%s", c->name);
+       if (c->id >= 0)
+               sprintf(p, ":%d", c->id);
+       d = debugfs_create_dir(s, pa ? pa->dentry : clk_debugfs_root);
+       if (!d)
+               return -ENOMEM;
+       c->dentry = d;
+
+       d = debugfs_create_u8("usecount", S_IRUGO, c->dentry, (u8 *)&c->usecount);
+       if (!d) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       d = debugfs_create_u32("rate", S_IRUGO, c->dentry, (u32 *)&c->rate);
+       if (!d) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       d = debugfs_create_x32("flags", S_IRUGO, c->dentry, (u32 *)&c->flags);
+       if (!d) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       return 0;
+
+err_out:
+       d = c->dentry;
+       list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+               debugfs_remove(child);
+       debugfs_remove(c->dentry);
+       return err;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+       int err;
+       struct clk *pa = c->parent;
+
+       if (pa && !pa->dentry) {
+               err = clk_debugfs_register(pa);
+               if (err)
+                       return err;
+       }
+
+       if (!c->dentry && c->name) {
+               err = clk_debugfs_register_one(c);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+       struct clk *c;
+       struct dentry *d;
+       int err;
+
+       d = debugfs_create_dir("clock", NULL);
+       if (!d)
+               return -ENOMEM;
+       clk_debugfs_root = d;
+
+       list_for_each_entry(c, &clock_list, node) {
+               err = clk_debugfs_register(c);
+               if (err)
+                       goto err_out;
+       }
+       return 0;
+err_out:
+       debugfs_remove_recursive(clk_debugfs_root);
+       return err;
+}
+late_initcall(clk_debugfs_init);
index 94ad6bd..c585574 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/topology.h>
 #include <linux/bitmap.h>
 #include <linux/cpumask.h>
+#include <asm/sizes.h>
 
 #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
        ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -45,6 +46,12 @@ struct intc_handle_int {
        unsigned long handle;
 };
 
+struct intc_window {
+       phys_addr_t phys;
+       void __iomem *virt;
+       unsigned long size;
+};
+
 struct intc_desc_int {
        struct list_head list;
        struct sys_device sysdev;
@@ -58,6 +65,8 @@ struct intc_desc_int {
        unsigned int nr_prio;
        struct intc_handle_int *sense;
        unsigned int nr_sense;
+       struct intc_window *window;
+       unsigned int nr_windows;
        struct irq_chip chip;
 };
 
@@ -87,8 +96,12 @@ static DEFINE_SPINLOCK(vector_lock);
 #define SMP_NR(d, x) 1
 #endif
 
-static unsigned int intc_prio_level[NR_IRQS]; /* for now */
+static unsigned int intc_prio_level[NR_IRQS];  /* for now */
+static unsigned int default_prio_level = 2;    /* 2 - 16 */
 static unsigned long ack_handle[NR_IRQS];
+#ifdef CONFIG_INTC_BALANCING
+static unsigned long dist_handle[NR_IRQS];
+#endif
 
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
@@ -96,6 +109,47 @@ static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
        return container_of(chip, struct intc_desc_int, chip);
 }
 
+static unsigned long intc_phys_to_virt(struct intc_desc_int *d,
+                                      unsigned long address)
+{
+       struct intc_window *window;
+       int k;
+
+       /* scan through physical windows and convert address */
+       for (k = 0; k < d->nr_windows; k++) {
+               window = d->window + k;
+
+               if (address < window->phys)
+                       continue;
+
+               if (address >= (window->phys + window->size))
+                       continue;
+
+               address -= window->phys;
+               address += (unsigned long)window->virt;
+
+               return address;
+       }
+
+       /* no windows defined, register must be 1:1 mapped virt:phys */
+       return address;
+}
+
+static unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address)
+{
+       unsigned int k;
+
+       address = intc_phys_to_virt(d, address);
+
+       for (k = 0; k < d->nr_reg; k++) {
+               if (d->reg[k] == address)
+                       return k;
+       }
+
+       BUG();
+       return 0;
+}
+
 static inline unsigned int set_field(unsigned int value,
                                     unsigned int field_value,
                                     unsigned int handle)
@@ -229,6 +283,85 @@ static void (*intc_disable_fns[])(unsigned long addr,
        [MODE_PCLR_REG] = intc_mode_field,
 };
 
+#ifdef CONFIG_INTC_BALANCING
+static inline void intc_balancing_enable(unsigned int irq)
+{
+       struct intc_desc_int *d = get_intc_desc(irq);
+       unsigned long handle = dist_handle[irq];
+       unsigned long addr;
+
+       if (irq_balancing_disabled(irq) || !handle)
+               return;
+
+       addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+       intc_reg_fns[_INTC_FN(handle)](addr, handle, 1);
+}
+
+static inline void intc_balancing_disable(unsigned int irq)
+{
+       struct intc_desc_int *d = get_intc_desc(irq);
+       unsigned long handle = dist_handle[irq];
+       unsigned long addr;
+
+       if (irq_balancing_disabled(irq) || !handle)
+               return;
+
+       addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
+       intc_reg_fns[_INTC_FN(handle)](addr, handle, 0);
+}
+
+static unsigned int intc_dist_data(struct intc_desc *desc,
+                                  struct intc_desc_int *d,
+                                  intc_enum enum_id)
+{
+       struct intc_mask_reg *mr = desc->hw.mask_regs;
+       unsigned int i, j, fn, mode;
+       unsigned long reg_e, reg_d;
+
+       for (i = 0; mr && enum_id && i < desc->hw.nr_mask_regs; i++) {
+               mr = desc->hw.mask_regs + i;
+
+               /*
+                * Skip this entry if there's no auto-distribution
+                * register associated with it.
+                */
+               if (!mr->dist_reg)
+                       continue;
+
+               for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) {
+                       if (mr->enum_ids[j] != enum_id)
+                               continue;
+
+                       fn = REG_FN_MODIFY_BASE;
+                       mode = MODE_ENABLE_REG;
+                       reg_e = mr->dist_reg;
+                       reg_d = mr->dist_reg;
+
+                       fn += (mr->reg_width >> 3) - 1;
+                       return _INTC_MK(fn, mode,
+                                       intc_get_reg(d, reg_e),
+                                       intc_get_reg(d, reg_d),
+                                       1,
+                                       (mr->reg_width - 1) - j);
+               }
+       }
+
+       /*
+        * It's possible we've gotten here with no distribution options
+        * available for the IRQ in question, so we just skip over those.
+        */
+       return 0;
+}
+#else
+static inline void intc_balancing_enable(unsigned int irq)
+{
+}
+
+static inline void intc_balancing_disable(unsigned int irq)
+{
+}
+#endif
+
 static inline void _intc_enable(unsigned int irq, unsigned long handle)
 {
        struct intc_desc_int *d = get_intc_desc(irq);
@@ -244,6 +377,8 @@ static inline void _intc_enable(unsigned int irq, unsigned long handle)
                intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
                                                    [_INTC_FN(handle)], irq);
        }
+
+       intc_balancing_enable(irq);
 }
 
 static void intc_enable(unsigned int irq)
@@ -254,10 +389,12 @@ static void intc_enable(unsigned int irq)
 static void intc_disable(unsigned int irq)
 {
        struct intc_desc_int *d = get_intc_desc(irq);
-       unsigned long handle = (unsigned long) get_irq_chip_data(irq);
+       unsigned long handle = (unsigned long)get_irq_chip_data(irq);
        unsigned long addr;
        unsigned int cpu;
 
+       intc_balancing_disable(irq);
+
        for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
 #ifdef CONFIG_SMP
                if (!cpumask_test_cpu(cpu, irq_to_desc(irq)->affinity))
@@ -336,8 +473,7 @@ static void intc_mask_ack(unsigned int irq)
 
        intc_disable(irq);
 
-       /* read register and write zero only to the assocaited bit */
-
+       /* read register and write zero only to the associated bit */
        if (handle) {
                addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
                switch (_INTC_FN(handle)) {
@@ -366,7 +502,8 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
 {
        int i;
 
-       /* this doesn't scale well, but...
+       /*
+        * this doesn't scale well, but...
         *
         * this function should only be used for cerain uncommon
         * operations such as intc_set_priority() and intc_set_sense()
@@ -377,7 +514,6 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
         * memory footprint down is to make sure the array is sorted
         * and then perform a bisect to lookup the irq.
         */
-
        for (i = 0; i < nr_hp; i++) {
                if ((hp + i)->irq != irq)
                        continue;
@@ -408,7 +544,6 @@ int intc_set_priority(unsigned int irq, unsigned int prio)
                 * primary masking method is using intc_prio_level[irq]
                 * priority level will be set during next enable()
                 */
-
                if (_INTC_FN(ihp->handle) != REG_FN_ERR)
                        _intc_enable(irq, ihp->handle);
        }
@@ -447,20 +582,6 @@ static int intc_set_sense(unsigned int irq, unsigned int type)
        return 0;
 }
 
-static unsigned int __init intc_get_reg(struct intc_desc_int *d,
-                                unsigned long address)
-{
-       unsigned int k;
-
-       for (k = 0; k < d->nr_reg; k++) {
-               if (d->reg[k] == address)
-                       return k;
-       }
-
-       BUG();
-       return 0;
-}
-
 static intc_enum __init intc_grp_id(struct intc_desc *desc,
                                    intc_enum enum_id)
 {
@@ -718,13 +839,14 @@ static void __init intc_register_irq(struct intc_desc *desc,
         */
        set_bit(irq, intc_irq_map);
 
-       /* Prefer single interrupt source bitmap over other combinations:
+       /*
+        * Prefer single interrupt source bitmap over other combinations:
+        *
         * 1. bitmap, single interrupt source
         * 2. priority, single interrupt source
         * 3. bitmap, multiple interrupt sources (groups)
         * 4. priority, multiple interrupt sources (groups)
         */
-
        data[0] = intc_mask_data(desc, d, enum_id, 0);
        data[1] = intc_prio_data(desc, d, enum_id, 0);
 
@@ -749,10 +871,11 @@ static void __init intc_register_irq(struct intc_desc *desc,
                                      handle_level_irq, "level");
        set_irq_chip_data(irq, (void *)data[primary]);
 
-       /* set priority level
+       /*
+        * set priority level
         * - this needs to be at least 2 for 5-bit priorities on 7780
         */
-       intc_prio_level[irq] = 2;
+       intc_prio_level[irq] = default_prio_level;
 
        /* enable secondary masking method if present */
        if (data[!primary])
@@ -769,7 +892,6 @@ static void __init intc_register_irq(struct intc_desc *desc,
                         * only secondary priority should access registers, so
                         * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority()
                         */
-
                        hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0);
                        hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0);
                }
@@ -790,6 +912,11 @@ static void __init intc_register_irq(struct intc_desc *desc,
        if (desc->hw.ack_regs)
                ack_handle[irq] = intc_ack_data(desc, d, enum_id);
 
+#ifdef CONFIG_INTC_BALANCING
+       if (desc->hw.mask_regs)
+               dist_handle[irq] = intc_dist_data(desc, d, enum_id);
+#endif
+
 #ifdef CONFIG_ARM
        set_irq_flags(irq, IRQF_VALID); /* Enable IRQ on ARM systems */
 #endif
@@ -801,6 +928,8 @@ static unsigned int __init save_reg(struct intc_desc_int *d,
                                    unsigned int smp)
 {
        if (value) {
+               value = intc_phys_to_virt(d, value);
+
                d->reg[cnt] = value;
 #ifdef CONFIG_SMP
                d->smp[cnt] = smp;
@@ -816,25 +945,59 @@ static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
        generic_handle_irq((unsigned int)get_irq_data(irq));
 }
 
-void __init register_intc_controller(struct intc_desc *desc)
+int __init register_intc_controller(struct intc_desc *desc)
 {
        unsigned int i, k, smp;
        struct intc_hw_desc *hw = &desc->hw;
        struct intc_desc_int *d;
+       struct resource *res;
+
+       pr_info("intc: Registered controller '%s' with %u IRQs\n",
+               desc->name, hw->nr_vectors);
 
        d = kzalloc(sizeof(*d), GFP_NOWAIT);
+       if (!d)
+               goto err0;
 
        INIT_LIST_HEAD(&d->list);
        list_add(&d->list, &intc_list);
 
+       if (desc->num_resources) {
+               d->nr_windows = desc->num_resources;
+               d->window = kzalloc(d->nr_windows * sizeof(*d->window),
+                                   GFP_NOWAIT);
+               if (!d->window)
+                       goto err1;
+
+               for (k = 0; k < d->nr_windows; k++) {
+                       res = desc->resource + k;
+                       WARN_ON(resource_type(res) != IORESOURCE_MEM);
+                       d->window[k].phys = res->start;
+                       d->window[k].size = resource_size(res);
+                       d->window[k].virt = ioremap_nocache(res->start,
+                                                        resource_size(res));
+                       if (!d->window[k].virt)
+                               goto err2;
+               }
+       }
+
        d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0;
+#ifdef CONFIG_INTC_BALANCING
+       if (d->nr_reg)
+               d->nr_reg += hw->nr_mask_regs;
+#endif
        d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0;
        d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0;
        d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0;
 
        d->reg = kzalloc(d->nr_reg * sizeof(*d->reg), GFP_NOWAIT);
+       if (!d->reg)
+               goto err2;
+
 #ifdef CONFIG_SMP
        d->smp = kzalloc(d->nr_reg * sizeof(*d->smp), GFP_NOWAIT);
+       if (!d->smp)
+               goto err3;
 #endif
        k = 0;
 
@@ -843,12 +1006,17 @@ void __init register_intc_controller(struct intc_desc *desc)
                        smp = IS_SMP(hw->mask_regs[i]);
                        k += save_reg(d, k, hw->mask_regs[i].set_reg, smp);
                        k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp);
+#ifdef CONFIG_INTC_BALANCING
+                       k += save_reg(d, k, hw->mask_regs[i].dist_reg, 0);
+#endif
                }
        }
 
        if (hw->prio_regs) {
                d->prio = kzalloc(hw->nr_vectors * sizeof(*d->prio),
                                  GFP_NOWAIT);
+               if (!d->prio)
+                       goto err4;
 
                for (i = 0; i < hw->nr_prio_regs; i++) {
                        smp = IS_SMP(hw->prio_regs[i]);
@@ -860,6 +1028,8 @@ void __init register_intc_controller(struct intc_desc *desc)
        if (hw->sense_regs) {
                d->sense = kzalloc(hw->nr_vectors * sizeof(*d->sense),
                                   GFP_NOWAIT);
+               if (!d->sense)
+                       goto err5;
 
                for (i = 0; i < hw->nr_sense_regs; i++)
                        k += save_reg(d, k, hw->sense_regs[i].reg, 0);
@@ -906,7 +1076,7 @@ void __init register_intc_controller(struct intc_desc *desc)
 
                irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
                if (unlikely(!irq_desc)) {
-                       pr_info("can't get irq_desc for %d\n", irq);
+                       pr_err("can't get irq_desc for %d\n", irq);
                        continue;
                }
 
@@ -926,7 +1096,7 @@ void __init register_intc_controller(struct intc_desc *desc)
                         */
                        irq_desc = irq_to_desc_alloc_node(irq2, numa_node_id());
                        if (unlikely(!irq_desc)) {
-                               pr_info("can't get irq_desc for %d\n", irq2);
+                               pr_err("can't get irq_desc for %d\n", irq2);
                                continue;
                        }
 
@@ -942,8 +1112,100 @@ void __init register_intc_controller(struct intc_desc *desc)
        /* enable bits matching force_enable after registering irqs */
        if (desc->force_enable)
                intc_enable_disable_enum(desc, d, desc->force_enable, 1);
+
+       return 0;
+err5:
+       kfree(d->prio);
+err4:
+#ifdef CONFIG_SMP
+       kfree(d->smp);
+err3:
+#endif
+       kfree(d->reg);
+err2:
+       for (k = 0; k < d->nr_windows; k++)
+               if (d->window[k].virt)
+                       iounmap(d->window[k].virt);
+
+       kfree(d->window);
+err1:
+       kfree(d);
+err0:
+       pr_err("unable to allocate INTC memory\n");
+
+       return -ENOMEM;
+}
+
+#ifdef CONFIG_INTC_USERIMASK
+static void __iomem *uimask;
+
+int register_intc_userimask(unsigned long addr)
+{
+       if (unlikely(uimask))
+               return -EBUSY;
+
+       uimask = ioremap_nocache(addr, SZ_4K);
+       if (unlikely(!uimask))
+               return -ENOMEM;
+
+       pr_info("intc: userimask support registered for levels 0 -> %d\n",
+               default_prio_level - 1);
+
+       return 0;
+}
+
+static ssize_t
+show_intc_userimask(struct sysdev_class *cls,
+                   struct sysdev_class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf);
+}
+
+static ssize_t
+store_intc_userimask(struct sysdev_class *cls,
+                    struct sysdev_class_attribute *attr,
+                    const char *buf, size_t count)
+{
+       unsigned long level;
+
+       level = simple_strtoul(buf, NULL, 10);
+
+       /*
+        * Minimal acceptable IRQ levels are in the 2 - 16 range, but
+        * these are chomped so as to not interfere with normal IRQs.
+        *
+        * Level 1 is a special case on some CPUs in that it's not
+        * directly settable, but given that USERIMASK cuts off below a
+        * certain level, we don't care about this limitation here.
+        * Level 0 on the other hand equates to user masking disabled.
+        *
+        * We use default_prio_level as a cut off so that only special
+        * case opt-in IRQs can be mangled.
+        */
+       if (level >= default_prio_level)
+               return -EINVAL;
+
+       __raw_writel(0xa5 << 24 | level << 4, uimask);
+
+       return count;
 }
 
+static SYSDEV_CLASS_ATTR(userimask, S_IRUSR | S_IWUSR,
+                        show_intc_userimask, store_intc_userimask);
+#endif
+
+static ssize_t
+show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf)
+{
+       struct intc_desc_int *d;
+
+       d = container_of(dev, struct intc_desc_int, sysdev);
+
+       return sprintf(buf, "%s\n", d->chip.name);
+}
+
+static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL);
+
 static int intc_suspend(struct sys_device *dev, pm_message_t state)
 {
        struct intc_desc_int *d;
@@ -1003,19 +1265,28 @@ static int __init register_intc_sysdevs(void)
        int id = 0;
 
        error = sysdev_class_register(&intc_sysdev_class);
+#ifdef CONFIG_INTC_USERIMASK
+       if (!error && uimask)
+               error = sysdev_class_create_file(&intc_sysdev_class,
+                                                &attr_userimask);
+#endif
        if (!error) {
                list_for_each_entry(d, &intc_list, list) {
                        d->sysdev.id = id;
                        d->sysdev.cls = &intc_sysdev_class;
                        error = sysdev_register(&d->sysdev);
+                       if (error == 0)
+                               error = sysdev_create_file(&d->sysdev,
+                                                          &attr_name);
                        if (error)
                                break;
+
                        id++;
                }
        }
 
        if (error)
-               pr_warning("intc: sysdev registration error\n");
+               pr_err("intc: sysdev registration error\n");
 
        return error;
 }
@@ -1048,7 +1319,7 @@ unsigned int create_irq_nr(unsigned int irq_want, int node)
 
        desc = irq_to_desc_alloc_node(new, node);
        if (unlikely(!desc)) {
-               pr_info("can't get irq_desc for %d\n", new);
+               pr_err("can't get irq_desc for %d\n", new);
                goto out_unlock;
        }
 
index d8356af..e0de0d0 100644 (file)
@@ -204,6 +204,7 @@ static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val)
 
        cs->chconf0 = val;
        mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val);
+       mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0);
 }
 
 static void omap2_mcspi_set_dma_req(const struct spi_device *spi,
@@ -532,7 +533,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        goto out;
                                }
 #ifdef VERBOSE
-                               dev_dbg(&spi->dev, "write-%d %04x\n",
+                               dev_dbg(&spi->dev, "write-%d %08x\n",
                                                word_len, *tx);
 #endif
                                __raw_writel(*tx++, tx_reg);
@@ -550,7 +551,7 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)
                                        mcspi_write_chconf0(spi, l);
                                *rx++ = __raw_readl(rx_reg);
 #ifdef VERBOSE
-                               dev_dbg(&spi->dev, "read-%d %04x\n",
+                               dev_dbg(&spi->dev, "read-%d %08x\n",
                                                word_len, *(rx - 1));
 #endif
                        }
index 3682835..e76b1af 100644 (file)
@@ -36,8 +36,7 @@
 #include <asm/delay.h>
 
 #include <mach/dma.h>
-#include <mach/regs-ssp.h>
-#include <mach/ssp.h>
+#include <plat/ssp.h>
 #include <mach/pxa2xx_spi.h>
 
 MODULE_AUTHOR("Stephen Street");
@@ -1318,14 +1317,14 @@ static int setup(struct spi_device *spi)
        /* NOTE:  PXA25x_SSP _could_ use external clocking ... */
        if (drv_data->ssp_type != PXA25x_SSP)
                dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
-                               clk_get_rate(ssp->clk)
-                                       / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-                               chip->enable_dma ? "DMA" : "PIO");
+                       clk_get_rate(ssp->clk)
+                               / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)),
+                       chip->enable_dma ? "DMA" : "PIO");
        else
                dev_dbg(&spi->dev, "%ld Hz actual, %s\n",
-                               clk_get_rate(ssp->clk) / 2
-                                       / (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
-                               chip->enable_dma ? "DMA" : "PIO");
+                       clk_get_rate(ssp->clk) / 2
+                               / (1 + ((chip->cr0 & SSCR0_SCR(0x0ff)) >> 8)),
+                       chip->enable_dma ? "DMA" : "PIO");
 
        if (spi->bits_per_word <= 8) {
                chip->n_bytes = 1;
@@ -1466,7 +1465,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
 
        platform_info = dev->platform_data;
 
-       ssp = ssp_request(pdev->id, pdev->name);
+       ssp = pxa_ssp_request(pdev->id, pdev->name);
        if (ssp == NULL) {
                dev_err(&pdev->dev, "failed to request SSP%d\n", pdev->id);
                return -ENODEV;
@@ -1476,7 +1475,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
        master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
        if (!master) {
                dev_err(&pdev->dev, "cannot alloc spi_master\n");
-               ssp_free(ssp);
+               pxa_ssp_free(ssp);
                return -ENOMEM;
        }
        drv_data = spi_master_get_devdata(master);
@@ -1558,7 +1557,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
        write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
                                SSCR1_TxTresh(TX_THRESH_DFLT),
                                drv_data->ioaddr);
-       write_SSCR0(SSCR0_SerClkDiv(2)
+       write_SSCR0(SSCR0_SCR(2)
                        | SSCR0_Motorola
                        | SSCR0_DataSize(8),
                        drv_data->ioaddr);
@@ -1605,7 +1604,7 @@ out_error_irq_alloc:
 
 out_error_master_alloc:
        spi_master_put(master);
-       ssp_free(ssp);
+       pxa_ssp_free(ssp);
        return status;
 }
 
@@ -1649,7 +1648,7 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
        free_irq(ssp->irq, drv_data);
 
        /* Release SSP */
-       ssp_free(ssp);
+       pxa_ssp_free(ssp);
 
        /* Disconnect from the SPI framework */
        spi_unregister_master(drv_data->master);
index 9ffb0fd..b3a1f92 100644 (file)
@@ -41,7 +41,7 @@ static void spidev_release(struct device *dev)
                spi->master->cleanup(spi);
 
        spi_master_put(spi->master);
-       kfree(dev);
+       kfree(spi);
 }
 
 static ssize_t
@@ -257,6 +257,7 @@ int spi_add_device(struct spi_device *spi)
 {
        static DEFINE_MUTEX(spi_add_lock);
        struct device *dev = spi->master->dev.parent;
+       struct device *d;
        int status;
 
        /* Chipselects are numbered 0..max; validate. */
@@ -278,10 +279,11 @@ int spi_add_device(struct spi_device *spi)
         */
        mutex_lock(&spi_add_lock);
 
-       if (bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev))
-                       != NULL) {
+       d = bus_find_device_by_name(&spi_bus_type, NULL, dev_name(&spi->dev));
+       if (d != NULL) {
                dev_err(dev, "chipselect %d already in use\n",
                                spi->chip_select);
+               put_device(d);
                status = -EBUSY;
                goto done;
        }
index f1dcd79..0e8d352 100644 (file)
@@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = {
        .pci_ops        = &ssb_pcicore_pciops,
        .io_resource    = &ssb_pcicore_io_resource,
        .mem_resource   = &ssb_pcicore_mem_resource,
-       .mem_offset     = 0x24000000,
 };
 
-static u32 ssb_pcicore_pcibus_iobase = 0x100;
-static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
-
 /* This function is called when doing a pci_enable_device().
  * We must first check if the device is a device on the PCI-core bridge. */
 int ssb_pcicore_plat_dev_init(struct pci_dev *d)
 {
-       struct resource *res;
-       int pos, size;
-       u32 *base;
-
        if (d->bus->ops != &ssb_pcicore_pciops) {
                /* This is not a device on the PCI-core bridge. */
                return -ENODEV;
@@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d)
        ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
                   pci_name(d));
 
-       /* Fix up resource bases */
-       for (pos = 0; pos < 6; pos++) {
-               res = &d->resource[pos];
-               if (res->flags & IORESOURCE_IO)
-                       base = &ssb_pcicore_pcibus_iobase;
-               else
-                       base = &ssb_pcicore_pcibus_membase;
-               res->flags |= IORESOURCE_PCI_FIXED;
-               if (res->end) {
-                       size = res->end - res->start + 1;
-                       if (*base & (size - 1))
-                               *base = (*base + size) & ~(size - 1);
-                       res->start = *base;
-                       res->end = res->start + size - 1;
-                       *base += size;
-                       pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
-               }
-               /* Fix up PCI bridge BAR0 only */
-               if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
-                       break;
-       }
        /* Fix up interrupt lines */
        d->irq = ssb_mips_irq(extpci_core->dev) + 2;
        pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
index a67c622..7ac2c6d 100644 (file)
@@ -57,19 +57,8 @@ MA 02111-1307 USA
 
 extern void printques(int);
 
-#ifdef MODULE
 #include <linux/module.h>
 #include <linux/interrupt.h>
-
-
-MODULE_LICENSE("GPL");
-
-#endif
-
-#ifndef CONFIG_PCI
-#error  "DT3155 :  Kernel PCI support not enabled (DT3155 drive requires PCI)"
-#endif
-
 #include <linux/pci.h>
 #include <linux/types.h>
 #include <linux/poll.h>
@@ -84,6 +73,9 @@ MODULE_LICENSE("GPL");
 #include "dt3155_io.h"
 #include "allocator.h"
 
+
+MODULE_LICENSE("GPL");
+
 /* Error variable.  Zero means no error. */
 int dt3155_errno = 0;
 
@@ -472,9 +464,9 @@ static void dt3155_init_isr(int minor)
   /* 50/60 Hz should be set before this point but let's make sure it is */
   /* right anyway */
 
-  ReadI2C(dt3155_lbase[ minor ], CONFIG, &i2c_csr2.reg);
+  ReadI2C(dt3155_lbase[ minor ], CSR2, &i2c_csr2.reg);
   i2c_csr2.fld.HZ50 = FORMAT50HZ;
-  WriteI2C(dt3155_lbase[ minor ], CONFIG, i2c_config.reg);
+  WriteI2C(dt3155_lbase[ minor ], CSR2, i2c_csr2.reg);
 
   /* enable busmaster chip, clear flags */
 
index 5d53889..3a1112d 100644 (file)
@@ -306,9 +306,9 @@ void HvCleanup(void)
        DPRINT_ENTER(VMBUS);
 
        if (gHvContext.SignalEventBuffer) {
+               kfree(gHvContext.SignalEventBuffer);
                gHvContext.SignalEventBuffer = NULL;
                gHvContext.SignalEventParam = NULL;
-               kfree(gHvContext.SignalEventBuffer);
        }
 
        if (gHvContext.HypercallPage) {
index cd2930d..6704f64 100644 (file)
@@ -751,6 +751,7 @@ static int RndisFilterOpenDevice(struct rndis_device *Device)
 
        ret = RndisFilterSetPacketFilter(Device,
                                         NDIS_PACKET_TYPE_BROADCAST |
+                                        NDIS_PACKET_TYPE_ALL_MULTICAST |
                                         NDIS_PACKET_TYPE_DIRECTED);
        if (ret == 0)
                Device->State = RNDIS_DEV_DATAINITIALIZED;
index 2ccb6b9..ab27d9a 100644 (file)
@@ -403,8 +403,7 @@ static int netvsc_probe(struct device *device)
        if (!net_drv_obj->Base.OnDeviceAdd)
                return -1;
 
-       net = alloc_netdev(sizeof(struct net_device_context), "seth%d",
-                          ether_setup);
+       net = alloc_etherdev(sizeof(struct net_device_context));
        if (!net)
                return -1;
 
index ea76902..82e4358 100644 (file)
@@ -618,7 +618,7 @@ static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
 static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
 {
        struct iio_work_cont *wc
-               = container_of(work_s, struct iio_work_cont, ws_nocheck);
+               = container_of(work_s, struct iio_work_cont, ws);
        struct lis3l02dq_state *st = wc->st;
        u8 t;
 
index 9371243..a4d97ea 100644 (file)
@@ -493,6 +493,9 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
        struct lis3l02dq_state *state = indio_dev->dev_data;
 
        state->trig = iio_allocate_trigger();
+       if (!state->trig)
+               return -ENOMEM;
+
        state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
        if (!state->trig->name) {
                ret = -ENOMEM;
index 790d1cc..773f1d1 100644 (file)
@@ -557,6 +557,7 @@ error_put_reg:
        if (!IS_ERR(st->reg))
                regulator_put(st->reg);
 error_free_st:
+       i2c_set_clientdata(client, NULL);
        kfree(st);
 
 error_ret:
@@ -574,6 +575,7 @@ static int max1363_remove(struct i2c_client *client)
                regulator_disable(st->reg);
                regulator_put(st->reg);
        }
+       i2c_set_clientdata(client, NULL);
        kfree(st);
 
        return 0;
index 37f58f6..1d77082 100644 (file)
@@ -537,6 +537,7 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
        sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
 }
 
+/* Return a negative errno on failure */
 int iio_get_new_idr_val(struct idr *this_idr)
 {
        int ret;
@@ -660,7 +661,7 @@ static int iio_device_register_eventset(struct iio_dev *dev_info)
        for (i = 0; i < dev_info->num_interrupt_lines; i++) {
                dev_info->event_interfaces[i].owner = dev_info->driver_module;
                ret = iio_get_new_idr_val(&iio_event_idr);
-               if (ret)
+               if (ret < 0)
                        goto error_free_setup_ev_ints;
                else
                        dev_info->event_interfaces[i].id = ret;
index 1ba4aa3..8770a00 100644 (file)
@@ -682,6 +682,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client,
 fail2:
        iio_device_unregister(chip->indio_dev);
 fail1:
+       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return err;
 }
@@ -692,6 +693,7 @@ static int tsl2563_remove(struct i2c_client *client)
 
        iio_device_unregister(chip->indio_dev);
 
+       i2c_set_clientdata(client, NULL);
        kfree(chip);
        return 0;
 }
index b104c3d..cf22c09 100644 (file)
@@ -293,7 +293,7 @@ again:
                return -EAGAIN;
        memcpy(data, last_written_p_copy, ring->buf.bpd);
 
-       if (unlikely(ring->last_written_p >= last_written_p_copy))
+       if (unlikely(ring->last_written_p != last_written_p_copy))
                goto again;
 
        iio_unmark_sw_rb_in_use(&ring->buf);
index 3085e38..00a555b 100644 (file)
@@ -153,6 +153,14 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
                 * through switch.
                 */
                return -1;
+
+       case CVMX_BOARD_TYPE_CUST_WSX16:
+               if (ipd_port >= 0 && ipd_port <= 3)
+                       return ipd_port;
+               else if (ipd_port >= 16 && ipd_port <= 19)
+                       return ipd_port - 16 + 4;
+               else
+                       return -1;
        }
 
        /* Some unknown board. Somebody forgot to update this function... */
index 1873a79..740db0c 100644 (file)
@@ -63,6 +63,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x07D1, 0x3C11)},   /* D-Link */
        {USB_DEVICE(0x14B2, 0x3C07)},   /* AL */
        {USB_DEVICE(0x050D, 0x8053)},   /* Belkin */
+       {USB_DEVICE(0x050D, 0x825B)},   /* Belkin */
        {USB_DEVICE(0x14B2, 0x3C23)},   /* Airlink */
        {USB_DEVICE(0x14B2, 0x3C27)},   /* Airlink */
        {USB_DEVICE(0x07AA, 0x002F)},   /* Corega */
index e16256f..04d9b85 100644 (file)
@@ -113,14 +113,17 @@ u32 rt_global_debug_component = \
 
 static const struct usb_device_id rtl8192_usb_id_tbl[] = {
        /* Realtek */
+       {USB_DEVICE(0x0bda, 0x8171)},
        {USB_DEVICE(0x0bda, 0x8192)},
        {USB_DEVICE(0x0bda, 0x8709)},
        /* Corega */
        {USB_DEVICE(0x07aa, 0x0043)},
        /* Belkin */
        {USB_DEVICE(0x050d, 0x805E)},
+       {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
        /* Sitecom */
        {USB_DEVICE(0x0df6, 0x0031)},
+       {USB_DEVICE(0x0df6, 0x004b)},   /* WL-349 */
        /* EnGenius */
        {USB_DEVICE(0x1740, 0x9201)},
        /* Dlink */
index 6da1021..a2566f1 100644 (file)
@@ -117,6 +117,9 @@ void usbip_stop_eh(struct usbip_device *ud)
 {
        struct usbip_task *eh = &ud->eh;
 
+       if (eh->thread == current)
+               return; /* do not wait for myself */
+
        wait_for_completion(&eh->thread_done);
        usbip_dbg_eh("usbip_eh has finished\n");
 }
index 68f2442..783051f 100644 (file)
@@ -2455,9 +2455,10 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
                err_chk ? "enabled" : "disabled");
 
-       if (tsi148_crcsr_init(tsi148_bridge, pdev))
+       if (tsi148_crcsr_init(tsi148_bridge, pdev)) {
                dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
                goto err_crcsr;
+       }
 
        retval = vme_register_bridge(tsi148_bridge);
        if (retval != 0) {
index be6331e..5e1a253 100644 (file)
@@ -1542,6 +1542,9 @@ static const struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
        .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
        },
+       { USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
+       .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+       },
 
        /* Nokia S60 phones expose two ACM channels. The first is
         * a modem and is picked up by the standard AT-command
index 97a819c..7e59444 100644 (file)
@@ -109,7 +109,7 @@ config USB_SUSPEND
 config USB_OTG
        bool
        depends on USB && EXPERIMENTAL
-       select USB_SUSPEND
+       depends on USB_SUSPEND
        default n
 
 
index 6a3b5ca..2f3dc4c 100644 (file)
@@ -301,7 +301,7 @@ static int usb_probe_interface(struct device *dev)
 
        intf->condition = USB_INTERFACE_BINDING;
 
-       /* Bound interfaces are initially active.  They are
+       /* Probed interfaces are initially active.  They are
         * runtime-PM-enabled only if the driver has autosuspend support.
         * They are sensitive to their children's power states.
         */
@@ -437,11 +437,11 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 
        iface->condition = USB_INTERFACE_BOUND;
 
-       /* Bound interfaces are initially active.  They are
+       /* Claimed interfaces are initially inactive (suspended).  They are
         * runtime-PM-enabled only if the driver has autosuspend support.
         * They are sensitive to their children's power states.
         */
-       pm_runtime_set_active(dev);
+       pm_runtime_set_suspended(dev);
        pm_suspend_ignore_children(dev, false);
        if (driver->supports_autosuspend)
                pm_runtime_enable(dev);
@@ -1170,7 +1170,7 @@ done:
 static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
 {
        int                     status = 0;
-       int                     i = 0;
+       int                     i = 0, n = 0;
        struct usb_interface    *intf;
 
        if (udev->state == USB_STATE_NOTATTACHED ||
@@ -1179,7 +1179,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
 
        /* Suspend all the interfaces and then udev itself */
        if (udev->actconfig) {
-               for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
+               n = udev->actconfig->desc.bNumInterfaces;
+               for (i = n - 1; i >= 0; --i) {
                        intf = udev->actconfig->interface[i];
                        status = usb_suspend_interface(udev, intf, msg);
                        if (status != 0)
@@ -1192,7 +1193,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
        /* If the suspend failed, resume interfaces that did get suspended */
        if (status != 0) {
                msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
-               while (--i >= 0) {
+               while (++i < n) {
                        intf = udev->actconfig->interface[i];
                        usb_resume_interface(udev, intf, msg, 0);
                }
@@ -1263,13 +1264,47 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg)
        return status;
 }
 
+static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
+{
+       int                     w, i;
+       struct usb_interface    *intf;
+
+       /* Remote wakeup is needed only when we actually go to sleep.
+        * For things like FREEZE and QUIESCE, if the device is already
+        * autosuspended then its current wakeup setting is okay.
+        */
+       if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) {
+               if (udev->state != USB_STATE_SUSPENDED)
+                       udev->do_remote_wakeup = 0;
+               return;
+       }
+
+       /* If remote wakeup is permitted, see whether any interface drivers
+        * actually want it.
+        */
+       w = 0;
+       if (device_may_wakeup(&udev->dev) && udev->actconfig) {
+               for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+                       intf = udev->actconfig->interface[i];
+                       w |= intf->needs_remote_wakeup;
+               }
+       }
+
+       /* If the device is autosuspended with the wrong wakeup setting,
+        * autoresume now so the setting can be changed.
+        */
+       if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup)
+               pm_runtime_resume(&udev->dev);
+       udev->do_remote_wakeup = w;
+}
+
 /* The device lock is held by the PM core */
 int usb_suspend(struct device *dev, pm_message_t msg)
 {
        struct usb_device       *udev = to_usb_device(dev);
 
        do_unbind_rebind(udev, DO_UNBIND);
-       udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+       choose_wakeup(udev, msg);
        return usb_suspend_both(udev, msg);
 }
 
index bdf87a8..2c95153 100644 (file)
@@ -120,7 +120,7 @@ int usb_choose_configuration(struct usb_device *udev)
                 * than a vendor-specific driver. */
                else if (udev->descriptor.bDeviceClass !=
                                                USB_CLASS_VENDOR_SPEC &&
-                               (!desc || desc->bInterfaceClass !=
+                               (desc && desc->bInterfaceClass !=
                                                USB_CLASS_VENDOR_SPEC)) {
                        best = c;
                        break;
index 97b40ce..111a01a 100644 (file)
@@ -380,6 +380,7 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
        mutex_lock(&inode->i_mutex);
        dentry_unhash(dentry);
        if (usbfs_empty(dentry)) {
+               dont_mount(dentry);
                drop_nlink(dentry->d_inode);
                drop_nlink(dentry->d_inode);
                dput(dentry);
@@ -515,13 +516,13 @@ static int fs_create_by_name (const char *name, mode_t mode,
        *dentry = NULL;
        mutex_lock(&parent->d_inode->i_mutex);
        *dentry = lookup_one_len(name, parent, strlen(name));
-       if (!IS_ERR(dentry)) {
+       if (!IS_ERR(*dentry)) {
                if ((mode & S_IFMT) == S_IFDIR)
                        error = usbfs_mkdir (parent->d_inode, *dentry, mode);
                else 
                        error = usbfs_create (parent->d_inode, *dentry, mode);
        } else
-               error = PTR_ERR(dentry);
+               error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
 
        return error;
index 1297e9b..0561430 100644 (file)
@@ -718,7 +718,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size,
 EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
 
 /**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
+ * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
  * @dev: device the buffer will be used with
  * @size: requested buffer size
  * @mem_flags: affect whether allocation may block
@@ -737,30 +737,30 @@ EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
  * architectures where CPU caches are not DMA-coherent.  On systems without
  * bus-snooping caches, these buffers are uncached.
  *
- * When the buffer is no longer used, free it with usb_buffer_free().
+ * When the buffer is no longer used, free it with usb_free_coherent().
  */
-void *usb_buffer_alloc(struct usb_device *dev, size_t size, gfp_t mem_flags,
-                      dma_addr_t *dma)
+void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,
+                        dma_addr_t *dma)
 {
        if (!dev || !dev->bus)
                return NULL;
        return hcd_buffer_alloc(dev->bus, size, mem_flags, dma);
 }
-EXPORT_SYMBOL_GPL(usb_buffer_alloc);
+EXPORT_SYMBOL_GPL(usb_alloc_coherent);
 
 /**
- * usb_buffer_free - free memory allocated with usb_buffer_alloc()
+ * usb_free_coherent - free memory allocated with usb_alloc_coherent()
  * @dev: device the buffer was used with
  * @size: requested buffer size
  * @addr: CPU address of buffer
  * @dma: DMA address of buffer
  *
  * This reclaims an I/O buffer, letting it be reused.  The memory must have
- * been allocated using usb_buffer_alloc(), and the parameters must match
+ * been allocated using usb_alloc_coherent(), and the parameters must match
  * those provided in that allocation request.
  */
-void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
-                    dma_addr_t dma)
+void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,
+                      dma_addr_t dma)
 {
        if (!dev || !dev->bus)
                return;
@@ -768,7 +768,7 @@ void usb_buffer_free(struct usb_device *dev, size_t size, void *addr,
                return;
        hcd_buffer_free(dev->bus, size, addr, dma);
 }
-EXPORT_SYMBOL_GPL(usb_buffer_free);
+EXPORT_SYMBOL_GPL(usb_free_coherent);
 
 /**
  * usb_buffer_map - create DMA mapping(s) for an urb
index df1bae9..eaa79c8 100644 (file)
@@ -366,6 +366,13 @@ rescan:
        if (is_done)
                done(ep, req, 0);
        else if (ep->is_pingpong) {
+               /*
+                * One dummy read to delay the code because of a HW glitch:
+                * CSR returns bad RXCOUNT when read too soon after updating
+                * RX_DATA_BK flags.
+                */
+               csr = __raw_readl(creg);
+
                bufferspace -= count;
                buf += count;
                goto rescan;
index 124a8cc..1f73b48 100644 (file)
@@ -2145,6 +2145,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        u32 epctrl;
        u32 mps;
        int dir_in;
+       int ret = 0;
 
        dev_dbg(hsotg->dev,
                "%s: ep %s: a 0x%02x, attr 0x%02x, mps 0x%04x, intr %d\n",
@@ -2196,7 +2197,8 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
        case USB_ENDPOINT_XFER_ISOC:
                dev_err(hsotg->dev, "no current ISOC support\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
 
        case USB_ENDPOINT_XFER_BULK:
                epctrl |= S3C_DxEPCTL_EPType_Bulk;
@@ -2235,8 +2237,9 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
        /* enable the endpoint interrupt */
        s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
 
+out:
        spin_unlock_irqrestore(&hs_ep->lock, flags);
-       return 0;
+       return ret;
 }
 
 static int s3c_hsotg_ep_disable(struct usb_ep *ep)
index 207e7a8..13ead00 100644 (file)
@@ -543,6 +543,7 @@ static int ehci_init(struct usb_hcd *hcd)
         */
        ehci->periodic_size = DEFAULT_I_TDPS;
        INIT_LIST_HEAD(&ehci->cached_itd_list);
+       INIT_LIST_HEAD(&ehci->cached_sitd_list);
        if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
                return retval;
 
index 1937267..c7178bc 100644 (file)
@@ -801,7 +801,7 @@ static int ehci_hub_control (
                         * this bit; seems too long to spin routinely...
                         */
                        retval = handshake(ehci, status_reg,
-                                       PORT_RESET, 0, 750);
+                                       PORT_RESET, 0, 1000);
                        if (retval != 0) {
                                ehci_err (ehci, "port %d reset error %d\n",
                                        wIndex + 1, retval);
index aeda96e..1f3f01e 100644 (file)
@@ -136,7 +136,7 @@ static inline void qh_put (struct ehci_qh *qh)
 
 static void ehci_mem_cleanup (struct ehci_hcd *ehci)
 {
-       free_cached_itd_list(ehci);
+       free_cached_lists(ehci);
        if (ehci->async)
                qh_put (ehci->async);
        ehci->async = NULL;
index a67a003..40a8583 100644 (file)
@@ -629,11 +629,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
                }
                snprintf(supply, sizeof(supply), "hsusb%d", i);
                omap->regulator[i] = regulator_get(omap->dev, supply);
-               if (IS_ERR(omap->regulator[i]))
+               if (IS_ERR(omap->regulator[i])) {
+                       omap->regulator[i] = NULL;
                        dev_dbg(&pdev->dev,
                        "failed to get ehci port%d regulator\n", i);
-               else
+               } else {
                        regulator_enable(omap->regulator[i]);
+               }
        }
 
        ret = omap_start_ehc(omap, hcd);
index a0aaaaf..805ec63 100644 (file)
@@ -510,7 +510,7 @@ static int disable_periodic (struct ehci_hcd *ehci)
        ehci_writel(ehci, cmd, &ehci->regs->command);
        /* posted write ... */
 
-       free_cached_itd_list(ehci);
+       free_cached_lists(ehci);
 
        ehci->next_uframe = -1;
        return 0;
@@ -2139,13 +2139,27 @@ sitd_complete (
                        (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
        }
        iso_stream_put (ehci, stream);
-       /* OK to recycle this SITD now that its completion callback ran. */
+
 done:
        sitd->urb = NULL;
-       sitd->stream = NULL;
-       list_move(&sitd->sitd_list, &stream->free_list);
-       iso_stream_put(ehci, stream);
-
+       if (ehci->clock_frame != sitd->frame) {
+               /* OK to recycle this SITD now. */
+               sitd->stream = NULL;
+               list_move(&sitd->sitd_list, &stream->free_list);
+               iso_stream_put(ehci, stream);
+       } else {
+               /* HW might remember this SITD, so we can't recycle it yet.
+                * Move it to a safe place until a new frame starts.
+                */
+               list_move(&sitd->sitd_list, &ehci->cached_sitd_list);
+               if (stream->refcount == 2) {
+                       /* If iso_stream_put() were called here, stream
+                        * would be freed.  Instead, just prevent reuse.
+                        */
+                       stream->ep->hcpriv = NULL;
+                       stream->ep = NULL;
+               }
+       }
        return retval;
 }
 
@@ -2211,9 +2225,10 @@ done:
 
 /*-------------------------------------------------------------------------*/
 
-static void free_cached_itd_list(struct ehci_hcd *ehci)
+static void free_cached_lists(struct ehci_hcd *ehci)
 {
        struct ehci_itd *itd, *n;
+       struct ehci_sitd *sitd, *sn;
 
        list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) {
                struct ehci_iso_stream  *stream = itd->stream;
@@ -2221,6 +2236,13 @@ static void free_cached_itd_list(struct ehci_hcd *ehci)
                list_move(&itd->itd_list, &stream->free_list);
                iso_stream_put(ehci, stream);
        }
+
+       list_for_each_entry_safe(sitd, sn, &ehci->cached_sitd_list, sitd_list) {
+               struct ehci_iso_stream  *stream = sitd->stream;
+               sitd->stream = NULL;
+               list_move(&sitd->sitd_list, &stream->free_list);
+               iso_stream_put(ehci, stream);
+       }
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2247,7 +2269,7 @@ scan_periodic (struct ehci_hcd *ehci)
                clock_frame = -1;
        }
        if (ehci->clock_frame != clock_frame) {
-               free_cached_itd_list(ehci);
+               free_cached_lists(ehci);
                ehci->clock_frame = clock_frame;
        }
        clock %= mod;
@@ -2414,7 +2436,7 @@ restart:
                        clock = now;
                        clock_frame = clock >> 3;
                        if (ehci->clock_frame != clock_frame) {
-                               free_cached_itd_list(ehci);
+                               free_cached_lists(ehci);
                                ehci->clock_frame = clock_frame;
                        }
                } else {
index b1dce96..556c0b4 100644 (file)
@@ -87,8 +87,9 @@ struct ehci_hcd {                     /* one per controller */
        int                     next_uframe;    /* scan periodic, start here */
        unsigned                periodic_sched; /* periodic activity count */
 
-       /* list of itds completed while clock_frame was still active */
+       /* list of itds & sitds completed while clock_frame was still active */
        struct list_head        cached_itd_list;
+       struct list_head        cached_sitd_list;
        unsigned                clock_frame;
 
        /* per root hub port */
@@ -195,7 +196,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
        clear_bit (action, &ehci->actions);
 }
 
-static void free_cached_itd_list(struct ehci_hcd *ehci);
+static void free_cached_lists(struct ehci_hcd *ehci);
 
 /*-------------------------------------------------------------------------*/
 
index 68b83ab..944291e 100644 (file)
@@ -331,6 +331,8 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
         */
        if (at91_suspend_entering_slow_clock()) {
                ohci_usb_reset (ohci);
+               /* flush the writes */
+               (void) ohci_readl (ohci, &ohci->regs->control);
                at91_stop_clock();
        }
 
index 4aa08d3..d22fb4d 100644 (file)
@@ -23,7 +23,7 @@
 #error "This file is DA8xx bus glue.  Define CONFIG_ARCH_DAVINCI_DA8XX."
 #endif
 
-#define CFGCHIP2       DA8XX_SYSCFG_VIRT(DA8XX_CFGCHIP2_REG)
+#define CFGCHIP2       DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)
 
 static struct clk *usb11_clk;
 static struct clk *usb20_clk;
index 32bbce9..65cac8c 100644 (file)
@@ -697,7 +697,7 @@ static int ohci_hub_control (
        u16             wLength
 ) {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
-       int             ports = hcd_to_bus (hcd)->root_hub->maxchild;
+       int             ports = ohci->num_ports;
        u32             temp;
        int             retval = 0;
 
index 50f57f4..e62b30b 100644 (file)
@@ -660,13 +660,13 @@ static struct ehci_qh *oxu_qh_alloc(struct oxu_hcd *oxu)
                if (qh->dummy == NULL) {
                        oxu_dbg(oxu, "no dummy td\n");
                        oxu->qh_used[i] = 0;
-
-                       return NULL;
+                       qh = NULL;
+                       goto unlock;
                }
 
                oxu->qh_used[i] = 1;
        }
-
+unlock:
        spin_unlock(&oxu->mem_lock);
 
        return qh;
index e11cc3a..3b867a8 100644 (file)
@@ -720,10 +720,10 @@ retry:
                /* port status seems weird until after reset, so
                 * force the reset and make khubd clean up later.
                 */
-               if (sl811->stat_insrmv & 1)
-                       sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
-               else
+               if (irqstat & SL11H_INTMASK_RD)
                        sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION);
+               else
+                       sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;
 
                sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION;
 
index c09539b..d64f572 100644 (file)
@@ -582,6 +582,19 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
        return EP_INTERVAL(interval);
 }
 
+/* The "Mult" field in the endpoint context is only set for SuperSpeed devices.
+ * High speed endpoint descriptors can define "the number of additional
+ * transaction opportunities per microframe", but that goes in the Max Burst
+ * endpoint context field.
+ */
+static inline u32 xhci_get_endpoint_mult(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp)
+               return 0;
+       return ep->ss_ep_comp->desc.bmAttributes;
+}
+
 static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
                struct usb_host_endpoint *ep)
 {
@@ -612,6 +625,36 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
        return type;
 }
 
+/* Return the maximum endpoint service interval time (ESIT) payload.
+ * Basically, this is the maxpacket size, multiplied by the burst size
+ * and mult size.
+ */
+static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
+               struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+{
+       int max_burst;
+       int max_packet;
+
+       /* Only applies for interrupt or isochronous endpoints */
+       if (usb_endpoint_xfer_control(&ep->desc) ||
+                       usb_endpoint_xfer_bulk(&ep->desc))
+               return 0;
+
+       if (udev->speed == USB_SPEED_SUPER) {
+               if (ep->ss_ep_comp)
+                       return ep->ss_ep_comp->desc.wBytesPerInterval;
+               xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
+               /* Assume no bursts, no multiple opportunities to send. */
+               return ep->desc.wMaxPacketSize;
+       }
+
+       max_packet = ep->desc.wMaxPacketSize & 0x3ff;
+       max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
+       /* A 0 in max burst means 1 transfer per ESIT */
+       return max_packet * (max_burst + 1);
+}
+
 int xhci_endpoint_init(struct xhci_hcd *xhci,
                struct xhci_virt_device *virt_dev,
                struct usb_device *udev,
@@ -623,6 +666,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        struct xhci_ring *ep_ring;
        unsigned int max_packet;
        unsigned int max_burst;
+       u32 max_esit_payload;
 
        ep_index = xhci_get_endpoint_index(&ep->desc);
        ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
@@ -644,6 +688,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
 
        ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
+       ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep));
 
        /* FIXME dig Mult and streams info out of ep companion desc */
 
@@ -689,6 +734,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
        default:
                BUG();
        }
+       max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
+       ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload);
+
+       /*
+        * XXX no idea how to calculate the average TRB buffer length for bulk
+        * endpoints, as the driver gives us no clue how big each scatter gather
+        * list entry (or buffer) is going to be.
+        *
+        * For isochronous and interrupt endpoints, we set it to the max
+        * available, until we have new API in the USB core to allow drivers to
+        * declare how much bandwidth they actually need.
+        *
+        * Normally, it would be calculated by taking the total of the buffer
+        * lengths in the TD and then dividing by the number of TRBs in a TD,
+        * including link TRBs, No-op TRBs, and Event data TRBs.  Since we don't
+        * use Event Data TRBs, and we don't chain in a link TRB on short
+        * transfers, we're basically dividing by 1.
+        */
+       ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload);
+
        /* FIXME Debug endpoint context */
        return 0;
 }
index e5eb09b..ea389e9 100644 (file)
@@ -609,6 +609,10 @@ struct xhci_ep_ctx {
 #define MAX_PACKET_MASK                (0xffff << 16)
 #define MAX_PACKET_DECODED(p)  (((p) >> 16) & 0xffff)
 
+/* tx_info bitmasks */
+#define AVG_TRB_LENGTH_FOR_EP(p)       ((p) & 0xffff)
+#define MAX_ESIT_PAYLOAD_FOR_EP(p)     (((p) & 0xffff) << 16)
+
 
 /**
  * struct xhci_input_control_context
index a9555cb..de8ef94 100644 (file)
@@ -49,6 +49,7 @@ struct usb_sevsegdev {
        u16 textlength;
 
        u8 shadow_power; /* for PM */
+       u8 has_interface_pm;
 };
 
 /* sysfs_streq can't replace this completely
@@ -68,12 +69,16 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
 {
        int rc;
 
-       if (!mydev->shadow_power && mydev->powered) {
+       if (mydev->powered && !mydev->has_interface_pm) {
                rc = usb_autopm_get_interface(mydev->intf);
                if (rc < 0)
                        return;
+               mydev->has_interface_pm = 1;
        }
 
+       if (mydev->shadow_power != 1)
+               return;
+
        rc = usb_control_msg(mydev->udev,
                        usb_sndctrlpipe(mydev->udev, 0),
                        0x12,
@@ -86,8 +91,10 @@ static void update_display_powered(struct usb_sevsegdev *mydev)
        if (rc < 0)
                dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
 
-       if (mydev->shadow_power && !mydev->powered)
+       if (!mydev->powered && mydev->has_interface_pm) {
                usb_autopm_put_interface(mydev->intf);
+               mydev->has_interface_pm = 0;
+       }
 }
 
 static void update_display_mode(struct usb_sevsegdev *mydev)
@@ -351,6 +358,10 @@ static int sevseg_probe(struct usb_interface *interface,
        mydev->intf = interface;
        usb_set_intfdata(interface, mydev);
 
+       /* PM */
+       mydev->shadow_power = 1; /* currently active */
+       mydev->has_interface_pm = 0; /* have not issued autopm_get */
+
        /*set defaults */
        mydev->textmode = 0x02; /* ascii mode */
        mydev->mode_msb = 0x06; /* 6 characters */
index b4c783c..07fe490 100644 (file)
@@ -42,7 +42,7 @@ config USB_MUSB_SOC
        default y if (BF52x && !BF522 && !BF523)
 
 comment "DaVinci 35x and 644x USB support"
-       depends on USB_MUSB_HDRC && ARCH_DAVINCI
+       depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx
 
 comment "OMAP 243x high speed USB support"
        depends on USB_MUSB_HDRC && ARCH_OMAP2430
index 85710cc..3a485da 100644 (file)
@@ -6,7 +6,7 @@ musb_hdrc-objs := musb_core.o
 
 obj-$(CONFIG_USB_MUSB_HDRC)    += musb_hdrc.o
 
-ifeq ($(CONFIG_ARCH_DAVINCI),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
        musb_hdrc-objs  += davinci.o
 endif
 
index 719a22d..ec8d324 100644 (file)
@@ -172,13 +172,7 @@ static irqreturn_t blackfin_interrupt(int irq, void *__hci)
 
        spin_unlock_irqrestore(&musb->lock, flags);
 
-       /* REVISIT we sometimes get spurious IRQs on g_ep0
-        * not clear why... fall in BF54x too.
-        */
-       if (retval != IRQ_HANDLED)
-               DBG(5, "spurious?\n");
-
-       return IRQ_HANDLED;
+       return retval;
 }
 
 static void musb_conn_timer_handler(unsigned long _musb)
index 29bce5c..ce2e16f 100644 (file)
@@ -444,6 +444,8 @@ int __init musb_platform_init(struct musb *musb)
        return 0;
 
 fail:
+       clk_disable(musb->clock);
+
        usb_nop_xceiv_unregister();
        return -ENODEV;
 }
index 0e8b8ab..705cc4a 100644 (file)
@@ -965,10 +965,8 @@ static void musb_shutdown(struct platform_device *pdev)
        spin_lock_irqsave(&musb->lock, flags);
        musb_platform_disable(musb);
        musb_generic_disable(musb);
-       if (musb->clock) {
+       if (musb->clock)
                clk_put(musb->clock);
-               musb->clock = NULL;
-       }
        spin_unlock_irqrestore(&musb->lock, flags);
 
        /* FIXME power down */
@@ -1853,15 +1851,6 @@ static void musb_free(struct musb *musb)
        put_device(musb->xceiv->dev);
 #endif
 
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-       musb_platform_exit(musb);
-       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
-
-       if (musb->clock) {
-               clk_disable(musb->clock);
-               clk_put(musb->clock);
-       }
-
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        usb_put_hcd(musb_to_hcd(musb));
 #else
@@ -1889,8 +1878,10 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
         */
        if (!plat) {
                dev_dbg(dev, "no platform_data?\n");
-               return -ENODEV;
+               status = -ENODEV;
+               goto fail0;
        }
+
        switch (plat->mode) {
        case MUSB_HOST:
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
@@ -1912,13 +1903,16 @@ bad_config:
 #endif
        default:
                dev_err(dev, "incompatible Kconfig role setting\n");
-               return -EINVAL;
+               status = -EINVAL;
+               goto fail0;
        }
 
        /* allocate */
        musb = allocate_instance(dev, plat->config, ctrl);
-       if (!musb)
-               return -ENOMEM;
+       if (!musb) {
+               status = -ENOMEM;
+               goto fail0;
+       }
 
        spin_lock_init(&musb->lock);
        musb->board_mode = plat->mode;
@@ -1936,7 +1930,7 @@ bad_config:
                if (IS_ERR(musb->clock)) {
                        status = PTR_ERR(musb->clock);
                        musb->clock = NULL;
-                       goto fail;
+                       goto fail1;
                }
        }
 
@@ -1955,12 +1949,12 @@ bad_config:
         */
        musb->isr = generic_interrupt;
        status = musb_platform_init(musb);
-
        if (status < 0)
-               goto fail;
+               goto fail2;
+
        if (!musb->isr) {
                status = -ENODEV;
-               goto fail2;
+               goto fail3;
        }
 
 #ifndef CONFIG_MUSB_PIO_ONLY
@@ -1986,7 +1980,7 @@ bad_config:
                        ? MUSB_CONTROLLER_MHDRC
                        : MUSB_CONTROLLER_HDRC, musb);
        if (status < 0)
-               goto fail2;
+               goto fail3;
 
 #ifdef CONFIG_USB_MUSB_OTG
        setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb);
@@ -1999,7 +1993,7 @@ bad_config:
        if (request_irq(nIrq, musb->isr, 0, dev_name(dev), musb)) {
                dev_err(dev, "request_irq %d failed!\n", nIrq);
                status = -ENODEV;
-               goto fail2;
+               goto fail3;
        }
        musb->nIrq = nIrq;
 /* FIXME this handles wakeup irqs wrong */
@@ -2039,8 +2033,6 @@ bad_config:
                musb->xceiv->state = OTG_STATE_A_IDLE;
 
                status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
-               if (status)
-                       goto fail;
 
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
@@ -2055,8 +2047,6 @@ bad_config:
                musb->xceiv->state = OTG_STATE_B_IDLE;
 
                status = musb_gadget_setup(musb);
-               if (status)
-                       goto fail;
 
                DBG(1, "%s mode, status %d, dev%02x\n",
                        is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2064,12 +2054,14 @@ bad_config:
                        musb_readb(musb->mregs, MUSB_DEVCTL));
 
        }
+       if (status < 0)
+               goto fail3;
 
 #ifdef CONFIG_SYSFS
        status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
-#endif
        if (status)
-               goto fail2;
+               goto fail4;
+#endif
 
        dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
                        ({char *s;
@@ -2085,17 +2077,29 @@ bad_config:
 
        return 0;
 
-fail2:
+fail4:
+       if (!is_otg_enabled(musb) && is_host_enabled(musb))
+               usb_remove_hcd(musb_to_hcd(musb));
+       else
+               musb_gadget_cleanup(musb);
+
+fail3:
+       if (musb->irq_wake)
+               device_init_wakeup(dev, 0);
        musb_platform_exit(musb);
-fail:
-       dev_err(musb->controller,
-               "musb_init_controller failed with status %d\n", status);
 
+fail2:
        if (musb->clock)
                clk_put(musb->clock);
-       device_init_wakeup(dev, 0);
+
+fail1:
+       dev_err(musb->controller,
+               "musb_init_controller failed with status %d\n", status);
+
        musb_free(musb);
 
+fail0:
+
        return status;
 
 }
@@ -2132,7 +2136,6 @@ static int __init musb_probe(struct platform_device *pdev)
        /* clobbered by use_dma=n */
        orig_dma_mask = dev->dma_mask;
 #endif
-
        status = musb_init_controller(dev, irq, base);
        if (status < 0)
                iounmap(base);
@@ -2155,6 +2158,10 @@ static int __exit musb_remove(struct platform_device *pdev)
        if (musb->board_mode == MUSB_HOST)
                usb_remove_hcd(musb_to_hcd(musb));
 #endif
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+       musb_platform_exit(musb);
+       musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
+
        musb_free(musb);
        iounmap(ctrl_base);
        device_init_wakeup(&pdev->dev, 0);
@@ -2176,6 +2183,7 @@ void musb_save_context(struct musb *musb)
        if (is_host_enabled(musb)) {
                musb_context.frame = musb_readw(musb_base, MUSB_FRAME);
                musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE);
+               musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs);
        }
        musb_context.power = musb_readb(musb_base, MUSB_POWER);
        musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE);
@@ -2247,6 +2255,7 @@ void musb_restore_context(struct musb *musb)
        if (is_host_enabled(musb)) {
                musb_writew(musb_base, MUSB_FRAME, musb_context.frame);
                musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode);
+               musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl);
        }
        musb_writeb(musb_base, MUSB_POWER, musb_context.power);
        musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe);
index cd9f4a9..ac17b00 100644 (file)
@@ -478,7 +478,7 @@ struct musb_context_registers {
        u16 frame;
        u8 index, testmode;
 
-       u8 devctl, misc;
+       u8 devctl, busctl, misc;
 
        struct musb_csr_regs index_regs[MUSB_C_NUM_EPS];
 };
index dec896e..877d20b 100644 (file)
@@ -2042,6 +2042,7 @@ static int musb_urb_enqueue(
                 * odd, rare, error prone, but legal.
                 */
                kfree(qh);
+               qh = NULL;
                ret = 0;
        } else
                ret = musb_schedule(musb, qh,
index 490cdf1..8259263 100644 (file)
@@ -331,8 +331,5 @@ int musb_platform_exit(struct musb *musb)
 
        musb_platform_suspend(musb);
 
-       clk_put(musb->clock);
-       musb->clock = NULL;
-
        return 0;
 }
index ab776a8..60d3938 100644 (file)
@@ -29,6 +29,19 @@ static void tusb_source_power(struct musb *musb, int is_on);
 #define TUSB_REV_MAJOR(reg_val)                ((reg_val >> 4) & 0xf)
 #define TUSB_REV_MINOR(reg_val)                (reg_val & 0xf)
 
+#ifdef CONFIG_PM
+/* REVISIT: These should be only needed if somebody implements off idle */
+void musb_platform_save_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+}
+
+void musb_platform_restore_context(struct musb *musb,
+                       struct musb_context_registers *musb_context)
+{
+}
+#endif
+
 /*
  * Checks the revision. We need to use the DMA register as 3.0 does not
  * have correct versions for TUSB_PRCM_REV or TUSB_INT_CTRL_REV.
index 5afa070..c061a88 100644 (file)
@@ -39,7 +39,7 @@ struct tusb_omap_dma_ch {
 
        struct tusb_omap_dma    *tusb_dma;
 
-       void __iomem            *dma_addr;
+       dma_addr_t              dma_addr;
 
        u32                     len;
        u16                     packet_sz;
@@ -126,6 +126,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
        struct tusb_omap_dma_ch *chdat = to_chdat(channel);
        struct tusb_omap_dma    *tusb_dma = chdat->tusb_dma;
        struct musb             *musb = chdat->musb;
+       struct device           *dev = musb->controller;
        struct musb_hw_ep       *hw_ep = chdat->hw_ep;
        void __iomem            *ep_conf = hw_ep->conf;
        void __iomem            *mbase = musb->mregs;
@@ -173,13 +174,15 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
                DBG(3, "Using PIO for remaining %lu bytes\n", pio);
                buf = phys_to_virt((u32)chdat->dma_addr) + chdat->transfer_len;
                if (chdat->tx) {
-                       dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-                                       chdat->transfer_len, DMA_TO_DEVICE);
+                       dma_unmap_single(dev, chdat->dma_addr,
+                                               chdat->transfer_len,
+                                               DMA_TO_DEVICE);
                        musb_write_fifo(hw_ep, pio, buf);
                } else {
+                       dma_unmap_single(dev, chdat->dma_addr,
+                                               chdat->transfer_len,
+                                               DMA_FROM_DEVICE);
                        musb_read_fifo(hw_ep, pio, buf);
-                       dma_cache_maint(phys_to_virt((u32)chdat->dma_addr),
-                                       chdat->transfer_len, DMA_FROM_DEVICE);
                }
                channel->actual_len += pio;
        }
@@ -224,6 +227,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        struct tusb_omap_dma_ch         *chdat = to_chdat(channel);
        struct tusb_omap_dma            *tusb_dma = chdat->tusb_dma;
        struct musb                     *musb = chdat->musb;
+       struct device                   *dev = musb->controller;
        struct musb_hw_ep               *hw_ep = chdat->hw_ep;
        void __iomem                    *mbase = musb->mregs;
        void __iomem                    *ep_conf = hw_ep->conf;
@@ -299,14 +303,16 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        chdat->packet_sz = packet_sz;
        chdat->len = len;
        channel->actual_len = 0;
-       chdat->dma_addr = (void __iomem *)dma_addr;
+       chdat->dma_addr = dma_addr;
        channel->status = MUSB_DMA_STATUS_BUSY;
 
        /* Since we're recycling dma areas, we need to clean or invalidate */
        if (chdat->tx)
-               dma_cache_maint(phys_to_virt(dma_addr), len, DMA_TO_DEVICE);
+               dma_map_single(dev, phys_to_virt(dma_addr), len,
+                               DMA_TO_DEVICE);
        else
-               dma_cache_maint(phys_to_virt(dma_addr), len, DMA_FROM_DEVICE);
+               dma_map_single(dev, phys_to_virt(dma_addr), len,
+                               DMA_FROM_DEVICE);
 
        /* Use 16-bit transfer if dma_addr is not 32-bit aligned */
        if ((dma_addr & 0x3) == 0) {
index ca9d866..84d0eda 100644 (file)
@@ -305,6 +305,11 @@ static int  option_resume(struct usb_serial *serial);
 #define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 #define ZTE_PRODUCT_AC8710                     0xfff1
 #define ZTE_PRODUCT_AC2726                     0xfff5
+#define ZTE_PRODUCT_AC8710T                    0xffff
+
+/* ZTE PRODUCTS -- alternate vendor ID */
+#define ZTE_VENDOR_ID2                         0x1d6b
+#define ZTE_PRODUCT_MF_330                     0x0002
 
 #define BENQ_VENDOR_ID                         0x04a5
 #define BENQ_PRODUCT_H10                       0x4068
@@ -373,6 +378,8 @@ static int  option_resume(struct usb_serial *serial);
 #define HAIER_VENDOR_ID                                0x201e
 #define HAIER_PRODUCT_CE100                    0x2009
 
+#define CINTERION_VENDOR_ID                    0x0681
+
 /* some devices interfaces need special handling due to a number of reasons */
 enum option_blacklist_reason {
                OPTION_BLACKLIST_NONE = 0,
@@ -679,6 +686,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(ZTE_VENDOR_ID2, ZTE_PRODUCT_MF_330) },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
        { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
@@ -716,6 +725,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
        { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
 
+       { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 73d5f34..c28b160 100644 (file)
@@ -59,6 +59,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
+       { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
@@ -97,6 +98,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
        { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
+       { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
index d640dc9..23c09b3 100644 (file)
@@ -20,6 +20,7 @@
 #define PL2303_PRODUCT_ID_ALDIGA       0x0611
 #define PL2303_PRODUCT_ID_MMX          0x0612
 #define PL2303_PRODUCT_ID_GPRS         0x0609
+#define PL2303_PRODUCT_ID_HCR331       0x331a
 
 #define ATEN_VENDOR_ID         0x0557
 #define ATEN_VENDOR_ID2                0x0547
 /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */
 #define SANWA_VENDOR_ID                0x11ad
 #define SANWA_PRODUCT_ID       0x0001
+
+/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
+#define ADLINK_VENDOR_ID        0x0b63
+#define ADLINK_ND6530_PRODUCT_ID       0x6530
index 0b93620..7e3bea2 100644 (file)
 #define CMOTECH_PRODUCT_CDU550                 0x5553
 #define CMOTECH_PRODUCT_CDX650                 0x6512
 
+/* LG devices */
+#define LG_VENDOR_ID                           0x1004
+#define LG_PRODUCT_VX4400_6000                 0x6000 /* VX4400/VX6000/Rumor */
+
+/* Sanyo devices */
+#define SANYO_VENDOR_ID                                0x0474
+#define SANYO_PRODUCT_KATANA_LX                        0x0754 /* SCP-3800 (Katana LX) */
+
 static struct usb_device_id id_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) },
@@ -51,6 +59,8 @@ static struct usb_device_id id_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_UM175_ALLTEL, 0xff, 0x00, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU550, 0xff, 0xff, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index 9202f94..ef0bdb0 100644 (file)
@@ -230,6 +230,7 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
 static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
        { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
+       { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */
        { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
 
        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
index 0afe5c7..e1bfda3 100644 (file)
@@ -172,7 +172,7 @@ static unsigned int product_5052_count;
 /* the array dimension is the number of default entries plus */
 /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
 /* null entry */
-static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -180,6 +180,9 @@ static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
        { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
        { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
        { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
@@ -192,7 +195,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
 };
 
-static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -200,6 +203,9 @@ static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1]
        { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
        { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234MU_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBA_PRODUCT_ID) },
+       { USB_DEVICE(MTS_VENDOR_ID, MTS_MT9234ZBAOLD_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -287,6 +293,8 @@ MODULE_FIRMWARE("ti_5052.fw");
 MODULE_FIRMWARE("mts_cdma.fw");
 MODULE_FIRMWARE("mts_gsm.fw");
 MODULE_FIRMWARE("mts_edge.fw");
+MODULE_FIRMWARE("mts_mt9234mu.fw");
+MODULE_FIRMWARE("mts_mt9234zba.fw");
 
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
@@ -1687,6 +1695,7 @@ static int ti_download_firmware(struct ti_device *tdev)
        const struct firmware *fw_p;
        char buf[32];
 
+       dbg("%s\n", __func__);
        /* try ID specific firmware first, then try generic firmware */
        sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
            dev->descriptor.idProduct);
@@ -1703,7 +1712,15 @@ static int ti_download_firmware(struct ti_device *tdev)
                        case MTS_EDGE_PRODUCT_ID:
                                strcpy(buf, "mts_edge.fw");
                                break;
-                       }
+                       case MTS_MT9234MU_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234mu.fw");
+                               break;
+                       case MTS_MT9234ZBA_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234zba.fw");
+                               break;
+                       case MTS_MT9234ZBAOLD_PRODUCT_ID:
+                               strcpy(buf, "mts_mt9234zba.fw");
+                               break;                  }
                }
                if (buf[0] == '\0') {
                        if (tdev->td_is_3410)
@@ -1718,7 +1735,7 @@ static int ti_download_firmware(struct ti_device *tdev)
                return -ENOENT;
        }
        if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
-               dev_err(&dev->dev, "%s - firmware too large\n", __func__);
+               dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
                return -ENOENT;
        }
 
@@ -1730,6 +1747,7 @@ static int ti_download_firmware(struct ti_device *tdev)
                status = ti_do_download(dev, pipe, buffer, fw_p->size);
                kfree(buffer);
        } else {
+               dbg("%s ENOMEM\n", __func__);
                status = -ENOMEM;
        }
        release_firmware(fw_p);
index f323c60..2aac195 100644 (file)
@@ -45,6 +45,9 @@
 #define MTS_CDMA_PRODUCT_ID            0xF110
 #define MTS_GSM_PRODUCT_ID             0xF111
 #define MTS_EDGE_PRODUCT_ID            0xF112
+#define MTS_MT9234MU_PRODUCT_ID                0xF114
+#define MTS_MT9234ZBA_PRODUCT_ID       0xF115
+#define MTS_MT9234ZBAOLD_PRODUCT_ID    0x0319
 
 /* Commands */
 #define TI_GET_VERSION                 0x01
index 46e79d3..7ec24e4 100644 (file)
@@ -438,7 +438,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
        old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
        keep_alives = 0;
        for (cnt = 0;
-            keep_alives <= WUIE_ELT_MAX && cnt < wusbhc->ports_max;
+            keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
             cnt++) {
                unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);
 
index 5be11c9..49fa953 100644 (file)
@@ -236,6 +236,10 @@ static int vq_memory_access_ok(void __user *log_base, struct vhost_memory *mem,
                               int log_all)
 {
        int i;
+
+        if (!mem)
+                return 0;
+
        for (i = 0; i < mem->nregions; ++i) {
                struct vhost_memory_region *m = mem->regions + i;
                unsigned long a = m->userspace_addr;
@@ -1031,7 +1035,12 @@ int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
 /* This actually signals the guest, using eventfd. */
 void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
 {
-       __u16 flags = 0;
+       __u16 flags;
+       /* Flush out used index updates. This is paired
+        * with the barrier that the Guest executes when enabling
+        * interrupts. */
+       smp_mb();
+
        if (get_user(flags, &vq->avail->flags)) {
                vq_err(vq, "Failed to get flags");
                return;
index dca48df..e5d6b56 100644 (file)
@@ -50,8 +50,9 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-
+#include <linux/platform_device.h>
 #include <linux/uaccess.h>
+
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/amigahw.h>
@@ -1135,7 +1136,7 @@ static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
         * Interface to the low level console driver
         */
 
-static void amifb_deinit(void);
+static void amifb_deinit(struct platform_device *pdev);
 
        /*
         * Internal routines
@@ -2246,7 +2247,7 @@ static inline void chipfree(void)
         * Initialisation
         */
 
-static int __init amifb_init(void)
+static int __init amifb_probe(struct platform_device *pdev)
 {
        int tag, i, err = 0;
        u_long chipptr;
@@ -2261,16 +2262,6 @@ static int __init amifb_init(void)
        }
        amifb_setup(option);
 #endif
-       if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
-               return -ENODEV;
-
-       /*
-        * We request all registers starting from bplpt[0]
-        */
-       if (!request_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120,
-                               "amifb [Denise/Lisa]"))
-               return -EBUSY;
-
        custom.dmacon = DMAF_ALL | DMAF_MASTER;
 
        switch (amiga_chipset) {
@@ -2377,6 +2368,7 @@ default_chipset:
        fb_info.fbops = &amifb_ops;
        fb_info.par = &currentpar;
        fb_info.flags = FBINFO_DEFAULT;
+       fb_info.device = &pdev->dev;
 
        if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb,
                          NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
@@ -2451,18 +2443,18 @@ default_chipset:
        return 0;
 
 amifb_error:
-       amifb_deinit();
+       amifb_deinit(pdev);
        return err;
 }
 
-static void amifb_deinit(void)
+static void amifb_deinit(struct platform_device *pdev)
 {
        if (fb_info.cmap.len)
                fb_dealloc_cmap(&fb_info.cmap);
+       fb_dealloc_cmap(&fb_info.cmap);
        chipfree();
        if (videomemory)
                iounmap((void*)videomemory);
-       release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120);
        custom.dmacon = DMAF_ALL | DMAF_MASTER;
 }
 
@@ -3794,14 +3786,35 @@ static void ami_rebuild_copper(void)
        }
 }
 
-static void __exit amifb_exit(void)
+static int __exit amifb_remove(struct platform_device *pdev)
 {
        unregister_framebuffer(&fb_info);
-       amifb_deinit();
+       amifb_deinit(pdev);
        amifb_video_off();
+       return 0;
+}
+
+static struct platform_driver amifb_driver = {
+       .remove = __exit_p(amifb_remove),
+       .driver   = {
+               .name   = "amiga-video",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init amifb_init(void)
+{
+       return platform_driver_probe(&amifb_driver, amifb_probe);
 }
 
 module_init(amifb_init);
+
+static void __exit amifb_exit(void)
+{
+       platform_driver_unregister(&amifb_driver);
+}
+
 module_exit(amifb_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:amiga-video");
index 44e49c2..c2ec3dc 100644 (file)
@@ -488,9 +488,9 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
        fbinfo->fbops = &bfin_t350mcqb_fb_ops;
        fbinfo->flags = FBINFO_FLAG_DEFAULT;
 
-       info->fb_buffer =
-           dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle,
-                              GFP_KERNEL);
+       info->fb_buffer = dma_alloc_coherent(NULL, fbinfo->fix.smem_len +
+                               ACTIVE_VIDEO_MEM_OFFSET,
+                               &info->dma_handle, GFP_KERNEL);
 
        if (NULL == info->fb_buffer) {
                printk(KERN_ERR DRIVER_NAME
@@ -568,8 +568,8 @@ out7:
 out6:
        fb_dealloc_cmap(&fbinfo->cmap);
 out4:
-       dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
-                         info->dma_handle);
+       dma_free_coherent(NULL, fbinfo->fix.smem_len + ACTIVE_VIDEO_MEM_OFFSET,
+                        info->fb_buffer, info->dma_handle);
 out3:
        framebuffer_release(fbinfo);
 out2:
@@ -592,8 +592,9 @@ static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev)
        free_irq(info->irq, info);
 
        if (info->fb_buffer != NULL)
-               dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
-                                 info->dma_handle);
+               dma_free_coherent(NULL, fbinfo->fix.smem_len +
+                       ACTIVE_VIDEO_MEM_OFFSET, info->fb_buffer,
+                       info->dma_handle);
 
        fb_dealloc_cmap(&fbinfo->cmap);
 
index 8d8dfda..6df7c54 100644 (file)
@@ -299,6 +299,7 @@ static const struct zorro_device_id cirrusfb_zorro_table[] = {
        },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
 
 static const struct {
        zorro_id id2;
index 581d2db..ecf4055 100644 (file)
@@ -49,6 +49,7 @@ enum {
        M_MBP_2,        /* MacBook Pro 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_UNKNOWN       /* placeholder */
 };
 
@@ -70,6 +71,7 @@ static struct efifb_dmi_info {
        [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
        [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_UNKNOWN] = { NULL, 0, 0, 0, 0 }
 };
 
@@ -106,6 +108,7 @@ static struct dmi_system_id __initdata dmi_system_table[] = {
        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),
        {},
 };
 
index 6c91c61..1b0feb8 100644 (file)
@@ -219,6 +219,7 @@ static struct zorro_device_id fm2fb_devices[] __devinitdata = {
        { ZORRO_PROD_HELFRICH_RAINBOW_II },
        { 0 }
 };
+MODULE_DEVICE_TABLE(zorro, fm2fb_devices);
 
 static struct zorro_driver fm2fb_driver = {
        .name           = "fm2fb",
index e14bd07..e8c7699 100644 (file)
@@ -695,6 +695,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
         * 1) Enable Runtime PM
         * 2) Force Runtime PM Resume since hardware is accessed from probe()
         */
+       priv->dev = &pdev->dev;
        pm_runtime_enable(priv->dev);
        pm_runtime_resume(priv->dev);
        return 0;
@@ -957,25 +958,24 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
 
        if (!pdev->dev.platform_data) {
                dev_err(&pdev->dev, "no platform data defined\n");
-               error = -EINVAL;
-               goto err0;
+               return -EINVAL;
        }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        i = platform_get_irq(pdev, 0);
        if (!res || i < 0) {
                dev_err(&pdev->dev, "cannot get platform resources\n");
-               error = -ENOENT;
-               goto err0;
+               return -ENOENT;
        }
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
                dev_err(&pdev->dev, "cannot allocate device data\n");
-               error = -ENOMEM;
-               goto err0;
+               return -ENOMEM;
        }
 
+       platform_set_drvdata(pdev, priv);
+
        error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED,
                            dev_name(&pdev->dev), priv);
        if (error) {
@@ -984,8 +984,6 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
        }
 
        priv->irq = i;
-       priv->dev = &pdev->dev;
-       platform_set_drvdata(pdev, priv);
        pdata = pdev->dev.platform_data;
 
        j = 0;
@@ -1099,9 +1097,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
                info = ch->info;
 
                if (info->fbdefio) {
-                       priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
+                       ch->sglist = vmalloc(sizeof(struct scatterlist) *
                                        info->fix.smem_len >> PAGE_SHIFT);
-                       if (!priv->ch->sglist) {
+                       if (!ch->sglist) {
                                dev_err(&pdev->dev, "cannot allocate sglist\n");
                                goto err1;
                        }
@@ -1126,9 +1124,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
        }
 
        return 0;
- err1:
+err1:
        sh_mobile_lcdc_remove(pdev);
- err0:
+
        return error;
 }
 
@@ -1139,7 +1137,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
-               if (priv->ch[i].info->dev)
+               if (priv->ch[i].info && priv->ch[i].info->dev)
                        unregister_framebuffer(priv->ch[i].info);
 
        sh_mobile_lcdc_stop(priv);
@@ -1162,7 +1160,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
        if (priv->dot_clk)
                clk_put(priv->dot_clk);
 
-       pm_runtime_disable(priv->dev);
+       if (priv->dev)
+               pm_runtime_disable(priv->dev);
 
        if (priv->base)
                iounmap(priv->base);
index 3aed388..bfec7c2 100644 (file)
@@ -103,7 +103,8 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
        num = min(num, ARRAY_SIZE(vb->pfns));
 
        for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
-               struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY);
+               struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
+                                       __GFP_NOMEMALLOC | __GFP_NOWARN);
                if (!page) {
                        if (printk_ratelimit())
                                dev_printk(KERN_INFO, &vb->vdev->dev,
index ef36fca..3a7e9ff 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 
 #include <asm/irq.h>
 #include <mach/hardware.h>
index 1ed3d55..17726a0 100644 (file)
@@ -115,9 +115,8 @@ static struct w1_therm_family_converter w1_therm_families[] = {
 
 static inline int w1_DS18B20_convert_temp(u8 rom[9])
 {
-       int t = ((s16)rom[1] << 8) | rom[0];
-       t = t*1000/16;
-       return t;
+       s16 t = le16_to_cpup((__le16 *)rom);
+       return t*1000/16;
 }
 
 static inline int w1_DS18S20_convert_temp(u8 rom[9])
index 0e8468f..b87ba23 100644 (file)
@@ -175,7 +175,7 @@ config SA1100_WATCHDOG
 
 config MPCORE_WATCHDOG
        tristate "MPcore watchdog"
-       depends on ARM_MPCORE_PLATFORM && LOCAL_TIMERS
+       depends on HAVE_ARM_TWD
        help
          Watchdog timer embedded into the MPcore system.
 
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG
 
 config OMAP_WATCHDOG
        tristate "OMAP Watchdog"
-       depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3
+       depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
        help
-         Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog.  Say 'Y'
-         here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
+         Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog.  Say 'Y'
+         here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
 
 config PNX4008_WATCHDOG
        tristate "PNX4008 Watchdog"
@@ -302,7 +302,7 @@ config TS72XX_WATCHDOG
 
 config MAX63XX_WATCHDOG
        tristate "Max63xx watchdog"
-       depends on ARM
+       depends on ARM && HAS_IOMEM
        help
          Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
 
index 8b724aa..801ead1 100644 (file)
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
 
 #ifdef CONFIG_FSL_BOOKE
 #define WDTP(x)                ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
-#define WDTP_MASK      (WDTP(0))
+#define WDTP_MASK      (WDTP(0x3f))
 #else
 #define WDTP(x)                (TCR_WP(x))
 #define WDTP_MASK      (TCR_WP_MASK)
@@ -121,7 +121,7 @@ static ssize_t booke_wdt_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct watchdog_info ident = {
+static struct watchdog_info ident = {
        .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
        .identity = "PowerPC Book-E Watchdog",
 };
index 88ed54e..59359c9 100644 (file)
@@ -244,7 +244,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout,
        "Watchdog timeout in seconds. (1<=timeout<=3600, default="
-                               __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
+                               __MODULE_STRING(WDT_TIMEOUT) ")");
 
 MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
                "Alessandro Zummo <a.zummo@towertech.it>");
index 75f3a83..3053ff0 100644 (file)
@@ -154,9 +154,14 @@ static void max63xx_wdt_enable(struct max63xx_timeout *entry)
 
 static void max63xx_wdt_disable(void)
 {
+       u8 val;
+
        spin_lock(&io_lock);
 
-       __raw_writeb(3, wdt_base);
+       val = __raw_readb(wdt_base);
+       val &= ~MAX6369_WDSET;
+       val |= 3;
+       __raw_writeb(val, wdt_base);
 
        spin_unlock(&io_lock);
 
index 016c6a7..b8ec7ac 100644 (file)
@@ -31,8 +31,9 @@
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 
-#include <asm/hardware/arm_twd.h>
+#include <asm/smp_twd.h>
 
 struct mpcore_wdt {
        unsigned long   timer_alive;
@@ -44,7 +45,7 @@ struct mpcore_wdt {
 };
 
 static struct platform_device *mpcore_wdt_dev;
-extern unsigned int mpcore_timer_rate;
+static DEFINE_SPINLOCK(wdt_lock);
 
 #define TIMER_MARGIN   60
 static int mpcore_margin = TIMER_MARGIN;
@@ -94,13 +95,15 @@ static irqreturn_t mpcore_wdt_fire(int irq, void *arg)
  */
 static void mpcore_wdt_keepalive(struct mpcore_wdt *wdt)
 {
-       unsigned int count;
+       unsigned long count;
 
+       spin_lock(&wdt_lock);
        /* Assume prescale is set to 256 */
-       count = (mpcore_timer_rate / 256) * mpcore_margin;
+       count =  __raw_readl(wdt->base + TWD_WDOG_COUNTER);
+       count = (0xFFFFFFFFU - count) * (HZ / 5);
+       count = (count / 256) * mpcore_margin;
 
        /* Reload the counter */
-       spin_lock(&wdt_lock);
        writel(count + wdt->perturb, wdt->base + TWD_WDOG_LOAD);
        wdt->perturb = wdt->perturb ? 0 : 1;
        spin_unlock(&wdt_lock);
@@ -119,7 +122,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
 {
        dev_printk(KERN_INFO, wdt->dev, "enabling watchdog.\n");
 
-       spin_lock(&wdt_lock);
        /* This loads the count register but does NOT start the count yet */
        mpcore_wdt_keepalive(wdt);
 
@@ -130,7 +132,6 @@ static void mpcore_wdt_start(struct mpcore_wdt *wdt)
                /* Enable watchdog - prescale=256, watchdog mode=1, enable=1 */
                writel(0x0000FF09, wdt->base + TWD_WDOG_CONTROL);
        }
-       spin_unlock(&wdt_lock);
 }
 
 static int mpcore_wdt_set_heartbeat(int t)
@@ -360,7 +361,7 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
        mpcore_wdt_miscdev.parent = &dev->dev;
        ret = misc_register(&mpcore_wdt_miscdev);
        if (ret) {
-               dev_printk(KERN_ERR, _dev,
+               dev_printk(KERN_ERR, wdt->dev,
                        "cannot register miscdev on minor=%d (err=%d)\n",
                                                        WATCHDOG_MINOR, ret);
                goto err_misc;
@@ -369,13 +370,13 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
        ret = request_irq(wdt->irq, mpcore_wdt_fire, IRQF_DISABLED,
                                                        "mpcore_wdt", wdt);
        if (ret) {
-               dev_printk(KERN_ERR, _dev,
+               dev_printk(KERN_ERR, wdt->dev,
                        "cannot register IRQ%d for watchdog\n", wdt->irq);
                goto err_irq;
        }
 
        mpcore_wdt_stop(wdt);
-       platform_set_drvdata(&dev->dev, wdt);
+       platform_set_drvdata(dev, wdt);
        mpcore_wdt_dev = dev;
 
        return 0;
index c8eadd4..88c83aa 100644 (file)
@@ -67,8 +67,8 @@ static DEFINE_SPINLOCK(sbwd_lock);
 void sbwdog_set(char __iomem *wdog, unsigned long t)
 {
        spin_lock(&sbwd_lock);
-       __raw_writeb(0, wdog - 0x10);
-       __raw_writeq(t & 0x7fffffUL, wdog);
+       __raw_writeb(0, wdog);
+       __raw_writeq(t & 0x7fffffUL, wdog - 0x10);
        spin_unlock(&sbwd_lock);
 }
 
index 8d44c9b..c7d67e9 100644 (file)
@@ -30,7 +30,7 @@
 static int nowayout = WATCHDOG_NOWAYOUT;
 static unsigned int margin = 60;       /* (secs) Default is 1 minute */
 static unsigned long wdt_status;
-static DEFINE_SPINLOCK(wdt_lock);
+static DEFINE_MUTEX(wdt_lock);
 
 #define WDT_IN_USE             0
 #define WDT_OK_TO_CLOSE                1
@@ -45,26 +45,26 @@ static DEFINE_SPINLOCK(wdt_lock);
 
 static void wdt_send_data(unsigned char command, unsigned char data)
 {
-       outb(command, COMMAND_PORT);
-       msleep(100);
        outb(data, DATA_PORT);
        msleep(200);
+       outb(command, COMMAND_PORT);
+       msleep(100);
 }
 
 static void wdt_enable(void)
 {
-       spin_lock(&wdt_lock);
+       mutex_lock(&wdt_lock);
        wdt_send_data(IFACE_ON_COMMAND, 1);
        wdt_send_data(REBOOT_COMMAND, margin);
-       spin_unlock(&wdt_lock);
+       mutex_unlock(&wdt_lock);
 }
 
 static void wdt_disable(void)
 {
-       spin_lock(&wdt_lock);
+       mutex_lock(&wdt_lock);
        wdt_send_data(IFACE_ON_COMMAND, 0);
        wdt_send_data(REBOOT_COMMAND, 0);
-       spin_unlock(&wdt_lock);
+       mutex_unlock(&wdt_lock);
 }
 
 static int fitpc2_wdt_open(struct inode *inode, struct file *file)
index 2ac4440..8943b8c 100644 (file)
@@ -80,12 +80,6 @@ static void do_suspend(void)
 
        shutting_down = SHUTDOWN_SUSPEND;
 
-       err = stop_machine_create();
-       if (err) {
-               printk(KERN_ERR "xen suspend: failed to setup stop_machine %d\n", err);
-               goto out;
-       }
-
 #ifdef CONFIG_PREEMPT
        /* If the kernel is preemptible, we need to freeze all the processes
           to prevent them from being in the middle of a pagetable update
@@ -93,7 +87,7 @@ static void do_suspend(void)
        err = freeze_processes();
        if (err) {
                printk(KERN_ERR "xen suspend: freeze failed %d\n", err);
-               goto out_destroy_sm;
+               goto out;
        }
 #endif
 
@@ -136,12 +130,8 @@ out_resume:
 out_thaw:
 #ifdef CONFIG_PREEMPT
        thaw_processes();
-
-out_destroy_sm:
-#endif
-       stop_machine_destroy();
-
 out:
+#endif
        shutting_down = SHUTDOWN_INVALID;
 }
 #endif /* CONFIG_PM_SLEEP */
index d47c47f..3c7046d 100644 (file)
@@ -97,7 +97,7 @@ static void zorro_seq_stop(struct seq_file *m, void *v)
 
 static int zorro_seq_show(struct seq_file *m, void *v)
 {
-       u_int slot = *(loff_t *)v;
+       unsigned int slot = *(loff_t *)v;
        struct zorro_dev *z = &zorro_autocon[slot];
 
        seq_printf(m, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot, z->id,
@@ -129,7 +129,7 @@ static const struct file_operations zorro_devices_proc_fops = {
 
 static struct proc_dir_entry *proc_bus_zorro_dir;
 
-static int __init zorro_proc_attach_device(u_int slot)
+static int __init zorro_proc_attach_device(unsigned int slot)
 {
        struct proc_dir_entry *entry;
        char name[4];
@@ -146,7 +146,7 @@ static int __init zorro_proc_attach_device(u_int slot)
 
 static int __init zorro_proc_init(void)
 {
-       u_int slot;
+       unsigned int slot;
 
        if (MACH_IS_AMIGA && AMIGAHW_PRESENT(ZORRO)) {
                proc_bus_zorro_dir = proc_mkdir("bus/zorro", NULL);
index 53180a3..7ee2b6e 100644 (file)
@@ -137,10 +137,34 @@ static int zorro_bus_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
+static int zorro_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+#ifdef CONFIG_HOTPLUG
+       struct zorro_dev *z;
+
+       if (!dev)
+               return -ENODEV;
+
+       z = to_zorro_dev(dev);
+       if (!z)
+               return -ENODEV;
+
+       if (add_uevent_var(env, "ZORRO_ID=%08X", z->id) ||
+           add_uevent_var(env, "ZORRO_SLOT_NAME=%s", dev_name(dev)) ||
+           add_uevent_var(env, "ZORRO_SLOT_ADDR=%04X", z->slotaddr) ||
+           add_uevent_var(env, "MODALIAS=" ZORRO_DEVICE_MODALIAS_FMT, z->id))
+               return -ENOMEM;
+
+       return 0;
+#else /* !CONFIG_HOTPLUG */
+       return -ENODEV;
+#endif /* !CONFIG_HOTPLUG */
+}
 
 struct bus_type zorro_bus_type = {
        .name   = "zorro",
        .match  = zorro_bus_match,
+       .uevent = zorro_uevent,
        .probe  = zorro_device_probe,
        .remove = zorro_device_remove,
 };
index 1d2a772..eb924e0 100644 (file)
@@ -77,6 +77,16 @@ static struct bin_attribute zorro_config_attr = {
        .read = zorro_read_config,
 };
 
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       struct zorro_dev *z = to_zorro_dev(dev);
+
+       return sprintf(buf, ZORRO_DEVICE_MODALIAS_FMT "\n", z->id);
+}
+
+static DEVICE_ATTR(modalias, S_IRUGO, modalias_show, NULL);
+
 int zorro_create_sysfs_dev_files(struct zorro_dev *z)
 {
        struct device *dev = &z->dev;
@@ -89,6 +99,7 @@ int zorro_create_sysfs_dev_files(struct zorro_dev *z)
            (error = device_create_file(dev, &dev_attr_slotaddr)) ||
            (error = device_create_file(dev, &dev_attr_slotsize)) ||
            (error = device_create_file(dev, &dev_attr_resource)) ||
+           (error = device_create_file(dev, &dev_attr_modalias)) ||
            (error = sysfs_create_bin_file(&dev->kobj, &zorro_config_attr)))
                return error;
 
index d45fb34..6455f3a 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/zorro.h>
 #include <linux/bitops.h>
 #include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include <asm/setup.h>
 #include <asm/amigahw.h>
      *  Zorro Expansion Devices
      */
 
-u_int zorro_num_autocon = 0;
+unsigned int zorro_num_autocon;
 struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
 
 
     /*
-     *  Single Zorro bus
+     *  Zorro bus
      */
 
-struct zorro_bus zorro_bus = {\
-    .resources = {
-       /* Zorro II regions (on Zorro II/III) */
-       { .name = "Zorro II exp", .start = 0x00e80000, .end = 0x00efffff },
-       { .name = "Zorro II mem", .start = 0x00200000, .end = 0x009fffff },
-       /* Zorro III regions (on Zorro III only) */
-       { .name = "Zorro III exp", .start = 0xff000000, .end = 0xffffffff },
-       { .name = "Zorro III cfg", .start = 0x40000000, .end = 0x7fffffff }
-    },
-    .name = "Zorro bus"
+struct zorro_bus {
+       struct list_head devices;       /* list of devices on this bus */
+       struct device dev;
 };
 
 
@@ -53,18 +48,19 @@ struct zorro_bus zorro_bus = {\
 
 struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
 {
-    struct zorro_dev *z;
+       struct zorro_dev *z;
 
-    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
-       return NULL;
+       if (!zorro_num_autocon)
+               return NULL;
 
-    for (z = from ? from+1 : &zorro_autocon[0];
-        z < zorro_autocon+zorro_num_autocon;
-        z++)
-       if (id == ZORRO_WILDCARD || id == z->id)
-           return z;
-    return NULL;
+       for (z = from ? from+1 : &zorro_autocon[0];
+            z < zorro_autocon+zorro_num_autocon;
+            z++)
+               if (id == ZORRO_WILDCARD || id == z->id)
+                       return z;
+       return NULL;
 }
+EXPORT_SYMBOL(zorro_find_device);
 
 
     /*
@@ -83,121 +79,138 @@ struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from)
      */
 
 DECLARE_BITMAP(zorro_unused_z2ram, 128);
+EXPORT_SYMBOL(zorro_unused_z2ram);
 
 
 static void __init mark_region(unsigned long start, unsigned long end,
                               int flag)
 {
-    if (flag)
-       start += Z2RAM_CHUNKMASK;
-    else
-       end += Z2RAM_CHUNKMASK;
-    start &= ~Z2RAM_CHUNKMASK;
-    end &= ~Z2RAM_CHUNKMASK;
-
-    if (end <= Z2RAM_START || start >= Z2RAM_END)
-       return;
-    start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
-    end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
-    while (start < end) {
-       u32 chunk = start>>Z2RAM_CHUNKSHIFT;
        if (flag)
-           set_bit(chunk, zorro_unused_z2ram);
+               start += Z2RAM_CHUNKMASK;
        else
-           clear_bit(chunk, zorro_unused_z2ram);
-       start += Z2RAM_CHUNKSIZE;
-    }
+               end += Z2RAM_CHUNKMASK;
+       start &= ~Z2RAM_CHUNKMASK;
+       end &= ~Z2RAM_CHUNKMASK;
+
+       if (end <= Z2RAM_START || start >= Z2RAM_END)
+               return;
+       start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START;
+       end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START;
+       while (start < end) {
+               u32 chunk = start>>Z2RAM_CHUNKSHIFT;
+               if (flag)
+                       set_bit(chunk, zorro_unused_z2ram);
+               else
+                       clear_bit(chunk, zorro_unused_z2ram);
+               start += Z2RAM_CHUNKSIZE;
+       }
 }
 
 
-static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z)
+static struct resource __init *zorro_find_parent_resource(
+       struct platform_device *bridge, struct zorro_dev *z)
 {
-    int i;
+       int i;
 
-    for (i = 0; i < zorro_bus.num_resources; i++)
-       if (zorro_resource_start(z) >= zorro_bus.resources[i].start &&
-           zorro_resource_end(z) <= zorro_bus.resources[i].end)
-               return &zorro_bus.resources[i];
-    return &iomem_resource;
+       for (i = 0; i < bridge->num_resources; i++) {
+               struct resource *r = &bridge->resource[i];
+               if (zorro_resource_start(z) >= r->start &&
+                   zorro_resource_end(z) <= r->end)
+                       return r;
+       }
+       return &iomem_resource;
 }
 
 
-    /*
-     *  Initialization
-     */
 
-static int __init zorro_init(void)
+static int __init amiga_zorro_probe(struct platform_device *pdev)
 {
-    struct zorro_dev *z;
-    unsigned int i;
-    int error;
-
-    if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
-       return 0;
-
-    pr_info("Zorro: Probing AutoConfig expansion devices: %d device%s\n",
-          zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
-
-    /* Initialize the Zorro bus */
-    INIT_LIST_HEAD(&zorro_bus.devices);
-    dev_set_name(&zorro_bus.dev, "zorro");
-    error = device_register(&zorro_bus.dev);
-    if (error) {
-       pr_err("Zorro: Error registering zorro_bus\n");
-       return error;
-    }
-
-    /* Request the resources */
-    zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
-    for (i = 0; i < zorro_bus.num_resources; i++)
-       request_resource(&iomem_resource, &zorro_bus.resources[i]);
-
-    /* Register all devices */
-    for (i = 0; i < zorro_num_autocon; i++) {
-       z = &zorro_autocon[i];
-       z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
-       if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
-           /* GVP quirk */
-           unsigned long magic = zorro_resource_start(z)+0x8000;
-           z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
-       }
-       sprintf(z->name, "Zorro device %08x", z->id);
-       zorro_name_device(z);
-       z->resource.name = z->name;
-       if (request_resource(zorro_find_parent_resource(z), &z->resource))
-           pr_err("Zorro: Address space collision on device %s %pR\n",
-                  z->name, &z->resource);
-       dev_set_name(&z->dev, "%02x", i);
-       z->dev.parent = &zorro_bus.dev;
-       z->dev.bus = &zorro_bus_type;
-       error = device_register(&z->dev);
+       struct zorro_bus *bus;
+       struct zorro_dev *z;
+       struct resource *r;
+       unsigned int i;
+       int error;
+
+       /* Initialize the Zorro bus */
+       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+       if (!bus)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&bus->devices);
+       bus->dev.parent = &pdev->dev;
+       dev_set_name(&bus->dev, "zorro");
+       error = device_register(&bus->dev);
        if (error) {
-           pr_err("Zorro: Error registering device %s\n", z->name);
-           continue;
+               pr_err("Zorro: Error registering zorro_bus\n");
+               kfree(bus);
+               return error;
        }
-       error = zorro_create_sysfs_dev_files(z);
-       if (error)
-           dev_err(&z->dev, "Error creating sysfs files\n");
-    }
-
-    /* Mark all available Zorro II memory */
-    zorro_for_each_dev(z) {
-       if (z->rom.er_Type & ERTF_MEMLIST)
-           mark_region(zorro_resource_start(z), zorro_resource_end(z)+1, 1);
-    }
-
-    /* Unmark all used Zorro II memory */
-    for (i = 0; i < m68k_num_memory; i++)
-       if (m68k_memory[i].addr < 16*1024*1024)
-           mark_region(m68k_memory[i].addr,
-                       m68k_memory[i].addr+m68k_memory[i].size, 0);
-
-    return 0;
+       platform_set_drvdata(pdev, bus);
+
+       /* Register all devices */
+       pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n",
+                zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
+
+       for (i = 0; i < zorro_num_autocon; i++) {
+               z = &zorro_autocon[i];
+               z->id = (z->rom.er_Manufacturer<<16) | (z->rom.er_Product<<8);
+               if (z->id == ZORRO_PROD_GVP_EPC_BASE) {
+                       /* GVP quirk */
+                       unsigned long magic = zorro_resource_start(z)+0x8000;
+                       z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK;
+               }
+               sprintf(z->name, "Zorro device %08x", z->id);
+               zorro_name_device(z);
+               z->resource.name = z->name;
+               r = zorro_find_parent_resource(pdev, z);
+               error = request_resource(r, &z->resource);
+               if (error)
+                       dev_err(&bus->dev,
+                               "Address space collision on device %s %pR\n",
+                               z->name, &z->resource);
+               dev_set_name(&z->dev, "%02x", i);
+               z->dev.parent = &bus->dev;
+               z->dev.bus = &zorro_bus_type;
+               error = device_register(&z->dev);
+               if (error) {
+                       dev_err(&bus->dev, "Error registering device %s\n",
+                               z->name);
+                       continue;
+               }
+               error = zorro_create_sysfs_dev_files(z);
+               if (error)
+                       dev_err(&z->dev, "Error creating sysfs files\n");
+       }
+
+       /* Mark all available Zorro II memory */
+       zorro_for_each_dev(z) {
+               if (z->rom.er_Type & ERTF_MEMLIST)
+                       mark_region(zorro_resource_start(z),
+                                   zorro_resource_end(z)+1, 1);
+       }
+
+       /* Unmark all used Zorro II memory */
+       for (i = 0; i < m68k_num_memory; i++)
+               if (m68k_memory[i].addr < 16*1024*1024)
+                       mark_region(m68k_memory[i].addr,
+                                   m68k_memory[i].addr+m68k_memory[i].size,
+                                   0);
+
+       return 0;
 }
 
-subsys_initcall(zorro_init);
+static struct platform_driver amiga_zorro_driver = {
+       .driver   = {
+               .name   = "amiga-zorro",
+               .owner  = THIS_MODULE,
+       },
+};
 
-EXPORT_SYMBOL(zorro_find_device);
-EXPORT_SYMBOL(zorro_unused_z2ram);
+static int __init amiga_zorro_init(void)
+{
+       return platform_driver_probe(&amiga_zorro_driver, amiga_zorro_probe);
+}
+
+module_init(amiga_zorro_init);
 
 MODULE_LICENSE("GPL");
index 5c5bc84..f8b86e9 100644 (file)
@@ -238,6 +238,13 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
                return ERR_PTR(-ENOMEM);
        }
 
+       rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
+       if (rc) {
+               __putname(v9ses->aname);
+               __putname(v9ses->uname);
+               return ERR_PTR(rc);
+       }
+
        spin_lock(&v9fs_sessionlist_lock);
        list_add(&v9ses->slist, &v9fs_sessionlist);
        spin_unlock(&v9fs_sessionlist_lock);
@@ -301,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
        return fid;
 
 error:
+       bdi_destroy(&v9ses->bdi);
        return ERR_PTR(retval);
 }
 
@@ -326,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
        __putname(v9ses->uname);
        __putname(v9ses->aname);
 
+       bdi_destroy(&v9ses->bdi);
+
        spin_lock(&v9fs_sessionlist_lock);
        list_del(&v9ses->slist);
        spin_unlock(&v9fs_sessionlist_lock);
index a0a8d3d..bec4d0b 100644 (file)
@@ -20,6 +20,7 @@
  *  Boston, MA  02111-1301  USA
  *
  */
+#include <linux/backing-dev.h>
 
 /**
  * enum p9_session_flags - option flags for each 9P session
@@ -102,6 +103,7 @@ struct v9fs_session_info {
        u32 uid;                /* if ACCESS_SINGLE, the uid that has access */
        struct p9_client *clnt; /* 9p client */
        struct list_head slist; /* list of sessions registered with v9fs */
+       struct backing_dev_info bdi;
 };
 
 struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
index 491108b..806da5d 100644 (file)
@@ -77,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
        sb->s_blocksize = 1 << sb->s_blocksize_bits;
        sb->s_magic = V9FS_MAGIC;
        sb->s_op = &v9fs_super_ops;
+       sb->s_bdi = &v9ses->bdi;
 
        sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
            MS_NOATIME;
index c54dad4..a10f258 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/workqueue.h>
 #include <linux/sched.h>
 #include <linux/fscache.h>
+#include <linux/backing-dev.h>
 
 #include "afs.h"
 #include "afs_vl.h"
@@ -313,6 +314,7 @@ struct afs_volume {
        unsigned short          rjservers;      /* number of servers discarded due to -ENOMEDIUM */
        struct afs_server       *servers[8];    /* servers on which volume resides (ordered) */
        struct rw_semaphore     server_sem;     /* lock for accessing current server */
+       struct backing_dev_info bdi;
 };
 
 /*
index 5e813a8..b3feddc 100644 (file)
@@ -138,9 +138,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
 {
        struct afs_super_info *super;
        struct vfsmount *mnt;
-       struct page *page = NULL;
+       struct page *page;
        size_t size;
-       char *buf, *devname = NULL, *options = NULL;
+       char *buf, *devname, *options;
        int ret;
 
        _enter("{%s}", mntpt->d_name.name);
@@ -150,22 +150,22 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
        ret = -EINVAL;
        size = mntpt->d_inode->i_size;
        if (size > PAGE_SIZE - 1)
-               goto error;
+               goto error_no_devname;
 
        ret = -ENOMEM;
        devname = (char *) get_zeroed_page(GFP_KERNEL);
        if (!devname)
-               goto error;
+               goto error_no_devname;
 
        options = (char *) get_zeroed_page(GFP_KERNEL);
        if (!options)
-               goto error;
+               goto error_no_options;
 
        /* read the contents of the AFS special symlink */
        page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL);
        if (IS_ERR(page)) {
                ret = PTR_ERR(page);
-               goto error;
+               goto error_no_page;
        }
 
        ret = -EIO;
@@ -196,12 +196,12 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
        return mnt;
 
 error:
-       if (page)
-               page_cache_release(page);
-       if (devname)
-               free_page((unsigned long) devname);
-       if (options)
-               free_page((unsigned long) options);
+       page_cache_release(page);
+error_no_page:
+       free_page((unsigned long) options);
+error_no_options:
+       free_page((unsigned long) devname);
+error_no_devname:
        _leave(" = %d", ret);
        return ERR_PTR(ret);
 }
index 14f6431..e932e5a 100644 (file)
@@ -311,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data)
        sb->s_magic             = AFS_FS_MAGIC;
        sb->s_op                = &afs_super_ops;
        sb->s_fs_info           = as;
+       sb->s_bdi               = &as->volume->bdi;
 
        /* allocate the root inode and dentry */
        fid.vid         = as->volume->vid;
index a353e69..401eeb2 100644 (file)
@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
        volume->cell            = params->cell;
        volume->vid             = vlocation->vldb.vid[params->type];
 
+       ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY);
+       if (ret)
+               goto error_bdi;
+
        init_rwsem(&volume->server_sem);
 
        /* look up all the applicable server records */
@@ -151,6 +155,8 @@ error:
        return ERR_PTR(ret);
 
 error_discard:
+       bdi_destroy(&volume->bdi);
+error_bdi:
        up_write(&params->cell->vl_sem);
 
        for (loop = volume->nservers - 1; loop >= 0; loop--)
@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume)
        for (loop = volume->nservers - 1; loop >= 0; loop--)
                afs_put_server(volume->servers[loop]);
 
+       bdi_destroy(&volume->bdi);
        kfree(volume);
 
        _leave(" [destroyed]");
index 109a6c6..e8e5e63 100644 (file)
@@ -177,8 +177,7 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
                }
        /* Trigger mount for path component or follow link */
        } else if (ino->flags & AUTOFS_INF_PENDING ||
-                       autofs4_need_mount(flags) ||
-                       current->link_count) {
+                       autofs4_need_mount(flags)) {
                DPRINTK("waiting for mount name=%.*s",
                        dentry->d_name.len, dentry->d_name.name);
 
@@ -262,7 +261,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
                spin_unlock(&dcache_lock);
                spin_unlock(&sbi->fs_lock);
 
-               status = try_to_fill_dentry(dentry, 0);
+               status = try_to_fill_dentry(dentry, nd->flags);
                if (status)
                        goto out_error;
 
index 7ab23e0..2c5f9a0 100644 (file)
@@ -1005,15 +1005,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
                                }
                        } else if (!mm->start_data) {
                                mm->start_data = seg->addr;
-#ifndef CONFIG_MMU
                                mm->end_data = seg->addr + phdr->p_memsz;
-#endif
                        }
-
-#ifdef CONFIG_MMU
-                       if (seg->addr + phdr->p_memsz > mm->end_data)
-                               mm->end_data = seg->addr + phdr->p_memsz;
-#endif
                }
 
                seg++;
index e0e769b..49566c1 100644 (file)
@@ -355,7 +355,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
 
        if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
                printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)",
-                      (int) r,(int)(start_brk-start_code),(int)text_len);
+                      (int) r,(int)(start_brk-start_data+text_len),(int)text_len);
                goto failed;
        }
 
index 2a6d019..6dcee88 100644 (file)
@@ -406,16 +406,23 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
  
 int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
 {
-       struct block_device *bdev = I_BDEV(filp->f_mapping->host);
+       struct inode *bd_inode = filp->f_mapping->host;
+       struct block_device *bdev = I_BDEV(bd_inode);
        int error;
 
-       error = sync_blockdev(bdev);
-       if (error)
-               return error;
-       
+       /*
+        * There is no need to serialise calls to blkdev_issue_flush with
+        * i_mutex and doing so causes performance issues with concurrent
+        * O_SYNC writers to a block device.
+        */
+       mutex_unlock(&bd_inode->i_mutex);
+
        error = blkdev_issue_flush(bdev, NULL);
        if (error == -EOPNOTSUPP)
                error = 0;
+
+       mutex_lock(&bd_inode->i_mutex);
+
        return error;
 }
 EXPORT_SYMBOL(blkdev_fsync);
index e7b8f2c..feca041 100644 (file)
@@ -44,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
 
-static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
-
 /*
  * end_io_wq structs are used to do processing in task context when an IO is
  * complete.  This is used during reads to verify checksums, and it is used
@@ -1375,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
 {
        int err;
 
-       bdi->name = "btrfs";
        bdi->capabilities = BDI_CAP_MAP_COPY;
-       err = bdi_init(bdi);
+       err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
        if (err)
                return err;
 
-       err = bdi_register(bdi, NULL, "btrfs-%d",
-                               atomic_inc_return(&btrfs_bdi_num));
-       if (err) {
-               bdi_destroy(bdi);
-               return err;
-       }
-
        bdi->ra_pages   = default_backing_dev_info.ra_pages;
        bdi->unplug_io_fn       = btrfs_unplug_io_fn;
        bdi->unplug_io_data     = info;
index 9e23ffe..b34d32f 100644 (file)
@@ -3235,7 +3235,8 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
                                u64 bytes)
 {
        struct btrfs_space_info *data_sinfo;
-       int ret = 0, committed = 0;
+       u64 used;
+       int ret = 0, committed = 0, flushed = 0;
 
        /* make sure bytes are sectorsize aligned */
        bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
@@ -3247,12 +3248,21 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
 again:
        /* make sure we have enough space to handle the data first */
        spin_lock(&data_sinfo->lock);
-       if (data_sinfo->total_bytes - data_sinfo->bytes_used -
-           data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
-           data_sinfo->bytes_pinned - data_sinfo->bytes_readonly -
-           data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) {
+       used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc +
+               data_sinfo->bytes_reserved + data_sinfo->bytes_pinned +
+               data_sinfo->bytes_readonly + data_sinfo->bytes_may_use +
+               data_sinfo->bytes_super;
+
+       if (used + bytes > data_sinfo->total_bytes) {
                struct btrfs_trans_handle *trans;
 
+               if (!flushed) {
+                       spin_unlock(&data_sinfo->lock);
+                       flush_delalloc(root, data_sinfo);
+                       flushed = 1;
+                       goto again;
+               }
+
                /*
                 * if we don't have enough free bytes in this space then we need
                 * to alloc a new chunk.
index e84ef60..97a9783 100644 (file)
@@ -1481,12 +1481,17 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
                ret = -EBADF;
                goto out_drop_write;
        }
+
        src = src_file->f_dentry->d_inode;
 
        ret = -EINVAL;
        if (src == inode)
                goto out_fput;
 
+       /* the src must be open for reading */
+       if (!(src_file->f_mode & FMODE_READ))
+               goto out_fput;
+
        ret = -EISDIR;
        if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
                goto out_fput;
index aa7dc36..8db7b14 100644 (file)
@@ -2250,6 +2250,12 @@ again:
        if (!looped)
                calc_size = max_t(u64, min_stripe_size, calc_size);
 
+       /*
+        * we're about to do_div by the stripe_len so lets make sure
+        * we end up with something bigger than a stripe
+        */
+       calc_size = max_t(u64, calc_size, stripe_len * 4);
+
        do_div(calc_size, stripe_len);
        calc_size *= stripe_len;
 
index f7c255f..a8cd821 100644 (file)
@@ -34,6 +34,7 @@ struct cachefiles_object {
        loff_t                          i_size;         /* object size */
        unsigned long                   flags;
 #define CACHEFILES_OBJECT_ACTIVE       0               /* T if marked active */
+#define CACHEFILES_OBJECT_BURIED       1               /* T if preemptively buried */
        atomic_t                        usage;          /* object usage count */
        uint8_t                         type;           /* object type */
        uint8_t                         new;            /* T if object new */
index d5db84a..f4a7840 100644 (file)
@@ -92,6 +92,59 @@ static noinline void cachefiles_printk_object(struct cachefiles_object *object,
        kfree(keybuf);
 }
 
+/*
+ * mark the owner of a dentry, if there is one, to indicate that that dentry
+ * has been preemptively deleted
+ * - the caller must hold the i_mutex on the dentry's parent as required to
+ *   call vfs_unlink(), vfs_rmdir() or vfs_rename()
+ */
+static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
+                                         struct dentry *dentry)
+{
+       struct cachefiles_object *object;
+       struct rb_node *p;
+
+       _enter(",'%*.*s'",
+              dentry->d_name.len, dentry->d_name.len, dentry->d_name.name);
+
+       write_lock(&cache->active_lock);
+
+       p = cache->active_nodes.rb_node;
+       while (p) {
+               object = rb_entry(p, struct cachefiles_object, active_node);
+               if (object->dentry > dentry)
+                       p = p->rb_left;
+               else if (object->dentry < dentry)
+                       p = p->rb_right;
+               else
+                       goto found_dentry;
+       }
+
+       write_unlock(&cache->active_lock);
+       _leave(" [no owner]");
+       return;
+
+       /* found the dentry for  */
+found_dentry:
+       kdebug("preemptive burial: OBJ%x [%s] %p",
+              object->fscache.debug_id,
+              fscache_object_states[object->fscache.state],
+              dentry);
+
+       if (object->fscache.state < FSCACHE_OBJECT_DYING) {
+               printk(KERN_ERR "\n");
+               printk(KERN_ERR "CacheFiles: Error:"
+                      " Can't preemptively bury live object\n");
+               cachefiles_printk_object(object, NULL);
+       } else if (test_and_set_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
+               printk(KERN_ERR "CacheFiles: Error:"
+                      " Object already preemptively buried\n");
+       }
+
+       write_unlock(&cache->active_lock);
+       _leave(" [owner marked]");
+}
+
 /*
  * record the fact that an object is now active
  */
@@ -219,7 +272,8 @@ requeue:
  */
 static int cachefiles_bury_object(struct cachefiles_cache *cache,
                                  struct dentry *dir,
-                                 struct dentry *rep)
+                                 struct dentry *rep,
+                                 bool preemptive)
 {
        struct dentry *grave, *trap;
        char nbuffer[8 + 8 + 1];
@@ -229,11 +283,16 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
               dir->d_name.len, dir->d_name.len, dir->d_name.name,
               rep->d_name.len, rep->d_name.len, rep->d_name.name);
 
+       _debug("remove %p from %p", rep, dir);
+
        /* non-directories can just be unlinked */
        if (!S_ISDIR(rep->d_inode->i_mode)) {
                _debug("unlink stale object");
                ret = vfs_unlink(dir->d_inode, rep);
 
+               if (preemptive)
+                       cachefiles_mark_object_buried(cache, rep);
+
                mutex_unlock(&dir->d_inode->i_mutex);
 
                if (ret == -EIO)
@@ -325,6 +384,9 @@ try_again:
        if (ret != 0 && ret != -ENOMEM)
                cachefiles_io_error(cache, "Rename failed with error %d", ret);
 
+       if (preemptive)
+               cachefiles_mark_object_buried(cache, rep);
+
        unlock_rename(cache->graveyard, dir);
        dput(grave);
        _leave(" = 0");
@@ -340,7 +402,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
        struct dentry *dir;
        int ret;
 
-       _enter(",{%p}", object->dentry);
+       _enter(",OBJ%x{%p}", object->fscache.debug_id, object->dentry);
 
        ASSERT(object->dentry);
        ASSERT(object->dentry->d_inode);
@@ -350,15 +412,25 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
 
        mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 
-       /* we need to check that our parent is _still_ our parent - it may have
-        * been renamed */
-       if (dir == object->dentry->d_parent) {
-               ret = cachefiles_bury_object(cache, dir, object->dentry);
-       } else {
-               /* it got moved, presumably by cachefilesd culling it, so it's
-                * no longer in the key path and we can ignore it */
+       if (test_bit(CACHEFILES_OBJECT_BURIED, &object->flags)) {
+               /* object allocation for the same key preemptively deleted this
+                * object's file so that it could create its own file */
+               _debug("object preemptively buried");
                mutex_unlock(&dir->d_inode->i_mutex);
                ret = 0;
+       } else {
+               /* we need to check that our parent is _still_ our parent - it
+                * may have been renamed */
+               if (dir == object->dentry->d_parent) {
+                       ret = cachefiles_bury_object(cache, dir,
+                                                    object->dentry, false);
+               } else {
+                       /* it got moved, presumably by cachefilesd culling it,
+                        * so it's no longer in the key path and we can ignore
+                        * it */
+                       mutex_unlock(&dir->d_inode->i_mutex);
+                       ret = 0;
+               }
        }
 
        dput(dir);
@@ -381,7 +453,9 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
        const char *name;
        int ret, nlen;
 
-       _enter("{%p},,%s,", parent->dentry, key);
+       _enter("OBJ%x{%p},OBJ%x,%s,",
+              parent->fscache.debug_id, parent->dentry,
+              object->fscache.debug_id, key);
 
        cache = container_of(parent->fscache.cache,
                             struct cachefiles_cache, cache);
@@ -509,7 +583,7 @@ lookup_again:
                         * mutex) */
                        object->dentry = NULL;
 
-                       ret = cachefiles_bury_object(cache, dir, next);
+                       ret = cachefiles_bury_object(cache, dir, next, true);
                        dput(next);
                        next = NULL;
 
@@ -828,7 +902,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
        /*  actually remove the victim (drops the dir mutex) */
        _debug("bury");
 
-       ret = cachefiles_bury_object(cache, dir, victim);
+       ret = cachefiles_bury_object(cache, dir, victim, false);
        if (ret < 0)
                goto error;
 
index b5808cd..039b501 100644 (file)
@@ -77,6 +77,8 @@ static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
 /*
  * check the security details of the on-disk cache
  * - must be called with security override in force
+ * - must return with a security override in force - even in the case of an
+ *   error
  */
 int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
                                        struct dentry *root,
@@ -99,6 +101,8 @@ int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
         * which create files */
        ret = set_create_files_as(new, root->d_inode);
        if (ret < 0) {
+               abort_creds(new);
+               cachefiles_begin_secure(cache, _saved_cred);
                _leave(" = %d [cfa]", ret);
                return ret;
        }
index aa3cd7c..a9005d8 100644 (file)
@@ -337,16 +337,15 @@ out:
 /*
  * Get ref for the oldest snapc for an inode with dirty data... that is, the
  * only snap context we are allowed to write back.
- *
- * Caller holds i_lock.
  */
-static struct ceph_snap_context *__get_oldest_context(struct inode *inode,
-                                                     u64 *snap_size)
+static struct ceph_snap_context *get_oldest_context(struct inode *inode,
+                                                   u64 *snap_size)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_snap_context *snapc = NULL;
        struct ceph_cap_snap *capsnap = NULL;
 
+       spin_lock(&inode->i_lock);
        list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
                dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap,
                     capsnap->context, capsnap->dirty_pages);
@@ -357,21 +356,11 @@ static struct ceph_snap_context *__get_oldest_context(struct inode *inode,
                        break;
                }
        }
-       if (!snapc && ci->i_snap_realm) {
-               snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);
+       if (!snapc && ci->i_head_snapc) {
+               snapc = ceph_get_snap_context(ci->i_head_snapc);
                dout(" head snapc %p has %d dirty pages\n",
                     snapc, ci->i_wrbuffer_ref_head);
        }
-       return snapc;
-}
-
-static struct ceph_snap_context *get_oldest_context(struct inode *inode,
-                                                   u64 *snap_size)
-{
-       struct ceph_snap_context *snapc = NULL;
-
-       spin_lock(&inode->i_lock);
-       snapc = __get_oldest_context(inode, snap_size);
        spin_unlock(&inode->i_lock);
        return snapc;
 }
@@ -392,7 +381,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
        int len = PAGE_CACHE_SIZE;
        loff_t i_size;
        int err = 0;
-       struct ceph_snap_context *snapc;
+       struct ceph_snap_context *snapc, *oldest;
        u64 snap_size = 0;
        long writeback_stat;
 
@@ -413,13 +402,16 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
                dout("writepage %p page %p not dirty?\n", inode, page);
                goto out;
        }
-       if (snapc != get_oldest_context(inode, &snap_size)) {
+       oldest = get_oldest_context(inode, &snap_size);
+       if (snapc->seq > oldest->seq) {
                dout("writepage %p page %p snapc %p not writeable - noop\n",
                     inode, page, (void *)page->private);
                /* we should only noop if called by kswapd */
                WARN_ON((current->flags & PF_MEMALLOC) == 0);
+               ceph_put_snap_context(oldest);
                goto out;
        }
+       ceph_put_snap_context(oldest);
 
        /* is this a partial page at end of file? */
        if (snap_size)
@@ -458,7 +450,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
        ClearPagePrivate(page);
        end_page_writeback(page);
        ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
-       ceph_put_snap_context(snapc);
+       ceph_put_snap_context(snapc);  /* page's reference */
 out:
        return err;
 }
@@ -512,12 +504,11 @@ static void writepages_finish(struct ceph_osd_request *req,
        int i;
        struct ceph_snap_context *snapc = req->r_snapc;
        struct address_space *mapping = inode->i_mapping;
-       struct writeback_control *wbc = req->r_wbc;
        __s32 rc = -EIO;
        u64 bytes = 0;
        struct ceph_client *client = ceph_inode_to_client(inode);
        long writeback_stat;
-       unsigned issued = __ceph_caps_issued(ci, NULL);
+       unsigned issued = ceph_caps_issued(ci);
 
        /* parse reply */
        replyhead = msg->front.iov_base;
@@ -554,13 +545,9 @@ static void writepages_finish(struct ceph_osd_request *req,
                        clear_bdi_congested(&client->backing_dev_info,
                                            BLK_RW_ASYNC);
 
-               if (i >= wrote) {
-                       dout("inode %p skipping page %p\n", inode, page);
-                       wbc->pages_skipped++;
-               }
+               ceph_put_snap_context((void *)page->private);
                page->private = 0;
                ClearPagePrivate(page);
-               ceph_put_snap_context(snapc);
                dout("unlocking %d %p\n", i, page);
                end_page_writeback(page);
 
@@ -618,7 +605,7 @@ static int ceph_writepages_start(struct address_space *mapping,
        int range_whole = 0;
        int should_loop = 1;
        pgoff_t max_pages = 0, max_pages_ever = 0;
-       struct ceph_snap_context *snapc = NULL, *last_snapc = NULL;
+       struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc;
        struct pagevec pvec;
        int done = 0;
        int rc = 0;
@@ -770,9 +757,10 @@ get_more_pages:
                        }
 
                        /* only if matching snap context */
-                       if (snapc != (void *)page->private) {
-                               dout("page snapc %p != oldest %p\n",
-                                    (void *)page->private, snapc);
+                       pgsnapc = (void *)page->private;
+                       if (pgsnapc->seq > snapc->seq) {
+                               dout("page snapc %p %lld > oldest %p %lld\n",
+                                    pgsnapc, pgsnapc->seq, snapc, snapc->seq);
                                unlock_page(page);
                                if (!locked_pages)
                                        continue; /* keep looking for snap */
@@ -806,7 +794,6 @@ get_more_pages:
                                alloc_page_vec(client, req);
                                req->r_callback = writepages_finish;
                                req->r_inode = inode;
-                               req->r_wbc = wbc;
                        }
 
                        /* note position of first page in pvec */
@@ -914,7 +901,10 @@ static int context_is_writeable_or_written(struct inode *inode,
                                           struct ceph_snap_context *snapc)
 {
        struct ceph_snap_context *oldest = get_oldest_context(inode, NULL);
-       return !oldest || snapc->seq <= oldest->seq;
+       int ret = !oldest || snapc->seq <= oldest->seq;
+
+       ceph_put_snap_context(oldest);
+       return ret;
 }
 
 /*
@@ -936,8 +926,8 @@ static int ceph_update_writeable_page(struct file *file,
        int pos_in_page = pos & ~PAGE_CACHE_MASK;
        int end_in_page = pos_in_page + len;
        loff_t i_size;
-       struct ceph_snap_context *snapc;
        int r;
+       struct ceph_snap_context *snapc, *oldest;
 
 retry_locked:
        /* writepages currently holds page lock, but if we change that later, */
@@ -947,23 +937,24 @@ retry_locked:
        BUG_ON(!ci->i_snap_realm);
        down_read(&mdsc->snap_rwsem);
        BUG_ON(!ci->i_snap_realm->cached_context);
-       if (page->private &&
-           (void *)page->private != ci->i_snap_realm->cached_context) {
+       snapc = (void *)page->private;
+       if (snapc && snapc != ci->i_head_snapc) {
                /*
                 * this page is already dirty in another (older) snap
                 * context!  is it writeable now?
                 */
-               snapc = get_oldest_context(inode, NULL);
+               oldest = get_oldest_context(inode, NULL);
                up_read(&mdsc->snap_rwsem);
 
-               if (snapc != (void *)page->private) {
+               if (snapc->seq > oldest->seq) {
+                       ceph_put_snap_context(oldest);
                        dout(" page %p snapc %p not current or oldest\n",
-                            page, (void *)page->private);
+                            page, snapc);
                        /*
                         * queue for writeback, and wait for snapc to
                         * be writeable or written
                         */
-                       snapc = ceph_get_snap_context((void *)page->private);
+                       snapc = ceph_get_snap_context(snapc);
                        unlock_page(page);
                        ceph_queue_writeback(inode);
                        r = wait_event_interruptible(ci->i_cap_wq,
@@ -973,6 +964,7 @@ retry_locked:
                                return r;
                        return -EAGAIN;
                }
+               ceph_put_snap_context(oldest);
 
                /* yay, writeable, do it now (without dropping page lock) */
                dout(" page %p snapc %p not current, but oldest\n",
index f6394b9..818afe7 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/slab.h>
 
 #include "types.h"
 #include "auth_none.h"
index 56c0553..8164df1 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _FS_CEPH_AUTH_NONE_H
 #define _FS_CEPH_AUTH_NONE_H
 
+#include <linux/slab.h>
+
 #include "auth.h"
 
 /*
index d9001a4..fee5a08 100644 (file)
@@ -12,8 +12,6 @@
 #include "auth.h"
 #include "decode.h"
 
-struct kmem_cache *ceph_x_ticketbuf_cachep;
-
 #define TEMP_TICKET_BUF_LEN    256
 
 static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed);
@@ -131,13 +129,12 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
        char *ticket_buf;
        u8 struct_v;
 
-       dbuf = kmem_cache_alloc(ceph_x_ticketbuf_cachep, GFP_NOFS | GFP_ATOMIC);
+       dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
        if (!dbuf)
                return -ENOMEM;
 
        ret = -ENOMEM;
-       ticket_buf = kmem_cache_alloc(ceph_x_ticketbuf_cachep,
-                                     GFP_NOFS | GFP_ATOMIC);
+       ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
        if (!ticket_buf)
                goto out_dbuf;
 
@@ -251,9 +248,9 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
 
        ret = 0;
 out:
-       kmem_cache_free(ceph_x_ticketbuf_cachep, ticket_buf);
+       kfree(ticket_buf);
 out_dbuf:
-       kmem_cache_free(ceph_x_ticketbuf_cachep, dbuf);
+       kfree(dbuf);
        return ret;
 
 bad:
@@ -605,8 +602,6 @@ static void ceph_x_destroy(struct ceph_auth_client *ac)
                remove_ticket_handler(ac, th);
        }
 
-       kmem_cache_destroy(ceph_x_ticketbuf_cachep);
-
        kfree(ac->private);
        ac->private = NULL;
 }
@@ -641,26 +636,20 @@ int ceph_x_init(struct ceph_auth_client *ac)
        int ret;
 
        dout("ceph_x_init %p\n", ac);
+       ret = -ENOMEM;
        xi = kzalloc(sizeof(*xi), GFP_NOFS);
        if (!xi)
-               return -ENOMEM;
+               goto out;
 
-       ret = -ENOMEM;
-       ceph_x_ticketbuf_cachep = kmem_cache_create("ceph_x_ticketbuf",
-                                     TEMP_TICKET_BUF_LEN, 8,
-                                     (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
-                                     NULL);
-       if (!ceph_x_ticketbuf_cachep)
-               goto done_nomem;
        ret = -EINVAL;
        if (!ac->secret) {
                pr_err("no secret set (for auth_x protocol)\n");
-               goto done_nomem;
+               goto out_nomem;
        }
 
        ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
        if (ret)
-               goto done_nomem;
+               goto out_nomem;
 
        xi->starting = true;
        xi->ticket_handlers = RB_ROOT;
@@ -670,10 +659,9 @@ int ceph_x_init(struct ceph_auth_client *ac)
        ac->ops = &ceph_x_ops;
        return 0;
 
-done_nomem:
+out_nomem:
        kfree(xi);
-       if (ceph_x_ticketbuf_cachep)
-               kmem_cache_destroy(ceph_x_ticketbuf_cachep);
+out:
        return ret;
 }
 
index 3710e07..d940053 100644 (file)
@@ -858,6 +858,8 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci)
 }
 
 /*
+ * Remove a cap.  Take steps to deal with a racing iterate_session_caps.
+ *
  * caller should hold i_lock.
  * caller will not hold session s_mutex if called from destroy_inode.
  */
@@ -866,15 +868,10 @@ void __ceph_remove_cap(struct ceph_cap *cap)
        struct ceph_mds_session *session = cap->session;
        struct ceph_inode_info *ci = cap->ci;
        struct ceph_mds_client *mdsc = &ceph_client(ci->vfs_inode.i_sb)->mdsc;
+       int removed = 0;
 
        dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode);
 
-       /* remove from inode list */
-       rb_erase(&cap->ci_node, &ci->i_caps);
-       cap->ci = NULL;
-       if (ci->i_auth_cap == cap)
-               ci->i_auth_cap = NULL;
-
        /* remove from session list */
        spin_lock(&session->s_cap_lock);
        if (session->s_cap_iterator == cap) {
@@ -885,10 +882,18 @@ void __ceph_remove_cap(struct ceph_cap *cap)
                list_del_init(&cap->session_caps);
                session->s_nr_caps--;
                cap->session = NULL;
+               removed = 1;
        }
+       /* protect backpointer with s_cap_lock: see iterate_session_caps */
+       cap->ci = NULL;
        spin_unlock(&session->s_cap_lock);
 
-       if (cap->session == NULL)
+       /* remove from inode list */
+       rb_erase(&cap->ci_node, &ci->i_caps);
+       if (ci->i_auth_cap == cap)
+               ci->i_auth_cap = NULL;
+
+       if (removed)
                ceph_put_cap(cap);
 
        if (!__ceph_is_any_caps(ci) && ci->i_snap_realm) {
@@ -1205,6 +1210,12 @@ retry:
                if (capsnap->dirty_pages || capsnap->writing)
                        continue;
 
+               /*
+                * if cap writeback already occurred, we should have dropped
+                * the capsnap in ceph_put_wrbuffer_cap_refs.
+                */
+               BUG_ON(capsnap->dirty == 0);
+
                /* pick mds, take s_mutex */
                mds = __ceph_get_cap_mds(ci, &mseq);
                if (session && session->s_mds != mds) {
@@ -1855,8 +1866,8 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
                } else {
                        pr_err("%p auth cap %p not mds%d ???\n", inode,
                               cap, session->s_mds);
-                       spin_unlock(&inode->i_lock);
                }
+               spin_unlock(&inode->i_lock);
        }
 }
 
@@ -2118,8 +2129,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
                }
        spin_unlock(&inode->i_lock);
 
-       dout("put_cap_refs %p had %s %s\n", inode, ceph_cap_string(had),
-            last ? "last" : "");
+       dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had),
+            last ? " last" : "", put ? " put" : "");
 
        if (last && !flushsnaps)
                ceph_check_caps(ci, 0, NULL);
@@ -2143,7 +2154,8 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
 {
        struct inode *inode = &ci->vfs_inode;
        int last = 0;
-       int last_snap = 0;
+       int complete_capsnap = 0;
+       int drop_capsnap = 0;
        int found = 0;
        struct ceph_cap_snap *capsnap = NULL;
 
@@ -2166,19 +2178,32 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
                list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
                        if (capsnap->context == snapc) {
                                found = 1;
-                               capsnap->dirty_pages -= nr;
-                               last_snap = !capsnap->dirty_pages;
                                break;
                        }
                }
                BUG_ON(!found);
+               capsnap->dirty_pages -= nr;
+               if (capsnap->dirty_pages == 0) {
+                       complete_capsnap = 1;
+                       if (capsnap->dirty == 0)
+                               /* cap writeback completed before we created
+                                * the cap_snap; no FLUSHSNAP is needed */
+                               drop_capsnap = 1;
+               }
                dout("put_wrbuffer_cap_refs on %p cap_snap %p "
-                    " snap %lld %d/%d -> %d/%d %s%s\n",
+                    " snap %lld %d/%d -> %d/%d %s%s%s\n",
                     inode, capsnap, capsnap->context->seq,
                     ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr,
                     ci->i_wrbuffer_ref, capsnap->dirty_pages,
                     last ? " (wrbuffer last)" : "",
-                    last_snap ? " (capsnap last)" : "");
+                    complete_capsnap ? " (complete capsnap)" : "",
+                    drop_capsnap ? " (drop capsnap)" : "");
+               if (drop_capsnap) {
+                       ceph_put_snap_context(capsnap->context);
+                       list_del(&capsnap->ci_item);
+                       list_del(&capsnap->flushing_item);
+                       ceph_put_cap_snap(capsnap);
+               }
        }
 
        spin_unlock(&inode->i_lock);
@@ -2186,10 +2211,12 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
        if (last) {
                ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
                iput(inode);
-       } else if (last_snap) {
+       } else if (complete_capsnap) {
                ceph_flush_snaps(ci);
                wake_up(&ci->i_cap_wq);
        }
+       if (drop_capsnap)
+               iput(inode);
 }
 
 /*
@@ -2465,8 +2492,8 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
                                break;
                        }
                        WARN_ON(capsnap->dirty_pages || capsnap->writing);
-                       dout(" removing cap_snap %p follows %lld\n",
-                            capsnap, follows);
+                       dout(" removing %p cap_snap %p follows %lld\n",
+                            inode, capsnap, follows);
                        ceph_put_snap_context(capsnap->context);
                        list_del(&capsnap->ci_item);
                        list_del(&capsnap->flushing_item);
index 7261dc6..650d2db 100644 (file)
@@ -171,11 +171,11 @@ more:
        spin_lock(&inode->i_lock);
        spin_lock(&dcache_lock);
 
+       last = dentry;
+
        if (err < 0)
                goto out_unlock;
 
-       last = dentry;
-
        p = p->prev;
        filp->f_pos++;
 
@@ -312,7 +312,7 @@ more:
                req->r_readdir_offset = fi->next_offset;
                req->r_args.readdir.frag = cpu_to_le32(frag);
                req->r_args.readdir.max_entries = cpu_to_le32(max_entries);
-               req->r_num_caps = max_entries;
+               req->r_num_caps = max_entries + 1;
                err = ceph_mdsc_do_request(mdsc, NULL, req);
                if (err < 0) {
                        ceph_mdsc_put_request(req);
@@ -489,6 +489,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
                struct inode *inode = ceph_get_snapdir(parent);
                dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
                     dentry, dentry->d_name.len, dentry->d_name.name, inode);
+               BUG_ON(!d_unhashed(dentry));
                d_add(dentry, inode);
                err = 0;
        }
@@ -879,7 +880,16 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
                 * do_request, above).  If there is no trace, we need
                 * to do it here.
                 */
+
+               /* d_move screws up d_subdirs order */
+               ceph_i_clear(new_dir, CEPH_I_COMPLETE);
+
                d_move(old_dentry, new_dentry);
+
+               /* ensure target dentry is invalidated, despite
+                  rehashing bug in vfs_rename_dir */
+               new_dentry->d_time = jiffies;
+               ceph_dentry(new_dentry)->lease_shared_gen = 0;
        }
        ceph_mdsc_put_request(req);
        return err;
index 4add3d5..ed6f197 100644 (file)
@@ -665,7 +665,8 @@ more:
                 * throw out any page cache pages in this range. this
                 * may block.
                 */
-               truncate_inode_pages_range(inode->i_mapping, pos, pos+len);
+               truncate_inode_pages_range(inode->i_mapping, pos, 
+                                          (pos+len) | (PAGE_CACHE_SIZE-1));
        } else {
                pages = alloc_page_vector(num_pages);
                if (IS_ERR(pages)) {
index aca82d5..85b4d2f 100644 (file)
@@ -733,6 +733,10 @@ no_change:
                                __ceph_get_fmode(ci, cap_fmode);
                        spin_unlock(&inode->i_lock);
                }
+       } else if (cap_fmode >= 0) {
+               pr_warning("mds issued no caps on %llx.%llx\n",
+                          ceph_vinop(inode));
+               __ceph_get_fmode(ci, cap_fmode);
        }
 
        /* update delegation info? */
@@ -886,6 +890,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        struct inode *in = NULL;
        struct ceph_mds_reply_inode *ininfo;
        struct ceph_vino vino;
+       struct ceph_client *client = ceph_sb_to_client(sb);
        int i = 0;
        int err = 0;
 
@@ -949,7 +954,14 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                        return err;
        }
 
-       if (rinfo->head->is_dentry && !req->r_aborted) {
+       /*
+        * ignore null lease/binding on snapdir ENOENT, or else we
+        * will have trouble splicing in the virtual snapdir later
+        */
+       if (rinfo->head->is_dentry && !req->r_aborted &&
+           (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
+                                              client->mount_args->snapdir_name,
+                                              req->r_dentry->d_name.len))) {
                /*
                 * lookup link rename   : null -> possibly existing inode
                 * mknod symlink mkdir  : null -> new inode
@@ -989,6 +1001,10 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                             dn, dn->d_name.len, dn->d_name.name);
                        dout("fill_trace doing d_move %p -> %p\n",
                             req->r_old_dentry, dn);
+
+                       /* d_move screws up d_subdirs order */
+                       ceph_i_clear(dir, CEPH_I_COMPLETE);
+
                        d_move(req->r_old_dentry, dn);
                        dout(" src %p '%.*s' dst %p '%.*s'\n",
                             req->r_old_dentry,
index 60a9a4a..24561a5 100644 (file)
@@ -736,9 +736,10 @@ static void cleanup_cap_releases(struct ceph_mds_session *session)
 }
 
 /*
- * Helper to safely iterate over all caps associated with a session.
+ * Helper to safely iterate over all caps associated with a session, with
+ * special care taken to handle a racing __ceph_remove_cap().
  *
- * caller must hold session s_mutex
+ * Caller must hold session s_mutex.
  */
 static int iterate_session_caps(struct ceph_mds_session *session,
                                 int (*cb)(struct inode *, struct ceph_cap *,
@@ -2136,7 +2137,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
        struct ceph_mds_session *session = NULL;
        struct ceph_msg *reply;
        struct rb_node *p;
-       int err;
+       int err = -ENOMEM;
        struct ceph_pagelist *pagelist;
 
        pr_info("reconnect to recovering mds%d\n", mds);
@@ -2185,7 +2186,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
                goto fail;
        err = iterate_session_caps(session, encode_caps_cb, pagelist);
        if (err < 0)
-               goto out;
+               goto fail;
 
        /*
         * snaprealms.  we provide mds with the ino, seq (version), and
@@ -2213,28 +2214,31 @@ send:
        reply->nr_pages = calc_pages_for(0, pagelist->length);
        ceph_con_send(&session->s_con, reply);
 
-       if (session) {
-               session->s_state = CEPH_MDS_SESSION_OPEN;
-               __wake_requests(mdsc, &session->s_waiting);
-       }
+       session->s_state = CEPH_MDS_SESSION_OPEN;
+       mutex_unlock(&session->s_mutex);
+
+       mutex_lock(&mdsc->mutex);
+       __wake_requests(mdsc, &session->s_waiting);
+       mutex_unlock(&mdsc->mutex);
+
+       ceph_put_mds_session(session);
 
-out:
        up_read(&mdsc->snap_rwsem);
-       if (session) {
-               mutex_unlock(&session->s_mutex);
-               ceph_put_mds_session(session);
-       }
        mutex_lock(&mdsc->mutex);
        return;
 
 fail:
        ceph_msg_put(reply);
+       up_read(&mdsc->snap_rwsem);
+       mutex_unlock(&session->s_mutex);
+       ceph_put_mds_session(session);
 fail_nomsg:
        ceph_pagelist_release(pagelist);
        kfree(pagelist);
 fail_nopagelist:
-       pr_err("ENOMEM preparing reconnect for mds%d\n", mds);
-       goto out;
+       pr_err("error %d preparing reconnect for mds%d\n", err, mds);
+       mutex_lock(&mdsc->mutex);
+       return;
 }
 
 
index 8f1715f..cd4fadb 100644 (file)
@@ -30,6 +30,10 @@ static char tag_msg = CEPH_MSGR_TAG_MSG;
 static char tag_ack = CEPH_MSGR_TAG_ACK;
 static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
 
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key socket_class;
+#endif
+
 
 static void queue_con(struct ceph_connection *con);
 static void con_work(struct work_struct *);
@@ -228,6 +232,10 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)
        con->sock = sock;
        sock->sk->sk_allocation = GFP_NOFS;
 
+#ifdef CONFIG_LOCKDEP
+       lockdep_set_class(&sock->sk->sk_lock, &socket_class);
+#endif
+
        set_sock_callbacks(sock, con);
 
        dout("connect %s\n", pr_addr(&con->peer_addr.in_addr));
@@ -333,6 +341,7 @@ static void reset_connection(struct ceph_connection *con)
                con->out_msg = NULL;
        }
        con->in_seq = 0;
+       con->in_seq_acked = 0;
 }
 
 /*
@@ -483,7 +492,14 @@ static void prepare_write_message(struct ceph_connection *con)
                list_move_tail(&m->list_head, &con->out_sent);
        }
 
-       m->hdr.seq = cpu_to_le64(++con->out_seq);
+       /*
+        * only assign outgoing seq # if we haven't sent this message
+        * yet.  if it is requeued, resend with it's original seq.
+        */
+       if (m->needs_out_seq) {
+               m->hdr.seq = cpu_to_le64(++con->out_seq);
+               m->needs_out_seq = false;
+       }
 
        dout("prepare_write_message %p seq %lld type %d len %d+%d+%d %d pgs\n",
             m, con->out_seq, le16_to_cpu(m->hdr.type),
@@ -1325,6 +1341,7 @@ static int read_partial_message(struct ceph_connection *con)
        unsigned front_len, middle_len, data_len, data_off;
        int datacrc = con->msgr->nocrc;
        int skip;
+       u64 seq;
 
        dout("read_partial_message con %p msg %p\n", con, m);
 
@@ -1359,6 +1376,25 @@ static int read_partial_message(struct ceph_connection *con)
                return -EIO;
        data_off = le16_to_cpu(con->in_hdr.data_off);
 
+       /* verify seq# */
+       seq = le64_to_cpu(con->in_hdr.seq);
+       if ((s64)seq - (s64)con->in_seq < 1) {
+               pr_info("skipping %s%lld %s seq %lld, expected %lld\n",
+                       ENTITY_NAME(con->peer_name),
+                       pr_addr(&con->peer_addr.in_addr),
+                       seq, con->in_seq + 1);
+               con->in_base_pos = -front_len - middle_len - data_len -
+                       sizeof(m->footer);
+               con->in_tag = CEPH_MSGR_TAG_READY;
+               con->in_seq++;
+               return 0;
+       } else if ((s64)seq - (s64)con->in_seq > 1) {
+               pr_err("read_partial_message bad seq %lld expected %lld\n",
+                      seq, con->in_seq + 1);
+               con->error_msg = "bad message sequence # for incoming message";
+               return -EBADMSG;
+       }
+
        /* allocate message? */
        if (!con->in_msg) {
                dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
@@ -1370,6 +1406,7 @@ static int read_partial_message(struct ceph_connection *con)
                        con->in_base_pos = -front_len - middle_len - data_len -
                                sizeof(m->footer);
                        con->in_tag = CEPH_MSGR_TAG_READY;
+                       con->in_seq++;
                        return 0;
                }
                if (IS_ERR(con->in_msg)) {
@@ -1956,6 +1993,8 @@ void ceph_con_send(struct ceph_connection *con, struct ceph_msg *msg)
 
        BUG_ON(msg->front.iov_len != le32_to_cpu(msg->hdr.front_len));
 
+       msg->needs_out_seq = true;
+
        /* queue */
        mutex_lock(&con->mutex);
        BUG_ON(!list_empty(&msg->list_head));
@@ -2021,6 +2060,7 @@ void ceph_con_revoke_message(struct ceph_connection *con, struct ceph_msg *msg)
                ceph_msg_put(con->in_msg);
                con->in_msg = NULL;
                con->in_tag = CEPH_MSGR_TAG_READY;
+               con->in_seq++;
        } else {
                dout("con_revoke_pages %p msg %p pages %p no-op\n",
                     con, con->in_msg, msg);
@@ -2054,15 +2094,19 @@ struct ceph_msg *ceph_msg_new(int type, int front_len,
        kref_init(&m->kref);
        INIT_LIST_HEAD(&m->list_head);
 
+       m->hdr.tid = 0;
        m->hdr.type = cpu_to_le16(type);
+       m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT);
+       m->hdr.version = 0;
        m->hdr.front_len = cpu_to_le32(front_len);
        m->hdr.middle_len = 0;
        m->hdr.data_len = cpu_to_le32(page_len);
        m->hdr.data_off = cpu_to_le16(page_off);
-       m->hdr.priority = cpu_to_le16(CEPH_MSG_PRIO_DEFAULT);
+       m->hdr.reserved = 0;
        m->footer.front_crc = 0;
        m->footer.middle_crc = 0;
        m->footer.data_crc = 0;
+       m->footer.flags = 0;
        m->front_max = front_len;
        m->front_is_vmalloc = false;
        m->more_to_follow = false;
index a343dae..a5caf91 100644 (file)
@@ -86,6 +86,7 @@ struct ceph_msg {
        struct kref kref;
        bool front_is_vmalloc;
        bool more_to_follow;
+       bool needs_out_seq;
        int front_max;
 
        struct ceph_msgpool *pool;
index c7b4ded..3514f71 100644 (file)
@@ -565,7 +565,8 @@ static int __map_osds(struct ceph_osd_client *osdc,
 {
        struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
        struct ceph_pg pgid;
-       int o = -1;
+       int acting[CEPH_PG_MAX_SIZE];
+       int o = -1, num = 0;
        int err;
 
        dout("map_osds %p tid %lld\n", req, req->r_tid);
@@ -576,10 +577,16 @@ static int __map_osds(struct ceph_osd_client *osdc,
        pgid = reqhead->layout.ol_pgid;
        req->r_pgid = pgid;
 
-       o = ceph_calc_pg_primary(osdc->osdmap, pgid);
+       err = ceph_calc_pg_acting(osdc->osdmap, pgid, acting);
+       if (err > 0) {
+               o = acting[0];
+               num = err;
+       }
 
        if ((req->r_osd && req->r_osd->o_osd == o &&
-            req->r_sent >= req->r_osd->o_incarnation) ||
+            req->r_sent >= req->r_osd->o_incarnation &&
+            req->r_num_pg_osds == num &&
+            memcmp(req->r_pg_osds, acting, sizeof(acting[0])*num) == 0) ||
            (req->r_osd == NULL && o == -1))
                return 0;  /* no change */
 
@@ -587,6 +594,10 @@ static int __map_osds(struct ceph_osd_client *osdc,
             req->r_tid, le32_to_cpu(pgid.pool), le16_to_cpu(pgid.ps), o,
             req->r_osd ? req->r_osd->o_osd : -1);
 
+       /* record full pg acting set */
+       memcpy(req->r_pg_osds, acting, sizeof(acting[0]) * num);
+       req->r_num_pg_osds = num;
+
        if (req->r_osd) {
                __cancel_request(req);
                list_del_init(&req->r_osd_item);
@@ -612,7 +623,7 @@ static int __map_osds(struct ceph_osd_client *osdc,
                __remove_osd_from_lru(req->r_osd);
                list_add(&req->r_osd_item, &req->r_osd->o_requests);
        }
-       err = 1;   /* osd changed */
+       err = 1;   /* osd or pg changed */
 
 out:
        return err;
@@ -779,16 +790,18 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
        struct ceph_osd_request *req;
        u64 tid;
        int numops, object_len, flags;
+       s32 result;
 
        tid = le64_to_cpu(msg->hdr.tid);
        if (msg->front.iov_len < sizeof(*rhead))
                goto bad;
        numops = le32_to_cpu(rhead->num_ops);
        object_len = le32_to_cpu(rhead->object_len);
+       result = le32_to_cpu(rhead->result);
        if (msg->front.iov_len != sizeof(*rhead) + object_len +
            numops * sizeof(struct ceph_osd_op))
                goto bad;
-       dout("handle_reply %p tid %llu\n", msg, tid);
+       dout("handle_reply %p tid %llu result %d\n", msg, tid, (int)result);
 
        /* lookup */
        mutex_lock(&osdc->request_mutex);
@@ -834,7 +847,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
        dout("handle_reply tid %llu flags %d\n", tid, flags);
 
        /* either this is a read, or we got the safe response */
-       if ((flags & CEPH_OSD_FLAG_ONDISK) ||
+       if (result < 0 ||
+           (flags & CEPH_OSD_FLAG_ONDISK) ||
            ((flags & CEPH_OSD_FLAG_WRITE) == 0))
                __unregister_request(osdc, req);
 
index b075991..ce77698 100644 (file)
@@ -48,6 +48,8 @@ struct ceph_osd_request {
        struct list_head r_osd_item;
        struct ceph_osd *r_osd;
        struct ceph_pg   r_pgid;
+       int              r_pg_osds[CEPH_PG_MAX_SIZE];
+       int              r_num_pg_osds;
 
        struct ceph_connection *r_con_filling_msg;
 
@@ -66,7 +68,6 @@ struct ceph_osd_request {
        struct list_head  r_unsafe_item;
 
        struct inode *r_inode;                /* for use by callbacks */
-       struct writeback_control *r_wbc;      /* ditto */
 
        char              r_oid[40];          /* object name */
        int               r_oid_len;
index 21c6623..cfdd8f4 100644 (file)
@@ -314,71 +314,6 @@ bad:
        return ERR_PTR(err);
 }
 
-
-/*
- * osd map
- */
-void ceph_osdmap_destroy(struct ceph_osdmap *map)
-{
-       dout("osdmap_destroy %p\n", map);
-       if (map->crush)
-               crush_destroy(map->crush);
-       while (!RB_EMPTY_ROOT(&map->pg_temp)) {
-               struct ceph_pg_mapping *pg =
-                       rb_entry(rb_first(&map->pg_temp),
-                                struct ceph_pg_mapping, node);
-               rb_erase(&pg->node, &map->pg_temp);
-               kfree(pg);
-       }
-       while (!RB_EMPTY_ROOT(&map->pg_pools)) {
-               struct ceph_pg_pool_info *pi =
-                       rb_entry(rb_first(&map->pg_pools),
-                                struct ceph_pg_pool_info, node);
-               rb_erase(&pi->node, &map->pg_pools);
-               kfree(pi);
-       }
-       kfree(map->osd_state);
-       kfree(map->osd_weight);
-       kfree(map->osd_addr);
-       kfree(map);
-}
-
-/*
- * adjust max osd value.  reallocate arrays.
- */
-static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
-{
-       u8 *state;
-       struct ceph_entity_addr *addr;
-       u32 *weight;
-
-       state = kcalloc(max, sizeof(*state), GFP_NOFS);
-       addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
-       weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
-       if (state == NULL || addr == NULL || weight == NULL) {
-               kfree(state);
-               kfree(addr);
-               kfree(weight);
-               return -ENOMEM;
-       }
-
-       /* copy old? */
-       if (map->osd_state) {
-               memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
-               memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
-               memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
-               kfree(map->osd_state);
-               kfree(map->osd_addr);
-               kfree(map->osd_weight);
-       }
-
-       map->osd_state = state;
-       map->osd_weight = weight;
-       map->osd_addr = addr;
-       map->max_osd = max;
-       return 0;
-}
-
 /*
  * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
  * to a set of osds)
@@ -482,6 +417,13 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
        return NULL;
 }
 
+static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
+{
+       rb_erase(&pi->node, root);
+       kfree(pi->name);
+       kfree(pi);
+}
+
 void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
 {
        ceph_decode_copy(p, &pi->v, sizeof(pi->v));
@@ -490,6 +432,98 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
        *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
 }
 
+static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
+{
+       struct ceph_pg_pool_info *pi;
+       u32 num, len, pool;
+
+       ceph_decode_32_safe(p, end, num, bad);
+       dout(" %d pool names\n", num);
+       while (num--) {
+               ceph_decode_32_safe(p, end, pool, bad);
+               ceph_decode_32_safe(p, end, len, bad);
+               dout("  pool %d len %d\n", pool, len);
+               pi = __lookup_pg_pool(&map->pg_pools, pool);
+               if (pi) {
+                       kfree(pi->name);
+                       pi->name = kmalloc(len + 1, GFP_NOFS);
+                       if (pi->name) {
+                               memcpy(pi->name, *p, len);
+                               pi->name[len] = '\0';
+                               dout("  name is %s\n", pi->name);
+                       }
+               }
+               *p += len;
+       }
+       return 0;
+
+bad:
+       return -EINVAL;
+}
+
+/*
+ * osd map
+ */
+void ceph_osdmap_destroy(struct ceph_osdmap *map)
+{
+       dout("osdmap_destroy %p\n", map);
+       if (map->crush)
+               crush_destroy(map->crush);
+       while (!RB_EMPTY_ROOT(&map->pg_temp)) {
+               struct ceph_pg_mapping *pg =
+                       rb_entry(rb_first(&map->pg_temp),
+                                struct ceph_pg_mapping, node);
+               rb_erase(&pg->node, &map->pg_temp);
+               kfree(pg);
+       }
+       while (!RB_EMPTY_ROOT(&map->pg_pools)) {
+               struct ceph_pg_pool_info *pi =
+                       rb_entry(rb_first(&map->pg_pools),
+                                struct ceph_pg_pool_info, node);
+               __remove_pg_pool(&map->pg_pools, pi);
+       }
+       kfree(map->osd_state);
+       kfree(map->osd_weight);
+       kfree(map->osd_addr);
+       kfree(map);
+}
+
+/*
+ * adjust max osd value.  reallocate arrays.
+ */
+static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
+{
+       u8 *state;
+       struct ceph_entity_addr *addr;
+       u32 *weight;
+
+       state = kcalloc(max, sizeof(*state), GFP_NOFS);
+       addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
+       weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
+       if (state == NULL || addr == NULL || weight == NULL) {
+               kfree(state);
+               kfree(addr);
+               kfree(weight);
+               return -ENOMEM;
+       }
+
+       /* copy old? */
+       if (map->osd_state) {
+               memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
+               memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
+               memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
+               kfree(map->osd_state);
+               kfree(map->osd_addr);
+               kfree(map->osd_weight);
+       }
+
+       map->osd_state = state;
+       map->osd_weight = weight;
+       map->osd_addr = addr;
+       map->max_osd = max;
+       return 0;
+}
+
 /*
  * decode a full map.
  */
@@ -526,7 +560,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
        ceph_decode_32_safe(p, end, max, bad);
        while (max--) {
                ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
-               pi = kmalloc(sizeof(*pi), GFP_NOFS);
+               pi = kzalloc(sizeof(*pi), GFP_NOFS);
                if (!pi)
                        goto bad;
                pi->id = ceph_decode_32(p);
@@ -539,6 +573,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
                __decode_pool(p, pi);
                __insert_pg_pool(&map->pg_pools, pi);
        }
+
+       if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+               goto bad;
+
        ceph_decode_32_safe(p, end, map->pool_max, bad);
 
        ceph_decode_32_safe(p, end, map->flags, bad);
@@ -712,7 +750,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                }
                pi = __lookup_pg_pool(&map->pg_pools, pool);
                if (!pi) {
-                       pi = kmalloc(sizeof(*pi), GFP_NOFS);
+                       pi = kzalloc(sizeof(*pi), GFP_NOFS);
                        if (!pi) {
                                err = -ENOMEM;
                                goto bad;
@@ -722,6 +760,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                }
                __decode_pool(p, pi);
        }
+       if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+               goto bad;
 
        /* old_pool */
        ceph_decode_32_safe(p, end, len, bad);
@@ -730,10 +770,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
 
                ceph_decode_32_safe(p, end, pool, bad);
                pi = __lookup_pg_pool(&map->pg_pools, pool);
-               if (pi) {
-                       rb_erase(&pi->node, &map->pg_pools);
-                       kfree(pi);
-               }
+               if (pi)
+                       __remove_pg_pool(&map->pg_pools, pi);
        }
 
        /* new_up */
@@ -1002,13 +1040,34 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
        return osds;
 }
 
+/*
+ * Return acting set for given pgid.
+ */
+int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+                       int *acting)
+{
+       int rawosds[CEPH_PG_MAX_SIZE], *osds;
+       int i, o, num = CEPH_PG_MAX_SIZE;
+
+       osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
+       if (!osds)
+               return -1;
+
+       /* primary is first up osd */
+       o = 0;
+       for (i = 0; i < num; i++)
+               if (ceph_osd_is_up(osdmap, osds[i]))
+                       acting[o++] = osds[i];
+       return o;
+}
+
 /*
  * Return primary osd for given pgid, or -1 if none.
  */
 int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
 {
-       int rawosds[10], *osds;
-       int i, num = ARRAY_SIZE(rawosds);
+       int rawosds[CEPH_PG_MAX_SIZE], *osds;
+       int i, num = CEPH_PG_MAX_SIZE;
 
        osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
        if (!osds)
@@ -1016,9 +1075,7 @@ int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
 
        /* primary is first up osd */
        for (i = 0; i < num; i++)
-               if (ceph_osd_is_up(osdmap, osds[i])) {
+               if (ceph_osd_is_up(osdmap, osds[i]))
                        return osds[i];
-                       break;
-               }
        return -1;
 }
index 1fb55af..970b547 100644 (file)
@@ -23,6 +23,7 @@ struct ceph_pg_pool_info {
        int id;
        struct ceph_pg_pool v;
        int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask;
+       char *name;
 };
 
 struct ceph_pg_mapping {
@@ -119,6 +120,8 @@ extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
                                   const char *oid,
                                   struct ceph_file_layout *fl,
                                   struct ceph_osdmap *osdmap);
+extern int ceph_calc_pg_acting(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
+                              int *acting);
 extern int ceph_calc_pg_primary(struct ceph_osdmap *osdmap,
                                struct ceph_pg pgid);
 
index 26ac8b8..fd56451 100644 (file)
 /*
  * osdmap encoding versions
  */
-#define CEPH_OSDMAP_INC_VERSION 4
-#define CEPH_OSDMAP_VERSION     4
+#define CEPH_OSDMAP_INC_VERSION     5
+#define CEPH_OSDMAP_INC_VERSION_EXT 5
+#define CEPH_OSDMAP_VERSION         5
+#define CEPH_OSDMAP_VERSION_EXT     5
 
 /*
  * fs id
@@ -56,6 +58,7 @@ struct ceph_timespec {
 #define CEPH_PG_LAYOUT_LINEAR 2
 #define CEPH_PG_LAYOUT_HYBRID 3
 
+#define CEPH_PG_MAX_SIZE      16  /* max # osds in a single pg */
 
 /*
  * placement group.
index e6f9bc5..d5114db 100644 (file)
@@ -431,8 +431,7 @@ static int dup_array(u64 **dst, __le64 *src, int num)
  * Caller must hold snap_rwsem for read (i.e., the realm topology won't
  * change).
  */
-void ceph_queue_cap_snap(struct ceph_inode_info *ci,
-                        struct ceph_snap_context *snapc)
+void ceph_queue_cap_snap(struct ceph_inode_info *ci)
 {
        struct inode *inode = &ci->vfs_inode;
        struct ceph_cap_snap *capsnap;
@@ -451,10 +450,11 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                   as no new writes are allowed to start when pending, so any
                   writes in progress now were started before the previous
                   cap_snap.  lucky us. */
-               dout("queue_cap_snap %p snapc %p seq %llu used %d"
-                    " already pending\n", inode, snapc, snapc->seq, used);
+               dout("queue_cap_snap %p already pending\n", inode);
                kfree(capsnap);
        } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) {
+               struct ceph_snap_context *snapc = ci->i_head_snapc;
+
                igrab(inode);
 
                atomic_set(&capsnap->nref, 1);
@@ -463,7 +463,6 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                INIT_LIST_HEAD(&capsnap->flushing_item);
 
                capsnap->follows = snapc->seq - 1;
-               capsnap->context = ceph_get_snap_context(snapc);
                capsnap->issued = __ceph_caps_issued(ci, NULL);
                capsnap->dirty = __ceph_caps_dirty(ci);
 
@@ -480,7 +479,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                   snapshot. */
                capsnap->dirty_pages = ci->i_wrbuffer_ref_head;
                ci->i_wrbuffer_ref_head = 0;
-               ceph_put_snap_context(ci->i_head_snapc);
+               capsnap->context = snapc;
                ci->i_head_snapc = NULL;
                list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
 
@@ -522,15 +521,17 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
        capsnap->ctime = inode->i_ctime;
        capsnap->time_warp_seq = ci->i_time_warp_seq;
        if (capsnap->dirty_pages) {
-               dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu "
+               dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu "
                     "still has %d dirty pages\n", inode, capsnap,
                     capsnap->context, capsnap->context->seq,
-                    capsnap->size, capsnap->dirty_pages);
+                    ceph_cap_string(capsnap->dirty), capsnap->size,
+                    capsnap->dirty_pages);
                return 0;
        }
-       dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu clean\n",
+       dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
             inode, capsnap, capsnap->context,
-            capsnap->context->seq, capsnap->size);
+            capsnap->context->seq, ceph_cap_string(capsnap->dirty),
+            capsnap->size);
 
        spin_lock(&mdsc->snap_flush_lock);
        list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
@@ -602,7 +603,7 @@ more:
                                if (lastinode)
                                        iput(lastinode);
                                lastinode = inode;
-                               ceph_queue_cap_snap(ci, realm->cached_context);
+                               ceph_queue_cap_snap(ci);
                                spin_lock(&realm->inodes_with_caps_lock);
                        }
                        spin_unlock(&realm->inodes_with_caps_lock);
@@ -824,8 +825,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
                        spin_unlock(&realm->inodes_with_caps_lock);
                        spin_unlock(&inode->i_lock);
 
-                       ceph_queue_cap_snap(ci,
-                                           ci->i_snap_realm->cached_context);
+                       ceph_queue_cap_snap(ci);
 
                        iput(inode);
                        continue;
@@ -869,16 +869,20 @@ skip_inode:
                                continue;
                        ci = ceph_inode(inode);
                        spin_lock(&inode->i_lock);
-                       if (!ci->i_snap_realm)
-                               goto split_skip_inode;
-                       ceph_put_snap_realm(mdsc, ci->i_snap_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);
-split_skip_inode:
+                       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);
                }
index 75d02ea..110857b 100644 (file)
@@ -47,10 +47,20 @@ const char *ceph_file_part(const char *s, int len)
  */
 static void ceph_put_super(struct super_block *s)
 {
-       struct ceph_client *cl = ceph_client(s);
+       struct ceph_client *client = ceph_sb_to_client(s);
 
        dout("put_super\n");
-       ceph_mdsc_close_sessions(&cl->mdsc);
+       ceph_mdsc_close_sessions(&client->mdsc);
+
+       /*
+        * ensure we release the bdi before put_anon_super releases
+        * the device name.
+        */
+       if (s->s_bdi == &client->backing_dev_info) {
+               bdi_unregister(&client->backing_dev_info);
+               s->s_bdi = NULL;
+       }
+
        return;
 }
 
@@ -636,6 +646,8 @@ static void ceph_destroy_client(struct ceph_client *client)
        destroy_workqueue(client->pg_inv_wq);
        destroy_workqueue(client->trunc_wq);
 
+       bdi_destroy(&client->backing_dev_info);
+
        if (client->msgr)
                ceph_messenger_destroy(client->msgr);
        mempool_destroy(client->wb_pagevec_pool);
@@ -876,14 +888,14 @@ static int ceph_register_bdi(struct super_block *sb, struct ceph_client *client)
 {
        int err;
 
-       sb->s_bdi = &client->backing_dev_info;
-
        /* set ra_pages based on rsize mount option? */
        if (client->mount_args->rsize >= PAGE_CACHE_SIZE)
                client->backing_dev_info.ra_pages =
                        (client->mount_args->rsize + PAGE_CACHE_SIZE - 1)
                        >> PAGE_SHIFT;
        err = bdi_register_dev(&client->backing_dev_info, sb->s_dev);
+       if (!err)
+               sb->s_bdi = &client->backing_dev_info;
        return err;
 }
 
@@ -957,9 +969,6 @@ static void ceph_kill_sb(struct super_block *s)
        dout("kill_sb %p\n", s);
        ceph_mdsc_pre_umount(&client->mdsc);
        kill_anon_super(s);    /* will call put_super after sb is r/o */
-       if (s->s_bdi == &client->backing_dev_info)
-               bdi_unregister(&client->backing_dev_info);
-       bdi_destroy(&client->backing_dev_info);
        ceph_destroy_client(client);
 }
 
@@ -996,9 +1005,10 @@ static int __init init_ceph(void)
        if (ret)
                goto out_icache;
 
-       pr_info("loaded %d.%d.%d (mon/mds/osd proto %d/%d/%d)\n",
-               CEPH_VERSION_MAJOR, CEPH_VERSION_MINOR, CEPH_VERSION_PATCH,
-               CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL);
+       pr_info("loaded (mon/mds/osd proto %d/%d/%d, osdmap %d/%d %d/%d)\n",
+               CEPH_MONC_PROTOCOL, CEPH_MDSC_PROTOCOL, CEPH_OSDC_PROTOCOL,
+               CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
+               CEPH_OSDMAP_INC_VERSION, CEPH_OSDMAP_INC_VERSION_EXT);
        return 0;
 
 out_icache:
index ca702c6..13513b8 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/fs.h>
 #include <linux/mempool.h>
 #include <linux/pagemap.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/writeback.h>
 #include <linux/slab.h>
@@ -715,8 +716,7 @@ extern int ceph_update_snap_trace(struct ceph_mds_client *m,
 extern void ceph_handle_snap(struct ceph_mds_client *mdsc,
                             struct ceph_mds_session *session,
                             struct ceph_msg *msg);
-extern void ceph_queue_cap_snap(struct ceph_inode_info *ci,
-                               struct ceph_snap_context *snapc);
+extern void ceph_queue_cap_snap(struct ceph_inode_info *ci);
 extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
                                  struct ceph_cap_snap *capsnap);
 extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc);
index a20bea5..cfd1ce3 100644 (file)
@@ -492,17 +492,13 @@ compare_oid(unsigned long *oid1, unsigned int oid1len,
 
 int
 decode_negTokenInit(unsigned char *security_blob, int length,
-                   enum securityEnum *secType)
+                   struct TCP_Server_Info *server)
 {
        struct asn1_ctx ctx;
        unsigned char *end;
        unsigned char *sequence_end;
        unsigned long *oid = NULL;
        unsigned int cls, con, tag, oidlen, rc;
-       bool use_ntlmssp = false;
-       bool use_kerberos = false;
-       bool use_kerberosu2u = false;
-       bool use_mskerberos = false;
 
        /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
 
@@ -510,11 +506,11 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 
        /* GSSAPI header */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding negTokenInit header"));
+               cFYI(1, "Error decoding negTokenInit header");
                return 0;
        } else if ((cls != ASN1_APL) || (con != ASN1_CON)
                   || (tag != ASN1_EOC)) {
-               cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag));
+               cFYI(1, "cls = %d con = %d tag = %d", cls, con, tag);
                return 0;
        }
 
@@ -535,56 +531,52 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 
        /* SPNEGO OID not present or garbled -- bail out */
        if (!rc) {
-               cFYI(1, ("Error decoding negTokenInit header"));
+               cFYI(1, "Error decoding negTokenInit header");
                return 0;
        }
 
        /* SPNEGO */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding negTokenInit"));
+               cFYI(1, "Error decoding negTokenInit");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
                   || (tag != ASN1_EOC)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
        /* negTokenInit */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding negTokenInit"));
+               cFYI(1, "Error decoding negTokenInit");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                   || (tag != ASN1_SEQ)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
        /* sequence */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding 2nd part of negTokenInit"));
+               cFYI(1, "Error decoding 2nd part of negTokenInit");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
                   || (tag != ASN1_EOC)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
        /* sequence of */
        if (asn1_header_decode
            (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding 2nd part of negTokenInit"));
+               cFYI(1, "Error decoding 2nd part of negTokenInit");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                   || (tag != ASN1_SEQ)) {
-               cFYI(1,
-                    ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
-                     cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1",
+                    cls, con, tag, end, *end);
                return 0;
        }
 
@@ -592,37 +584,33 @@ decode_negTokenInit(unsigned char *security_blob, int length,
        while (!asn1_eoc_decode(&ctx, sequence_end)) {
                rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
                if (!rc) {
-                       cFYI(1,
-                            ("Error decoding negTokenInit hdr exit2"));
+                       cFYI(1, "Error decoding negTokenInit hdr exit2");
                        return 0;
                }
                if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
                        if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
 
-                               cFYI(1, ("OID len = %d oid = 0x%lx 0x%lx "
-                                        "0x%lx 0x%lx", oidlen, *oid,
-                                        *(oid + 1), *(oid + 2), *(oid + 3)));
+                               cFYI(1, "OID len = %d oid = 0x%lx 0x%lx "
+                                       "0x%lx 0x%lx", oidlen, *oid,
+                                       *(oid + 1), *(oid + 2), *(oid + 3));
 
                                if (compare_oid(oid, oidlen, MSKRB5_OID,
-                                               MSKRB5_OID_LEN) &&
-                                               !use_mskerberos)
-                                       use_mskerberos = true;
+                                               MSKRB5_OID_LEN))
+                                       server->sec_mskerberos = true;
                                else if (compare_oid(oid, oidlen, KRB5U2U_OID,
-                                                    KRB5U2U_OID_LEN) &&
-                                                    !use_kerberosu2u)
-                                       use_kerberosu2u = true;
+                                                    KRB5U2U_OID_LEN))
+                                       server->sec_kerberosu2u = true;
                                else if (compare_oid(oid, oidlen, KRB5_OID,
-                                                    KRB5_OID_LEN) &&
-                                                    !use_kerberos)
-                                       use_kerberos = true;
+                                                    KRB5_OID_LEN))
+                                       server->sec_kerberos = true;
                                else if (compare_oid(oid, oidlen, NTLMSSP_OID,
                                                     NTLMSSP_OID_LEN))
-                                       use_ntlmssp = true;
+                                       server->sec_ntlmssp = true;
 
                                kfree(oid);
                        }
                } else {
-                       cFYI(1, ("Should be an oid what is going on?"));
+                       cFYI(1, "Should be an oid what is going on?");
                }
        }
 
@@ -632,54 +620,47 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                   no mechListMic (e.g. NTLMSSP instead of KRB5) */
                if (ctx.error == ASN1_ERR_DEC_EMPTY)
                        goto decode_negtoken_exit;
-               cFYI(1, ("Error decoding last part negTokenInit exit3"));
+               cFYI(1, "Error decoding last part negTokenInit exit3");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
                /* tag = 3 indicating mechListMIC */
-               cFYI(1, ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
-                        cls, con, tag, end, *end));
+               cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
                return 0;
        }
 
        /* sequence */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding last part negTokenInit exit5"));
+               cFYI(1, "Error decoding last part negTokenInit exit5");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
                   || (tag != ASN1_SEQ)) {
-               cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
-                       cls, con, tag, end, *end));
+               cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
        }
 
        /* sequence of */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding last part negTokenInit exit 7"));
+               cFYI(1, "Error decoding last part negTokenInit exit 7");
                return 0;
        } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
-               cFYI(1, ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
-                        cls, con, tag, end, *end));
+               cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
                return 0;
        }
 
        /* general string */
        if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-               cFYI(1, ("Error decoding last part negTokenInit exit9"));
+               cFYI(1, "Error decoding last part negTokenInit exit9");
                return 0;
        } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
                   || (tag != ASN1_GENSTR)) {
-               cFYI(1, ("Exit10 cls = %d con = %d tag = %d end = %p (%d)",
-                        cls, con, tag, end, *end));
+               cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)",
+                       cls, con, tag, end, *end);
                return 0;
        }
-       cFYI(1, ("Need to call asn1_octets_decode() function for %s",
-                ctx.pointer)); /* is this UTF-8 or ASCII? */
+       cFYI(1, "Need to call asn1_octets_decode() function for %s",
+               ctx.pointer);   /* is this UTF-8 or ASCII? */
 decode_negtoken_exit:
-       if (use_kerberos)
-               *secType = Kerberos;
-       else if (use_mskerberos)
-               *secType = MSKerberos;
-       else if (use_ntlmssp)
-               *secType = RawNTLMSSP;
-
        return 1;
 }
index 42cec2a..4fce6e6 100644 (file)
@@ -60,10 +60,10 @@ cifs_dump_mem(char *label, void *data, int length)
 #ifdef CONFIG_CIFS_DEBUG2
 void cifs_dump_detail(struct smb_hdr *smb)
 {
-       cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
+       cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
                  smb->Command, smb->Status.CifsError,
-                 smb->Flags, smb->Flags2, smb->Mid, smb->Pid));
-       cERROR(1, ("smb buf %p len %d", smb, smbCalcSize_LE(smb)));
+                 smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
+       cERROR(1, "smb buf %p len %d", smb, smbCalcSize_LE(smb));
 }
 
 
@@ -75,25 +75,25 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
        if (server == NULL)
                return;
 
-       cERROR(1, ("Dump pending requests:"));
+       cERROR(1, "Dump pending requests:");
        spin_lock(&GlobalMid_Lock);
        list_for_each(tmp, &server->pending_mid_q) {
                mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-               cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
+               cERROR(1, "State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
                        mid_entry->midState,
                        (int)mid_entry->command,
                        mid_entry->pid,
                        mid_entry->tsk,
-                       mid_entry->mid));
+                       mid_entry->mid);
 #ifdef CONFIG_CIFS_STATS2
-               cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld",
+               cERROR(1, "IsLarge: %d buf: %p time rcv: %ld now: %ld",
                        mid_entry->largeBuf,
                        mid_entry->resp_buf,
                        mid_entry->when_received,
-                       jiffies));
+                       jiffies);
 #endif /* STATS2 */
-               cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
-                         mid_entry->multiEnd));
+               cERROR(1, "IsMult: %d IsEnd: %d", mid_entry->multiRsp,
+                         mid_entry->multiEnd);
                if (mid_entry->resp_buf) {
                        cifs_dump_detail(mid_entry->resp_buf);
                        cifs_dump_mem("existing buf: ",
@@ -716,7 +716,7 @@ static const struct file_operations cifs_multiuser_mount_proc_fops = {
 
 static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
 {
-       seq_printf(m, "0x%x\n", extended_security);
+       seq_printf(m, "0x%x\n", global_secflags);
        return 0;
 }
 
@@ -744,13 +744,13 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
                /* single char or single char followed by null */
                c = flags_string[0];
                if (c == '0' || c == 'n' || c == 'N') {
-                       extended_security = CIFSSEC_DEF; /* default */
+                       global_secflags = CIFSSEC_DEF; /* default */
                        return count;
                } else if (c == '1' || c == 'y' || c == 'Y') {
-                       extended_security = CIFSSEC_MAX;
+                       global_secflags = CIFSSEC_MAX;
                        return count;
                } else if (!isdigit(c)) {
-                       cERROR(1, ("invalid flag %c", c));
+                       cERROR(1, "invalid flag %c", c);
                        return -EINVAL;
                }
        }
@@ -758,26 +758,26 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
 
        flags = simple_strtoul(flags_string, NULL, 0);
 
-       cFYI(1, ("sec flags 0x%x", flags));
+       cFYI(1, "sec flags 0x%x", flags);
 
        if (flags <= 0)  {
-               cERROR(1, ("invalid security flags %s", flags_string));
+               cERROR(1, "invalid security flags %s", flags_string);
                return -EINVAL;
        }
 
        if (flags & ~CIFSSEC_MASK) {
-               cERROR(1, ("attempt to set unsupported security flags 0x%x",
-                       flags & ~CIFSSEC_MASK));
+               cERROR(1, "attempt to set unsupported security flags 0x%x",
+                       flags & ~CIFSSEC_MASK);
                return -EINVAL;
        }
        /* flags look ok - update the global security flags for cifs module */
-       extended_security = flags;
-       if (extended_security & CIFSSEC_MUST_SIGN) {
+       global_secflags = flags;
+       if (global_secflags & CIFSSEC_MUST_SIGN) {
                /* requiring signing implies signing is allowed */
-               extended_security |= CIFSSEC_MAY_SIGN;
-               cFYI(1, ("packet signing now required"));
-       } else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
-               cFYI(1, ("packet signing disabled"));
+               global_secflags |= CIFSSEC_MAY_SIGN;
+               cFYI(1, "packet signing now required");
+       } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) {
+               cFYI(1, "packet signing disabled");
        }
        /* BB should we turn on MAY flags for other MUST options? */
        return count;
index 5eb3b83..aa31689 100644 (file)
@@ -43,34 +43,54 @@ void dump_smb(struct smb_hdr *, int);
  */
 #ifdef CIFS_DEBUG
 
-
 /* information message: e.g., configuration, major event */
 extern int cifsFYI;
-#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
+#define cifsfyi(fmt, arg...)                                           \
+do {                                                                   \
+       if (cifsFYI & CIFS_INFO)                                        \
+               printk(KERN_DEBUG "%s: " fmt "\n", __FILE__, ##arg);    \
+} while (0)
 
-#define cFYI(button,prspec) if (button) cifsfyi prspec
+#define cFYI(set, fmt, arg...)                 \
+do {                                           \
+       if (set)                                \
+               cifsfyi(fmt, ##arg);            \
+} while (0)
 
-#define cifswarn(format, arg...) printk(KERN_WARNING ": " format "\n" , ## arg)
+#define cifswarn(fmt, arg...)                  \
+       printk(KERN_WARNING fmt "\n", ##arg)
 
 /* debug event message: */
 extern int cifsERROR;
 
-#define cEVENT(format,arg...) if (cifsERROR) printk(KERN_EVENT __FILE__ ": " format "\n" , ## arg)
+#define cEVENT(fmt, arg...)                                            \
+do {                                                                   \
+       if (cifsERROR)                                                  \
+               printk(KERN_EVENT "%s: " fmt "\n", __FILE__, ##arg);    \
+} while (0)
 
 /* error event message: e.g., i/o error */
-#define cifserror(format,arg...) if (cifsERROR) printk(KERN_ERR " CIFS VFS: " format "\n" "" , ## arg)
+#define cifserror(fmt, arg...)                                 \
+do {                                                           \
+       if (cifsERROR)                                          \
+               printk(KERN_ERR "CIFS VFS: " fmt "\n", ##arg);  \
+} while (0)
 
-#define cERROR(button, prspec) if (button) cifserror prspec
+#define cERROR(set, fmt, arg...)               \
+do {                                           \
+       if (set)                                \
+               cifserror(fmt, ##arg);          \
+} while (0)
 
 /*
  *     debug OFF
  *     ---------
  */
 #else          /* _CIFS_DEBUG */
-#define cERROR(button, prspec)
-#define cEVENT(format, arg...)
-#define cFYI(button, prspec)
-#define cifserror(format, arg...)
+#define cERROR(set, fmt, arg...)
+#define cEVENT(fmt, arg...)
+#define cFYI(set, fmt, arg...)
+#define cifserror(fmt, arg...)
 #endif         /* _CIFS_DEBUG */
 
 #endif                         /* _H_CIFS_DEBUG */
index 78e4d2a..ac19a6f 100644 (file)
@@ -85,8 +85,8 @@ static char *cifs_get_share_name(const char *node_name)
        /* find server name end */
        pSep = memchr(UNC+2, '\\', len-2);
        if (!pSep) {
-               cERROR(1, ("%s: no server name end in node name: %s",
-                       __func__, node_name));
+               cERROR(1, "%s: no server name end in node name: %s",
+                       __func__, node_name);
                kfree(UNC);
                return ERR_PTR(-EINVAL);
        }
@@ -142,8 +142,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
 
        rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
        if (rc != 0) {
-               cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
-                         __func__, *devname, rc));
+               cERROR(1, "%s: Failed to resolve server part of %s to IP: %d",
+                         __func__, *devname, rc);
                goto compose_mount_options_err;
        }
        /* md_len = strlen(...) + 12 for 'sep+prefixpath='
@@ -217,8 +217,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
                strcat(mountdata, fullpath + ref->path_consumed);
        }
 
-       /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
-       /*cFYI(1, ("%s: submount mountdata: %s", __func__, mountdata ));*/
+       /*cFYI(1, "%s: parent mountdata: %s", __func__,sb_mountdata);*/
+       /*cFYI(1, "%s: submount mountdata: %s", __func__, mountdata );*/
 
 compose_mount_options_out:
        kfree(srvIP);
@@ -294,11 +294,11 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
 
 static void dump_referral(const struct dfs_info3_param *ref)
 {
-       cFYI(1, ("DFS: ref path: %s", ref->path_name));
-       cFYI(1, ("DFS: node path: %s", ref->node_name));
-       cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type));
-       cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
-                               ref->path_consumed));
+       cFYI(1, "DFS: ref path: %s", ref->path_name);
+       cFYI(1, "DFS: node path: %s", ref->node_name);
+       cFYI(1, "DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type);
+       cFYI(1, "DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
+                               ref->path_consumed);
 }
 
 
@@ -314,7 +314,7 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        int rc = 0;
        struct vfsmount *mnt = ERR_PTR(-ENOENT);
 
-       cFYI(1, ("in %s", __func__));
+       cFYI(1, "in %s", __func__);
        BUG_ON(IS_ROOT(dentry));
 
        xid = GetXid();
@@ -352,15 +352,15 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
                /* connect to a node */
                len = strlen(referrals[i].node_name);
                if (len < 2) {
-                       cERROR(1, ("%s: Net Address path too short: %s",
-                                       __func__, referrals[i].node_name));
+                       cERROR(1, "%s: Net Address path too short: %s",
+                                       __func__, referrals[i].node_name);
                        rc = -EINVAL;
                        goto out_err;
                }
                mnt = cifs_dfs_do_refmount(nd->path.mnt,
                                nd->path.dentry, referrals + i);
-               cFYI(1, ("%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
-                                       referrals[i].node_name, mnt));
+               cFYI(1, "%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
+                                       referrals[i].node_name, mnt);
 
                /* complete mount procedure if we accured submount */
                if (!IS_ERR(mnt))
@@ -378,7 +378,7 @@ out:
        FreeXid(xid);
        free_dfs_info_array(referrals, num_referrals);
        kfree(full_path);
-       cFYI(1, ("leaving %s" , __func__));
+       cFYI(1, "leaving %s" , __func__);
        return ERR_PTR(rc);
 out_err:
        path_put(&nd->path);
index 4797787..246a167 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef _CIFS_FS_SB_H
 #define _CIFS_FS_SB_H
 
+#include <linux/backing-dev.h>
+
 #define CIFS_MOUNT_NO_PERM      1 /* do not do client vfs_perm check */
 #define CIFS_MOUNT_SET_UID      2 /* set current's euid in create etc. */
 #define CIFS_MOUNT_SERVER_INUM  4 /* inode numbers from uniqueid from server  */
@@ -50,5 +52,6 @@ struct cifs_sb_info {
 #ifdef CONFIG_CIFS_DFS_UPCALL
        char   *mountdata; /* mount options received at mount time */
 #endif
+       struct backing_dev_info bdi;
 };
 #endif                         /* _CIFS_FS_SB_H */
index 310d12f..379bd7d 100644 (file)
@@ -133,9 +133,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
        dp = description + strlen(description);
 
        /* for now, only sec=krb5 and sec=mskrb5 are valid */
-       if (server->secType == Kerberos)
+       if (server->sec_kerberos)
                sprintf(dp, ";sec=krb5");
-       else if (server->secType == MSKerberos)
+       else if (server->sec_mskerberos)
                sprintf(dp, ";sec=mskrb5");
        else
                goto out;
@@ -149,7 +149,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
        dp = description + strlen(description);
        sprintf(dp, ";pid=0x%x", current->pid);
 
-       cFYI(1, ("key description = %s", description));
+       cFYI(1, "key description = %s", description);
        spnego_key = request_key(&cifs_spnego_key_type, description, "");
 
 #ifdef CONFIG_CIFS_DEBUG2
index d07676b..430f510 100644 (file)
@@ -200,9 +200,8 @@ cifs_strtoUCS(__le16 *to, const char *from, int len,
                /* works for 2.4.0 kernel or later */
                charlen = codepage->char2uni(from, len, &wchar_to[i]);
                if (charlen < 1) {
-                       cERROR(1,
-                              ("strtoUCS: char2uni of %d returned %d",
-                               (int)*from, charlen));
+                       cERROR(1, "strtoUCS: char2uni of %d returned %d",
+                               (int)*from, charlen);
                        /* A question mark */
                        to[i] = cpu_to_le16(0x003f);
                        charlen = 1;
index 9b716d0..85d7cf7 100644 (file)
@@ -87,11 +87,11 @@ int match_sid(struct cifs_sid *ctsid)
                                continue; /* all sub_auth values do not match */
                }
 
-               cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
+               cFYI(1, "matching sid: %s\n", wksidarr[i].sidname);
                return 0; /* sids compare/match */
        }
 
-       cFYI(1, ("No matching sid"));
+       cFYI(1, "No matching sid");
        return -1;
 }
 
@@ -208,14 +208,14 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
                        *pbits_to_set &= ~S_IXUGO;
                return;
        } else if (type != ACCESS_ALLOWED) {
-               cERROR(1, ("unknown access control type %d", type));
+               cERROR(1, "unknown access control type %d", type);
                return;
        }
        /* else ACCESS_ALLOWED type */
 
        if (flags & GENERIC_ALL) {
                *pmode |= (S_IRWXUGO & (*pbits_to_set));
-               cFYI(DBG2, ("all perms"));
+               cFYI(DBG2, "all perms");
                return;
        }
        if ((flags & GENERIC_WRITE) ||
@@ -228,7 +228,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
                        ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
                *pmode |= (S_IXUGO & (*pbits_to_set));
 
-       cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode));
+       cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
        return;
 }
 
@@ -257,7 +257,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
        if (mode & S_IXUGO)
                *pace_flags |= SET_FILE_EXEC_RIGHTS;
 
-       cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
+       cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
        return;
 }
 
@@ -297,24 +297,24 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
        /* validate that we do not go past end of acl */
 
        if (le16_to_cpu(pace->size) < 16) {
-               cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size)));
+               cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
                return;
        }
 
        if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
-               cERROR(1, ("ACL too small to parse ACE"));
+               cERROR(1, "ACL too small to parse ACE");
                return;
        }
 
        num_subauth = pace->sid.num_subauth;
        if (num_subauth) {
                int i;
-               cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
+               cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
                        pace->sid.revision, pace->sid.num_subauth, pace->type,
-                       pace->flags, le16_to_cpu(pace->size)));
+                       pace->flags, le16_to_cpu(pace->size));
                for (i = 0; i < num_subauth; ++i) {
-                       cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
-                               le32_to_cpu(pace->sid.sub_auth[i])));
+                       cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
+                               le32_to_cpu(pace->sid.sub_auth[i]));
                }
 
                /* BB add length check to make sure that we do not have huge
@@ -347,13 +347,13 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 
        /* validate that we do not go past end of acl */
        if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
-               cERROR(1, ("ACL too small to parse DACL"));
+               cERROR(1, "ACL too small to parse DACL");
                return;
        }
 
-       cFYI(DBG2, ("DACL revision %d size %d num aces %d",
+       cFYI(DBG2, "DACL revision %d size %d num aces %d",
                le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
-               le32_to_cpu(pdacl->num_aces)));
+               le32_to_cpu(pdacl->num_aces));
 
        /* reset rwx permissions for user/group/other.
           Also, if num_aces is 0 i.e. DACL has no ACEs,
@@ -437,25 +437,25 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
        /* validate that we do not go past end of ACL - sid must be at least 8
           bytes long (assuming no sub-auths - e.g. the null SID */
        if (end_of_acl < (char *)psid + 8) {
-               cERROR(1, ("ACL too small to parse SID %p", psid));
+               cERROR(1, "ACL too small to parse SID %p", psid);
                return -EINVAL;
        }
 
        if (psid->num_subauth) {
 #ifdef CONFIG_CIFS_DEBUG2
                int i;
-               cFYI(1, ("SID revision %d num_auth %d",
-                       psid->revision, psid->num_subauth));
+               cFYI(1, "SID revision %d num_auth %d",
+                       psid->revision, psid->num_subauth);
 
                for (i = 0; i < psid->num_subauth; i++) {
-                       cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
-                               le32_to_cpu(psid->sub_auth[i])));
+                       cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
+                               le32_to_cpu(psid->sub_auth[i]));
                }
 
                /* BB add length check to make sure that we do not have huge
                        num auths and therefore go off the end */
-               cFYI(1, ("RID 0x%x",
-                       le32_to_cpu(psid->sub_auth[psid->num_subauth-1])));
+               cFYI(1, "RID 0x%x",
+                       le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
 #endif
        }
 
@@ -482,11 +482,11 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
                                le32_to_cpu(pntsd->gsidoffset));
        dacloffset = le32_to_cpu(pntsd->dacloffset);
        dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
-       cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
+       cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
                 "sacloffset 0x%x dacloffset 0x%x",
                 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
                 le32_to_cpu(pntsd->gsidoffset),
-                le32_to_cpu(pntsd->sacloffset), dacloffset));
+                le32_to_cpu(pntsd->sacloffset), dacloffset);
 /*     cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
        rc = parse_sid(owner_sid_ptr, end_of_acl);
        if (rc)
@@ -500,7 +500,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
                parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
                           group_sid_ptr, fattr);
        else
-               cFYI(1, ("no ACL")); /* BB grant all or default perms? */
+               cFYI(1, "no ACL"); /* BB grant all or default perms? */
 
 /*     cifscred->uid = owner_sid_ptr->rid;
        cifscred->gid = group_sid_ptr->rid;
@@ -563,7 +563,7 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
        FreeXid(xid);
 
 
-       cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
+       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
        return pntsd;
 }
 
@@ -581,12 +581,12 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
-               cERROR(1, ("Unable to open file to get ACL"));
+               cERROR(1, "Unable to open file to get ACL");
                goto out;
        }
 
        rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
-       cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
+       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
 
        CIFSSMBClose(xid, cifs_sb->tcon, fid);
  out:
@@ -621,7 +621,7 @@ static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
        rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
        FreeXid(xid);
 
-       cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
+       cFYI(DBG2, "SetCIFSACL rc = %d", rc);
        return rc;
 }
 
@@ -638,12 +638,12 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
-               cERROR(1, ("Unable to open file to set ACL"));
+               cERROR(1, "Unable to open file to set ACL");
                goto out;
        }
 
        rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
-       cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
+       cFYI(DBG2, "SetCIFSACL rc = %d", rc);
 
        CIFSSMBClose(xid, cifs_sb->tcon, fid);
  out:
@@ -659,7 +659,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
        struct cifsFileInfo *open_file;
        int rc;
 
-       cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
+       cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
 
        open_file = find_readable_file(CIFS_I(inode));
        if (!open_file)
@@ -679,7 +679,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
        u32 acllen = 0;
        int rc = 0;
 
-       cFYI(DBG2, ("converting ACL to mode for %s", path));
+       cFYI(DBG2, "converting ACL to mode for %s", path);
 
        if (pfid)
                pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
@@ -690,7 +690,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
        if (pntsd)
                rc = parse_sec_desc(pntsd, acllen, fattr);
        if (rc)
-               cFYI(1, ("parse sec desc failed rc = %d", rc));
+               cFYI(1, "parse sec desc failed rc = %d", rc);
 
        kfree(pntsd);
        return;
@@ -704,7 +704,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
        struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
        struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
 
-       cFYI(DBG2, ("set ACL from mode for %s", path));
+       cFYI(DBG2, "set ACL from mode for %s", path);
 
        /* Get the security descriptor */
        pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
@@ -721,19 +721,19 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
                                        DEFSECDESCLEN : secdesclen;
                pnntsd = kmalloc(secdesclen, GFP_KERNEL);
                if (!pnntsd) {
-                       cERROR(1, ("Unable to allocate security descriptor"));
+                       cERROR(1, "Unable to allocate security descriptor");
                        kfree(pntsd);
                        return -ENOMEM;
                }
 
                rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
 
-               cFYI(DBG2, ("build_sec_desc rc: %d", rc));
+               cFYI(DBG2, "build_sec_desc rc: %d", rc);
 
                if (!rc) {
                        /* Set the security descriptor */
                        rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
-                       cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
+                       cFYI(DBG2, "set_cifs_acl rc: %d", rc);
                }
 
                kfree(pnntsd);
index fbe9864..847628d 100644 (file)
@@ -103,7 +103,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
                if (iov[i].iov_len == 0)
                        continue;
                if (iov[i].iov_base == NULL) {
-                       cERROR(1, ("null iovec entry"));
+                       cERROR(1, "null iovec entry");
                        return -EIO;
                }
                /* The first entry includes a length field (which does not get
@@ -181,8 +181,8 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
 
        /* Do not need to verify session setups with signature "BSRSPYL "  */
        if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
-               cFYI(1, ("dummy signature received for smb command 0x%x",
-                       cifs_pdu->Command));
+               cFYI(1, "dummy signature received for smb command 0x%x",
+                       cifs_pdu->Command);
 
        /* save off the origiginal signature so we can modify the smb and check
                its signature against what the server sent */
@@ -291,7 +291,7 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
        if (password)
                strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
 
-       if (!encrypt && extended_security & CIFSSEC_MAY_PLNTXT) {
+       if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
                memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
                memcpy(lnm_session_key, password_with_pad,
                        CIFS_ENCPWD_SIZE);
@@ -398,7 +398,7 @@ void setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
        /* calculate buf->ntlmv2_hash */
        rc = calc_ntlmv2_hash(ses, nls_cp);
        if (rc)
-               cERROR(1, ("could not get v2 hash rc %d", rc));
+               cERROR(1, "could not get v2 hash rc %d", rc);
        CalcNTLMv2_response(ses, resp_buf);
 
        /* now calculate the MAC key for NTLMv2 */
index ded66be..78c02eb 100644 (file)
 #include "cifs_spnego.h"
 #define CIFS_MAGIC_NUMBER 0xFF534D42   /* the first four bytes of SMB PDUs */
 
-#ifdef CONFIG_CIFS_QUOTA
-static const struct quotactl_ops cifs_quotactl_ops;
-#endif /* QUOTA */
-
 int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
@@ -61,7 +57,7 @@ unsigned int experimEnabled = 0;
 unsigned int linuxExtEnabled = 1;
 unsigned int lookupCacheEnabled = 1;
 unsigned int multiuser_mount = 0;
-unsigned int extended_security = CIFSSEC_DEF;
+unsigned int global_secflags = CIFSSEC_DEF;
 /* unsigned int ntlmv2_support = 0; */
 unsigned int sign_CIFS_PDUs = 1;
 static const struct super_operations cifs_super_ops;
@@ -86,8 +82,6 @@ extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
 
-extern struct kmem_cache *cifs_oplock_cachep;
-
 static int
 cifs_read_super(struct super_block *sb, void *data,
                const char *devname, int silent)
@@ -103,6 +97,12 @@ cifs_read_super(struct super_block *sb, void *data,
        if (cifs_sb == NULL)
                return -ENOMEM;
 
+       rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
+       if (rc) {
+               kfree(cifs_sb);
+               return rc;
+       }
+
 #ifdef CONFIG_CIFS_DFS_UPCALL
        /* copy mount params to sb for use in submounts */
        /* BB: should we move this after the mount so we
@@ -115,6 +115,7 @@ cifs_read_super(struct super_block *sb, void *data,
                int len = strlen(data);
                cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
                if (cifs_sb->mountdata == NULL) {
+                       bdi_destroy(&cifs_sb->bdi);
                        kfree(sb->s_fs_info);
                        sb->s_fs_info = NULL;
                        return -ENOMEM;
@@ -128,19 +129,16 @@ cifs_read_super(struct super_block *sb, void *data,
 
        if (rc) {
                if (!silent)
-                       cERROR(1,
-                              ("cifs_mount failed w/return code = %d", rc));
+                       cERROR(1, "cifs_mount failed w/return code = %d", rc);
                goto out_mount_failed;
        }
 
        sb->s_magic = CIFS_MAGIC_NUMBER;
        sb->s_op = &cifs_super_ops;
+       sb->s_bdi = &cifs_sb->bdi;
 /*     if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
            sb->s_blocksize =
                cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
-#ifdef CONFIG_CIFS_QUOTA
-       sb->s_qcop = &cifs_quotactl_ops;
-#endif
        sb->s_blocksize = CIFS_MAX_MSGSIZE;
        sb->s_blocksize_bits = 14;      /* default 2**14 = CIFS_MAX_MSGSIZE */
        inode = cifs_root_iget(sb, ROOT_I);
@@ -160,7 +158,7 @@ cifs_read_super(struct super_block *sb, void *data,
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
-               cFYI(1, ("export ops supported"));
+               cFYI(1, "export ops supported");
                sb->s_export_op = &cifs_export_ops;
        }
 #endif /* EXPERIMENTAL */
@@ -168,7 +166,7 @@ cifs_read_super(struct super_block *sb, void *data,
        return 0;
 
 out_no_root:
-       cERROR(1, ("cifs_read_super: get root inode failed"));
+       cERROR(1, "cifs_read_super: get root inode failed");
        if (inode)
                iput(inode);
 
@@ -183,6 +181,7 @@ out_mount_failed:
                }
 #endif
                unload_nls(cifs_sb->local_nls);
+               bdi_destroy(&cifs_sb->bdi);
                kfree(cifs_sb);
        }
        return rc;
@@ -194,10 +193,10 @@ cifs_put_super(struct super_block *sb)
        int rc = 0;
        struct cifs_sb_info *cifs_sb;
 
-       cFYI(1, ("In cifs_put_super"));
+       cFYI(1, "In cifs_put_super");
        cifs_sb = CIFS_SB(sb);
        if (cifs_sb == NULL) {
-               cFYI(1, ("Empty cifs superblock info passed to unmount"));
+               cFYI(1, "Empty cifs superblock info passed to unmount");
                return;
        }
 
@@ -205,7 +204,7 @@ cifs_put_super(struct super_block *sb)
 
        rc = cifs_umount(sb, cifs_sb);
        if (rc)
-               cERROR(1, ("cifs_umount failed with return code %d", rc));
+               cERROR(1, "cifs_umount failed with return code %d", rc);
 #ifdef CONFIG_CIFS_DFS_UPCALL
        if (cifs_sb->mountdata) {
                kfree(cifs_sb->mountdata);
@@ -214,6 +213,7 @@ cifs_put_super(struct super_block *sb)
 #endif
 
        unload_nls(cifs_sb->local_nls);
+       bdi_destroy(&cifs_sb->bdi);
        kfree(cifs_sb);
 
        unlock_kernel();
@@ -290,7 +290,6 @@ static int cifs_permission(struct inode *inode, int mask)
 static struct kmem_cache *cifs_inode_cachep;
 static struct kmem_cache *cifs_req_cachep;
 static struct kmem_cache *cifs_mid_cachep;
-struct kmem_cache *cifs_oplock_cachep;
 static struct kmem_cache *cifs_sm_req_cachep;
 mempool_t *cifs_sm_req_poolp;
 mempool_t *cifs_req_poolp;
@@ -422,106 +421,6 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
        return 0;
 }
 
-#ifdef CONFIG_CIFS_QUOTA
-int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
-               struct fs_disk_quota *pdquota)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
-                   struct fs_disk_quota *pdquota)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
-{
-       int xid;
-       int rc = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-       struct cifsTconInfo *pTcon;
-
-       if (cifs_sb)
-               pTcon = cifs_sb->tcon;
-       else
-               return -EIO;
-
-       xid = GetXid();
-       if (pTcon) {
-               cFYI(1, ("pqstats %p", qstats));
-       } else
-               rc = -EIO;
-
-       FreeXid(xid);
-       return rc;
-}
-
-static const struct quotactl_ops cifs_quotactl_ops = {
-       .set_xquota     = cifs_xquota_set,
-       .get_xquota     = cifs_xquota_get,
-       .set_xstate     = cifs_xstate_set,
-       .get_xstate     = cifs_xstate_get,
-};
-#endif
-
 static void cifs_umount_begin(struct super_block *sb)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -548,7 +447,7 @@ static void cifs_umount_begin(struct super_block *sb)
        /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
        /* cancel_notify_requests(tcon); */
        if (tcon->ses && tcon->ses->server) {
-               cFYI(1, ("wake up tasks now - umount begin not complete"));
+               cFYI(1, "wake up tasks now - umount begin not complete");
                wake_up_all(&tcon->ses->server->request_q);
                wake_up_all(&tcon->ses->server->response_q);
                msleep(1); /* yield */
@@ -599,7 +498,7 @@ cifs_get_sb(struct file_system_type *fs_type,
        int rc;
        struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
 
-       cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
+       cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
 
        if (IS_ERR(sb))
                return PTR_ERR(sb);
@@ -646,7 +545,6 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
        return generic_file_llseek_unlocked(file, offset, origin);
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
 {
        /* note that this is called by vfs setlease with the BKL held
@@ -675,7 +573,6 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
        else
                return -EAGAIN;
 }
-#endif
 
 struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
@@ -752,10 +649,7 @@ const struct file_operations cifs_file_ops = {
 #ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
 const struct file_operations cifs_file_direct_ops = {
@@ -774,9 +668,7 @@ const struct file_operations cifs_file_direct_ops = {
        .unlocked_ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 const struct file_operations cifs_file_nobrl_ops = {
        .read = do_sync_read,
@@ -793,10 +685,7 @@ const struct file_operations cifs_file_nobrl_ops = {
 #ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
-
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
 const struct file_operations cifs_file_direct_nobrl_ops = {
@@ -814,9 +703,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
        .unlocked_ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
        .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_EXPERIMENTAL
        .setlease = cifs_setlease,
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
 
 const struct file_operations cifs_dir_ops = {
@@ -868,7 +755,7 @@ cifs_init_request_bufs(void)
        } else {
                CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
        }
-/*     cERROR(1,("CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize)); */
+/*     cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */
        cifs_req_cachep = kmem_cache_create("cifs_request",
                                            CIFSMaxBufSize +
                                            MAX_CIFS_HDR_SIZE, 0,
@@ -880,7 +767,7 @@ cifs_init_request_bufs(void)
                cifs_min_rcv = 1;
        else if (cifs_min_rcv > 64) {
                cifs_min_rcv = 64;
-               cERROR(1, ("cifs_min_rcv set to maximum (64)"));
+               cERROR(1, "cifs_min_rcv set to maximum (64)");
        }
 
        cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
@@ -911,7 +798,7 @@ cifs_init_request_bufs(void)
                cifs_min_small = 2;
        else if (cifs_min_small > 256) {
                cifs_min_small = 256;
-               cFYI(1, ("cifs_min_small set to maximum (256)"));
+               cFYI(1, "cifs_min_small set to maximum (256)");
        }
 
        cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
@@ -952,15 +839,6 @@ cifs_init_mids(void)
                return -ENOMEM;
        }
 
-       cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
-                                       sizeof(struct oplock_q_entry), 0,
-                                       SLAB_HWCACHE_ALIGN, NULL);
-       if (cifs_oplock_cachep == NULL) {
-               mempool_destroy(cifs_mid_poolp);
-               kmem_cache_destroy(cifs_mid_cachep);
-               return -ENOMEM;
-       }
-
        return 0;
 }
 
@@ -969,7 +847,6 @@ cifs_destroy_mids(void)
 {
        mempool_destroy(cifs_mid_poolp);
        kmem_cache_destroy(cifs_mid_cachep);
-       kmem_cache_destroy(cifs_oplock_cachep);
 }
 
 static int __init
@@ -1009,10 +886,10 @@ init_cifs(void)
 
        if (cifs_max_pending < 2) {
                cifs_max_pending = 2;
-               cFYI(1, ("cifs_max_pending set to min of 2"));
+               cFYI(1, "cifs_max_pending set to min of 2");
        } else if (cifs_max_pending > 256) {
                cifs_max_pending = 256;
-               cFYI(1, ("cifs_max_pending set to max of 256"));
+               cFYI(1, "cifs_max_pending set to max of 256");
        }
 
        rc = cifs_init_inodecache();
@@ -1070,7 +947,7 @@ init_cifs(void)
 static void __exit
 exit_cifs(void)
 {
-       cFYI(DBG2, ("exit_cifs"));
+       cFYI(DBG2, "exit_cifs");
        cifs_proc_clean();
 #ifdef CONFIG_CIFS_DFS_UPCALL
        cifs_dfs_release_automount_timer();
index 7aa57ec..0242ff9 100644 (file)
@@ -114,5 +114,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.62"
+#define CIFS_VERSION   "1.64"
 #endif                         /* _CIFSFS_H */
index ecf0ffb..a88479c 100644 (file)
@@ -87,7 +87,6 @@ enum securityEnum {
        RawNTLMSSP,             /* NTLMSSP without SPNEGO, NTLMv2 hash */
 /*     NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */
        Kerberos,               /* Kerberos via SPNEGO */
-       MSKerberos,             /* MS Kerberos via SPNEGO */
 };
 
 enum protocolEnum {
@@ -185,6 +184,12 @@ struct TCP_Server_Info {
        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 */
+       bool    sec_kerberos;           /* supports plain Kerberos */
+       bool    sec_mskerberos;         /* supports legacy MS Kerberos */
+       bool    sec_kerberosu2u;        /* supports U2U Kerberos */
+       bool    sec_ntlmssp;            /* supports NTLMSSP */
 };
 
 /*
@@ -502,6 +507,7 @@ struct dfs_info3_param {
 #define CIFS_FATTR_DFS_REFERRAL                0x1
 #define CIFS_FATTR_DELETE_PENDING      0x2
 #define CIFS_FATTR_NEED_REVAL          0x4
+#define CIFS_FATTR_INO_COLLISION       0x8
 
 struct cifs_fattr {
        u32             cf_flags;
@@ -717,7 +723,7 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
 GLOBAL_EXTERN unsigned int oplockEnabled;
 GLOBAL_EXTERN unsigned int experimEnabled;
 GLOBAL_EXTERN unsigned int lookupCacheEnabled;
-GLOBAL_EXTERN unsigned int extended_security;  /* if on, session setup sent
+GLOBAL_EXTERN unsigned int global_secflags;    /* if on, session setup sent
                                with more secure ntlmssp2 challenge/resp */
 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
index 39e47f4..fb1657e 100644 (file)
@@ -39,8 +39,20 @@ extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
                        unsigned int /* length */);
 extern unsigned int _GetXid(void);
 extern void _FreeXid(unsigned int);
-#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid()));
-#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));}
+#define GetXid()                                               \
+({                                                             \
+       int __xid = (int)_GetXid();                             \
+       cFYI(1, "CIFS VFS: in %s as Xid: %d with uid: %d",      \
+            __func__, __xid, current_fsuid());                 \
+       __xid;                                                  \
+})
+
+#define FreeXid(curr_xid)                                      \
+do {                                                           \
+       _FreeXid(curr_xid);                                     \
+       cFYI(1, "CIFS VFS: leaving %s (xid = %d) rc = %d",      \
+            __func__, curr_xid, (int)rc);                      \
+} while (0)
 extern char *build_path_from_dentry(struct dentry *);
 extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
@@ -73,7 +85,7 @@ extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *);
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
-                       enum securityEnum *secType);
+                       struct TCP_Server_Info *server);
 extern int cifs_convert_address(char *src, void *dst);
 extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
 extern void header_assemble(struct smb_hdr *, char /* command */ ,
@@ -83,7 +95,6 @@ extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
                                struct cifsSesInfo *ses,
                                void **request_buf);
 extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
-                            const int stage,
                             const struct nls_table *nls_cp);
 extern __u16 GetNextMid(struct TCP_Server_Info *server);
 extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
@@ -95,8 +106,11 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
                                __u16 fileHandle, struct file *file,
                                struct vfsmount *mnt, unsigned int oflags);
 extern int cifs_posix_open(char *full_path, struct inode **pinode,
-                          struct vfsmount *mnt, int mode, int oflags,
-                          __u32 *poplock, __u16 *pnetfid, int xid);
+                               struct vfsmount *mnt,
+                               struct super_block *sb,
+                               int mode, int oflags,
+                               __u32 *poplock, __u16 *pnetfid, int xid);
+void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
 extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
                                     FILE_UNIX_BASIC_INFO *info,
                                     struct cifs_sb_info *cifs_sb);
@@ -125,7 +139,9 @@ extern void cifs_dfs_release_automount_timer(void);
 void cifs_proc_init(void);
 void cifs_proc_clean(void);
 
-extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
+extern int cifs_negotiate_protocol(unsigned int xid,
+                                 struct cifsSesInfo *ses);
+extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
                        struct nls_table *nls_info);
 extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
 
index 5d3f29f..c65c341 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifssmb.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2009
+ *   Copyright (C) International Business Machines  Corp., 2002,2010
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   Contains the routines for constructing the SMB PDUs themselves
@@ -130,8 +130,8 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
                if (smb_command != SMB_COM_WRITE_ANDX &&
                    smb_command != SMB_COM_OPEN_ANDX &&
                    smb_command != SMB_COM_TREE_DISCONNECT) {
-                       cFYI(1, ("can not send cmd %d while umounting",
-                               smb_command));
+                       cFYI(1, "can not send cmd %d while umounting",
+                               smb_command);
                        return -ENODEV;
                }
        }
@@ -157,7 +157,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
                 * back on-line
                 */
                if (!tcon->retry || ses->status == CifsExiting) {
-                       cFYI(1, ("gave up waiting on reconnect in smb_init"));
+                       cFYI(1, "gave up waiting on reconnect in smb_init");
                        return -EHOSTDOWN;
                }
        }
@@ -172,7 +172,8 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
         * reconnect the same SMB session
         */
        mutex_lock(&ses->session_mutex);
-       if (ses->need_reconnect)
+       rc = cifs_negotiate_protocol(0, ses);
+       if (rc == 0 && ses->need_reconnect)
                rc = cifs_setup_session(0, ses, nls_codepage);
 
        /* do we need to reconnect tcon? */
@@ -184,7 +185,7 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
        mark_open_files_invalid(tcon);
        rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
        mutex_unlock(&ses->session_mutex);
-       cFYI(1, ("reconnect tcon rc = %d", rc));
+       cFYI(1, "reconnect tcon rc = %d", rc);
 
        if (rc)
                goto out;
@@ -355,7 +356,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        struct TCP_Server_Info *server;
        u16 count;
        unsigned int secFlags;
-       u16 dialect;
 
        if (ses->server)
                server = ses->server;
@@ -372,9 +372,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
                secFlags = ses->overrideSecFlg;  /* BB FIXME fix sign flags? */
        else /* if override flags set only sign/seal OR them with global auth */
-               secFlags = extended_security | ses->overrideSecFlg;
+               secFlags = global_secflags | ses->overrideSecFlg;
 
-       cFYI(1, ("secFlags 0x%x", secFlags));
+       cFYI(1, "secFlags 0x%x", secFlags);
 
        pSMB->hdr.Mid = GetNextMid(server);
        pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
@@ -382,14 +382,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
-               cFYI(1, ("Kerberos only mechanism, enable extended security"));
+               cFYI(1, "Kerberos only mechanism, enable extended security");
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        }
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
-               cFYI(1, ("NTLMSSP only mechanism, enable extended security"));
+               cFYI(1, "NTLMSSP only mechanism, enable extended security");
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        }
 #endif
@@ -408,10 +408,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        if (rc != 0)
                goto neg_err_exit;
 
-       dialect = le16_to_cpu(pSMBr->DialectIndex);
-       cFYI(1, ("Dialect: %d", dialect));
+       server->dialect = le16_to_cpu(pSMBr->DialectIndex);
+       cFYI(1, "Dialect: %d", server->dialect);
        /* Check wct = 1 error case */
-       if ((pSMBr->hdr.WordCount < 13) || (dialect == BAD_PROT)) {
+       if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
                /* core returns wct = 1, but we do not ask for core - otherwise
                small wct just comes when dialect index is -1 indicating we
                could not negotiate a common dialect */
@@ -419,8 +419,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                goto neg_err_exit;
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        } else if ((pSMBr->hdr.WordCount == 13)
-                       && ((dialect == LANMAN_PROT)
-                               || (dialect == LANMAN2_PROT))) {
+                       && ((server->dialect == LANMAN_PROT)
+                               || (server->dialect == LANMAN2_PROT))) {
                __s16 tmp;
                struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
 
@@ -428,8 +428,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        (secFlags & CIFSSEC_MAY_PLNTXT))
                        server->secType = LANMAN;
                else {
-                       cERROR(1, ("mount failed weak security disabled"
-                                  " in /proc/fs/cifs/SecurityFlags"));
+                       cERROR(1, "mount failed weak security disabled"
+                                  " in /proc/fs/cifs/SecurityFlags");
                        rc = -EOPNOTSUPP;
                        goto neg_err_exit;
                }
@@ -462,9 +462,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        utc = CURRENT_TIME;
                        ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
                                            rsp->SrvTime.Time, 0);
-                       cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d",
+                       cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
                                (int)ts.tv_sec, (int)utc.tv_sec,
-                               (int)(utc.tv_sec - ts.tv_sec)));
+                               (int)(utc.tv_sec - ts.tv_sec));
                        val = (int)(utc.tv_sec - ts.tv_sec);
                        seconds = abs(val);
                        result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
@@ -478,7 +478,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        server->timeAdj = (int)tmp;
                        server->timeAdj *= 60; /* also in seconds */
                }
-               cFYI(1, ("server->timeAdj: %d seconds", server->timeAdj));
+               cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
 
 
                /* BB get server time for time conversions and add
@@ -493,14 +493,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        goto neg_err_exit;
                }
 
-               cFYI(1, ("LANMAN negotiated"));
+               cFYI(1, "LANMAN negotiated");
                /* we will not end up setting signing flags - as no signing
                was in LANMAN and server did not return the flags on */
                goto signing_check;
 #else /* weak security disabled */
        } else if (pSMBr->hdr.WordCount == 13) {
-               cERROR(1, ("mount failed, cifs module not built "
-                         "with CIFS_WEAK_PW_HASH support"));
+               cERROR(1, "mount failed, cifs module not built "
+                         "with CIFS_WEAK_PW_HASH support");
                rc = -EOPNOTSUPP;
 #endif /* WEAK_PW_HASH */
                goto neg_err_exit;
@@ -512,14 +512,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        /* else wct == 17 NTLM */
        server->secMode = pSMBr->SecurityMode;
        if ((server->secMode & SECMODE_USER) == 0)
-               cFYI(1, ("share mode security"));
+               cFYI(1, "share mode security");
 
        if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
 #endif /* CIFS_WEAK_PW_HASH */
-                       cERROR(1, ("Server requests plain text password"
-                                 " but client support disabled"));
+                       cERROR(1, "Server requests plain text password"
+                                 " but client support disabled");
 
        if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
                server->secType = NTLMv2;
@@ -539,7 +539,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 #endif */
        else {
                rc = -EOPNOTSUPP;
-               cERROR(1, ("Invalid security type"));
+               cERROR(1, "Invalid security type");
                goto neg_err_exit;
        }
        /* else ... any others ...? */
@@ -551,7 +551,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize),
                        (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
        server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
-       cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf));
+       cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
        GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
        server->capabilities = le32_to_cpu(pSMBr->Capabilities);
        server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
@@ -582,7 +582,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        if (memcmp(server->server_GUID,
                                   pSMBr->u.extended_response.
                                   GUID, 16) != 0) {
-                               cFYI(1, ("server UID changed"));
+                               cFYI(1, "server UID changed");
                                memcpy(server->server_GUID,
                                        pSMBr->u.extended_response.GUID,
                                        16);
@@ -597,13 +597,19 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        server->secType = RawNTLMSSP;
                } else {
                        rc = decode_negTokenInit(pSMBr->u.extended_response.
-                                                SecurityBlob,
-                                                count - 16,
-                                                &server->secType);
+                                                SecurityBlob, count - 16,
+                                                server);
                        if (rc == 1)
                                rc = 0;
                        else
                                rc = -EINVAL;
+
+                       if (server->sec_kerberos || server->sec_mskerberos)
+                               server->secType = Kerberos;
+                       else if (server->sec_ntlmssp)
+                               server->secType = RawNTLMSSP;
+                       else
+                               rc = -EOPNOTSUPP;
                }
        } else
                server->capabilities &= ~CAP_EXTENDED_SECURITY;
@@ -614,22 +620,21 @@ signing_check:
        if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
                /* MUST_SIGN already includes the MAY_SIGN FLAG
                   so if this is zero it means that signing is disabled */
-               cFYI(1, ("Signing disabled"));
+               cFYI(1, "Signing disabled");
                if (server->secMode & SECMODE_SIGN_REQUIRED) {
-                       cERROR(1, ("Server requires "
+                       cERROR(1, "Server requires "
                                   "packet signing to be enabled in "
-                                  "/proc/fs/cifs/SecurityFlags."));
+                                  "/proc/fs/cifs/SecurityFlags.");
                        rc = -EOPNOTSUPP;
                }
                server->secMode &=
                        ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
        } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
                /* signing required */
-               cFYI(1, ("Must sign - secFlags 0x%x", secFlags));
+               cFYI(1, "Must sign - secFlags 0x%x", secFlags);
                if ((server->secMode &
                        (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
-                       cERROR(1,
-                               ("signing required but server lacks support"));
+                       cERROR(1, "signing required but server lacks support");
                        rc = -EOPNOTSUPP;
                } else
                        server->secMode |= SECMODE_SIGN_REQUIRED;
@@ -643,7 +648,7 @@ signing_check:
 neg_err_exit:
        cifs_buf_release(pSMB);
 
-       cFYI(1, ("negprot rc %d", rc));
+       cFYI(1, "negprot rc %d", rc);
        return rc;
 }
 
@@ -653,7 +658,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
        struct smb_hdr *smb_buffer;
        int rc = 0;
 
-       cFYI(1, ("In tree disconnect"));
+       cFYI(1, "In tree disconnect");
 
        /* BB: do we need to check this? These should never be NULL. */
        if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
@@ -675,7 +680,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
 
        rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0);
        if (rc)
-               cFYI(1, ("Tree disconnect failed %d", rc));
+               cFYI(1, "Tree disconnect failed %d", rc);
 
        /* No need to return error on this operation if tid invalidated and
           closed on server already e.g. due to tcp session crashing */
@@ -691,7 +696,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
        LOGOFF_ANDX_REQ *pSMB;
        int rc = 0;
 
-       cFYI(1, ("In SMBLogoff for session disconnect"));
+       cFYI(1, "In SMBLogoff for session disconnect");
 
        /*
         * BB: do we need to check validity of ses and server? They should
@@ -744,7 +749,7 @@ CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In POSIX delete"));
+       cFYI(1, "In POSIX delete");
 PsxDelete:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -796,7 +801,7 @@ PsxDelete:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("Posix delete returned %d", rc));
+               cFYI(1, "Posix delete returned %d", rc);
        cifs_buf_release(pSMB);
 
        cifs_stats_inc(&tcon->num_deletes);
@@ -843,7 +848,7 @@ DelFileRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_deletes);
        if (rc)
-               cFYI(1, ("Error in RMFile = %d", rc));
+               cFYI(1, "Error in RMFile = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -862,7 +867,7 @@ CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In CIFSSMBRmDir"));
+       cFYI(1, "In CIFSSMBRmDir");
 RmDirRetry:
        rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -887,7 +892,7 @@ RmDirRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_rmdirs);
        if (rc)
-               cFYI(1, ("Error in RMDir = %d", rc));
+               cFYI(1, "Error in RMDir = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -905,7 +910,7 @@ CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In CIFSSMBMkDir"));
+       cFYI(1, "In CIFSSMBMkDir");
 MkDirRetry:
        rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -930,7 +935,7 @@ MkDirRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_mkdirs);
        if (rc)
-               cFYI(1, ("Error in Mkdir = %d", rc));
+               cFYI(1, "Error in Mkdir = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -953,7 +958,7 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
        OPEN_PSX_REQ *pdata;
        OPEN_PSX_RSP *psx_rsp;
 
-       cFYI(1, ("In POSIX Create"));
+       cFYI(1, "In POSIX Create");
 PsxCreat:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -1007,11 +1012,11 @@ PsxCreat:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Posix create returned %d", rc));
+               cFYI(1, "Posix create returned %d", rc);
                goto psx_create_err;
        }
 
-       cFYI(1, ("copying inode info"));
+       cFYI(1, "copying inode info");
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
        if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
@@ -1033,11 +1038,11 @@ PsxCreat:
        /* check to make sure response data is there */
        if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
                pRetData->Type = cpu_to_le32(-1); /* unknown */
-               cFYI(DBG2, ("unknown type"));
+               cFYI(DBG2, "unknown type");
        } else {
                if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
                                        + sizeof(FILE_UNIX_BASIC_INFO)) {
-                       cERROR(1, ("Open response data too small"));
+                       cERROR(1, "Open response data too small");
                        pRetData->Type = cpu_to_le32(-1);
                        goto psx_create_err;
                }
@@ -1084,7 +1089,7 @@ static __u16 convert_disposition(int disposition)
                        ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
                        break;
                default:
-                       cFYI(1, ("unknown disposition %d", disposition));
+                       cFYI(1, "unknown disposition %d", disposition);
                        ofun =  SMBOPEN_OAPPEND; /* regular open */
        }
        return ofun;
@@ -1175,7 +1180,7 @@ OldOpenRetry:
                        (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
        cifs_stats_inc(&tcon->num_opens);
        if (rc) {
-               cFYI(1, ("Error in Open = %d", rc));
+               cFYI(1, "Error in Open = %d", rc);
        } else {
        /* BB verify if wct == 15 */
 
@@ -1288,7 +1293,7 @@ openRetry:
                        (struct smb_hdr *)pSMBr, &bytes_returned, CIFS_LONG_OP);
        cifs_stats_inc(&tcon->num_opens);
        if (rc) {
-               cFYI(1, ("Error in Open = %d", rc));
+               cFYI(1, "Error in Open = %d", rc);
        } else {
                *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
                *netfid = pSMBr->Fid;   /* cifs fid stays in le */
@@ -1326,7 +1331,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
        int resp_buf_type = 0;
        struct kvec iov[1];
 
-       cFYI(1, ("Reading %d bytes on fid %d", count, netfid));
+       cFYI(1, "Reading %d bytes on fid %d", count, netfid);
        if (tcon->ses->capabilities & CAP_LARGE_FILES)
                wct = 12;
        else {
@@ -1371,7 +1376,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
        cifs_stats_inc(&tcon->num_reads);
        pSMBr = (READ_RSP *)iov[0].iov_base;
        if (rc) {
-               cERROR(1, ("Send error in read = %d", rc));
+               cERROR(1, "Send error in read = %d", rc);
        } else {
                int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
                data_length = data_length << 16;
@@ -1381,15 +1386,15 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
                /*check that DataLength would not go beyond end of SMB */
                if ((data_length > CIFSMaxBufSize)
                                || (data_length > count)) {
-                       cFYI(1, ("bad length %d for count %d",
-                                data_length, count));
+                       cFYI(1, "bad length %d for count %d",
+                                data_length, count);
                        rc = -EIO;
                        *nbytes = 0;
                } else {
                        pReadData = (char *) (&pSMBr->hdr.Protocol) +
                                        le16_to_cpu(pSMBr->DataOffset);
 /*                     if (rc = copy_to_user(buf, pReadData, data_length)) {
-                               cERROR(1,("Faulting on read rc = %d",rc));
+                               cERROR(1, "Faulting on read rc = %d",rc);
                                rc = -EFAULT;
                        }*/ /* can not use copy_to_user when using page cache*/
                        if (*buf)
@@ -1433,7 +1438,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
 
        *nbytes = 0;
 
-       /* cFYI(1, ("write at %lld %d bytes", offset, count));*/
+       /* cFYI(1, "write at %lld %d bytes", offset, count);*/
        if (tcon->ses == NULL)
                return -ECONNABORTED;
 
@@ -1514,7 +1519,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
                         (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
-               cFYI(1, ("Send error in write = %d", rc));
+               cFYI(1, "Send error in write = %d", rc);
        } else {
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
                *nbytes = (*nbytes) << 16;
@@ -1551,7 +1556,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
 
        *nbytes = 0;
 
-       cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count));
+       cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
 
        if (tcon->ses->capabilities & CAP_LARGE_FILES) {
                wct = 14;
@@ -1606,7 +1611,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
                          long_op);
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
-               cFYI(1, ("Send error Write2 = %d", rc));
+               cFYI(1, "Send error Write2 = %d", rc);
        } else if (resp_buf_type == 0) {
                /* presumably this can not happen, but best to be safe */
                rc = -EIO;
@@ -1651,7 +1656,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
        int timeout = 0;
        __u16 count;
 
-       cFYI(1, ("CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock));
+       cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
        rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
 
        if (rc)
@@ -1699,7 +1704,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
        }
        cifs_stats_inc(&tcon->num_locks);
        if (rc)
-               cFYI(1, ("Send error in Lock = %d", rc));
+               cFYI(1, "Send error in Lock = %d", rc);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
        since file handle passed in no longer valid */
@@ -1722,7 +1727,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
        __u16 params, param_offset, offset, byte_count, count;
        struct kvec iov[1];
 
-       cFYI(1, ("Posix Lock"));
+       cFYI(1, "Posix Lock");
 
        if (pLockData == NULL)
                return -EINVAL;
@@ -1792,7 +1797,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
        }
 
        if (rc) {
-               cFYI(1, ("Send error in Posix Lock = %d", rc));
+               cFYI(1, "Send error in Posix Lock = %d", rc);
        } else if (get_flag) {
                /* lock structure can be returned on get */
                __u16 data_offset;
@@ -1849,7 +1854,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 {
        int rc = 0;
        CLOSE_REQ *pSMB = NULL;
-       cFYI(1, ("In CIFSSMBClose"));
+       cFYI(1, "In CIFSSMBClose");
 
 /* do not retry on dead session on close */
        rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
@@ -1866,7 +1871,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
        if (rc) {
                if (rc != -EINTR) {
                        /* EINTR is expected when user ctl-c to kill app */
-                       cERROR(1, ("Send error in Close = %d", rc));
+                       cERROR(1, "Send error in Close = %d", rc);
                }
        }
 
@@ -1882,7 +1887,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
 {
        int rc = 0;
        FLUSH_REQ *pSMB = NULL;
-       cFYI(1, ("In CIFSSMBFlush"));
+       cFYI(1, "In CIFSSMBFlush");
 
        rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
        if (rc)
@@ -1893,7 +1898,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        cifs_stats_inc(&tcon->num_flushes);
        if (rc)
-               cERROR(1, ("Send error in Flush = %d", rc));
+               cERROR(1, "Send error in Flush = %d", rc);
 
        return rc;
 }
@@ -1910,7 +1915,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
        int name_len, name_len2;
        __u16 count;
 
-       cFYI(1, ("In CIFSSMBRename"));
+       cFYI(1, "In CIFSSMBRename");
 renameRetry:
        rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -1956,7 +1961,7 @@ renameRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_renames);
        if (rc)
-               cFYI(1, ("Send error in rename = %d", rc));
+               cFYI(1, "Send error in rename = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -1980,7 +1985,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
        int len_of_str;
        __u16 params, param_offset, offset, count, byte_count;
 
-       cFYI(1, ("Rename to File by handle"));
+       cFYI(1, "Rename to File by handle");
        rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
                        (void **) &pSMBr);
        if (rc)
@@ -2035,7 +2040,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&pTcon->num_t2renames);
        if (rc)
-               cFYI(1, ("Send error in Rename (by file handle) = %d", rc));
+               cFYI(1, "Send error in Rename (by file handle) = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -2057,7 +2062,7 @@ CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
        int name_len, name_len2;
        __u16 count;
 
-       cFYI(1, ("In CIFSSMBCopy"));
+       cFYI(1, "In CIFSSMBCopy");
 copyRetry:
        rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
                        (void **) &pSMBr);
@@ -2102,8 +2107,8 @@ copyRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in copy = %d with %d files copied",
-                       rc, le16_to_cpu(pSMBr->CopyCount)));
+               cFYI(1, "Send error in copy = %d with %d files copied",
+                       rc, le16_to_cpu(pSMBr->CopyCount));
        }
        cifs_buf_release(pSMB);
 
@@ -2127,7 +2132,7 @@ CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In Symlink Unix style"));
+       cFYI(1, "In Symlink Unix style");
 createSymLinkRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -2192,7 +2197,7 @@ createSymLinkRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_symlinks);
        if (rc)
-               cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc));
+               cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -2216,7 +2221,7 @@ CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In Create Hard link Unix style"));
+       cFYI(1, "In Create Hard link Unix style");
 createHardLinkRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -2278,7 +2283,7 @@ createHardLinkRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_hardlinks);
        if (rc)
-               cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
+               cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -2299,7 +2304,7 @@ CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
        int name_len, name_len2;
        __u16 count;
 
-       cFYI(1, ("In CIFSCreateHardLink"));
+       cFYI(1, "In CIFSCreateHardLink");
 winCreateHardLinkRetry:
 
        rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
@@ -2350,7 +2355,7 @@ winCreateHardLinkRetry:
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_hardlinks);
        if (rc)
-               cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
+               cFYI(1, "Send error in hard link (NT rename) = %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -2373,7 +2378,7 @@ CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
        __u16 params, byte_count;
        char *data_start;
 
-       cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName));
+       cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
 
 querySymLinkRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -2420,7 +2425,7 @@ querySymLinkRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc));
+               cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
        } else {
                /* decode response */
 
@@ -2521,21 +2526,21 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
 
        /* should we also check that parm and data areas do not overlap? */
        if (*ppparm > end_of_smb) {
-               cFYI(1, ("parms start after end of smb"));
+               cFYI(1, "parms start after end of smb");
                return -EINVAL;
        } else if (parm_count + *ppparm > end_of_smb) {
-               cFYI(1, ("parm end after end of smb"));
+               cFYI(1, "parm end after end of smb");
                return -EINVAL;
        } else if (*ppdata > end_of_smb) {
-               cFYI(1, ("data starts after end of smb"));
+               cFYI(1, "data starts after end of smb");
                return -EINVAL;
        } else if (data_count + *ppdata > end_of_smb) {
-               cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p",
+               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
                        *ppdata, data_count, (data_count + *ppdata),
-                       end_of_smb, pSMBr));
+                       end_of_smb, pSMBr);
                return -EINVAL;
        } else if (parm_count + data_count > pSMBr->ByteCount) {
-               cFYI(1, ("parm count and data count larger than SMB"));
+               cFYI(1, "parm count and data count larger than SMB");
                return -EINVAL;
        }
        *pdatalen = data_count;
@@ -2554,7 +2559,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
        struct smb_com_transaction_ioctl_req *pSMB;
        struct smb_com_transaction_ioctl_rsp *pSMBr;
 
-       cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
+       cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
@@ -2583,7 +2588,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc));
+               cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
        } else {                /* decode response */
                __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
                __u32 data_count = le32_to_cpu(pSMBr->DataCount);
@@ -2607,7 +2612,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        if ((reparse_buf->LinkNamesBuf +
                                reparse_buf->TargetNameOffset +
                                reparse_buf->TargetNameLen) > end_of_smb) {
-                               cFYI(1, ("reparse buf beyond SMB"));
+                               cFYI(1, "reparse buf beyond SMB");
                                rc = -EIO;
                                goto qreparse_out;
                        }
@@ -2628,12 +2633,12 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        }
                } else {
                        rc = -EIO;
-                       cFYI(1, ("Invalid return data count on "
-                                "get reparse info ioctl"));
+                       cFYI(1, "Invalid return data count on "
+                                "get reparse info ioctl");
                }
                symlinkinfo[buflen] = 0; /* just in case so the caller
                                        does not go off the end of the buffer */
-               cFYI(1, ("readlink result - %s", symlinkinfo));
+               cFYI(1, "readlink result - %s", symlinkinfo);
        }
 
 qreparse_out:
@@ -2656,7 +2661,7 @@ static void cifs_convert_ace(posix_acl_xattr_entry *ace,
        ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
        ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
        ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
-       /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
+       /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
 
        return;
 }
@@ -2682,8 +2687,8 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
                size += sizeof(struct cifs_posix_ace) * count;
                /* check if we would go beyond end of SMB */
                if (size_of_data_area < size) {
-                       cFYI(1, ("bad CIFS POSIX ACL size %d vs. %d",
-                               size_of_data_area, size));
+                       cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
+                               size_of_data_area, size);
                        return -EINVAL;
                }
        } else if (acl_type & ACL_TYPE_DEFAULT) {
@@ -2730,7 +2735,7 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
                cifs_ace->cifs_uid = cpu_to_le64(-1);
        } else
                cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
-       /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
+       /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
        return rc;
 }
 
@@ -2748,12 +2753,12 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
                return 0;
 
        count = posix_acl_xattr_count((size_t)buflen);
-       cFYI(1, ("setting acl with %d entries from buf of length %d and "
+       cFYI(1, "setting acl with %d entries from buf of length %d and "
                "version of %d",
-               count, buflen, le32_to_cpu(local_acl->a_version)));
+               count, buflen, le32_to_cpu(local_acl->a_version));
        if (le32_to_cpu(local_acl->a_version) != 2) {
-               cFYI(1, ("unknown POSIX ACL version %d",
-                    le32_to_cpu(local_acl->a_version)));
+               cFYI(1, "unknown POSIX ACL version %d",
+                    le32_to_cpu(local_acl->a_version));
                return 0;
        }
        cifs_acl->version = cpu_to_le16(1);
@@ -2762,7 +2767,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
        else if (acl_type == ACL_TYPE_DEFAULT)
                cifs_acl->default_entry_count = cpu_to_le16(count);
        else {
-               cFYI(1, ("unknown ACL type %d", acl_type));
+               cFYI(1, "unknown ACL type %d", acl_type);
                return 0;
        }
        for (i = 0; i < count; i++) {
@@ -2795,7 +2800,7 @@ CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName));
+       cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
 
 queryAclRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -2847,7 +2852,7 @@ queryAclRetry:
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        cifs_stats_inc(&tcon->num_acl_get);
        if (rc) {
-               cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
+               cFYI(1, "Send error in Query POSIX ACL = %d", rc);
        } else {
                /* decode response */
 
@@ -2884,7 +2889,7 @@ CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, byte_count, data_count, param_offset, offset;
 
-       cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName));
+       cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
 setAclRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -2939,7 +2944,7 @@ setAclRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("Set POSIX ACL returned %d", rc));
+               cFYI(1, "Set POSIX ACL returned %d", rc);
 
 setACLerrorExit:
        cifs_buf_release(pSMB);
@@ -2959,7 +2964,7 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned;
        __u16 params, byte_count;
 
-       cFYI(1, ("In GetExtAttr"));
+       cFYI(1, "In GetExtAttr");
        if (tcon == NULL)
                return -ENODEV;
 
@@ -2998,7 +3003,7 @@ GetExtAttrRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("error %d in GetExtAttr", rc));
+               cFYI(1, "error %d in GetExtAttr", rc);
        } else {
                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -3013,7 +3018,7 @@ GetExtAttrRetry:
                        struct file_chattr_info *pfinfo;
                        /* BB Do we need a cast or hash here ? */
                        if (count != 16) {
-                               cFYI(1, ("Illegal size ret in GetExtAttr"));
+                               cFYI(1, "Illegal size ret in GetExtAttr");
                                rc = -EIO;
                                goto GetExtAttrOut;
                        }
@@ -3043,7 +3048,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
        QUERY_SEC_DESC_REQ *pSMB;
        struct kvec iov[1];
 
-       cFYI(1, ("GetCifsACL"));
+       cFYI(1, "GetCifsACL");
 
        *pbuflen = 0;
        *acl_inf = NULL;
@@ -3068,7 +3073,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                         CIFS_STD_OP);
        cifs_stats_inc(&tcon->num_acl_get);
        if (rc) {
-               cFYI(1, ("Send error in QuerySecDesc = %d", rc));
+               cFYI(1, "Send error in QuerySecDesc = %d", rc);
        } else {                /* decode response */
                __le32 *parm;
                __u32 parm_len;
@@ -3083,7 +3088,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                        goto qsec_out;
                pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
 
-               cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, *acl_inf));
+               cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
 
                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
                        rc = -EIO;      /* bad smb */
@@ -3095,8 +3100,8 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
 
                acl_len = le32_to_cpu(*parm);
                if (acl_len != *pbuflen) {
-                       cERROR(1, ("acl length %d does not match %d",
-                                  acl_len, *pbuflen));
+                       cERROR(1, "acl length %d does not match %d",
+                                  acl_len, *pbuflen);
                        if (*pbuflen > acl_len)
                                *pbuflen = acl_len;
                }
@@ -3105,7 +3110,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
                   header followed by the smallest SID */
                if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
                    (*pbuflen >= 64 * 1024)) {
-                       cERROR(1, ("bad acl length %d", *pbuflen));
+                       cERROR(1, "bad acl length %d", *pbuflen);
                        rc = -EINVAL;
                        *pbuflen = 0;
                } else {
@@ -3179,9 +3184,9 @@ setCifsAclRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
 
-       cFYI(1, ("SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc));
+       cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
        if (rc)
-               cFYI(1, ("Set CIFS ACL returned %d", rc));
+               cFYI(1, "Set CIFS ACL returned %d", rc);
        cifs_buf_release(pSMB);
 
        if (rc == -EAGAIN)
@@ -3205,7 +3210,7 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In SMBQPath path %s", searchName));
+       cFYI(1, "In SMBQPath path %s", searchName);
 QInfRetry:
        rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -3231,7 +3236,7 @@ QInfRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QueryInfo = %d", rc));
+               cFYI(1, "Send error in QueryInfo = %d", rc);
        } else if (pFinfo) {
                struct timespec ts;
                __u32 time = le32_to_cpu(pSMBr->last_write_time);
@@ -3305,7 +3310,7 @@ QFileInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QPathInfo = %d", rc));
+               cFYI(1, "Send error in QPathInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -3343,7 +3348,7 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-/* cFYI(1, ("In QPathInfo path %s", searchName)); */
+/* cFYI(1, "In QPathInfo path %s", searchName); */
 QPathInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -3393,7 +3398,7 @@ QPathInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QPathInfo = %d", rc));
+               cFYI(1, "Send error in QPathInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -3473,14 +3478,14 @@ UnixQFileInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QPathInfo = %d", rc));
+               cFYI(1, "Send error in QPathInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
-                       cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+                       cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
                                   "Unix Extensions can be disabled on mount "
-                                  "by specifying the nosfu mount option."));
+                                  "by specifying the nosfu mount option.");
                        rc = -EIO;      /* bad smb */
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3512,7 +3517,7 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QPathInfo (Unix) the path %s", searchName));
+       cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
 UnixQPathInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -3559,14 +3564,14 @@ UnixQPathInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QPathInfo = %d", rc));
+               cFYI(1, "Send error in QPathInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
-                       cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+                       cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
                                   "Unix Extensions can be disabled on mount "
-                                  "by specifying the nosfu mount option."));
+                                  "by specifying the nosfu mount option.");
                        rc = -EIO;      /* bad smb */
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3600,7 +3605,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
        int name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In FindFirst for %s", searchName));
+       cFYI(1, "In FindFirst for %s", searchName);
 
 findFirstRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -3677,7 +3682,7 @@ findFirstRetry:
        if (rc) {/* BB add logic to retry regular search if Unix search
                        rejected unexpectedly by server */
                /* BB Add code to handle unsupported level rc */
-               cFYI(1, ("Error in FindFirst = %d", rc));
+               cFYI(1, "Error in FindFirst = %d", rc);
 
                cifs_buf_release(pSMB);
 
@@ -3716,7 +3721,7 @@ findFirstRetry:
                        lnoff = le16_to_cpu(parms->LastNameOffset);
                        if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
                              lnoff) {
-                               cERROR(1, ("ignoring corrupt resume name"));
+                               cERROR(1, "ignoring corrupt resume name");
                                psrch_inf->last_entry = NULL;
                                return rc;
                        }
@@ -3744,7 +3749,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned, name_len;
        __u16 params, byte_count;
 
-       cFYI(1, ("In FindNext"));
+       cFYI(1, "In FindNext");
 
        if (psrch_inf->endOfSearch)
                return -ENOENT;
@@ -3808,7 +3813,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                        cifs_buf_release(pSMB);
                        rc = 0; /* search probably was closed at end of search*/
                } else
-                       cFYI(1, ("FindNext returned = %d", rc));
+                       cFYI(1, "FindNext returned = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -3844,15 +3849,15 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
                        lnoff = le16_to_cpu(parms->LastNameOffset);
                        if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
                              lnoff) {
-                               cERROR(1, ("ignoring corrupt resume name"));
+                               cERROR(1, "ignoring corrupt resume name");
                                psrch_inf->last_entry = NULL;
                                return rc;
                        } else
                                psrch_inf->last_entry =
                                        psrch_inf->srch_entries_start + lnoff;
 
-/*  cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
-           psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
+/*  cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
+           psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
 
                        /* BB fixme add unlock here */
                }
@@ -3877,7 +3882,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        FINDCLOSE_REQ *pSMB = NULL;
 
-       cFYI(1, ("In CIFSSMBFindClose"));
+       cFYI(1, "In CIFSSMBFindClose");
        rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
 
        /* no sense returning error if session restarted
@@ -3891,7 +3896,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
        pSMB->ByteCount = 0;
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cERROR(1, ("Send error in FindClose = %d", rc));
+               cERROR(1, "Send error in FindClose = %d", rc);
 
        cifs_stats_inc(&tcon->num_fclose);
 
@@ -3914,7 +3919,7 @@ CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
        int name_len, bytes_returned;
        __u16 params, byte_count;
 
-       cFYI(1, ("In GetSrvInodeNum for %s", searchName));
+       cFYI(1, "In GetSrvInodeNum for %s", searchName);
        if (tcon == NULL)
                return -ENODEV;
 
@@ -3964,7 +3969,7 @@ GetInodeNumberRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("error %d in QueryInternalInfo", rc));
+               cFYI(1, "error %d in QueryInternalInfo", rc);
        } else {
                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -3979,7 +3984,7 @@ GetInodeNumberRetry:
                        struct file_internal_info *pfinfo;
                        /* BB Do we need a cast or hash here ? */
                        if (count < 8) {
-                               cFYI(1, ("Illegal size ret in QryIntrnlInf"));
+                               cFYI(1, "Illegal size ret in QryIntrnlInf");
                                rc = -EIO;
                                goto GetInodeNumOut;
                        }
@@ -4020,16 +4025,16 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
        *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
 
        if (*num_of_nodes < 1) {
-               cERROR(1, ("num_referrals: must be at least > 0,"
-                       "but we get num_referrals = %d\n", *num_of_nodes));
+               cERROR(1, "num_referrals: must be at least > 0,"
+                       "but we get num_referrals = %d\n", *num_of_nodes);
                rc = -EINVAL;
                goto parse_DFS_referrals_exit;
        }
 
        ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
        if (ref->VersionNumber != cpu_to_le16(3)) {
-               cERROR(1, ("Referrals of V%d version are not supported,"
-                       "should be V3", le16_to_cpu(ref->VersionNumber)));
+               cERROR(1, "Referrals of V%d version are not supported,"
+                       "should be V3", le16_to_cpu(ref->VersionNumber));
                rc = -EINVAL;
                goto parse_DFS_referrals_exit;
        }
@@ -4038,14 +4043,14 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
        data_end = (char *)(&(pSMBr->PathConsumed)) +
                                le16_to_cpu(pSMBr->t2.DataCount);
 
-       cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n",
+       cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
                        *num_of_nodes,
-                       le32_to_cpu(pSMBr->DFSFlags)));
+                       le32_to_cpu(pSMBr->DFSFlags));
 
        *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
                        *num_of_nodes, GFP_KERNEL);
        if (*target_nodes == NULL) {
-               cERROR(1, ("Failed to allocate buffer for target_nodes\n"));
+               cERROR(1, "Failed to allocate buffer for target_nodes\n");
                rc = -ENOMEM;
                goto parse_DFS_referrals_exit;
        }
@@ -4121,7 +4126,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
        *num_of_nodes = 0;
        *target_nodes = NULL;
 
-       cFYI(1, ("In GetDFSRefer the path %s", searchName));
+       cFYI(1, "In GetDFSRefer the path %s", searchName);
        if (ses == NULL)
                return -ENODEV;
 getDFSRetry:
@@ -4188,7 +4193,7 @@ getDFSRetry:
        rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in GetDFSRefer = %d", rc));
+               cFYI(1, "Send error in GetDFSRefer = %d", rc);
                goto GetDFSRefExit;
        }
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -4199,9 +4204,9 @@ getDFSRetry:
                goto GetDFSRefExit;
        }
 
-       cFYI(1, ("Decoding GetDFSRefer response BCC: %d  Offset %d",
+       cFYI(1, "Decoding GetDFSRefer response BCC: %d  Offset %d",
                                pSMBr->ByteCount,
-                               le16_to_cpu(pSMBr->t2.DataOffset)));
+                               le16_to_cpu(pSMBr->t2.DataOffset));
 
        /* parse returned result into more usable form */
        rc = parse_DFS_referrals(pSMBr, num_of_nodes,
@@ -4229,7 +4234,7 @@ SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("OldQFSInfo"));
+       cFYI(1, "OldQFSInfo");
 oldQFSInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                (void **) &pSMBr);
@@ -4262,7 +4267,7 @@ oldQFSInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSInfo = %d", rc));
+               cFYI(1, "Send error in QFSInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4270,8 +4275,8 @@ oldQFSInfoRetry:
                        rc = -EIO;      /* bad smb */
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-                       cFYI(1, ("qfsinf resp BCC: %d  Offset %d",
-                                pSMBr->ByteCount, data_offset));
+                       cFYI(1, "qfsinf resp BCC: %d  Offset %d",
+                                pSMBr->ByteCount, data_offset);
 
                        response_data = (FILE_SYSTEM_ALLOC_INFO *)
                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
@@ -4283,11 +4288,10 @@ oldQFSInfoRetry:
                               le32_to_cpu(response_data->TotalAllocationUnits);
                        FSData->f_bfree = FSData->f_bavail =
                                le32_to_cpu(response_data->FreeAllocationUnits);
-                       cFYI(1,
-                            ("Blocks: %lld  Free: %lld Block size %ld",
-                             (unsigned long long)FSData->f_blocks,
-                             (unsigned long long)FSData->f_bfree,
-                             FSData->f_bsize));
+                       cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
+                            (unsigned long long)FSData->f_blocks,
+                            (unsigned long long)FSData->f_bfree,
+                            FSData->f_bsize);
                }
        }
        cifs_buf_release(pSMB);
@@ -4309,7 +4313,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSInfo"));
+       cFYI(1, "In QFSInfo");
 QFSInfoRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4342,7 +4346,7 @@ QFSInfoRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSInfo = %d", rc));
+               cFYI(1, "Send error in QFSInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4363,11 +4367,10 @@ QFSInfoRetry:
                            le64_to_cpu(response_data->TotalAllocationUnits);
                        FSData->f_bfree = FSData->f_bavail =
                            le64_to_cpu(response_data->FreeAllocationUnits);
-                       cFYI(1,
-                            ("Blocks: %lld  Free: %lld Block size %ld",
-                             (unsigned long long)FSData->f_blocks,
-                             (unsigned long long)FSData->f_bfree,
-                             FSData->f_bsize));
+                       cFYI(1, "Blocks: %lld  Free: %lld Block size %ld",
+                            (unsigned long long)FSData->f_blocks,
+                            (unsigned long long)FSData->f_bfree,
+                            FSData->f_bsize);
                }
        }
        cifs_buf_release(pSMB);
@@ -4389,7 +4392,7 @@ CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSAttributeInfo"));
+       cFYI(1, "In QFSAttributeInfo");
 QFSAttributeRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4423,7 +4426,7 @@ QFSAttributeRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in QFSAttributeInfo = %d", rc));
+               cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4459,7 +4462,7 @@ CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSDeviceInfo"));
+       cFYI(1, "In QFSDeviceInfo");
 QFSDeviceRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4494,7 +4497,7 @@ QFSDeviceRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSDeviceInfo = %d", rc));
+               cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4529,7 +4532,7 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSUnixInfo"));
+       cFYI(1, "In QFSUnixInfo");
 QFSUnixRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4563,7 +4566,7 @@ QFSUnixRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in QFSUnixInfo = %d", rc));
+               cERROR(1, "Send error in QFSUnixInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4598,7 +4601,7 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
        int bytes_returned = 0;
        __u16 params, param_offset, offset, byte_count;
 
-       cFYI(1, ("In SETFSUnixInfo"));
+       cFYI(1, "In SETFSUnixInfo");
 SETFSUnixRetry:
        /* BB switch to small buf init to save memory */
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -4646,7 +4649,7 @@ SETFSUnixRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
+               cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                if (rc)
@@ -4674,7 +4677,7 @@ CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned = 0;
        __u16 params, byte_count;
 
-       cFYI(1, ("In QFSPosixInfo"));
+       cFYI(1, "In QFSPosixInfo");
 QFSPosixRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4708,7 +4711,7 @@ QFSPosixRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QFSUnixInfo = %d", rc));
+               cFYI(1, "Send error in QFSUnixInfo = %d", rc);
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
@@ -4768,7 +4771,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
        int bytes_returned = 0;
        __u16 params, byte_count, data_count, param_offset, offset;
 
-       cFYI(1, ("In SetEOF"));
+       cFYI(1, "In SetEOF");
 SetEOFRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -4834,7 +4837,7 @@ SetEOFRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (file size) returned %d", rc));
+               cFYI(1, "SetPathInfo (file size) returned %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -4854,8 +4857,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
-                       (long long)size));
+       cFYI(1, "SetFileSize (via SetFileInfo) %lld",
+                       (long long)size);
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -4914,9 +4917,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
        pSMB->ByteCount = cpu_to_le16(byte_count);
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc) {
-               cFYI(1,
-                    ("Send error in SetFileInfo (SetFileSize) = %d",
-                     rc));
+               cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
        }
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
@@ -4940,7 +4941,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("Set Times (via SetFileInfo)"));
+       cFYI(1, "Set Times (via SetFileInfo)");
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -4985,7 +4986,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
        memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
+               cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
                since file handle passed in no longer valid */
@@ -5002,7 +5003,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("Set File Disposition (via SetFileInfo)"));
+       cFYI(1, "Set File Disposition (via SetFileInfo)");
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -5044,7 +5045,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
        *data_offset = delete_file ? 1 : 0;
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cFYI(1, ("Send error in SetFileDisposition = %d", rc));
+               cFYI(1, "Send error in SetFileDisposition = %d", rc);
 
        return rc;
 }
@@ -5062,7 +5063,7 @@ CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
        char *data_offset;
        __u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("In SetTimes"));
+       cFYI(1, "In SetTimes");
 
 SetTimesRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
@@ -5118,7 +5119,7 @@ SetTimesRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (times) returned %d", rc));
+               cFYI(1, "SetPathInfo (times) returned %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -5143,7 +5144,7 @@ CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
        int bytes_returned;
        int name_len;
 
-       cFYI(1, ("In SetAttrLegacy"));
+       cFYI(1, "In SetAttrLegacy");
 
 SetAttrLgcyRetry:
        rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
@@ -5169,7 +5170,7 @@ SetAttrLgcyRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("Error in LegacySetAttr = %d", rc));
+               cFYI(1, "Error in LegacySetAttr = %d", rc);
 
        cifs_buf_release(pSMB);
 
@@ -5231,7 +5232,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
        int rc = 0;
        u16 params, param_offset, offset, byte_count, count;
 
-       cFYI(1, ("Set Unix Info (via SetFileInfo)"));
+       cFYI(1, "Set Unix Info (via SetFileInfo)");
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -5276,7 +5277,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
 
        rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
        if (rc)
-               cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc));
+               cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
 
        /* Note: On -EAGAIN error only caller can retry on handle based calls
                since file handle passed in no longer valid */
@@ -5297,7 +5298,7 @@ CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
        FILE_UNIX_BASIC_INFO *data_offset;
        __u16 params, param_offset, offset, count, byte_count;
 
-       cFYI(1, ("In SetUID/GID/Mode"));
+       cFYI(1, "In SetUID/GID/Mode");
 setPermsRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -5353,7 +5354,7 @@ setPermsRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (perms) returned %d", rc));
+               cFYI(1, "SetPathInfo (perms) returned %d", rc);
 
        cifs_buf_release(pSMB);
        if (rc == -EAGAIN)
@@ -5372,7 +5373,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
        struct dir_notify_req *dnotify_req;
        int bytes_returned;
 
-       cFYI(1, ("In CIFSSMBNotify for file handle %d", (int)netfid));
+       cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
        rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
        if (rc)
@@ -5406,7 +5407,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
                         (struct smb_hdr *)pSMBr, &bytes_returned,
                         CIFS_ASYNC_OP);
        if (rc) {
-               cFYI(1, ("Error in Notify = %d", rc));
+               cFYI(1, "Error in Notify = %d", rc);
        } else {
                /* Add file to outstanding requests */
                /* BB change to kmem cache alloc */
@@ -5462,7 +5463,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
        char *end_of_smb;
        __u16 params, byte_count, data_offset;
 
-       cFYI(1, ("In Query All EAs path %s", searchName));
+       cFYI(1, "In Query All EAs path %s", searchName);
 QAllEAsRetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -5509,7 +5510,7 @@ QAllEAsRetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
-               cFYI(1, ("Send error in QueryAllEAs = %d", rc));
+               cFYI(1, "Send error in QueryAllEAs = %d", rc);
                goto QAllEAsOut;
        }
 
@@ -5537,16 +5538,16 @@ QAllEAsRetry:
                                (((char *) &pSMBr->hdr.Protocol) + data_offset);
 
        list_len = le32_to_cpu(ea_response_data->list_len);
-       cFYI(1, ("ea length %d", list_len));
+       cFYI(1, "ea length %d", list_len);
        if (list_len <= 8) {
-               cFYI(1, ("empty EA list returned from server"));
+               cFYI(1, "empty EA list returned from server");
                goto QAllEAsOut;
        }
 
        /* make sure list_len doesn't go past end of SMB */
        end_of_smb = (char *)pByteArea(&pSMBr->hdr) + BCC(&pSMBr->hdr);
        if ((char *)ea_response_data + list_len > end_of_smb) {
-               cFYI(1, ("EA list appears to go beyond SMB"));
+               cFYI(1, "EA list appears to go beyond SMB");
                rc = -EIO;
                goto QAllEAsOut;
        }
@@ -5563,7 +5564,7 @@ QAllEAsRetry:
                temp_ptr += 4;
                /* make sure we can read name_len and value_len */
                if (list_len < 0) {
-                       cFYI(1, ("EA entry goes beyond length of list"));
+                       cFYI(1, "EA entry goes beyond length of list");
                        rc = -EIO;
                        goto QAllEAsOut;
                }
@@ -5572,7 +5573,7 @@ QAllEAsRetry:
                value_len = le16_to_cpu(temp_fea->value_len);
                list_len -= name_len + 1 + value_len;
                if (list_len < 0) {
-                       cFYI(1, ("EA entry goes beyond length of list"));
+                       cFYI(1, "EA entry goes beyond length of list");
                        rc = -EIO;
                        goto QAllEAsOut;
                }
@@ -5639,7 +5640,7 @@ CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
        int bytes_returned = 0;
        __u16 params, param_offset, byte_count, offset, count;
 
-       cFYI(1, ("In SetEA"));
+       cFYI(1, "In SetEA");
 SetEARetry:
        rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
                      (void **) &pSMBr);
@@ -5721,7 +5722,7 @@ SetEARetry:
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc)
-               cFYI(1, ("SetPathInfo (EA) returned %d", rc));
+               cFYI(1, "SetPathInfo (EA) returned %d", rc);
 
        cifs_buf_release(pSMB);
 
index d9566bf..2208f06 100644 (file)
@@ -102,6 +102,7 @@ struct smb_vol {
        bool sockopt_tcp_nodelay:1;
        unsigned short int port;
        char *prepath;
+       struct nls_table *local_nls;
 };
 
 static int ipv4_connect(struct TCP_Server_Info *server);
@@ -135,7 +136,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        spin_unlock(&GlobalMid_Lock);
        server->maxBuf = 0;
 
-       cFYI(1, ("Reconnecting tcp session"));
+       cFYI(1, "Reconnecting tcp session");
 
        /* before reconnecting the tcp session, mark the smb session (uid)
                and the tid bad so they are not used until reconnected */
@@ -153,12 +154,12 @@ cifs_reconnect(struct TCP_Server_Info *server)
        /* do not want to be sending data on a socket we are freeing */
        mutex_lock(&server->srv_mutex);
        if (server->ssocket) {
-               cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
-                       server->ssocket->flags));
+               cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
+                       server->ssocket->flags);
                kernel_sock_shutdown(server->ssocket, SHUT_WR);
-               cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
+               cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
                        server->ssocket->state,
-                       server->ssocket->flags));
+                       server->ssocket->flags);
                sock_release(server->ssocket);
                server->ssocket = NULL;
        }
@@ -187,7 +188,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                else
                        rc = ipv4_connect(server);
                if (rc) {
-                       cFYI(1, ("reconnect error %d", rc));
+                       cFYI(1, "reconnect error %d", rc);
                        msleep(3000);
                } else {
                        atomic_inc(&tcpSesReconnectCount);
@@ -223,7 +224,7 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
        /* check for plausible wct, bcc and t2 data and parm sizes */
        /* check for parm and data offset going beyond end of smb */
        if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
-               cFYI(1, ("invalid transact2 word count"));
+               cFYI(1, "invalid transact2 word count");
                return -EINVAL;
        }
 
@@ -237,15 +238,15 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
        if (remaining == 0)
                return 0;
        else if (remaining < 0) {
-               cFYI(1, ("total data %d smaller than data in frame %d",
-                       total_data_size, data_in_this_rsp));
+               cFYI(1, "total data %d smaller than data in frame %d",
+                       total_data_size, data_in_this_rsp);
                return -EINVAL;
        } else {
-               cFYI(1, ("missing %d bytes from transact2, check next response",
-                       remaining));
+               cFYI(1, "missing %d bytes from transact2, check next response",
+                       remaining);
                if (total_data_size > maxBufSize) {
-                       cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
-                               total_data_size, maxBufSize));
+                       cERROR(1, "TotalDataSize %d is over maximum buffer %d",
+                               total_data_size, maxBufSize);
                        return -EINVAL;
                }
                return remaining;
@@ -267,7 +268,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
        total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
 
        if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
-               cFYI(1, ("total data size of primary and secondary t2 differ"));
+               cFYI(1, "total data size of primary and secondary t2 differ");
        }
 
        total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
@@ -282,7 +283,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
 
        total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
        if (remaining < total_in_buf2) {
-               cFYI(1, ("transact2 2nd response contains too much data"));
+               cFYI(1, "transact2 2nd response contains too much data");
        }
 
        /* find end of first SMB data area */
@@ -311,7 +312,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
        pTargetSMB->smb_buf_length = byte_count;
 
        if (remaining == total_in_buf2) {
-               cFYI(1, ("found the last secondary response"));
+               cFYI(1, "found the last secondary response");
                return 0; /* we are done */
        } else /* more responses to go */
                return 1;
@@ -339,7 +340,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
        int reconnect;
 
        current->flags |= PF_MEMALLOC;
-       cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
+       cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
 
        length = atomic_inc_return(&tcpSesAllocCount);
        if (length > 1)
@@ -353,7 +354,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                if (bigbuf == NULL) {
                        bigbuf = cifs_buf_get();
                        if (!bigbuf) {
-                               cERROR(1, ("No memory for large SMB response"));
+                               cERROR(1, "No memory for large SMB response");
                                msleep(3000);
                                /* retry will check if exiting */
                                continue;
@@ -366,7 +367,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                if (smallbuf == NULL) {
                        smallbuf = cifs_small_buf_get();
                        if (!smallbuf) {
-                               cERROR(1, ("No memory for SMB response"));
+                               cERROR(1, "No memory for SMB response");
                                msleep(1000);
                                /* retry will check if exiting */
                                continue;
@@ -391,9 +392,9 @@ incomplete_rcv:
                if (server->tcpStatus == CifsExiting) {
                        break;
                } else if (server->tcpStatus == CifsNeedReconnect) {
-                       cFYI(1, ("Reconnect after server stopped responding"));
+                       cFYI(1, "Reconnect after server stopped responding");
                        cifs_reconnect(server);
-                       cFYI(1, ("call to reconnect done"));
+                       cFYI(1, "call to reconnect done");
                        csocket = server->ssocket;
                        continue;
                } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
@@ -411,7 +412,7 @@ incomplete_rcv:
                                continue;
                } else if (length <= 0) {
                        if (server->tcpStatus == CifsNew) {
-                               cFYI(1, ("tcp session abend after SMBnegprot"));
+                               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,
@@ -419,18 +420,18 @@ incomplete_rcv:
                                break;
                        }
                        if (!try_to_freeze() && (length == -EINTR)) {
-                               cFYI(1, ("cifsd thread killed"));
+                               cFYI(1, "cifsd thread killed");
                                break;
                        }
-                       cFYI(1, ("Reconnect after unexpected peek error %d",
-                               length));
+                       cFYI(1, "Reconnect after unexpected peek error %d",
+                               length);
                        cifs_reconnect(server);
                        csocket = server->ssocket;
                        wake_up(&server->response_q);
                        continue;
                } else if (length < pdu_length) {
-                       cFYI(1, ("requested %d bytes but only got %d bytes",
-                                 pdu_length, length));
+                       cFYI(1, "requested %d bytes but only got %d bytes",
+                                 pdu_length, length);
                        pdu_length -= length;
                        msleep(1);
                        goto incomplete_rcv;
@@ -450,18 +451,18 @@ incomplete_rcv:
                pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
                smb_buffer->smb_buf_length = pdu_length;
 
-               cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
+               cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
 
                if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
                        continue;
                } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
-                       cFYI(1, ("Good RFC 1002 session rsp"));
+                       cFYI(1, "Good RFC 1002 session rsp");
                        continue;
                } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
                        /* we get this from Windows 98 instead of
                           an error on SMB negprot response */
-                       cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
-                               pdu_length));
+                       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
@@ -484,7 +485,7 @@ incomplete_rcv:
                                continue;
                        }
                } else if (temp != (char) 0) {
-                       cERROR(1, ("Unknown RFC 1002 frame"));
+                       cERROR(1, "Unknown RFC 1002 frame");
                        cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
                                      length);
                        cifs_reconnect(server);
@@ -495,8 +496,8 @@ incomplete_rcv:
                /* else we have an SMB response */
                if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
                            (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
-                       cERROR(1, ("Invalid size SMB length %d pdu_length %d",
-                                       length, pdu_length+4));
+                       cERROR(1, "Invalid size SMB length %d pdu_length %d",
+                                       length, pdu_length+4);
                        cifs_reconnect(server);
                        csocket = server->ssocket;
                        wake_up(&server->response_q);
@@ -539,8 +540,8 @@ incomplete_rcv:
                                length = 0;
                                continue;
                        } else if (length <= 0) {
-                               cERROR(1, ("Received no data, expecting %d",
-                                             pdu_length - total_read));
+                               cERROR(1, "Received no data, expecting %d",
+                                             pdu_length - total_read);
                                cifs_reconnect(server);
                                csocket = server->ssocket;
                                reconnect = 1;
@@ -588,7 +589,7 @@ incomplete_rcv:
                                                }
                                        } else {
                                                if (!isLargeBuf) {
-                                                       cERROR(1,("1st trans2 resp needs bigbuf"));
+                                                       cERROR(1, "1st trans2 resp needs bigbuf");
                                        /* BB maybe we can fix this up,  switch
                                           to already allocated large buffer? */
                                                } else {
@@ -630,8 +631,8 @@ multi_t2_fnd:
                        wake_up_process(task_to_wake);
                } else if (!is_valid_oplock_break(smb_buffer, server) &&
                           !isMultiRsp) {
-                       cERROR(1, ("No task to wake, unknown frame received! "
-                                  "NumMids %d", midCount.counter));
+                       cERROR(1, "No task to wake, unknown frame received! "
+                                  "NumMids %d", midCount.counter);
                        cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
                                      sizeof(struct smb_hdr));
 #ifdef CONFIG_CIFS_DEBUG2
@@ -708,8 +709,8 @@ multi_t2_fnd:
                list_for_each(tmp, &server->pending_mid_q) {
                mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
                        if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
-                               cFYI(1, ("Clearing Mid 0x%x - waking up ",
-                                        mid_entry->mid));
+                               cFYI(1, "Clearing Mid 0x%x - waking up ",
+                                        mid_entry->mid);
                                task_to_wake = mid_entry->tsk;
                                if (task_to_wake)
                                        wake_up_process(task_to_wake);
@@ -728,7 +729,7 @@ multi_t2_fnd:
                to wait at least 45 seconds before giving up
                on a request getting a response and going ahead
                and killing cifsd */
-               cFYI(1, ("Wait for exit from demultiplex thread"));
+               cFYI(1, "Wait for exit from demultiplex thread");
                msleep(46000);
                /* if threads still have not exited they are probably never
                coming home not much else we can do but free the memory */
@@ -849,7 +850,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        separator[0] = options[4];
                        options += 5;
                } else {
-                       cFYI(1, ("Null separator not allowed"));
+                       cFYI(1, "Null separator not allowed");
                }
        }
 
@@ -974,7 +975,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        }
                } else if (strnicmp(data, "sec", 3) == 0) {
                        if (!value || !*value) {
-                               cERROR(1, ("no security value specified"));
+                               cERROR(1, "no security value specified");
                                continue;
                        } else if (strnicmp(value, "krb5i", 5) == 0) {
                                vol->secFlg |= CIFSSEC_MAY_KRB5 |
@@ -982,7 +983,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        } else if (strnicmp(value, "krb5p", 5) == 0) {
                                /* vol->secFlg |= CIFSSEC_MUST_SEAL |
                                        CIFSSEC_MAY_KRB5; */
-                               cERROR(1, ("Krb5 cifs privacy not supported"));
+                               cERROR(1, "Krb5 cifs privacy not supported");
                                return 1;
                        } else if (strnicmp(value, "krb5", 4) == 0) {
                                vol->secFlg |= CIFSSEC_MAY_KRB5;
@@ -1014,7 +1015,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        } else if (strnicmp(value, "none", 4) == 0) {
                                vol->nullauth = 1;
                        } else {
-                               cERROR(1, ("bad security option: %s", value));
+                               cERROR(1, "bad security option: %s", value);
                                return 1;
                        }
                } else if ((strnicmp(data, "unc", 3) == 0)
@@ -1053,7 +1054,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                        a domain name and need special handling? */
                        if (strnlen(value, 256) < 256) {
                                vol->domainname = value;
-                               cFYI(1, ("Domain name set"));
+                               cFYI(1, "Domain name set");
                        } else {
                                printk(KERN_WARNING "CIFS: domain name too "
                                                    "long\n");
@@ -1076,7 +1077,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        strcpy(vol->prepath+1, value);
                                } else
                                        strcpy(vol->prepath, value);
-                               cFYI(1, ("prefix path %s", vol->prepath));
+                               cFYI(1, "prefix path %s", vol->prepath);
                        } else {
                                printk(KERN_WARNING "CIFS: prefix too long\n");
                                return 1;
@@ -1092,7 +1093,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        vol->iocharset = value;
                                /* if iocharset not set then load_nls_default
                                   is used by caller */
-                               cFYI(1, ("iocharset set to %s", value));
+                               cFYI(1, "iocharset set to %s", value);
                        } else {
                                printk(KERN_WARNING "CIFS: iocharset name "
                                                    "too long.\n");
@@ -1144,14 +1145,14 @@ cifs_parse_mount_options(char *options, const char *devname,
                        }
                } else if (strnicmp(data, "sockopt", 5) == 0) {
                        if (!value || !*value) {
-                               cERROR(1, ("no socket option specified"));
+                               cERROR(1, "no socket option specified");
                                continue;
                        } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
                                vol->sockopt_tcp_nodelay = 1;
                        }
                } else if (strnicmp(data, "netbiosname", 4) == 0) {
                        if (!value || !*value || (*value == ' ')) {
-                               cFYI(1, ("invalid (empty) netbiosname"));
+                               cFYI(1, "invalid (empty) netbiosname");
                        } else {
                                memset(vol->source_rfc1001_name, 0x20, 15);
                                for (i = 0; i < 15; i++) {
@@ -1175,7 +1176,7 @@ cifs_parse_mount_options(char *options, const char *devname,
                } else if (strnicmp(data, "servern", 7) == 0) {
                        /* servernetbiosname specified override *SMBSERVER */
                        if (!value || !*value || (*value == ' ')) {
-                               cFYI(1, ("empty server netbiosname specified"));
+                               cFYI(1, "empty server netbiosname specified");
                        } else {
                                /* last byte, type, is 0x20 for servr type */
                                memset(vol->target_rfc1001_name, 0x20, 16);
@@ -1434,7 +1435,7 @@ cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
 
                ++server->srv_count;
                write_unlock(&cifs_tcp_ses_lock);
-               cFYI(1, ("Existing tcp session with server found"));
+               cFYI(1, "Existing tcp session with server found");
                return server;
        }
        write_unlock(&cifs_tcp_ses_lock);
@@ -1475,7 +1476,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 
        memset(&addr, 0, sizeof(struct sockaddr_storage));
 
-       cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip));
+       cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
 
        if (volume_info->UNCip && volume_info->UNC) {
                rc = cifs_convert_address(volume_info->UNCip, &addr);
@@ -1487,13 +1488,12 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        } else if (volume_info->UNCip) {
                /* BB using ip addr as tcp_ses name to connect to the
                   DFS root below */
-               cERROR(1, ("Connecting to DFS root not implemented yet"));
+               cERROR(1, "Connecting to DFS root not implemented yet");
                rc = -EINVAL;
                goto out_err;
        } else /* which tcp_sess DFS root would we conect to */ {
-               cERROR(1,
-                      ("CIFS mount error: No UNC path (e.g. -o "
-                       "unc=//192.168.1.100/public) specified"));
+               cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
+                       "unc=//192.168.1.100/public) specified");
                rc = -EINVAL;
                goto out_err;
        }
@@ -1540,7 +1540,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
        ++tcp_ses->srv_count;
 
        if (addr.ss_family == AF_INET6) {
-               cFYI(1, ("attempting ipv6 connect"));
+               cFYI(1, "attempting ipv6 connect");
                /* BB should we allow ipv6 on port 139? */
                /* other OS never observed in Wild doing 139 with v6 */
                sin_server6->sin6_port = htons(volume_info->port);
@@ -1554,7 +1554,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                rc = ipv4_connect(tcp_ses);
        }
        if (rc < 0) {
-               cERROR(1, ("Error connecting to socket. Aborting operation"));
+               cERROR(1, "Error connecting to socket. Aborting operation");
                goto out_err;
        }
 
@@ -1567,7 +1567,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                                  tcp_ses, "cifsd");
        if (IS_ERR(tcp_ses->tsk)) {
                rc = PTR_ERR(tcp_ses->tsk);
-               cERROR(1, ("error %d create cifsd thread", rc));
+               cERROR(1, "error %d create cifsd thread", rc);
                module_put(THIS_MODULE);
                goto out_err;
        }
@@ -1616,6 +1616,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
        int xid;
        struct TCP_Server_Info *server = ses->server;
 
+       cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
        write_lock(&cifs_tcp_ses_lock);
        if (--ses->ses_count > 0) {
                write_unlock(&cifs_tcp_ses_lock);
@@ -1634,6 +1635,102 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
        cifs_put_tcp_session(server);
 }
 
+static struct cifsSesInfo *
+cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
+{
+       int rc = -ENOMEM, xid;
+       struct cifsSesInfo *ses;
+
+       xid = GetXid();
+
+       ses = cifs_find_smb_ses(server, volume_info->username);
+       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) {
+                       mutex_unlock(&ses->session_mutex);
+                       /* problem -- put our ses reference */
+                       cifs_put_smb_ses(ses);
+                       FreeXid(xid);
+                       return ERR_PTR(rc);
+               }
+               if (ses->need_reconnect) {
+                       cFYI(1, "Session needs reconnect");
+                       rc = cifs_setup_session(xid, ses,
+                                               volume_info->local_nls);
+                       if (rc) {
+                               mutex_unlock(&ses->session_mutex);
+                               /* problem -- put our reference */
+                               cifs_put_smb_ses(ses);
+                               FreeXid(xid);
+                               return ERR_PTR(rc);
+                       }
+               }
+               mutex_unlock(&ses->session_mutex);
+               FreeXid(xid);
+               return ses;
+       }
+
+       cFYI(1, "Existing smb sess not found");
+       ses = sesInfoAlloc();
+       if (ses == NULL)
+               goto get_ses_fail;
+
+       /* new SMB session uses our server ref */
+       ses->server = server;
+       if (server->addr.sockAddr6.sin6_family == AF_INET6)
+               sprintf(ses->serverName, "%pI6",
+                       &server->addr.sockAddr6.sin6_addr);
+       else
+               sprintf(ses->serverName, "%pI4",
+                       &server->addr.sockAddr.sin_addr.s_addr);
+
+       if (volume_info->username)
+               strncpy(ses->userName, volume_info->username,
+                       MAX_USERNAME_SIZE);
+
+       /* volume_info->password freed at unmount */
+       if (volume_info->password) {
+               ses->password = kstrdup(volume_info->password, GFP_KERNEL);
+               if (!ses->password)
+                       goto get_ses_fail;
+       }
+       if (volume_info->domainname) {
+               int len = strlen(volume_info->domainname);
+               ses->domainName = kmalloc(len + 1, GFP_KERNEL);
+               if (ses->domainName)
+                       strcpy(ses->domainName, volume_info->domainname);
+       }
+       ses->linux_uid = volume_info->linux_uid;
+       ses->overrideSecFlg = volume_info->secFlg;
+
+       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)
+               goto get_ses_fail;
+
+       /* success, put it on the list */
+       write_lock(&cifs_tcp_ses_lock);
+       list_add(&ses->smb_ses_list, &server->smb_ses_list);
+       write_unlock(&cifs_tcp_ses_lock);
+
+       FreeXid(xid);
+       return ses;
+
+get_ses_fail:
+       sesInfoFree(ses);
+       FreeXid(xid);
+       return ERR_PTR(rc);
+}
+
 static struct cifsTconInfo *
 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
 {
@@ -1662,6 +1759,7 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
        int xid;
        struct cifsSesInfo *ses = tcon->ses;
 
+       cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
        write_lock(&cifs_tcp_ses_lock);
        if (--tcon->tc_count > 0) {
                write_unlock(&cifs_tcp_ses_lock);
@@ -1679,6 +1777,80 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
        cifs_put_smb_ses(ses);
 }
 
+static struct cifsTconInfo *
+cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
+{
+       int rc, xid;
+       struct cifsTconInfo *tcon;
+
+       tcon = cifs_find_tcon(ses, volume_info->UNC);
+       if (tcon) {
+               cFYI(1, "Found match on UNC path");
+               /* existing tcon already has a reference */
+               cifs_put_smb_ses(ses);
+               if (tcon->seal != volume_info->seal)
+                       cERROR(1, "transport encryption setting "
+                                  "conflicts with existing tid");
+               return tcon;
+       }
+
+       tcon = tconInfoAlloc();
+       if (tcon == NULL) {
+               rc = -ENOMEM;
+               goto out_fail;
+       }
+
+       tcon->ses = ses;
+       if (volume_info->password) {
+               tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
+               if (!tcon->password) {
+                       rc = -ENOMEM;
+                       goto out_fail;
+               }
+       }
+
+       if (strchr(volume_info->UNC + 3, '\\') == NULL
+           && strchr(volume_info->UNC + 3, '/') == NULL) {
+               cERROR(1, "Missing share name");
+               rc = -ENODEV;
+               goto out_fail;
+       }
+
+       /* BB Do we need to wrap session_mutex around
+        * this TCon call and Unix SetFS as
+        * we do on SessSetup and reconnect? */
+       xid = GetXid();
+       rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
+       FreeXid(xid);
+       cFYI(1, "CIFS Tcon rc = %d", rc);
+       if (rc)
+               goto out_fail;
+
+       if (volume_info->nodfs) {
+               tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
+               cFYI(1, "DFS disabled (%d)", tcon->Flags);
+       }
+       tcon->seal = volume_info->seal;
+       /* we can have only one retry value for a connection
+          to a share so for resources mounted more than once
+          to the same server share the last value passed in
+          for the retry flag is used */
+       tcon->retry = volume_info->retry;
+       tcon->nocase = volume_info->nocase;
+       tcon->local_lease = volume_info->local_lease;
+
+       write_lock(&cifs_tcp_ses_lock);
+       list_add(&tcon->tcon_list, &ses->tcon_list);
+       write_unlock(&cifs_tcp_ses_lock);
+
+       return tcon;
+
+out_fail:
+       tconInfoFree(tcon);
+       return ERR_PTR(rc);
+}
+
+
 int
 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
             const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
@@ -1703,8 +1875,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
                strcpy(temp_unc + 2, pSesInfo->serverName);
                strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
                rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
-               cFYI(1,
-                    ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
+               cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
                kfree(temp_unc);
        }
        if (rc == 0)
@@ -1777,12 +1948,12 @@ ipv4_connect(struct TCP_Server_Info *server)
                rc = sock_create_kern(PF_INET, SOCK_STREAM,
                                      IPPROTO_TCP, &socket);
                if (rc < 0) {
-                       cERROR(1, ("Error %d creating socket", rc));
+                       cERROR(1, "Error %d creating socket", rc);
                        return rc;
                }
 
                /* BB other socket options to set KEEPALIVE, NODELAY? */
-               cFYI(1, ("Socket created"));
+               cFYI(1, "Socket created");
                server->ssocket = socket;
                socket->sk->sk_allocation = GFP_NOFS;
                cifs_reclassify_socket4(socket);
@@ -1827,7 +1998,7 @@ ipv4_connect(struct TCP_Server_Info *server)
        if (!connected) {
                if (orig_port)
                        server->addr.sockAddr.sin_port = orig_port;
-               cFYI(1, ("Error %d connecting to server via ipv4", rc));
+               cFYI(1, "Error %d connecting to server via ipv4", rc);
                sock_release(socket);
                server->ssocket = NULL;
                return rc;
@@ -1855,12 +2026,12 @@ ipv4_connect(struct TCP_Server_Info *server)
                rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
                                (char *)&val, sizeof(val));
                if (rc)
-                       cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
+                       cFYI(1, "set TCP_NODELAY socket option error %d", rc);
        }
 
-        cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
+        cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
                 socket->sk->sk_sndbuf,
-                socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
+                socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
 
        /* send RFC1001 sessinit */
        if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
@@ -1938,13 +2109,13 @@ ipv6_connect(struct TCP_Server_Info *server)
                rc = sock_create_kern(PF_INET6, SOCK_STREAM,
                                      IPPROTO_TCP, &socket);
                if (rc < 0) {
-                       cERROR(1, ("Error %d creating ipv6 socket", rc));
+                       cERROR(1, "Error %d creating ipv6 socket", rc);
                        socket = NULL;
                        return rc;
                }
 
                /* BB other socket options to set KEEPALIVE, NODELAY? */
-               cFYI(1, ("ipv6 Socket created"));
+               cFYI(1, "ipv6 Socket created");
                server->ssocket = socket;
                socket->sk->sk_allocation = GFP_NOFS;
                cifs_reclassify_socket6(socket);
@@ -1988,7 +2159,7 @@ ipv6_connect(struct TCP_Server_Info *server)
        if (!connected) {
                if (orig_port)
                        server->addr.sockAddr6.sin6_port = orig_port;
-               cFYI(1, ("Error %d connecting to server via ipv6", rc));
+               cFYI(1, "Error %d connecting to server via ipv6", rc);
                sock_release(socket);
                server->ssocket = NULL;
                return rc;
@@ -2007,7 +2178,7 @@ ipv6_connect(struct TCP_Server_Info *server)
                rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
                                (char *)&val, sizeof(val));
                if (rc)
-                       cFYI(1, ("set TCP_NODELAY socket option error %d", rc));
+                       cFYI(1, "set TCP_NODELAY socket option error %d", rc);
        }
 
        server->ssocket = socket;
@@ -2032,13 +2203,13 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
        if (vol_info && vol_info->no_linux_ext) {
                tcon->fsUnixInfo.Capability = 0;
                tcon->unix_ext = 0; /* Unix Extensions disabled */
-               cFYI(1, ("Linux protocol extensions disabled"));
+               cFYI(1, "Linux protocol extensions disabled");
                return;
        } else if (vol_info)
                tcon->unix_ext = 1; /* Unix Extensions supported */
 
        if (tcon->unix_ext == 0) {
-               cFYI(1, ("Unix extensions disabled so not set on reconnect"));
+               cFYI(1, "Unix extensions disabled so not set on reconnect");
                return;
        }
 
@@ -2054,12 +2225,11 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                                cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
                        if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
                                if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
-                                       cERROR(1, ("POSIXPATH support change"));
+                                       cERROR(1, "POSIXPATH support change");
                                cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
                        } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
-                               cERROR(1, ("possible reconnect error"));
-                               cERROR(1,
-                                       ("server disabled POSIX path support"));
+                               cERROR(1, "possible reconnect error");
+                               cERROR(1, "server disabled POSIX path support");
                        }
                }
 
@@ -2067,7 +2237,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                if (vol_info && vol_info->no_psx_acl)
                        cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
                else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
-                       cFYI(1, ("negotiated posix acl support"));
+                       cFYI(1, "negotiated posix acl support");
                        if (sb)
                                sb->s_flags |= MS_POSIXACL;
                }
@@ -2075,7 +2245,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                if (vol_info && vol_info->posix_paths == 0)
                        cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
                else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
-                       cFYI(1, ("negotiate posix pathnames"));
+                       cFYI(1, "negotiate posix pathnames");
                        if (sb)
                                CIFS_SB(sb)->mnt_cifs_flags |=
                                        CIFS_MOUNT_POSIX_PATHS;
@@ -2090,39 +2260,38 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
                if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
                        if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
                                CIFS_SB(sb)->rsize = 127 * 1024;
-                               cFYI(DBG2,
-                                       ("larger reads not supported by srv"));
+                               cFYI(DBG2, "larger reads not supported by srv");
                        }
                }
 
 
-               cFYI(1, ("Negotiate caps 0x%x", (int)cap));
+               cFYI(1, "Negotiate caps 0x%x", (int)cap);
 #ifdef CONFIG_CIFS_DEBUG2
                if (cap & CIFS_UNIX_FCNTL_CAP)
-                       cFYI(1, ("FCNTL cap"));
+                       cFYI(1, "FCNTL cap");
                if (cap & CIFS_UNIX_EXTATTR_CAP)
-                       cFYI(1, ("EXTATTR cap"));
+                       cFYI(1, "EXTATTR cap");
                if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
-                       cFYI(1, ("POSIX path cap"));
+                       cFYI(1, "POSIX path cap");
                if (cap & CIFS_UNIX_XATTR_CAP)
-                       cFYI(1, ("XATTR cap"));
+                       cFYI(1, "XATTR cap");
                if (cap & CIFS_UNIX_POSIX_ACL_CAP)
-                       cFYI(1, ("POSIX ACL cap"));
+                       cFYI(1, "POSIX ACL cap");
                if (cap & CIFS_UNIX_LARGE_READ_CAP)
-                       cFYI(1, ("very large read cap"));
+                       cFYI(1, "very large read cap");
                if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
-                       cFYI(1, ("very large write cap"));
+                       cFYI(1, "very large write cap");
 #endif /* CIFS_DEBUG2 */
                if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
                        if (vol_info == NULL) {
-                               cFYI(1, ("resetting capabilities failed"));
+                               cFYI(1, "resetting capabilities failed");
                        } else
-                               cERROR(1, ("Negotiating Unix capabilities "
+                               cERROR(1, "Negotiating Unix capabilities "
                                           "with the server failed.  Consider "
                                           "mounting with the Unix Extensions\n"
                                           "disabled, if problems are found, "
                                           "by specifying the nounix mount "
-                                          "option."));
+                                          "option.");
 
                }
        }
@@ -2152,8 +2321,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
                          struct cifs_sb_info *cifs_sb)
 {
        if (pvolume_info->rsize > CIFSMaxBufSize) {
-               cERROR(1, ("rsize %d too large, using MaxBufSize",
-                       pvolume_info->rsize));
+               cERROR(1, "rsize %d too large, using MaxBufSize",
+                       pvolume_info->rsize);
                cifs_sb->rsize = CIFSMaxBufSize;
        } else if ((pvolume_info->rsize) &&
                        (pvolume_info->rsize <= CIFSMaxBufSize))
@@ -2162,8 +2331,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
                cifs_sb->rsize = CIFSMaxBufSize;
 
        if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
-               cERROR(1, ("wsize %d too large, using 4096 instead",
-                         pvolume_info->wsize));
+               cERROR(1, "wsize %d too large, using 4096 instead",
+                         pvolume_info->wsize);
                cifs_sb->wsize = 4096;
        } else if (pvolume_info->wsize)
                cifs_sb->wsize = pvolume_info->wsize;
@@ -2181,7 +2350,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        if (cifs_sb->rsize < 2048) {
                cifs_sb->rsize = 2048;
                /* Windows ME may prefer this */
-               cFYI(1, ("readsize set to minimum: 2048"));
+               cFYI(1, "readsize set to minimum: 2048");
        }
        /* calculate prepath */
        cifs_sb->prepath = pvolume_info->prepath;
@@ -2199,8 +2368,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        cifs_sb->mnt_gid = pvolume_info->linux_gid;
        cifs_sb->mnt_file_mode = pvolume_info->file_mode;
        cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
-       cFYI(1, ("file mode: 0x%x  dir mode: 0x%x",
-               cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
+       cFYI(1, "file mode: 0x%x  dir mode: 0x%x",
+               cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
 
        if (pvolume_info->noperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -2229,13 +2398,13 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        if (pvolume_info->dynperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
        if (pvolume_info->direct_io) {
-               cFYI(1, ("mounting share using direct i/o"));
+               cFYI(1, "mounting share using direct i/o");
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
        }
 
        if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
-               cERROR(1, ("mount option dynperm ignored if cifsacl "
-                          "mount option supported"));
+               cERROR(1, "mount option dynperm ignored if cifsacl "
+                          "mount option supported");
 }
 
 static int
@@ -2262,7 +2431,7 @@ cleanup_volume_info(struct smb_vol **pvolume_info)
 {
        struct smb_vol *volume_info;
 
-       if (!pvolume_info && !*pvolume_info)
+       if (!pvolume_info || !*pvolume_info)
                return;
 
        volume_info = *pvolume_info;
@@ -2344,11 +2513,11 @@ try_mount_again:
        }
 
        if (volume_info->nullauth) {
-               cFYI(1, ("null user"));
+               cFYI(1, "null user");
                volume_info->username = "";
        } else if (volume_info->username) {
                /* BB fixme parse for domain name here */
-               cFYI(1, ("Username: %s", volume_info->username));
+               cFYI(1, "Username: %s", volume_info->username);
        } else {
                cifserror("No username specified");
        /* In userspace mount helper we can get user name from alternate
@@ -2357,20 +2526,20 @@ try_mount_again:
                goto out;
        }
 
-
        /* this is needed for ASCII cp to Unicode converts */
        if (volume_info->iocharset == NULL) {
-               cifs_sb->local_nls = load_nls_default();
-       /* load_nls_default can not return null */
+               /* load_nls_default cannot return null */
+               volume_info->local_nls = load_nls_default();
        } else {
-               cifs_sb->local_nls = load_nls(volume_info->iocharset);
-               if (cifs_sb->local_nls == NULL) {
-                       cERROR(1, ("CIFS mount error: iocharset %s not found",
-                                volume_info->iocharset));
+               volume_info->local_nls = load_nls(volume_info->iocharset);
+               if (volume_info->local_nls == NULL) {
+                       cERROR(1, "CIFS mount error: iocharset %s not found",
+                                volume_info->iocharset);
                        rc = -ELIBACC;
                        goto out;
                }
        }
+       cifs_sb->local_nls = volume_info->local_nls;
 
        /* get a reference to a tcp session */
        srvTcp = cifs_get_tcp_session(volume_info);
@@ -2379,148 +2548,30 @@ try_mount_again:
                goto out;
        }
 
-       pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
-       if (pSesInfo) {
-               cFYI(1, ("Existing smb sess found (status=%d)",
-                       pSesInfo->status));
-               /*
-                * The existing SMB session already has a reference to srvTcp,
-                * so we can put back the extra one we got before
-                */
-               cifs_put_tcp_session(srvTcp);
-
-               mutex_lock(&pSesInfo->session_mutex);
-               if (pSesInfo->need_reconnect) {
-                       cFYI(1, ("Session needs reconnect"));
-                       rc = cifs_setup_session(xid, pSesInfo,
-                                               cifs_sb->local_nls);
-               }
-               mutex_unlock(&pSesInfo->session_mutex);
-       } else if (!rc) {
-               cFYI(1, ("Existing smb sess not found"));
-               pSesInfo = sesInfoAlloc();
-               if (pSesInfo == NULL) {
-                       rc = -ENOMEM;
-                       goto mount_fail_check;
-               }
-
-               /* new SMB session uses our srvTcp ref */
-               pSesInfo->server = srvTcp;
-               if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
-                       sprintf(pSesInfo->serverName, "%pI6",
-                               &srvTcp->addr.sockAddr6.sin6_addr);
-               else
-                       sprintf(pSesInfo->serverName, "%pI4",
-                               &srvTcp->addr.sockAddr.sin_addr.s_addr);
-
-               write_lock(&cifs_tcp_ses_lock);
-               list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
-               write_unlock(&cifs_tcp_ses_lock);
-
-               /* volume_info->password freed at unmount */
-               if (volume_info->password) {
-                       pSesInfo->password = kstrdup(volume_info->password,
-                                                    GFP_KERNEL);
-                       if (!pSesInfo->password) {
-                               rc = -ENOMEM;
-                               goto mount_fail_check;
-                       }
-               }
-               if (volume_info->username)
-                       strncpy(pSesInfo->userName, volume_info->username,
-                               MAX_USERNAME_SIZE);
-               if (volume_info->domainname) {
-                       int len = strlen(volume_info->domainname);
-                       pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
-                       if (pSesInfo->domainName)
-                               strcpy(pSesInfo->domainName,
-                                       volume_info->domainname);
-               }
-               pSesInfo->linux_uid = volume_info->linux_uid;
-               pSesInfo->overrideSecFlg = volume_info->secFlg;
-               mutex_lock(&pSesInfo->session_mutex);
-
-               /* BB FIXME need to pass vol->secFlgs BB */
-               rc = cifs_setup_session(xid, pSesInfo,
-                                       cifs_sb->local_nls);
-               mutex_unlock(&pSesInfo->session_mutex);
+       /* get a reference to a SMB session */
+       pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
+       if (IS_ERR(pSesInfo)) {
+               rc = PTR_ERR(pSesInfo);
+               pSesInfo = NULL;
+               goto mount_fail_check;
        }
 
-       /* search for existing tcon to this server share */
-       if (!rc) {
-               setup_cifs_sb(volume_info, cifs_sb);
-
-               tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
-               if (tcon) {
-                       cFYI(1, ("Found match on UNC path"));
-                       /* existing tcon already has a reference */
-                       cifs_put_smb_ses(pSesInfo);
-                       if (tcon->seal != volume_info->seal)
-                               cERROR(1, ("transport encryption setting "
-                                          "conflicts with existing tid"));
-               } else {
-                       tcon = tconInfoAlloc();
-                       if (tcon == NULL) {
-                               rc = -ENOMEM;
-                               goto mount_fail_check;
-                       }
-
-                       tcon->ses = pSesInfo;
-                       if (volume_info->password) {
-                               tcon->password = kstrdup(volume_info->password,
-                                                        GFP_KERNEL);
-                               if (!tcon->password) {
-                                       rc = -ENOMEM;
-                                       goto mount_fail_check;
-                               }
-                       }
-
-                       if ((strchr(volume_info->UNC + 3, '\\') == NULL)
-                           && (strchr(volume_info->UNC + 3, '/') == NULL)) {
-                               cERROR(1, ("Missing share name"));
-                               rc = -ENODEV;
-                               goto mount_fail_check;
-                       } else {
-                               /* BB Do we need to wrap sesSem around
-                                * this TCon call and Unix SetFS as
-                                * we do on SessSetup and reconnect? */
-                               rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
-                                             tcon, cifs_sb->local_nls);
-                               cFYI(1, ("CIFS Tcon rc = %d", rc));
-                               if (volume_info->nodfs) {
-                                       tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
-                                       cFYI(1, ("DFS disabled (%d)",
-                                               tcon->Flags));
-                               }
-                       }
-                       if (rc)
-                               goto remote_path_check;
-                       tcon->seal = volume_info->seal;
-                       write_lock(&cifs_tcp_ses_lock);
-                       list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
-                       write_unlock(&cifs_tcp_ses_lock);
-               }
-
-               /* we can have only one retry value for a connection
-                  to a share so for resources mounted more than once
-                  to the same server share the last value passed in
-                  for the retry flag is used */
-               tcon->retry = volume_info->retry;
-               tcon->nocase = volume_info->nocase;
-               tcon->local_lease = volume_info->local_lease;
-       }
-       if (pSesInfo) {
-               if (pSesInfo->capabilities & CAP_LARGE_FILES)
-                       sb->s_maxbytes = MAX_LFS_FILESIZE;
-               else
-                       sb->s_maxbytes = MAX_NON_LFS;
-       }
+       setup_cifs_sb(volume_info, cifs_sb);
+       if (pSesInfo->capabilities & CAP_LARGE_FILES)
+               sb->s_maxbytes = MAX_LFS_FILESIZE;
+       else
+               sb->s_maxbytes = MAX_NON_LFS;
 
        /* BB FIXME fix time_gran to be larger for LANMAN sessions */
        sb->s_time_gran = 100;
 
-       if (rc)
+       /* search for existing tcon to this server share */
+       tcon = cifs_get_tcon(pSesInfo, volume_info);
+       if (IS_ERR(tcon)) {
+               rc = PTR_ERR(tcon);
+               tcon = NULL;
                goto remote_path_check;
+       }
 
        cifs_sb->tcon = tcon;
 
@@ -2544,7 +2595,7 @@ try_mount_again:
 
        if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
                cifs_sb->rsize = 1024 * 127;
-               cFYI(DBG2, ("no very large read support, rsize now 127K"));
+               cFYI(DBG2, "no very large read support, rsize now 127K");
        }
        if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
                cifs_sb->wsize = min(cifs_sb->wsize,
@@ -2593,7 +2644,7 @@ remote_path_check:
                        goto mount_fail_check;
                }
 
-               cFYI(1, ("Getting referral for: %s", full_path));
+               cFYI(1, "Getting referral for: %s", full_path);
                rc = get_dfs_path(xid, pSesInfo , full_path + 1,
                        cifs_sb->local_nls, &num_referrals, &referrals,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -2707,7 +2758,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                   by Samba (not sure whether other servers allow
                   NTLMv2 password here) */
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-               if ((extended_security & CIFSSEC_MAY_LANMAN) &&
+               if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
                    (ses->server->secType == LANMAN))
                        calc_lanman_hash(tcon->password, ses->server->cryptKey,
                                         ses->server->secMode &
@@ -2778,13 +2829,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                if (length == 3) {
                        if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
                            (bcc_ptr[2] == 'C')) {
-                               cFYI(1, ("IPC connection"));
+                               cFYI(1, "IPC connection");
                                tcon->ipc = 1;
                        }
                } else if (length == 2) {
                        if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
                                /* the most common case */
-                               cFYI(1, ("disk share connection"));
+                               cFYI(1, "disk share connection");
                        }
                }
                bcc_ptr += length + 1;
@@ -2797,7 +2848,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                                                      bytes_left, is_unicode,
                                                      nls_codepage);
 
-               cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem));
+               cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
 
                if ((smb_buffer_response->WordCount == 3) ||
                         (smb_buffer_response->WordCount == 7))
@@ -2805,7 +2856,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
                else
                        tcon->Flags = 0;
-               cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
+               cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
        } else if ((rc == 0) && tcon == NULL) {
                /* all we need to save for IPC$ connection */
                ses->ipc_tid = smb_buffer_response->Tid;
@@ -2833,57 +2884,61 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
        return rc;
 }
 
-int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
-                                          struct nls_table *nls_info)
+int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
 {
        int rc = 0;
-       int first_time = 0;
-       struct TCP_Server_Info *server = pSesInfo->server;
-
-       /* what if server changes its buffer size after dropping the session? */
-       if (server->maxBuf == 0) /* no need to send on reconnect */ {
-               rc = CIFSSMBNegotiate(xid, pSesInfo);
-               if (rc == -EAGAIN) {
-                       /* retry only once on 1st time connection */
-                       rc = CIFSSMBNegotiate(xid, pSesInfo);
-                       if (rc == -EAGAIN)
-                               rc = -EHOSTDOWN;
-               }
-               if (rc == 0) {
-                       spin_lock(&GlobalMid_Lock);
-                       if (server->tcpStatus != CifsExiting)
-                               server->tcpStatus = CifsGood;
-                       else
-                               rc = -EHOSTDOWN;
-                       spin_unlock(&GlobalMid_Lock);
+       struct TCP_Server_Info *server = ses->server;
+
+       /* only send once per connect */
+       if (server->maxBuf != 0)
+               return 0;
+
+       rc = CIFSSMBNegotiate(xid, ses);
+       if (rc == -EAGAIN) {
+               /* retry only once on 1st time connection */
+               rc = CIFSSMBNegotiate(xid, ses);
+               if (rc == -EAGAIN)
+                       rc = -EHOSTDOWN;
+       }
+       if (rc == 0) {
+               spin_lock(&GlobalMid_Lock);
+               if (server->tcpStatus != CifsExiting)
+                       server->tcpStatus = CifsGood;
+               else
+                       rc = -EHOSTDOWN;
+               spin_unlock(&GlobalMid_Lock);
 
-               }
-               first_time = 1;
        }
 
-       if (rc)
-               goto ss_err_exit;
+       return rc;
+}
+
+
+int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
+                       struct nls_table *nls_info)
+{
+       int rc = 0;
+       struct TCP_Server_Info *server = ses->server;
 
-       pSesInfo->flags = 0;
-       pSesInfo->capabilities = server->capabilities;
+       ses->flags = 0;
+       ses->capabilities = server->capabilities;
        if (linuxExtEnabled == 0)
-               pSesInfo->capabilities &= (~CAP_UNIX);
+               ses->capabilities &= (~CAP_UNIX);
 
-       cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
-                server->secMode, server->capabilities, server->timeAdj));
+       cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
+                server->secMode, server->capabilities, server->timeAdj);
 
-       rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
+       rc = CIFS_SessSetup(xid, ses, nls_info);
        if (rc) {
-               cERROR(1, ("Send error in SessSetup = %d", rc));
+               cERROR(1, "Send error in SessSetup = %d", rc);
        } else {
-               cFYI(1, ("CIFS Session Established successfully"));
+               cFYI(1, "CIFS Session Established successfully");
                spin_lock(&GlobalMid_Lock);
-               pSesInfo->status = CifsGood;
-               pSesInfo->need_reconnect = false;
+               ses->status = CifsGood;
+               ses->need_reconnect = false;
                spin_unlock(&GlobalMid_Lock);
        }
 
-ss_err_exit:
        return rc;
 }
 
index e9f7ecc..391816b 100644 (file)
@@ -73,7 +73,7 @@ cifs_bp_rename_retry:
                namelen += (1 + temp->d_name.len);
                temp = temp->d_parent;
                if (temp == NULL) {
-                       cERROR(1, ("corrupt dentry"));
+                       cERROR(1, "corrupt dentry");
                        return NULL;
                }
        }
@@ -90,19 +90,18 @@ cifs_bp_rename_retry:
                        full_path[namelen] = dirsep;
                        strncpy(full_path + namelen + 1, temp->d_name.name,
                                temp->d_name.len);
-                       cFYI(0, ("name: %s", full_path + namelen));
+                       cFYI(0, "name: %s", full_path + namelen);
                }
                temp = temp->d_parent;
                if (temp == NULL) {
-                       cERROR(1, ("corrupt dentry"));
+                       cERROR(1, "corrupt dentry");
                        kfree(full_path);
                        return NULL;
                }
        }
        if (namelen != pplen + dfsplen) {
-               cERROR(1,
-                      ("did not end path lookup where expected namelen is %d",
-                       namelen));
+               cERROR(1, "did not end path lookup where expected namelen is %d",
+                       namelen);
                /* presumably this is only possible if racing with a rename
                of one of the parent directories  (we can not lock the dentries
                above us to prevent this, but retrying should be harmless) */
@@ -130,6 +129,12 @@ cifs_bp_rename_retry:
        return full_path;
 }
 
+/*
+ * When called with struct file pointer set to NULL, there is no way we could
+ * update file->private_data, but getting it stuck on openFileList provides a
+ * way to access it from cifs_fill_filedata and thereby set file->private_data
+ * from cifs_open.
+ */
 struct cifsFileInfo *
 cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
                  struct file *file, struct vfsmount *mnt, unsigned int oflags)
@@ -173,7 +178,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
                if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                        pCifsInode->clientCanCacheAll = true;
                        pCifsInode->clientCanCacheRead = true;
-                       cFYI(1, ("Exclusive Oplock inode %p", newinode));
+                       cFYI(1, "Exclusive Oplock inode %p", newinode);
                } else if ((oplock & 0xF) == OPLOCK_READ)
                                pCifsInode->clientCanCacheRead = true;
        }
@@ -183,16 +188,17 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
 }
 
 int cifs_posix_open(char *full_path, struct inode **pinode,
-                   struct vfsmount *mnt, int mode, int oflags,
-                   __u32 *poplock, __u16 *pnetfid, int xid)
+                       struct vfsmount *mnt, struct super_block *sb,
+                       int mode, int oflags,
+                       __u32 *poplock, __u16 *pnetfid, int xid)
 {
        int rc;
        FILE_UNIX_BASIC_INFO *presp_data;
        __u32 posix_flags = 0;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct cifs_fattr fattr;
 
-       cFYI(1, ("posix open %s", full_path));
+       cFYI(1, "posix open %s", full_path);
 
        presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
        if (presp_data == NULL)
@@ -242,7 +248,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
 
        /* get new inode and set it up */
        if (*pinode == NULL) {
-               *pinode = cifs_iget(mnt->mnt_sb, &fattr);
+               cifs_fill_uniqueid(sb, &fattr);
+               *pinode = cifs_iget(sb, &fattr);
                if (!*pinode) {
                        rc = -ENOMEM;
                        goto posix_open_ret;
@@ -251,7 +258,18 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
                cifs_fattr_to_inode(*pinode, &fattr);
        }
 
-       cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
+       /*
+        * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to
+        * file->private_data.
+        */
+       if (mnt) {
+               struct cifsFileInfo *pfile_info;
+
+               pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt,
+                                              oflags);
+               if (pfile_info == NULL)
+                       rc = -ENOMEM;
+       }
 
 posix_open_ret:
        kfree(presp_data);
@@ -315,13 +333,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        if (nd && (nd->flags & LOOKUP_OPEN))
                oflags = nd->intent.open.flags;
        else
-               oflags = FMODE_READ;
+               oflags = FMODE_READ | SMB_O_CREAT;
 
        if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
-               rc = cifs_posix_open(full_path, &newinode, nd->path.mnt,
-                                    mode, oflags, &oplock, &fileHandle, xid);
+               rc = cifs_posix_open(full_path, &newinode,
+                       nd ? nd->path.mnt : NULL,
+                       inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
                /* EIO could indicate that (posix open) operation is not
                   supported, despite what server claimed in capability
                   negotation.  EREMOTE indicates DFS junction, which is not
@@ -358,7 +377,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                else if ((oflags & O_CREAT) == O_CREAT)
                        disposition = FILE_OPEN_IF;
                else
-                       cFYI(1, ("Create flag not set in create function"));
+                       cFYI(1, "Create flag not set in create function");
        }
 
        /* BB add processing to set equivalent of mode - e.g. via CreateX with
@@ -394,7 +413,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
        if (rc) {
-               cFYI(1, ("cifs_create returned 0x%x", rc));
+               cFYI(1, "cifs_create returned 0x%x", rc);
                goto cifs_create_out;
        }
 
@@ -457,15 +476,22 @@ cifs_create_set_dentry:
        if (rc == 0)
                setup_cifs_dentry(tcon, direntry, newinode);
        else
-               cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc));
+               cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
 
        /* nfsd case - nfs srv does not set nd */
        if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
                /* mknod case - do not leave file open */
                CIFSSMBClose(xid, tcon, fileHandle);
        } else if (!(posix_create) && (newinode)) {
-                       cifs_new_fileinfo(newinode, fileHandle, NULL,
-                                               nd->path.mnt, oflags);
+               struct cifsFileInfo *pfile_info;
+               /*
+                * cifs_fill_filedata() takes care of setting cifsFileInfo
+                * pointer to file->private_data.
+                */
+               pfile_info = cifs_new_fileinfo(newinode, fileHandle, NULL,
+                                              nd->path.mnt, oflags);
+               if (pfile_info == NULL)
+                       rc = -ENOMEM;
        }
 cifs_create_out:
        kfree(buf);
@@ -531,7 +557,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
                        u16 fileHandle;
                        FILE_ALL_INFO *buf;
 
-                       cFYI(1, ("sfu compat create special file"));
+                       cFYI(1, "sfu compat create special file");
 
                        buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
                        if (buf == NULL) {
@@ -616,8 +642,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 
        xid = GetXid();
 
-       cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p",
-             parent_dir_inode, direntry->d_name.name, direntry));
+       cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
+             parent_dir_inode, direntry->d_name.name, direntry);
 
        /* check whether path exists */
 
@@ -632,7 +658,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
                int i;
                for (i = 0; i < direntry->d_name.len; i++)
                        if (direntry->d_name.name[i] == '\\') {
-                               cFYI(1, ("Invalid file name"));
+                               cFYI(1, "Invalid file name");
                                FreeXid(xid);
                                return ERR_PTR(-EINVAL);
                        }
@@ -657,11 +683,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
        }
 
        if (direntry->d_inode != NULL) {
-               cFYI(1, ("non-NULL inode in lookup"));
+               cFYI(1, "non-NULL inode in lookup");
        } else {
-               cFYI(1, ("NULL inode in lookup"));
+               cFYI(1, "NULL inode in lookup");
        }
-       cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
+       cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
 
        /* Posix open is only called (at lookup time) for file create now.
         * For opens (rather than creates), because we do not know if it
@@ -678,6 +704,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
                     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
                     (nd->intent.open.flags & O_CREAT)) {
                        rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
+                                       parent_dir_inode->i_sb,
                                        nd->intent.open.create_mode,
                                        nd->intent.open.flags, &oplock,
                                        &fileHandle, xid);
@@ -723,7 +750,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
        /*      if it was once a directory (but how can we tell?) we could do
                shrink_dcache_parent(direntry); */
        } else if (rc != -EACCES) {
-               cERROR(1, ("Unexpected lookup error %d", rc));
+               cERROR(1, "Unexpected lookup error %d", rc);
                /* We special case check for Access Denied - since that
                is a common return code */
        }
@@ -742,8 +769,8 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
                if (cifs_revalidate_dentry(direntry))
                        return 0;
        } else {
-               cFYI(1, ("neg dentry 0x%p name = %s",
-                        direntry, direntry->d_name.name));
+               cFYI(1, "neg dentry 0x%p name = %s",
+                        direntry, direntry->d_name.name);
                if (time_after(jiffies, direntry->d_time + HZ) ||
                        !lookupCacheEnabled) {
                        d_drop(direntry);
@@ -758,7 +785,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
 {
        int rc = 0;
 
-       cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name));
+       cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
 
        return rc;
 }     */
index 6f8a0e3..4db2c5e 100644 (file)
@@ -106,14 +106,14 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        /* search for server name delimiter */
        len = strlen(unc);
        if (len < 3) {
-               cFYI(1, ("%s: unc is too short: %s", __func__, unc));
+               cFYI(1, "%s: unc is too short: %s", __func__, unc);
                return -EINVAL;
        }
        len -= 2;
        name = memchr(unc+2, '\\', len);
        if (!name) {
-               cFYI(1, ("%s: probably server name is whole unc: %s",
-                                       __func__, unc));
+               cFYI(1, "%s: probably server name is whole unc: %s",
+                                       __func__, unc);
        } else {
                len = (name - unc) - 2/* leading // */;
        }
@@ -127,8 +127,8 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
        name[len] = 0;
 
        if (is_ip(name)) {
-               cFYI(1, ("%s: it is IP, skipping dns upcall: %s",
-                                       __func__, name));
+               cFYI(1, "%s: it is IP, skipping dns upcall: %s",
+                                       __func__, name);
                data = name;
                goto skip_upcall;
        }
@@ -138,7 +138,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
                len = rkey->type_data.x[0];
                data = rkey->payload.data;
        } else {
-               cERROR(1, ("%s: unable to resolve: %s", __func__, name));
+               cERROR(1, "%s: unable to resolve: %s", __func__, name);
                goto out;
        }
 
@@ -148,10 +148,10 @@ skip_upcall:
                if (*ip_addr) {
                        memcpy(*ip_addr, data, len + 1);
                        if (!IS_ERR(rkey))
-                               cFYI(1, ("%s: resolved: %s to %s", __func__,
+                               cFYI(1, "%s: resolved: %s to %s", __func__,
                                                        name,
                                                        *ip_addr
-                                       ));
+                                       );
                        rc = 0;
                } else {
                        rc = -ENOMEM;
index 6177f7c..993f820 100644 (file)
@@ -49,7 +49,7 @@
 static struct dentry *cifs_get_parent(struct dentry *dentry)
 {
        /* BB need to add code here eventually to enable export via NFSD */
-       cFYI(1, ("get parent for %p", dentry));
+       cFYI(1, "get parent for %p", dentry);
        return ERR_PTR(-EACCES);
 }
 
index 9b11a8f..a83541e 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   vfs operations that deal with files
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2007
+ *   Copyright (C) International Business Machines  Corp., 2002,2010
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *              Jeremy Allison (jra@samba.org)
  *
@@ -108,8 +108,7 @@ static inline int cifs_get_disposition(unsigned int flags)
 /* all arguments to this function must be checked for validity in caller */
 static inline int
 cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
-                            struct cifsInodeInfo *pCifsInode,
-                            struct cifsFileInfo *pCifsFile, __u32 oplock,
+                            struct cifsInodeInfo *pCifsInode, __u32 oplock,
                             u16 netfid)
 {
 
@@ -136,15 +135,15 @@ cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
        if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
                           (file->f_path.dentry->d_inode->i_size ==
                            (loff_t)le64_to_cpu(buf->EndOfFile))) {
-               cFYI(1, ("inode unchanged on server"));
+               cFYI(1, "inode unchanged on server");
        } else {
                if (file->f_path.dentry->d_inode->i_mapping) {
                        rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
                        if (rc != 0)
                                CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
                }
-               cFYI(1, ("invalidating remote inode since open detected it "
-                        "changed"));
+               cFYI(1, "invalidating remote inode since open detected it "
+                        "changed");
                invalidate_remote_inode(file->f_path.dentry->d_inode);
        } */
 
@@ -152,8 +151,8 @@ psx_client_can_cache:
        if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                pCifsInode->clientCanCacheAll = true;
                pCifsInode->clientCanCacheRead = true;
-               cFYI(1, ("Exclusive Oplock granted on inode %p",
-                        file->f_path.dentry->d_inode));
+               cFYI(1, "Exclusive Oplock granted on inode %p",
+                        file->f_path.dentry->d_inode);
        } else if ((oplock & 0xF) == OPLOCK_READ)
                pCifsInode->clientCanCacheRead = true;
 
@@ -190,8 +189,8 @@ cifs_fill_filedata(struct file *file)
        if (file->private_data != NULL) {
                return pCifsFile;
        } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL))
-                       cERROR(1, ("could not find file instance for "
-                                  "new file %p", file));
+                       cERROR(1, "could not find file instance for "
+                                  "new file %p", file);
        return NULL;
 }
 
@@ -217,7 +216,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
        if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
                           (file->f_path.dentry->d_inode->i_size ==
                            (loff_t)le64_to_cpu(buf->EndOfFile))) {
-               cFYI(1, ("inode unchanged on server"));
+               cFYI(1, "inode unchanged on server");
        } else {
                if (file->f_path.dentry->d_inode->i_mapping) {
                        /* BB no need to lock inode until after invalidate
@@ -226,8 +225,8 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
                        if (rc != 0)
                                CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
                }
-               cFYI(1, ("invalidating remote inode since open detected it "
-                        "changed"));
+               cFYI(1, "invalidating remote inode since open detected it "
+                        "changed");
                invalidate_remote_inode(file->f_path.dentry->d_inode);
        }
 
@@ -242,8 +241,8 @@ client_can_cache:
        if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                pCifsInode->clientCanCacheAll = true;
                pCifsInode->clientCanCacheRead = true;
-               cFYI(1, ("Exclusive Oplock granted on inode %p",
-                        file->f_path.dentry->d_inode));
+               cFYI(1, "Exclusive Oplock granted on inode %p",
+                        file->f_path.dentry->d_inode);
        } else if ((*oplock & 0xF) == OPLOCK_READ)
                pCifsInode->clientCanCacheRead = true;
 
@@ -285,8 +284,8 @@ int cifs_open(struct inode *inode, struct file *file)
                return rc;
        }
 
-       cFYI(1, ("inode = 0x%p file flags are 0x%x for %s",
-                inode, file->f_flags, full_path));
+       cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
+                inode, file->f_flags, full_path);
 
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
@@ -298,27 +297,29 @@ int cifs_open(struct inode *inode, struct file *file)
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                int oflags = (int) cifs_posix_convert_flags(file->f_flags);
+               oflags |= SMB_O_CREAT;
                /* can not refresh inode info since size could be stale */
                rc = cifs_posix_open(full_path, &inode, file->f_path.mnt,
-                                    cifs_sb->mnt_file_mode /* ignored */,
-                                    oflags, &oplock, &netfid, xid);
+                               inode->i_sb,
+                               cifs_sb->mnt_file_mode /* ignored */,
+                               oflags, &oplock, &netfid, xid);
                if (rc == 0) {
-                       cFYI(1, ("posix open succeeded"));
+                       cFYI(1, "posix open succeeded");
                        /* no need for special case handling of setting mode
                           on read only files needed here */
 
                        pCifsFile = cifs_fill_filedata(file);
                        cifs_posix_open_inode_helper(inode, file, pCifsInode,
-                                                    pCifsFile, oplock, netfid);
+                                                    oplock, netfid);
                        goto out;
                } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        if (tcon->ses->serverNOS)
-                               cERROR(1, ("server %s of type %s returned"
+                               cERROR(1, "server %s of type %s returned"
                                           " unexpected error on SMB posix open"
                                           ", disabling posix open support."
                                           " Check if server update available.",
                                           tcon->ses->serverName,
-                                          tcon->ses->serverNOS));
+                                          tcon->ses->serverNOS);
                        tcon->broken_posix_open = true;
                } else if ((rc != -EIO) && (rc != -EREMOTE) &&
                         (rc != -EOPNOTSUPP)) /* path not found or net err */
@@ -386,7 +387,7 @@ int cifs_open(struct inode *inode, struct file *file)
                                & CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
        if (rc) {
-               cFYI(1, ("cifs_open returned 0x%x", rc));
+               cFYI(1, "cifs_open returned 0x%x", rc);
                goto out;
        }
 
@@ -469,7 +470,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
        }
 
        if (file->f_path.dentry == NULL) {
-               cERROR(1, ("no valid name if dentry freed"));
+               cERROR(1, "no valid name if dentry freed");
                dump_stack();
                rc = -EBADF;
                goto reopen_error_exit;
@@ -477,7 +478,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush)
 
        inode = file->f_path.dentry->d_inode;
        if (inode == NULL) {
-               cERROR(1, ("inode not valid"));
+               cERROR(1, "inode not valid");
                dump_stack();
                rc = -EBADF;
                goto reopen_error_exit;
@@ -499,8 +500,8 @@ reopen_error_exit:
                return rc;
        }
 
-       cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
-                inode, file->f_flags, full_path));
+       cFYI(1, "inode = 0x%p file flags 0x%x for %s",
+                inode, file->f_flags, full_path);
 
        if (oplockEnabled)
                oplock = REQ_OPLOCK;
@@ -513,10 +514,11 @@ reopen_error_exit:
                int oflags = (int) cifs_posix_convert_flags(file->f_flags);
                /* can not refresh inode info since size could be stale */
                rc = cifs_posix_open(full_path, NULL, file->f_path.mnt,
-                                    cifs_sb->mnt_file_mode /* ignored */,
-                                    oflags, &oplock, &netfid, xid);
+                               inode->i_sb,
+                               cifs_sb->mnt_file_mode /* ignored */,
+                               oflags, &oplock, &netfid, xid);
                if (rc == 0) {
-                       cFYI(1, ("posix reopen succeeded"));
+                       cFYI(1, "posix reopen succeeded");
                        goto reopen_success;
                }
                /* fallthrough to retry open the old way on errors, especially
@@ -537,8 +539,8 @@ reopen_error_exit:
                                CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
                mutex_unlock(&pCifsFile->fh_mutex);
-               cFYI(1, ("cifs_open returned 0x%x", rc));
-               cFYI(1, ("oplock: %d", oplock));
+               cFYI(1, "cifs_open returned 0x%x", rc);
+               cFYI(1, "oplock: %d", oplock);
        } else {
 reopen_success:
                pCifsFile->netfid = netfid;
@@ -570,8 +572,8 @@ reopen_success:
                        if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
                                pCifsInode->clientCanCacheAll = true;
                                pCifsInode->clientCanCacheRead = true;
-                               cFYI(1, ("Exclusive Oplock granted on inode %p",
-                                        file->f_path.dentry->d_inode));
+                               cFYI(1, "Exclusive Oplock granted on inode %p",
+                                        file->f_path.dentry->d_inode);
                        } else if ((oplock & 0xF) == OPLOCK_READ) {
                                pCifsInode->clientCanCacheRead = true;
                                pCifsInode->clientCanCacheAll = false;
@@ -619,8 +621,7 @@ int cifs_close(struct inode *inode, struct file *file)
                                        the struct would be in each open file,
                                        but this should give enough time to
                                        clear the socket */
-                                       cFYI(DBG2,
-                                               ("close delay, write pending"));
+                                       cFYI(DBG2, "close delay, write pending");
                                        msleep(timeout);
                                        timeout *= 4;
                                }
@@ -653,7 +654,7 @@ int cifs_close(struct inode *inode, struct file *file)
 
        read_lock(&GlobalSMBSeslock);
        if (list_empty(&(CIFS_I(inode)->openFileList))) {
-               cFYI(1, ("closing last open instance for inode %p", inode));
+               cFYI(1, "closing last open instance for inode %p", inode);
                /* if the file is not open we do not know if we can cache info
                   on this inode, much less write behind and read ahead */
                CIFS_I(inode)->clientCanCacheRead = false;
@@ -674,7 +675,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
            (struct cifsFileInfo *)file->private_data;
        char *ptmp;
 
-       cFYI(1, ("Closedir inode = 0x%p", inode));
+       cFYI(1, "Closedir inode = 0x%p", inode);
 
        xid = GetXid();
 
@@ -685,22 +686,22 @@ int cifs_closedir(struct inode *inode, struct file *file)
 
                pTcon = cifs_sb->tcon;
 
-               cFYI(1, ("Freeing private data in close dir"));
+               cFYI(1, "Freeing private data in close dir");
                write_lock(&GlobalSMBSeslock);
                if (!pCFileStruct->srch_inf.endOfSearch &&
                    !pCFileStruct->invalidHandle) {
                        pCFileStruct->invalidHandle = true;
                        write_unlock(&GlobalSMBSeslock);
                        rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
-                       cFYI(1, ("Closing uncompleted readdir with rc %d",
-                                rc));
+                       cFYI(1, "Closing uncompleted readdir with rc %d",
+                                rc);
                        /* not much we can do if it fails anyway, ignore rc */
                        rc = 0;
                } else
                        write_unlock(&GlobalSMBSeslock);
                ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
                if (ptmp) {
-                       cFYI(1, ("closedir free smb buf in srch struct"));
+                       cFYI(1, "closedir free smb buf in srch struct");
                        pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
                        if (pCFileStruct->srch_inf.smallBuf)
                                cifs_small_buf_release(ptmp);
@@ -748,49 +749,49 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
        rc = -EACCES;
        xid = GetXid();
 
-       cFYI(1, ("Lock parm: 0x%x flockflags: "
+       cFYI(1, "Lock parm: 0x%x flockflags: "
                 "0x%x flocktype: 0x%x start: %lld end: %lld",
                cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
-               pfLock->fl_end));
+               pfLock->fl_end);
 
        if (pfLock->fl_flags & FL_POSIX)
-               cFYI(1, ("Posix"));
+               cFYI(1, "Posix");
        if (pfLock->fl_flags & FL_FLOCK)
-               cFYI(1, ("Flock"));
+               cFYI(1, "Flock");
        if (pfLock->fl_flags & FL_SLEEP) {
-               cFYI(1, ("Blocking lock"));
+               cFYI(1, "Blocking lock");
                wait_flag = true;
        }
        if (pfLock->fl_flags & FL_ACCESS)
-               cFYI(1, ("Process suspended by mandatory locking - "
-                        "not implemented yet"));
+               cFYI(1, "Process suspended by mandatory locking - "
+                        "not implemented yet");
        if (pfLock->fl_flags & FL_LEASE)
-               cFYI(1, ("Lease on file - not implemented yet"));
+               cFYI(1, "Lease on file - not implemented yet");
        if (pfLock->fl_flags &
            (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
-               cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags));
+               cFYI(1, "Unknown lock flags 0x%x", pfLock->fl_flags);
 
        if (pfLock->fl_type == F_WRLCK) {
-               cFYI(1, ("F_WRLCK "));
+               cFYI(1, "F_WRLCK ");
                numLock = 1;
        } else if (pfLock->fl_type == F_UNLCK) {
-               cFYI(1, ("F_UNLCK"));
+               cFYI(1, "F_UNLCK");
                numUnlock = 1;
                /* Check if unlock includes more than
                one lock range */
        } else if (pfLock->fl_type == F_RDLCK) {
-               cFYI(1, ("F_RDLCK"));
+               cFYI(1, "F_RDLCK");
                lockType |= LOCKING_ANDX_SHARED_LOCK;
                numLock = 1;
        } else if (pfLock->fl_type == F_EXLCK) {
-               cFYI(1, ("F_EXLCK"));
+               cFYI(1, "F_EXLCK");
                numLock = 1;
        } else if (pfLock->fl_type == F_SHLCK) {
-               cFYI(1, ("F_SHLCK"));
+               cFYI(1, "F_SHLCK");
                lockType |= LOCKING_ANDX_SHARED_LOCK;
                numLock = 1;
        } else
-               cFYI(1, ("Unknown type of lock"));
+               cFYI(1, "Unknown type of lock");
 
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        tcon = cifs_sb->tcon;
@@ -833,8 +834,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                         0 /* wait flag */ );
                        pfLock->fl_type = F_UNLCK;
                        if (rc != 0)
-                               cERROR(1, ("Error unlocking previously locked "
-                                          "range %d during test of lock", rc));
+                               cERROR(1, "Error unlocking previously locked "
+                                          "range %d during test of lock", rc);
                        rc = 0;
 
                } else {
@@ -856,9 +857,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                                0 /* wait flag */);
                                        pfLock->fl_type = F_RDLCK;
                                        if (rc != 0)
-                                               cERROR(1, ("Error unlocking "
+                                               cERROR(1, "Error unlocking "
                                                "previously locked range %d "
-                                               "during test of lock", rc));
+                                               "during test of lock", rc);
                                        rc = 0;
                                } else {
                                        pfLock->fl_type = F_WRLCK;
@@ -923,9 +924,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                                                        1, 0, li->type, false);
                                        if (stored_rc)
                                                rc = stored_rc;
-
-                                       list_del(&li->llist);
-                                       kfree(li);
+                                       else {
+                                               list_del(&li->llist);
+                                               kfree(li);
+                                       }
                                }
                        }
                        mutex_unlock(&fid->lock_mutex);
@@ -988,9 +990,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
 
        pTcon = cifs_sb->tcon;
 
-       /* cFYI(1,
-          (" write %d bytes to offset %lld of %s", write_size,
-          *poffset, file->f_path.dentry->d_name.name)); */
+       /* cFYI(1, " write %d bytes to offset %lld of %s", write_size,
+          *poffset, file->f_path.dentry->d_name.name); */
 
        if (file->private_data == NULL)
                return -EBADF;
@@ -1091,8 +1092,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
 
        pTcon = cifs_sb->tcon;
 
-       cFYI(1, ("write %zd bytes to offset %lld of %s", write_size,
-          *poffset, file->f_path.dentry->d_name.name));
+       cFYI(1, "write %zd bytes to offset %lld of %s", write_size,
+          *poffset, file->f_path.dentry->d_name.name);
 
        if (file->private_data == NULL)
                return -EBADF;
@@ -1233,7 +1234,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
        it being zero) during stress testcases so we need to check for it */
 
        if (cifs_inode == NULL) {
-               cERROR(1, ("Null inode passed to cifs_writeable_file"));
+               cERROR(1, "Null inode passed to cifs_writeable_file");
                dump_stack();
                return NULL;
        }
@@ -1277,7 +1278,7 @@ refind_writable:
                        again. Note that it would be bad
                        to hold up writepages here (rather than
                        in caller) with continuous retries */
-                       cFYI(1, ("wp failed on reopen file"));
+                       cFYI(1, "wp failed on reopen file");
                        read_lock(&GlobalSMBSeslock);
                        /* can not use this handle, no write
                           pending on this one after all */
@@ -1353,7 +1354,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
                else if (bytes_written < 0)
                        rc = bytes_written;
        } else {
-               cFYI(1, ("No writeable filehandles for inode"));
+               cFYI(1, "No writeable filehandles for inode");
                rc = -EIO;
        }
 
@@ -1525,7 +1526,7 @@ retry:
                         */
                        open_file = find_writable_file(CIFS_I(mapping->host));
                        if (!open_file) {
-                               cERROR(1, ("No writable handles for inode"));
+                               cERROR(1, "No writable handles for inode");
                                rc = -EBADF;
                        } else {
                                long_op = cifs_write_timeout(cifsi, offset);
@@ -1538,8 +1539,8 @@ retry:
                                cifs_update_eof(cifsi, offset, bytes_written);
 
                                if (rc || bytes_written < bytes_to_write) {
-                                       cERROR(1, ("Write2 ret %d, wrote %d",
-                                                 rc, bytes_written));
+                                       cERROR(1, "Write2 ret %d, wrote %d",
+                                                 rc, bytes_written);
                                        /* BB what if continued retry is
                                           requested via mount flags? */
                                        if (rc == -ENOSPC)
@@ -1600,7 +1601,7 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc)
 /* BB add check for wbc flags */
        page_cache_get(page);
        if (!PageUptodate(page))
-               cFYI(1, ("ppw - page not up to date"));
+               cFYI(1, "ppw - page not up to date");
 
        /*
         * Set the "writeback" flag, and clear "dirty" in the radix tree.
@@ -1629,8 +1630,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
        int rc;
        struct inode *inode = mapping->host;
 
-       cFYI(1, ("write_end for page %p from pos %lld with %d bytes",
-                page, pos, copied));
+       cFYI(1, "write_end for page %p from pos %lld with %d bytes",
+                page, pos, copied);
 
        if (PageChecked(page)) {
                if (copied == len)
@@ -1686,8 +1687,8 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
 
        xid = GetXid();
 
-       cFYI(1, ("Sync file - name: %s datasync: 0x%x",
-               dentry->d_name.name, datasync));
+       cFYI(1, "Sync file - name: %s datasync: 0x%x",
+               dentry->d_name.name, datasync);
 
        rc = filemap_write_and_wait(inode->i_mapping);
        if (rc == 0) {
@@ -1711,7 +1712,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
        unsigned int rpages = 0;
        int rc = 0;
 
-       cFYI(1, ("sync page %p",page));
+       cFYI(1, "sync page %p", page);
        mapping = page->mapping;
        if (!mapping)
                return 0;
@@ -1722,7 +1723,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
 /*     fill in rpages then
        result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
 
-/*     cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index));
+/*     cFYI(1, "rpages is %d for sync page of Index %ld", rpages, index);
 
 #if 0
        if (rc < 0)
@@ -1756,7 +1757,7 @@ int cifs_flush(struct file *file, fl_owner_t id)
                CIFS_I(inode)->write_behind_rc = 0;
        }
 
-       cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc));
+       cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc);
 
        return rc;
 }
@@ -1788,7 +1789,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
        open_file = (struct cifsFileInfo *)file->private_data;
 
        if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-               cFYI(1, ("attempting read on write only file instance"));
+               cFYI(1, "attempting read on write only file instance");
 
        for (total_read = 0, current_offset = read_data;
             read_size > total_read;
@@ -1869,7 +1870,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
        open_file = (struct cifsFileInfo *)file->private_data;
 
        if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-               cFYI(1, ("attempting read on write only file instance"));
+               cFYI(1, "attempting read on write only file instance");
 
        for (total_read = 0, current_offset = read_data;
             read_size > total_read;
@@ -1920,7 +1921,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
        xid = GetXid();
        rc = cifs_revalidate_file(file);
        if (rc) {
-               cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
+               cFYI(1, "Validation prior to mmap failed, error=%d", rc);
                FreeXid(xid);
                return rc;
        }
@@ -1931,8 +1932,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
 
 
 static void cifs_copy_cache_pages(struct address_space *mapping,
-       struct list_head *pages, int bytes_read, char *data,
-       struct pagevec *plru_pvec)
+       struct list_head *pages, int bytes_read, char *data)
 {
        struct page *page;
        char *target;
@@ -1944,10 +1944,10 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
                page = list_entry(pages->prev, struct page, lru);
                list_del(&page->lru);
 
-               if (add_to_page_cache(page, mapping, page->index,
+               if (add_to_page_cache_lru(page, mapping, page->index,
                                      GFP_KERNEL)) {
                        page_cache_release(page);
-                       cFYI(1, ("Add page cache failed"));
+                       cFYI(1, "Add page cache failed");
                        data += PAGE_CACHE_SIZE;
                        bytes_read -= PAGE_CACHE_SIZE;
                        continue;
@@ -1970,8 +1970,6 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
                flush_dcache_page(page);
                SetPageUptodate(page);
                unlock_page(page);
-               if (!pagevec_add(plru_pvec, page))
-                       __pagevec_lru_add_file(plru_pvec);
                data += PAGE_CACHE_SIZE;
        }
        return;
@@ -1990,7 +1988,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        unsigned int read_size, i;
        char *smb_read_data = NULL;
        struct smb_com_read_rsp *pSMBr;
-       struct pagevec lru_pvec;
        struct cifsFileInfo *open_file;
        int buf_type = CIFS_NO_BUFFER;
 
@@ -2004,8 +2001,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
        cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
-       pagevec_init(&lru_pvec, 0);
-       cFYI(DBG2, ("rpages: num pages %d", num_pages));
+       cFYI(DBG2, "rpages: num pages %d", num_pages);
        for (i = 0; i < num_pages; ) {
                unsigned contig_pages;
                struct page *tmp_page;
@@ -2038,8 +2034,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                /* Read size needs to be in multiples of one page */
                read_size = min_t(const unsigned int, read_size,
                                  cifs_sb->rsize & PAGE_CACHE_MASK);
-               cFYI(DBG2, ("rpages: read size 0x%x  contiguous pages %d",
-                               read_size, contig_pages));
+               cFYI(DBG2, "rpages: read size 0x%x  contiguous pages %d",
+                               read_size, contig_pages);
                rc = -EAGAIN;
                while (rc == -EAGAIN) {
                        if ((open_file->invalidHandle) &&
@@ -2066,14 +2062,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                        }
                }
                if ((rc < 0) || (smb_read_data == NULL)) {
-                       cFYI(1, ("Read error in readpages: %d", rc));
+                       cFYI(1, "Read error in readpages: %d", rc);
                        break;
                } else if (bytes_read > 0) {
                        task_io_account_read(bytes_read);
                        pSMBr = (struct smb_com_read_rsp *)smb_read_data;
                        cifs_copy_cache_pages(mapping, page_list, bytes_read,
                                smb_read_data + 4 /* RFC1001 hdr */ +
-                               le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
+                               le16_to_cpu(pSMBr->DataOffset));
 
                        i +=  bytes_read >> PAGE_CACHE_SHIFT;
                        cifs_stats_bytes_read(pTcon, bytes_read);
@@ -2089,9 +2085,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                                /* break; */
                        }
                } else {
-                       cFYI(1, ("No bytes read (%d) at offset %lld . "
-                                "Cleaning remaining pages from readahead list",
-                                bytes_read, offset));
+                       cFYI(1, "No bytes read (%d) at offset %lld . "
+                               "Cleaning remaining pages from readahead list",
+                               bytes_read, offset);
                        /* BB turn off caching and do new lookup on
                           file size at server? */
                        break;
@@ -2106,8 +2102,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
                bytes_read = 0;
        }
 
-       pagevec_lru_add_file(&lru_pvec);
-
 /* need to free smb_read_data buf before exit */
        if (smb_read_data) {
                if (buf_type == CIFS_SMALL_BUFFER)
@@ -2136,7 +2130,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page,
        if (rc < 0)
                goto io_error;
        else
-               cFYI(1, ("Bytes read %d", rc));
+               cFYI(1, "Bytes read %d", rc);
 
        file->f_path.dentry->d_inode->i_atime =
                current_fs_time(file->f_path.dentry->d_inode->i_sb);
@@ -2168,8 +2162,8 @@ static int cifs_readpage(struct file *file, struct page *page)
                return rc;
        }
 
-       cFYI(1, ("readpage %p at offset %d 0x%x\n",
-                page, (int)offset, (int)offset));
+       cFYI(1, "readpage %p at offset %d 0x%x\n",
+                page, (int)offset, (int)offset);
 
        rc = cifs_readpage_worker(file, page, &offset);
 
@@ -2239,7 +2233,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
        struct page *page;
        int rc = 0;
 
-       cFYI(1, ("write_begin from %lld len %d", (long long)pos, len));
+       cFYI(1, "write_begin from %lld len %d", (long long)pos, len);
 
        page = grab_cache_page_write_begin(mapping, index, flags);
        if (!page) {
@@ -2311,12 +2305,10 @@ cifs_oplock_break(struct slow_work *work)
        int rc, waitrc = 0;
 
        if (inode && S_ISREG(inode->i_mode)) {
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               if (cinode->clientCanCacheAll == 0)
+               if (cinode->clientCanCacheRead)
                        break_lease(inode, O_RDONLY);
-               else if (cinode->clientCanCacheRead == 0)
+               else
                        break_lease(inode, O_WRONLY);
-#endif
                rc = filemap_fdatawrite(inode->i_mapping);
                if (cinode->clientCanCacheRead == 0) {
                        waitrc = filemap_fdatawait(inode->i_mapping);
@@ -2326,7 +2318,7 @@ cifs_oplock_break(struct slow_work *work)
                        rc = waitrc;
                if (rc)
                        cinode->write_behind_rc = rc;
-               cFYI(1, ("Oplock flush inode %p rc %d", inode, rc));
+               cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
        }
 
        /*
@@ -2338,7 +2330,7 @@ cifs_oplock_break(struct slow_work *work)
        if (!cfile->closePend && !cfile->oplock_break_cancelled) {
                rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,
                                 LOCKING_ANDX_OPLOCK_RELEASE, false);
-               cFYI(1, ("Oplock release rc = %d", rc));
+               cFYI(1, "Oplock release rc = %d", rc);
        }
 }
 
index 35ec117..62b324f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/inode.c
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2008
+ *   Copyright (C) International Business Machines  Corp., 2002,2010
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *
  *   This library is free software; you can redistribute it and/or modify
@@ -86,30 +86,30 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
 {
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
 
-       cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid));
+       cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
 
        if (inode->i_state & I_NEW) {
-               cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid));
+               cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
                return;
        }
 
        /* don't bother with revalidation if we have an oplock */
        if (cifs_i->clientCanCacheRead) {
-               cFYI(1, ("%s: inode %llu is oplocked", __func__,
-                        cifs_i->uniqueid));
+               cFYI(1, "%s: inode %llu is oplocked", __func__,
+                        cifs_i->uniqueid);
                return;
        }
 
         /* revalidate if mtime or size have changed */
        if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
            cifs_i->server_eof == fattr->cf_eof) {
-               cFYI(1, ("%s: inode %llu is unchanged", __func__,
-                        cifs_i->uniqueid));
+               cFYI(1, "%s: inode %llu is unchanged", __func__,
+                        cifs_i->uniqueid);
                return;
        }
 
-       cFYI(1, ("%s: invalidating inode %llu mapping", __func__,
-                cifs_i->uniqueid));
+       cFYI(1, "%s: invalidating inode %llu mapping", __func__,
+                cifs_i->uniqueid);
        cifs_i->invalid_mapping = true;
 }
 
@@ -137,15 +137,14 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
                inode->i_mode = fattr->cf_mode;
 
        cifs_i->cifsAttrs = fattr->cf_cifsattrs;
-       cifs_i->uniqueid = fattr->cf_uniqueid;
 
        if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
                cifs_i->time = 0;
        else
                cifs_i->time = jiffies;
 
-       cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
-                oldtime, cifs_i->time));
+       cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
+                oldtime, cifs_i->time);
 
        cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
 
@@ -170,6 +169,17 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
        cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
 }
 
+void
+cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
+{
+       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
+               return;
+
+       fattr->cf_uniqueid = iunique(sb, ROOT_I);
+}
+
 /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
 void
 cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
@@ -227,7 +237,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
                /* safest to call it a file if we do not know */
                fattr->cf_mode |= S_IFREG;
                fattr->cf_dtype = DT_REG;
-               cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
+               cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
                break;
        }
 
@@ -256,7 +266,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
-       cFYI(1, ("creating fake fattr for DFS referral"));
+       cFYI(1, "creating fake fattr for DFS referral");
 
        memset(fattr, 0, sizeof(*fattr));
        fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
@@ -305,7 +315,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 
        tcon = cifs_sb->tcon;
-       cFYI(1, ("Getting info on %s", full_path));
+       cFYI(1, "Getting info on %s", full_path);
 
        /* could have done a find first instead but this returns more info */
        rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
@@ -323,6 +333,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
 
        if (*pinode == NULL) {
                /* get new inode */
+               cifs_fill_uniqueid(sb, &fattr);
                *pinode = cifs_iget(sb, &fattr);
                if (!*pinode)
                        rc = -ENOMEM;
@@ -373,7 +384,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
                                 &bytes_read, &pbuf, &buf_type);
                if ((rc == 0) && (bytes_read >= 8)) {
                        if (memcmp("IntxBLK", pbuf, 8) == 0) {
-                               cFYI(1, ("Block device"));
+                               cFYI(1, "Block device");
                                fattr->cf_mode |= S_IFBLK;
                                fattr->cf_dtype = DT_BLK;
                                if (bytes_read == 24) {
@@ -385,7 +396,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
                                        fattr->cf_rdev = MKDEV(mjr, mnr);
                                }
                        } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
-                               cFYI(1, ("Char device"));
+                               cFYI(1, "Char device");
                                fattr->cf_mode |= S_IFCHR;
                                fattr->cf_dtype = DT_CHR;
                                if (bytes_read == 24) {
@@ -397,7 +408,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
                                        fattr->cf_rdev = MKDEV(mjr, mnr);
                                }
                        } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
-                               cFYI(1, ("Symlink"));
+                               cFYI(1, "Symlink");
                                fattr->cf_mode |= S_IFLNK;
                                fattr->cf_dtype = DT_LNK;
                        } else {
@@ -439,10 +450,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
        else if (rc > 3) {
                mode = le32_to_cpu(*((__le32 *)ea_value));
                fattr->cf_mode &= ~SFBITS_MASK;
-               cFYI(1, ("special bits 0%o org mode 0%o", mode,
-                        fattr->cf_mode));
+               cFYI(1, "special bits 0%o org mode 0%o", mode,
+                        fattr->cf_mode);
                fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
-               cFYI(1, ("special mode bits 0%o", mode));
+               cFYI(1, "special mode bits 0%o", mode);
        }
 
        return 0;
@@ -548,11 +559,11 @@ int cifs_get_inode_info(struct inode **pinode,
        struct cifs_fattr fattr;
 
        pTcon = cifs_sb->tcon;
-       cFYI(1, ("Getting info on %s", full_path));
+       cFYI(1, "Getting info on %s", full_path);
 
        if ((pfindData == NULL) && (*pinode != NULL)) {
                if (CIFS_I(*pinode)->clientCanCacheRead) {
-                       cFYI(1, ("No need to revalidate cached inode sizes"));
+                       cFYI(1, "No need to revalidate cached inode sizes");
                        return rc;
                }
        }
@@ -618,7 +629,7 @@ int cifs_get_inode_info(struct inode **pinode,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (rc1 || !fattr.cf_uniqueid) {
-                               cFYI(1, ("GetSrvInodeNum rc %d", rc1));
+                               cFYI(1, "GetSrvInodeNum rc %d", rc1);
                                fattr.cf_uniqueid = iunique(sb, ROOT_I);
                                cifs_autodisable_serverino(cifs_sb);
                        }
@@ -634,13 +645,13 @@ int cifs_get_inode_info(struct inode **pinode,
            cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
                tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
                if (tmprc)
-                       cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
+                       cFYI(1, "cifs_sfu_type failed: %d", tmprc);
        }
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        /* fill in 0777 bits from ACL */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
-               cFYI(1, ("Getting mode bits from ACL"));
+               cFYI(1, "Getting mode bits from ACL");
                cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
        }
 #endif
@@ -715,6 +726,16 @@ cifs_find_inode(struct inode *inode, void *opaque)
        if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
                return 0;
 
+       /*
+        * uh oh -- it's a directory. We can't use it since hardlinked dirs are
+        * verboten. Disable serverino and return it as if it were found, the
+        * caller can discard it, generate a uniqueid and retry the find
+        */
+       if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
+               fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
+               cifs_autodisable_serverino(CIFS_SB(inode->i_sb));
+       }
+
        return 1;
 }
 
@@ -734,15 +755,22 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
        unsigned long hash;
        struct inode *inode;
 
-       cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
+retry_iget5_locked:
+       cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
 
        /* hash down to 32-bits on 32-bit arch */
        hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
 
        inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
-
-       /* we have fattrs in hand, update the inode */
        if (inode) {
+               /* was there a problematic inode number collision? */
+               if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
+                       iput(inode);
+                       fattr->cf_uniqueid = iunique(sb, ROOT_I);
+                       fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
+                       goto retry_iget5_locked;
+               }
+
                cifs_fattr_to_inode(inode, fattr);
                if (sb->s_flags & MS_NOATIME)
                        inode->i_flags |= S_NOATIME | S_NOCMTIME;
@@ -780,7 +808,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
                return ERR_PTR(-ENOMEM);
 
        if (rc && cifs_sb->tcon->ipc) {
-               cFYI(1, ("ipc connection - fake read inode"));
+               cFYI(1, "ipc connection - fake read inode");
                inode->i_mode |= S_IFDIR;
                inode->i_nlink = 2;
                inode->i_op = &cifs_ipc_inode_ops;
@@ -842,7 +870,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
         * server times.
         */
        if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
-               cFYI(1, ("CIFS - CTIME changed"));
+               cFYI(1, "CIFS - CTIME changed");
                info_buf.ChangeTime =
                    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
        } else
@@ -877,8 +905,8 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
                        goto out;
        }
 
-       cFYI(1, ("calling SetFileInfo since SetPathInfo for "
-                "times not supported by this server"));
+       cFYI(1, "calling SetFileInfo since SetPathInfo for "
+                "times not supported by this server");
        rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
                         SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
                         CREATE_NOT_DIR, &netfid, &oplock,
@@ -1036,7 +1064,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
        struct iattr *attrs = NULL;
        __u32 dosattr = 0, origattr = 0;
 
-       cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
+       cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
 
        xid = GetXid();
 
@@ -1055,7 +1083,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
                rc = CIFSPOSIXDelFile(xid, tcon, full_path,
                        SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-               cFYI(1, ("posix del rc %d", rc));
+               cFYI(1, "posix del rc %d", rc);
                if ((rc == 0) || (rc == -ENOENT))
                        goto psx_del_no_retry;
        }
@@ -1129,7 +1157,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
        struct inode *newinode = NULL;
        struct cifs_fattr fattr;
 
-       cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
+       cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
 
        xid = GetXid();
 
@@ -1164,7 +1192,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        kfree(pInfo);
                        goto mkdir_retry_old;
                } else if (rc) {
-                       cFYI(1, ("posix mkdir returned 0x%x", rc));
+                       cFYI(1, "posix mkdir returned 0x%x", rc);
                        d_drop(direntry);
                } else {
                        if (pInfo->Type == cpu_to_le32(-1)) {
@@ -1181,6 +1209,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                                direntry->d_op = &cifs_dentry_ops;
 
                        cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
+                       cifs_fill_uniqueid(inode->i_sb, &fattr);
                        newinode = cifs_iget(inode->i_sb, &fattr);
                        if (!newinode) {
                                kfree(pInfo);
@@ -1190,12 +1219,12 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        d_instantiate(direntry, newinode);
 
 #ifdef CONFIG_CIFS_DEBUG2
-                       cFYI(1, ("instantiated dentry %p %s to inode %p",
-                               direntry, direntry->d_name.name, newinode));
+                       cFYI(1, "instantiated dentry %p %s to inode %p",
+                               direntry, direntry->d_name.name, newinode);
 
                        if (newinode->i_nlink != 2)
-                               cFYI(1, ("unexpected number of links %d",
-                                       newinode->i_nlink));
+                               cFYI(1, "unexpected number of links %d",
+                                       newinode->i_nlink);
 #endif
                }
                kfree(pInfo);
@@ -1206,7 +1235,7 @@ mkdir_retry_old:
        rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
-               cFYI(1, ("cifs_mkdir returned 0x%x", rc));
+               cFYI(1, "cifs_mkdir returned 0x%x", rc);
                d_drop(direntry);
        } else {
 mkdir_get_info:
@@ -1309,7 +1338,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
        char *full_path = NULL;
        struct cifsInodeInfo *cifsInode;
 
-       cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
+       cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
 
        xid = GetXid();
 
@@ -1511,6 +1540,11 @@ cifs_inode_needs_reval(struct inode *inode)
        if (time_after_eq(jiffies, cifs_i->time + HZ))
                return true;
 
+       /* hardlinked files w/ noserverino get "special" treatment */
+       if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+           S_ISREG(inode->i_mode) && inode->i_nlink != 1)
+               return true;
+
        return false;
 }
 
@@ -1577,9 +1611,9 @@ int cifs_revalidate_dentry(struct dentry *dentry)
                goto check_inval;
        }
 
-       cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
+       cFYI(1, "Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
                 "jiffies %ld", full_path, inode, inode->i_count.counter,
-                dentry, dentry->d_time, jiffies));
+                dentry, dentry->d_time, jiffies);
 
        if (CIFS_SB(sb)->tcon->unix_ext)
                rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
@@ -1673,12 +1707,12 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
                                        npid, false);
                cifsFileInfo_put(open_file);
-               cFYI(1, ("SetFSize for attrs rc = %d", rc));
+               cFYI(1, "SetFSize for attrs rc = %d", rc);
                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        unsigned int bytes_written;
                        rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
                                          &bytes_written, NULL, NULL, 1);
-                       cFYI(1, ("Wrt seteof rc %d", rc));
+                       cFYI(1, "Wrt seteof rc %d", rc);
                }
        } else
                rc = -EINVAL;
@@ -1692,7 +1726,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                                   false, cifs_sb->local_nls,
                                   cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
-               cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
+               cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
                if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
                        __u16 netfid;
                        int oplock = 0;
@@ -1709,7 +1743,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                                                  attrs->ia_size,
                                                  &bytes_written, NULL,
                                                  NULL, 1);
-                               cFYI(1, ("wrt seteof rc %d", rc));
+                               cFYI(1, "wrt seteof rc %d", rc);
                                CIFSSMBClose(xid, pTcon, netfid);
                        }
                }
@@ -1737,8 +1771,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
        struct cifs_unix_set_info_args *args = NULL;
        struct cifsFileInfo *open_file;
 
-       cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
-                direntry->d_name.name, attrs->ia_valid));
+       cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
+                direntry->d_name.name, attrs->ia_valid);
 
        xid = GetXid();
 
@@ -1868,8 +1902,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
        xid = GetXid();
 
-       cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
-                direntry->d_name.name, attrs->ia_valid));
+       cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
+                direntry->d_name.name, attrs->ia_valid);
 
        if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
                /* check if we have permission to change attrs */
@@ -1926,7 +1960,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
                attrs->ia_valid &= ~ATTR_MODE;
 
        if (attrs->ia_valid & ATTR_MODE) {
-               cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
+               cFYI(1, "Mode changed to 0%o", attrs->ia_mode);
                mode = attrs->ia_mode;
        }
 
@@ -2012,7 +2046,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 #if 0
 void cifs_delete_inode(struct inode *inode)
 {
-       cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
+       cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
        /* may have to add back in if and when safe distributed caching of
           directories added e.g. via FindNotify */
 }
index f946506..505926f 100644 (file)
@@ -47,7 +47,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
 
        xid = GetXid();
 
-       cFYI(1, ("ioctl file %p  cmd %u  arg %lu", filep, command, arg));
+       cFYI(1, "ioctl file %p  cmd %u  arg %lu", filep, command, arg);
 
        cifs_sb = CIFS_SB(inode->i_sb);
 
@@ -64,12 +64,12 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
 
        switch (command) {
                case CIFS_IOC_CHECKUMOUNT:
-                       cFYI(1, ("User unmount attempted"));
+                       cFYI(1, "User unmount attempted");
                        if (cifs_sb->mnt_uid == current_uid())
                                rc = 0;
                        else {
                                rc = -EACCES;
-                               cFYI(1, ("uids do not match"));
+                               cFYI(1, "uids do not match");
                        }
                        break;
 #ifdef CONFIG_CIFS_POSIX
@@ -97,11 +97,11 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
                                /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
                                        extAttrBits, &ExtAttrMask);*/
                        }
-                       cFYI(1, ("set flags not implemented yet"));
+                       cFYI(1, "set flags not implemented yet");
                        break;
 #endif /* CONFIG_CIFS_POSIX */
                default:
-                       cFYI(1, ("unsupported ioctl"));
+                       cFYI(1, "unsupported ioctl");
                        break;
        }
 
index c1a9d42..473ca80 100644 (file)
@@ -139,7 +139,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
        if (!full_path)
                goto out;
 
-       cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
+       cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
 
        rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
                                     cifs_sb->local_nls);
@@ -178,8 +178,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                return rc;
        }
 
-       cFYI(1, ("Full path: %s", full_path));
-       cFYI(1, ("symname is %s", symname));
+       cFYI(1, "Full path: %s", full_path);
+       cFYI(1, "symname is %s", symname);
 
        /* BB what if DFS and this volume is on different share? BB */
        if (pTcon->unix_ext)
@@ -198,8 +198,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                                                 inode->i_sb, xid, NULL);
 
                if (rc != 0) {
-                       cFYI(1, ("Create symlink ok, getinodeinfo fail rc = %d",
-                             rc));
+                       cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
+                             rc);
                } else {
                        if (pTcon->nocase)
                                direntry->d_op = &cifs_ci_dentry_ops;
index d147499..1394aa3 100644 (file)
@@ -51,7 +51,7 @@ _GetXid(void)
        if (GlobalTotalActiveXid > GlobalMaxActiveXid)
                GlobalMaxActiveXid = GlobalTotalActiveXid;
        if (GlobalTotalActiveXid > 65000)
-               cFYI(1, ("warning: more than 65000 requests active"));
+               cFYI(1, "warning: more than 65000 requests active");
        xid = GlobalCurrentXid++;
        spin_unlock(&GlobalMid_Lock);
        return xid;
@@ -88,7 +88,7 @@ void
 sesInfoFree(struct cifsSesInfo *buf_to_free)
 {
        if (buf_to_free == NULL) {
-               cFYI(1, ("Null buffer passed to sesInfoFree"));
+               cFYI(1, "Null buffer passed to sesInfoFree");
                return;
        }
 
@@ -126,7 +126,7 @@ void
 tconInfoFree(struct cifsTconInfo *buf_to_free)
 {
        if (buf_to_free == NULL) {
-               cFYI(1, ("Null buffer passed to tconInfoFree"));
+               cFYI(1, "Null buffer passed to tconInfoFree");
                return;
        }
        atomic_dec(&tconInfoAllocCount);
@@ -166,7 +166,7 @@ void
 cifs_buf_release(void *buf_to_free)
 {
        if (buf_to_free == NULL) {
-               /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
+               /* cFYI(1, "Null buffer passed to cifs_buf_release");*/
                return;
        }
        mempool_free(buf_to_free, cifs_req_poolp);
@@ -202,7 +202,7 @@ cifs_small_buf_release(void *buf_to_free)
 {
 
        if (buf_to_free == NULL) {
-               cFYI(1, ("Null buffer passed to cifs_small_buf_release"));
+               cFYI(1, "Null buffer passed to cifs_small_buf_release");
                return;
        }
        mempool_free(buf_to_free, cifs_sm_req_poolp);
@@ -345,19 +345,19 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
                /*      with userid/password pairs found on the smb session   */
                /*      for other target tcp/ip addresses               BB    */
                                if (current_fsuid() != treeCon->ses->linux_uid) {
-                                       cFYI(1, ("Multiuser mode and UID "
-                                                "did not match tcon uid"));
+                                       cFYI(1, "Multiuser mode and UID "
+                                                "did not match tcon uid");
                                        read_lock(&cifs_tcp_ses_lock);
                                        list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
                                                ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
                                                if (ses->linux_uid == current_fsuid()) {
                                                        if (ses->server == treeCon->ses->server) {
-                                                               cFYI(1, ("found matching uid substitute right smb_uid"));
+                                                               cFYI(1, "found matching uid substitute right smb_uid");
                                                                buffer->Uid = ses->Suid;
                                                                break;
                                                        } else {
                                /* BB eventually call cifs_setup_session here */
-                                                               cFYI(1, ("local UID found but no smb sess with this server exists"));
+                                                               cFYI(1, "local UID found but no smb sess with this server exists");
                                                        }
                                                }
                                        }
@@ -394,17 +394,16 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
                        if (smb->Command == SMB_COM_LOCKING_ANDX)
                                return 0;
                        else
-                               cERROR(1, ("Received Request not response"));
+                               cERROR(1, "Received Request not response");
                }
        } else { /* bad signature or mid */
                if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
-                       cERROR(1,
-                              ("Bad protocol string signature header %x",
-                               *(unsigned int *) smb->Protocol));
+                       cERROR(1, "Bad protocol string signature header %x",
+                               *(unsigned int *) smb->Protocol);
                if (mid != smb->Mid)
-                       cERROR(1, ("Mids do not match"));
+                       cERROR(1, "Mids do not match");
        }
-       cERROR(1, ("bad smb detected. The Mid=%d", smb->Mid));
+       cERROR(1, "bad smb detected. The Mid=%d", smb->Mid);
        return 1;
 }
 
@@ -413,7 +412,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
 {
        __u32 len = smb->smb_buf_length;
        __u32 clc_len;  /* calculated length */
-       cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
+       cFYI(0, "checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len);
 
        if (length < 2 + sizeof(struct smb_hdr)) {
                if ((length >= sizeof(struct smb_hdr) - 1)
@@ -437,15 +436,15 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                                tmp[sizeof(struct smb_hdr)+1] = 0;
                                return 0;
                        }
-                       cERROR(1, ("rcvd invalid byte count (bcc)"));
+                       cERROR(1, "rcvd invalid byte count (bcc)");
                } else {
-                       cERROR(1, ("Length less than smb header size"));
+                       cERROR(1, "Length less than smb header size");
                }
                return 1;
        }
        if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
-                                  smb->Mid));
+               cERROR(1, "smb length greater than MaxBufSize, mid=%d",
+                                  smb->Mid);
                return 1;
        }
 
@@ -454,8 +453,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
        clc_len = smbCalcSize_LE(smb);
 
        if (4 + len != length) {
-               cERROR(1, ("Length read does not match RFC1001 length %d",
-                          len));
+               cERROR(1, "Length read does not match RFC1001 length %d",
+                          len);
                return 1;
        }
 
@@ -466,8 +465,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                        if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
                                return 0; /* bcc wrapped */
                }
-               cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
-                               clc_len, 4 + len, smb->Mid));
+               cFYI(1, "Calculated size %d vs length %d mismatch for mid %d",
+                               clc_len, 4 + len, smb->Mid);
                /* Windows XP can return a few bytes too much, presumably
                an illegal pad, at the end of byte range lock responses
                so we allow for that three byte pad, as long as actual
@@ -482,8 +481,8 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                if ((4+len > clc_len) && (len <= clc_len + 512))
                        return 0;
                else {
-                       cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
-                                       len, smb->Mid));
+                       cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d",
+                                       len, smb->Mid);
                        return 1;
                }
        }
@@ -501,7 +500,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
        struct cifsFileInfo *netfile;
        int rc;
 
-       cFYI(1, ("Checking for oplock break or dnotify response"));
+       cFYI(1, "Checking for oplock break or dnotify response");
        if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
           (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
                struct smb_com_transaction_change_notify_rsp *pSMBr =
@@ -513,15 +512,15 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
 
                        pnotify = (struct file_notify_information *)
                                ((char *)&pSMBr->hdr.Protocol + data_offset);
-                       cFYI(1, ("dnotify on %s Action: 0x%x",
-                                pnotify->FileName, pnotify->Action));
+                       cFYI(1, "dnotify on %s Action: 0x%x",
+                                pnotify->FileName, pnotify->Action);
                        /*   cifs_dump_mem("Rcvd notify Data: ",buf,
                                sizeof(struct smb_hdr)+60); */
                        return true;
                }
                if (pSMBr->hdr.Status.CifsError) {
-                       cFYI(1, ("notify err 0x%d",
-                               pSMBr->hdr.Status.CifsError));
+                       cFYI(1, "notify err 0x%d",
+                               pSMBr->hdr.Status.CifsError);
                        return true;
                }
                return false;
@@ -535,7 +534,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                   large dirty files cached on the client */
                if ((NT_STATUS_INVALID_HANDLE) ==
                   le32_to_cpu(pSMB->hdr.Status.CifsError)) {
-                       cFYI(1, ("invalid handle on oplock break"));
+                       cFYI(1, "invalid handle on oplock break");
                        return true;
                } else if (ERRbadfid ==
                   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
@@ -547,8 +546,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
        if (pSMB->hdr.WordCount != 8)
                return false;
 
-       cFYI(1, ("oplock type 0x%d level 0x%d",
-                pSMB->LockType, pSMB->OplockLevel));
+       cFYI(1, "oplock type 0x%d level 0x%d",
+                pSMB->LockType, pSMB->OplockLevel);
        if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
                return false;
 
@@ -579,15 +578,15 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                                        return true;
                                }
 
-                               cFYI(1, ("file id match, oplock break"));
+                               cFYI(1, "file id match, oplock break");
                                pCifsInode = CIFS_I(netfile->pInode);
                                pCifsInode->clientCanCacheAll = false;
                                if (pSMB->OplockLevel == 0)
                                        pCifsInode->clientCanCacheRead = false;
                                rc = slow_work_enqueue(&netfile->oplock_break);
                                if (rc) {
-                                       cERROR(1, ("failed to enqueue oplock "
-                                                  "break: %d\n", rc));
+                                       cERROR(1, "failed to enqueue oplock "
+                                                  "break: %d\n", rc);
                                } else {
                                        netfile->oplock_break_cancelled = false;
                                }
@@ -597,12 +596,12 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                        }
                        read_unlock(&GlobalSMBSeslock);
                        read_unlock(&cifs_tcp_ses_lock);
-                       cFYI(1, ("No matching file for oplock break"));
+                       cFYI(1, "No matching file for oplock break");
                        return true;
                }
        }
        read_unlock(&cifs_tcp_ses_lock);
-       cFYI(1, ("Can not process oplock break for non-existent connection"));
+       cFYI(1, "Can not process oplock break for non-existent connection");
        return true;
 }
 
@@ -721,11 +720,11 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
 {
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
                cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
-               cERROR(1, ("Autodisabling the use of server inode numbers on "
+               cERROR(1, "Autodisabling the use of server inode numbers on "
                           "%s. This server doesn't seem to support them "
                           "properly. Hardlinks will not be recognized on this "
                           "mount. Consider mounting with the \"noserverino\" "
                           "option to silence this message.",
-                          cifs_sb->tcon->treeName));
+                          cifs_sb->tcon->treeName);
        }
 }
index bd6d689..d35d528 100644 (file)
@@ -149,7 +149,7 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst)
        else if (address_family == AF_INET6)
                ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
 
-       cFYI(DBG2, ("address conversion returned %d for %s", ret, cp));
+       cFYI(DBG2, "address conversion returned %d for %s", ret, cp);
        if (ret > 0)
                ret = 1;
        return ret;
@@ -870,8 +870,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
        }
        /* else ERRHRD class errors or junk  - return EIO */
 
-       cFYI(1, ("Mapping smb error code %d to POSIX err %d",
-                smberrcode, rc));
+       cFYI(1, "Mapping smb error code %d to POSIX err %d",
+                smberrcode, rc);
 
        /* generic corrective action e.g. reconnect SMB session on
         * ERRbaduid could be added */
@@ -940,20 +940,20 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
        SMB_TIME *st = (SMB_TIME *)&time;
        SMB_DATE *sd = (SMB_DATE *)&date;
 
-       cFYI(1, ("date %d time %d", date, time));
+       cFYI(1, "date %d time %d", date, time);
 
        sec = 2 * st->TwoSeconds;
        min = st->Minutes;
        if ((sec > 59) || (min > 59))
-               cERROR(1, ("illegal time min %d sec %d", min, sec));
+               cERROR(1, "illegal time min %d sec %d", min, sec);
        sec += (min * 60);
        sec += 60 * 60 * st->Hours;
        if (st->Hours > 24)
-               cERROR(1, ("illegal hours %d", st->Hours));
+               cERROR(1, "illegal hours %d", st->Hours);
        days = sd->Day;
        month = sd->Month;
        if ((days > 31) || (month > 12)) {
-               cERROR(1, ("illegal date, month %d day: %d", month, days));
+               cERROR(1, "illegal date, month %d day: %d", month, days);
                if (month > 12)
                        month = 12;
        }
@@ -979,7 +979,7 @@ struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
 
        ts.tv_sec = sec + offset;
 
-       /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
+       /* cFYI(1, "sec after cnvrt dos to unix time %d",sec); */
 
        ts.tv_nsec = 0;
        return ts;
index 18e0bc1..daf1753 100644 (file)
@@ -47,15 +47,15 @@ static void dump_cifs_file_struct(struct file *file, char *label)
        if (file) {
                cf = file->private_data;
                if (cf == NULL) {
-                       cFYI(1, ("empty cifs private file data"));
+                       cFYI(1, "empty cifs private file data");
                        return;
                }
                if (cf->invalidHandle)
-                       cFYI(1, ("invalid handle"));
+                       cFYI(1, "invalid handle");
                if (cf->srch_inf.endOfSearch)
-                       cFYI(1, ("end of search"));
+                       cFYI(1, "end of search");
                if (cf->srch_inf.emptyDir)
-                       cFYI(1, ("empty dir"));
+                       cFYI(1, "empty dir");
        }
 }
 #else
@@ -76,7 +76,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
        struct inode *inode;
        struct super_block *sb = parent->d_inode->i_sb;
 
-       cFYI(1, ("For %s", name->name));
+       cFYI(1, "For %s", name->name);
 
        if (parent->d_op && parent->d_op->d_hash)
                parent->d_op->d_hash(parent, name);
@@ -214,7 +214,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
                                fid,
                                cifs_sb->local_nls);
                if (CIFSSMBClose(xid, ptcon, fid)) {
-                       cFYI(1, ("Error closing temporary reparsepoint open)"));
+                       cFYI(1, "Error closing temporary reparsepoint open");
                }
        }
 }
@@ -252,7 +252,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
        if (full_path == NULL)
                return -ENOMEM;
 
-       cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos));
+       cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos);
 
 ffirst_retry:
        /* test for Unix extensions */
@@ -297,7 +297,7 @@ static int cifs_unicode_bytelen(char *str)
                if (ustr[len] == 0)
                        return len << 1;
        }
-       cFYI(1, ("Unicode string longer than PATH_MAX found"));
+       cFYI(1, "Unicode string longer than PATH_MAX found");
        return len << 1;
 }
 
@@ -314,19 +314,18 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
                                pfData->FileNameLength;
        } else
                new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
-       cFYI(1, ("new entry %p old entry %p", new_entry, old_entry));
+       cFYI(1, "new entry %p old entry %p", new_entry, old_entry);
        /* validate that new_entry is not past end of SMB */
        if (new_entry >= end_of_smb) {
-               cERROR(1,
-                     ("search entry %p began after end of SMB %p old entry %p",
-                       new_entry, end_of_smb, old_entry));
+               cERROR(1, "search entry %p began after end of SMB %p old entry %p",
+                       new_entry, end_of_smb, old_entry);
                return NULL;
        } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
                    (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))
                  || ((level != SMB_FIND_FILE_INFO_STANDARD) &&
                   (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb)))  {
-               cERROR(1, ("search entry %p extends after end of SMB %p",
-                       new_entry, end_of_smb));
+               cERROR(1, "search entry %p extends after end of SMB %p",
+                       new_entry, end_of_smb);
                return NULL;
        } else
                return new_entry;
@@ -380,8 +379,8 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
                filename = &pFindData->FileName[0];
                len = pFindData->FileNameLength;
        } else {
-               cFYI(1, ("Unknown findfirst level %d",
-                        cfile->srch_inf.info_level));
+               cFYI(1, "Unknown findfirst level %d",
+                        cfile->srch_inf.info_level);
        }
 
        if (filename) {
@@ -481,7 +480,7 @@ static int cifs_save_resume_key(const char *current_entry,
                len = (unsigned int)pFindData->FileNameLength;
                cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
        } else {
-               cFYI(1, ("Unknown findfirst level %d", level));
+               cFYI(1, "Unknown findfirst level %d", level);
                return -EINVAL;
        }
        cifsFile->srch_inf.resume_name_len = len;
@@ -525,7 +524,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
             is_dir_changed(file)) ||
           (index_to_find < first_entry_in_buffer)) {
                /* close and restart search */
-               cFYI(1, ("search backing up - close and restart search"));
+               cFYI(1, "search backing up - close and restart search");
                write_lock(&GlobalSMBSeslock);
                if (!cifsFile->srch_inf.endOfSearch &&
                    !cifsFile->invalidHandle) {
@@ -535,7 +534,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                } else
                        write_unlock(&GlobalSMBSeslock);
                if (cifsFile->srch_inf.ntwrk_buf_start) {
-                       cFYI(1, ("freeing SMB ff cache buf on search rewind"));
+                       cFYI(1, "freeing SMB ff cache buf on search rewind");
                        if (cifsFile->srch_inf.smallBuf)
                                cifs_small_buf_release(cifsFile->srch_inf.
                                                ntwrk_buf_start);
@@ -546,8 +545,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                }
                rc = initiate_cifs_search(xid, file);
                if (rc) {
-                       cFYI(1, ("error %d reinitiating a search on rewind",
-                                rc));
+                       cFYI(1, "error %d reinitiating a search on rewind",
+                                rc);
                        return rc;
                }
                cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
@@ -555,7 +554,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
 
        while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
              (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
-               cFYI(1, ("calling findnext2"));
+               cFYI(1, "calling findnext2");
                rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
                                  &cifsFile->srch_inf);
                cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
@@ -575,7 +574,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
                                        - cifsFile->srch_inf.entries_in_buffer;
                pos_in_buf = index_to_find - first_entry_in_buffer;
-               cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf));
+               cFYI(1, "found entry - pos_in_buf %d", pos_in_buf);
 
                for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
                        /* go entry by entry figuring out which is first */
@@ -584,19 +583,19 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                }
                if ((current_entry == NULL) && (i < pos_in_buf)) {
                        /* BB fixme - check if we should flag this error */
-                       cERROR(1, ("reached end of buf searching for pos in buf"
+                       cERROR(1, "reached end of buf searching for pos in buf"
                          " %d index to find %lld rc %d",
-                         pos_in_buf, index_to_find, rc));
+                         pos_in_buf, index_to_find, rc);
                }
                rc = 0;
                *ppCurrentEntry = current_entry;
        } else {
-               cFYI(1, ("index not in buffer - could not findnext into it"));
+               cFYI(1, "index not in buffer - could not findnext into it");
                return 0;
        }
 
        if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
-               cFYI(1, ("can not return entries pos_in_buf beyond last"));
+               cFYI(1, "can not return entries pos_in_buf beyond last");
                *num_to_ret = 0;
        } else
                *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
@@ -656,12 +655,12 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
                /* one byte length, no name conversion */
                len = (unsigned int)pFindData->FileNameLength;
        } else {
-               cFYI(1, ("Unknown findfirst level %d", level));
+               cFYI(1, "Unknown findfirst level %d", level);
                return -EINVAL;
        }
 
        if (len > max_len) {
-               cERROR(1, ("bad search response length %d past smb end", len));
+               cERROR(1, "bad search response length %d past smb end", len);
                return -EINVAL;
        }
 
@@ -754,7 +753,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
         * case already. Why should we be clobbering other errors from it?
         */
        if (rc) {
-               cFYI(1, ("filldir rc = %d", rc));
+               cFYI(1, "filldir rc = %d", rc);
                rc = -EOVERFLOW;
        }
        dput(tmp_dentry);
@@ -786,7 +785,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
        case 0:
                if (filldir(direntry, ".", 1, file->f_pos,
                     file->f_path.dentry->d_inode->i_ino, DT_DIR) < 0) {
-                       cERROR(1, ("Filldir for current dir failed"));
+                       cERROR(1, "Filldir for current dir failed");
                        rc = -ENOMEM;
                        break;
                }
@@ -794,7 +793,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
        case 1:
                if (filldir(direntry, "..", 2, file->f_pos,
                     file->f_path.dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
-                       cERROR(1, ("Filldir for parent dir failed"));
+                       cERROR(1, "Filldir for parent dir failed");
                        rc = -ENOMEM;
                        break;
                }
@@ -807,7 +806,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 
                if (file->private_data == NULL) {
                        rc = initiate_cifs_search(xid, file);
-                       cFYI(1, ("initiate cifs search rc %d", rc));
+                       cFYI(1, "initiate cifs search rc %d", rc);
                        if (rc) {
                                FreeXid(xid);
                                return rc;
@@ -821,7 +820,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                cifsFile = file->private_data;
                if (cifsFile->srch_inf.endOfSearch) {
                        if (cifsFile->srch_inf.emptyDir) {
-                               cFYI(1, ("End of search, empty dir"));
+                               cFYI(1, "End of search, empty dir");
                                rc = 0;
                                break;
                        }
@@ -833,16 +832,16 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                rc = find_cifs_entry(xid, pTcon, file,
                                &current_entry, &num_to_fill);
                if (rc) {
-                       cFYI(1, ("fce error %d", rc));
+                       cFYI(1, "fce error %d", rc);
                        goto rddir2_exit;
                } else if (current_entry != NULL) {
-                       cFYI(1, ("entry %lld found", file->f_pos));
+                       cFYI(1, "entry %lld found", file->f_pos);
                } else {
-                       cFYI(1, ("could not find entry"));
+                       cFYI(1, "could not find entry");
                        goto rddir2_exit;
                }
-               cFYI(1, ("loop through %d times filling dir for net buf %p",
-                       num_to_fill, cifsFile->srch_inf.ntwrk_buf_start));
+               cFYI(1, "loop through %d times filling dir for net buf %p",
+                       num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
                max_len = smbCalcSize((struct smb_hdr *)
                                cifsFile->srch_inf.ntwrk_buf_start);
                end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
@@ -851,8 +850,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
                        if (current_entry == NULL) {
                                /* evaluate whether this case is an error */
-                               cERROR(1, ("past SMB end,  num to fill %d i %d",
-                                         num_to_fill, i));
+                               cERROR(1, "past SMB end,  num to fill %d i %d",
+                                         num_to_fill, i);
                                break;
                        }
                        /* if buggy server returns . and .. late do
@@ -867,8 +866,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                        file->f_pos++;
                        if (file->f_pos ==
                                cifsFile->srch_inf.index_of_last_entry) {
-                               cFYI(1, ("last entry in buf at pos %lld %s",
-                                       file->f_pos, tmp_buf));
+                               cFYI(1, "last entry in buf at pos %lld %s",
+                                       file->f_pos, tmp_buf);
                                cifs_save_resume_key(current_entry, cifsFile);
                                break;
                        } else
index 7c3fd74..7707389 100644 (file)
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
                         unsigned char *p24);
 
-/* Checks if this is the first smb session to be reconnected after
-   the socket has been reestablished (so we know whether to use vc 0).
-   Called while holding the cifs_tcp_ses_lock, so do not block */
+/*
+ * Checks if this is the first smb session to be reconnected after
+ * the socket has been reestablished (so we know whether to use vc 0).
+ * Called while holding the cifs_tcp_ses_lock, so do not block
+ */
 static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
 {
        struct list_head *tmp;
@@ -284,7 +286,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
        int len;
        char *data = *pbcc_area;
 
-       cFYI(1, ("bleft %d", bleft));
+       cFYI(1, "bleft %d", bleft);
 
        /*
         * Windows servers do not always double null terminate their final
@@ -301,7 +303,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
 
        kfree(ses->serverOS);
        ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
-       cFYI(1, ("serverOS=%s", ses->serverOS));
+       cFYI(1, "serverOS=%s", ses->serverOS);
        len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
        data += len;
        bleft -= len;
@@ -310,7 +312,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
 
        kfree(ses->serverNOS);
        ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
-       cFYI(1, ("serverNOS=%s", ses->serverNOS));
+       cFYI(1, "serverNOS=%s", ses->serverNOS);
        len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
        data += len;
        bleft -= len;
@@ -319,7 +321,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
 
        kfree(ses->serverDomain);
        ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
-       cFYI(1, ("serverDomain=%s", ses->serverDomain));
+       cFYI(1, "serverDomain=%s", ses->serverDomain);
 
        return;
 }
@@ -332,7 +334,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        int len;
        char *bcc_ptr = *pbcc_area;
 
-       cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
+       cFYI(1, "decode sessetup ascii. bleft %d", bleft);
 
        len = strnlen(bcc_ptr, bleft);
        if (len >= bleft)
@@ -344,7 +346,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        if (ses->serverOS)
                strncpy(ses->serverOS, bcc_ptr, len);
        if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
-                       cFYI(1, ("OS/2 server"));
+                       cFYI(1, "OS/2 server");
                        ses->flags |= CIFS_SES_OS2;
        }
 
@@ -373,7 +375,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
        /* BB For newer servers which do not support Unicode,
           but thus do return domain here we could add parsing
           for it later, but it is not very important */
-       cFYI(1, ("ascii: bytes left %d", bleft));
+       cFYI(1, "ascii: bytes left %d", bleft);
 
        return rc;
 }
@@ -384,16 +386,16 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
        CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
 
        if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
-               cERROR(1, ("challenge blob len %d too small", blob_len));
+               cERROR(1, "challenge blob len %d too small", blob_len);
                return -EINVAL;
        }
 
        if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
-               cERROR(1, ("blob signature incorrect %s", pblob->Signature));
+               cERROR(1, "blob signature incorrect %s", pblob->Signature);
                return -EINVAL;
        }
        if (pblob->MessageType != NtLmChallenge) {
-               cERROR(1, ("Incorrect message type %d", pblob->MessageType));
+               cERROR(1, "Incorrect message type %d", pblob->MessageType);
                return -EINVAL;
        }
 
@@ -447,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
    This function returns the length of the data in the blob */
 static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                                   struct cifsSesInfo *ses,
-                                  const struct nls_table *nls_cp, int first)
+                                  const struct nls_table *nls_cp, bool first)
 {
        AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
        __u32 flags;
@@ -546,7 +548,7 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
 
 static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
                                  struct cifsSesInfo *ses,
-                                 const struct nls_table *nls, int first_time)
+                                 const struct nls_table *nls, bool first_time)
 {
        int bloblen;
 
@@ -559,8 +561,8 @@ static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,
 #endif
 
 int
-CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
-               const struct nls_table *nls_cp)
+CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
+              const struct nls_table *nls_cp)
 {
        int rc = 0;
        int wct;
@@ -577,13 +579,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
        int bytes_remaining;
        struct key *spnego_key = NULL;
        __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
+       bool first_time;
 
        if (ses == NULL)
                return -EINVAL;
 
+       read_lock(&cifs_tcp_ses_lock);
+       first_time = is_first_ses_reconnect(ses);
+       read_unlock(&cifs_tcp_ses_lock);
+
        type = ses->server->secType;
 
-       cFYI(1, ("sess setup type %d", type));
+       cFYI(1, "sess setup type %d", type);
 ssetup_ntlmssp_authenticate:
        if (phase == NtLmChallenge)
                phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
@@ -664,7 +671,7 @@ ssetup_ntlmssp_authenticate:
                changed to do higher than lanman dialect and
                we reconnected would we ever calc signing_key? */
 
-               cFYI(1, ("Negotiating LANMAN setting up strings"));
+               cFYI(1, "Negotiating LANMAN setting up strings");
                /* Unicode not allowed for LANMAN dialects */
                ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 #endif
@@ -744,7 +751,7 @@ ssetup_ntlmssp_authenticate:
                        unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
                } else
                        ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
-       } else if (type == Kerberos || type == MSKerberos) {
+       } else if (type == Kerberos) {
 #ifdef CONFIG_CIFS_UPCALL
                struct cifs_spnego_msg *msg;
                spnego_key = cifs_get_spnego_key(ses);
@@ -758,17 +765,17 @@ ssetup_ntlmssp_authenticate:
                /* check version field to make sure that cifs.upcall is
                   sending us a response in an expected form */
                if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
-                       cERROR(1, ("incorrect version of cifs.upcall (expected"
+                       cERROR(1, "incorrect version of cifs.upcall (expected"
                                   " %d but got %d)",
-                                  CIFS_SPNEGO_UPCALL_VERSION, msg->version));
+                                  CIFS_SPNEGO_UPCALL_VERSION, msg->version);
                        rc = -EKEYREJECTED;
                        goto ssetup_exit;
                }
                /* bail out if key is too long */
                if (msg->sesskey_len >
                    sizeof(ses->server->mac_signing_key.data.krb5)) {
-                       cERROR(1, ("Kerberos signing key too long (%u bytes)",
-                               msg->sesskey_len));
+                       cERROR(1, "Kerberos signing key too long (%u bytes)",
+                               msg->sesskey_len);
                        rc = -EOVERFLOW;
                        goto ssetup_exit;
                }
@@ -796,7 +803,7 @@ ssetup_ntlmssp_authenticate:
                /* BB: is this right? */
                        ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 #else /* ! CONFIG_CIFS_UPCALL */
-               cERROR(1, ("Kerberos negotiated but upcall support disabled!"));
+               cERROR(1, "Kerberos negotiated but upcall support disabled!");
                rc = -ENOSYS;
                goto ssetup_exit;
 #endif /* CONFIG_CIFS_UPCALL */
@@ -804,12 +811,12 @@ ssetup_ntlmssp_authenticate:
 #ifdef CONFIG_CIFS_EXPERIMENTAL
                if (type == RawNTLMSSP) {
                        if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
-                               cERROR(1, ("NTLMSSP requires Unicode support"));
+                               cERROR(1, "NTLMSSP requires Unicode support");
                                rc = -ENOSYS;
                                goto ssetup_exit;
                        }
 
-                       cFYI(1, ("ntlmssp session setup phase %d", phase));
+                       cFYI(1, "ntlmssp session setup phase %d", phase);
                        pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
                        capabilities |= CAP_EXTENDED_SECURITY;
                        pSMB->req.Capabilities |= cpu_to_le32(capabilities);
@@ -827,7 +834,7 @@ ssetup_ntlmssp_authenticate:
                                   on the response (challenge) */
                                smb_buf->Uid = ses->Suid;
                        } else {
-                               cERROR(1, ("invalid phase %d", phase));
+                               cERROR(1, "invalid phase %d", phase);
                                rc = -ENOSYS;
                                goto ssetup_exit;
                        }
@@ -839,12 +846,12 @@ ssetup_ntlmssp_authenticate:
                        }
                        unicode_oslm_strings(&bcc_ptr, nls_cp);
                } else {
-                       cERROR(1, ("secType %d not supported!", type));
+                       cERROR(1, "secType %d not supported!", type);
                        rc = -ENOSYS;
                        goto ssetup_exit;
                }
 #else
-               cERROR(1, ("secType %d not supported!", type));
+               cERROR(1, "secType %d not supported!", type);
                rc = -ENOSYS;
                goto ssetup_exit;
 #endif
@@ -862,7 +869,7 @@ ssetup_ntlmssp_authenticate:
                          CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
        /* SMB request buf freed in SendReceive2 */
 
-       cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
+       cFYI(1, "ssetup rc from sendrecv2 is %d", rc);
 
        pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
        smb_buf = (struct smb_hdr *)iov[0].iov_base;
@@ -870,7 +877,7 @@ ssetup_ntlmssp_authenticate:
        if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
                        cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
                if (phase != NtLmNegotiate) {
-                       cERROR(1, ("Unexpected more processing error"));
+                       cERROR(1, "Unexpected more processing error");
                        goto ssetup_exit;
                }
                /* NTLMSSP Negotiate sent now processing challenge (response) */
@@ -882,14 +889,14 @@ ssetup_ntlmssp_authenticate:
 
        if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
                rc = -EIO;
-               cERROR(1, ("bad word count %d", smb_buf->WordCount));
+               cERROR(1, "bad word count %d", smb_buf->WordCount);
                goto ssetup_exit;
        }
        action = le16_to_cpu(pSMB->resp.Action);
        if (action & GUEST_LOGIN)
-               cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
+               cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
-       cFYI(1, ("UID = %d ", ses->Suid));
+       cFYI(1, "UID = %d ", ses->Suid);
        /* response can have either 3 or 4 word count - Samba sends 3 */
        /* and lanman response is 3 */
        bytes_remaining = BCC(smb_buf);
@@ -899,7 +906,7 @@ ssetup_ntlmssp_authenticate:
                __u16 blob_len;
                blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
                if (blob_len > bytes_remaining) {
-                       cERROR(1, ("bad security blob length %d", blob_len));
+                       cERROR(1, "bad security blob length %d", blob_len);
                        rc = -EINVAL;
                        goto ssetup_exit;
                }
@@ -933,7 +940,7 @@ ssetup_exit:
        }
        kfree(str_area);
        if (resp_buf_type == CIFS_SMALL_BUFFER) {
-               cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
+               cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
                cifs_small_buf_release(iov[0].iov_base);
        } else if (resp_buf_type == CIFS_LARGE_BUFFER)
                cifs_buf_release(iov[0].iov_base);
index ad081fe..82f78c4 100644 (file)
@@ -35,7 +35,6 @@
 #include "cifs_debug.h"
 
 extern mempool_t *cifs_mid_poolp;
-extern struct kmem_cache *cifs_oplock_cachep;
 
 static struct mid_q_entry *
 AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
@@ -43,7 +42,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
        struct mid_q_entry *temp;
 
        if (server == NULL) {
-               cERROR(1, ("Null TCP session in AllocMidQEntry"));
+               cERROR(1, "Null TCP session in AllocMidQEntry");
                return NULL;
        }
 
@@ -55,7 +54,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
                temp->mid = smb_buffer->Mid;    /* always LE */
                temp->pid = current->pid;
                temp->command = smb_buffer->Command;
-               cFYI(1, ("For smb_command %d", temp->command));
+               cFYI(1, "For smb_command %d", temp->command);
        /*      do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
                /* when mid allocated can be before when sent */
                temp->when_alloc = jiffies;
@@ -140,7 +139,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                total_len += iov[i].iov_len;
 
        smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
-       cFYI(1, ("Sending smb:  total_len %d", total_len));
+       cFYI(1, "Sending smb:  total_len %d", total_len);
        dump_smb(smb_buffer, len);
 
        i = 0;
@@ -168,9 +167,8 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                           reconnect which may clear the network problem.
                        */
                        if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
-                               cERROR(1,
-                                  ("sends on sock %p stuck for 15 seconds",
-                                   ssocket));
+                               cERROR(1, "sends on sock %p stuck for 15 seconds",
+                                   ssocket);
                                rc = -EAGAIN;
                                break;
                        }
@@ -184,13 +182,13 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                        total_len = 0;
                        break;
                } else if (rc > total_len) {
-                       cERROR(1, ("sent %d requested %d", rc, total_len));
+                       cERROR(1, "sent %d requested %d", rc, total_len);
                        break;
                }
                if (rc == 0) {
                        /* should never happen, letting socket clear before
                           retrying is our only obvious option here */
-                       cERROR(1, ("tcp sent no data"));
+                       cERROR(1, "tcp sent no data");
                        msleep(500);
                        continue;
                }
@@ -213,8 +211,8 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
        }
 
        if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
-               cFYI(1, ("partial send (%d remaining), terminating session",
-                       total_len));
+               cFYI(1, "partial send (%d remaining), terminating session",
+                       total_len);
                /* If we have only sent part of an SMB then the next SMB
                   could be taken as the remainder of this one.  We need
                   to kill the socket so the server throws away the partial
@@ -223,7 +221,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
        }
 
        if (rc < 0) {
-               cERROR(1, ("Error %d sending data on socket to server", rc));
+               cERROR(1, "Error %d sending data on socket to server", rc);
        } else
                rc = 0;
 
@@ -296,7 +294,7 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
        }
 
        if (ses->server->tcpStatus == CifsNeedReconnect) {
-               cFYI(1, ("tcp session dead - return to caller to retry"));
+               cFYI(1, "tcp session dead - return to caller to retry");
                return -EAGAIN;
        }
 
@@ -348,7 +346,7 @@ static int wait_for_response(struct cifsSesInfo *ses,
                        lrt += time_to_wait;
                        if (time_after(jiffies, lrt)) {
                                /* No replies for time_to_wait. */
-                               cERROR(1, ("server not responding"));
+                               cERROR(1, "server not responding");
                                return -1;
                        }
                } else {
@@ -379,7 +377,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
        iov[0].iov_len = in_buf->smb_buf_length + 4;
        flags |= CIFS_NO_RESP;
        rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
-       cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc));
+       cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
 
        return rc;
 }
@@ -402,7 +400,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
 
        if ((ses == NULL) || (ses->server == NULL)) {
                cifs_small_buf_release(in_buf);
-               cERROR(1, ("Null session"));
+               cERROR(1, "Null session");
                return -EIO;
        }
 
@@ -471,7 +469,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        else if (long_op == CIFS_BLOCKING_OP)
                timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */
        else {
-               cERROR(1, ("unknown timeout flag %d", long_op));
+               cERROR(1, "unknown timeout flag %d", long_op);
                rc = -EIO;
                goto out;
        }
@@ -490,8 +488,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        spin_lock(&GlobalMid_Lock);
 
        if (midQ->resp_buf == NULL) {
-               cERROR(1, ("No response to cmd %d mid %d",
-                       midQ->command, midQ->mid));
+               cERROR(1, "No response to cmd %d mid %d",
+                       midQ->command, midQ->mid);
                if (midQ->midState == MID_REQUEST_SUBMITTED) {
                        if (ses->server->tcpStatus == CifsExiting)
                                rc = -EHOSTDOWN;
@@ -504,7 +502,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                if (rc != -EHOSTDOWN) {
                        if (midQ->midState == MID_RETRY_NEEDED) {
                                rc = -EAGAIN;
-                               cFYI(1, ("marking request for retry"));
+                               cFYI(1, "marking request for retry");
                        } else {
                                rc = -EIO;
                        }
@@ -521,8 +519,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
        receive_len = midQ->resp_buf->smb_buf_length;
 
        if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
+               cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
+                       receive_len, xid);
                rc = -EIO;
                goto out;
        }
@@ -548,7 +546,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                                                &ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                        if (rc) {
-                               cERROR(1, ("Unexpected SMB signature"));
+                               cERROR(1, "Unexpected SMB signature");
                                /* BB FIXME add code to kill session */
                        }
                }
@@ -569,7 +567,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                                                   DeleteMidQEntry */
        } else {
                rc = -EIO;
-               cFYI(1, ("Bad MID state?"));
+               cFYI(1, "Bad MID state?");
        }
 
 out:
@@ -591,11 +589,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        struct mid_q_entry *midQ;
 
        if (ses == NULL) {
-               cERROR(1, ("Null smb session"));
+               cERROR(1, "Null smb session");
                return -EIO;
        }
        if (ses->server == NULL) {
-               cERROR(1, ("Null tcp session"));
+               cERROR(1, "Null tcp session");
                return -EIO;
        }
 
@@ -607,8 +605,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
           use ses->maxReq */
 
        if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("Illegal length, greater than maximum frame, %d",
-                          in_buf->smb_buf_length));
+               cERROR(1, "Illegal length, greater than maximum frame, %d",
+                          in_buf->smb_buf_length);
                return -EIO;
        }
 
@@ -665,7 +663,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        else if (long_op == CIFS_BLOCKING_OP)
                timeout = 0x7FFFFFFF; /* large but no so large as to wrap */
        else {
-               cERROR(1, ("unknown timeout flag %d", long_op));
+               cERROR(1, "unknown timeout flag %d", long_op);
                rc = -EIO;
                goto out;
        }
@@ -681,8 +679,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
 
        spin_lock(&GlobalMid_Lock);
        if (midQ->resp_buf == NULL) {
-               cERROR(1, ("No response for cmd %d mid %d",
-                         midQ->command, midQ->mid));
+               cERROR(1, "No response for cmd %d mid %d",
+                         midQ->command, midQ->mid);
                if (midQ->midState == MID_REQUEST_SUBMITTED) {
                        if (ses->server->tcpStatus == CifsExiting)
                                rc = -EHOSTDOWN;
@@ -695,7 +693,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                if (rc != -EHOSTDOWN) {
                        if (midQ->midState == MID_RETRY_NEEDED) {
                                rc = -EAGAIN;
-                               cFYI(1, ("marking request for retry"));
+                               cFYI(1, "marking request for retry");
                        } else {
                                rc = -EIO;
                        }
@@ -712,8 +710,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
        receive_len = midQ->resp_buf->smb_buf_length;
 
        if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
+               cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
+                       receive_len, xid);
                rc = -EIO;
                goto out;
        }
@@ -736,7 +734,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                                                &ses->server->mac_signing_key,
                                                midQ->sequence_number+1);
                        if (rc) {
-                               cERROR(1, ("Unexpected SMB signature"));
+                               cERROR(1, "Unexpected SMB signature");
                                /* BB FIXME add code to kill session */
                        }
                }
@@ -753,7 +751,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                        BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
        } else {
                rc = -EIO;
-               cERROR(1, ("Bad MID state?"));
+               cERROR(1, "Bad MID state?");
        }
 
 out:
@@ -824,13 +822,13 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
        struct cifsSesInfo *ses;
 
        if (tcon == NULL || tcon->ses == NULL) {
-               cERROR(1, ("Null smb session"));
+               cERROR(1, "Null smb session");
                return -EIO;
        }
        ses = tcon->ses;
 
        if (ses->server == NULL) {
-               cERROR(1, ("Null tcp session"));
+               cERROR(1, "Null tcp session");
                return -EIO;
        }
 
@@ -842,8 +840,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
           use ses->maxReq */
 
        if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
-               cERROR(1, ("Illegal length, greater than maximum frame, %d",
-                          in_buf->smb_buf_length));
+               cERROR(1, "Illegal length, greater than maximum frame, %d",
+                          in_buf->smb_buf_length);
                return -EIO;
        }
 
@@ -933,8 +931,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                spin_unlock(&GlobalMid_Lock);
                receive_len = midQ->resp_buf->smb_buf_length;
        } else {
-               cERROR(1, ("No response for cmd %d mid %d",
-                         midQ->command, midQ->mid));
+               cERROR(1, "No response for cmd %d mid %d",
+                         midQ->command, midQ->mid);
                if (midQ->midState == MID_REQUEST_SUBMITTED) {
                        if (ses->server->tcpStatus == CifsExiting)
                                rc = -EHOSTDOWN;
@@ -947,7 +945,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                if (rc != -EHOSTDOWN) {
                        if (midQ->midState == MID_RETRY_NEEDED) {
                                rc = -EAGAIN;
-                               cFYI(1, ("marking request for retry"));
+                               cFYI(1, "marking request for retry");
                        } else {
                                rc = -EIO;
                        }
@@ -958,8 +956,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
        }
 
        if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
-               cERROR(1, ("Frame too large received.  Length: %d  Xid: %d",
-                       receive_len, xid));
+               cERROR(1, "Frame too large received.  Length: %d  Xid: %d",
+                       receive_len, xid);
                rc = -EIO;
                goto out;
        }
@@ -968,7 +966,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
 
        if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
                rc = -EIO;
-               cERROR(1, ("Bad MID state?"));
+               cERROR(1, "Bad MID state?");
                goto out;
        }
 
@@ -986,7 +984,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                                           &ses->server->mac_signing_key,
                                           midQ->sequence_number+1);
                if (rc) {
-                       cERROR(1, ("Unexpected SMB signature"));
+                       cERROR(1, "Unexpected SMB signature");
                        /* BB FIXME add code to kill session */
                }
        }
index f555ce0..a150920 100644 (file)
@@ -70,12 +70,12 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
                return rc;
        }
        if (ea_name == NULL) {
-               cFYI(1, ("Null xattr names not supported"));
+               cFYI(1, "Null xattr names not supported");
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)
                && (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {
                cFYI(1,
-                   ("illegal xattr request %s (only user namespace supported)",
-                       ea_name));
+                    "illegal xattr request %s (only user namespace supported)",
+                    ea_name);
                /* BB what if no namespace prefix? */
                /* Should we just pass them to server, except for
                system and perhaps security prefixes? */
@@ -131,19 +131,19 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                search server for EAs or streams to
                returns as xattrs */
        if (value_size > MAX_EA_VALUE_SIZE) {
-               cFYI(1, ("size of EA value too large"));
+               cFYI(1, "size of EA value too large");
                kfree(full_path);
                FreeXid(xid);
                return -EOPNOTSUPP;
        }
 
        if (ea_name == NULL) {
-               cFYI(1, ("Null xattr names not supported"));
+               cFYI(1, "Null xattr names not supported");
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto set_ea_exit;
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
-                       cFYI(1, ("attempt to set cifs inode metadata"));
+                       cFYI(1, "attempt to set cifs inode metadata");
 
                ea_name += 5; /* skip past user. prefix */
                rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
@@ -169,9 +169,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                                        ACL_TYPE_ACCESS, cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       cFYI(1, ("set POSIX ACL rc %d", rc));
+                       cFYI(1, "set POSIX ACL rc %d", rc);
 #else
-                       cFYI(1, ("set POSIX ACL not supported"));
+                       cFYI(1, "set POSIX ACL not supported");
 #endif
                } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
                                   strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -182,13 +182,13 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                                        ACL_TYPE_DEFAULT, cifs_sb->local_nls,
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
-                       cFYI(1, ("set POSIX default ACL rc %d", rc));
+                       cFYI(1, "set POSIX default ACL rc %d", rc);
 #else
-                       cFYI(1, ("set default POSIX ACL not supported"));
+                       cFYI(1, "set default POSIX ACL not supported");
 #endif
                } else {
-                       cFYI(1, ("illegal xattr request %s (only user namespace"
-                                " supported)", ea_name));
+                       cFYI(1, "illegal xattr request %s (only user namespace"
+                               " supported)", ea_name);
                  /* BB what if no namespace prefix? */
                  /* Should we just pass them to server, except for
                  system and perhaps security prefixes? */
@@ -235,13 +235,13 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
        /* return dos attributes as pseudo xattr */
        /* return alt name if available as pseudo attr */
        if (ea_name == NULL) {
-               cFYI(1, ("Null xattr names not supported"));
+               cFYI(1, "Null xattr names not supported");
        } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto get_ea_exit;
 
                if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
-                       cFYI(1, ("attempt to query cifs inode metadata"));
+                       cFYI(1, "attempt to query cifs inode metadata");
                        /* revalidate/getattr then populate from inode */
                } /* BB add else when above is implemented */
                ea_name += 5; /* skip past user. prefix */
@@ -287,7 +287,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                }
 #endif /* EXPERIMENTAL */
 #else
-               cFYI(1, ("query POSIX ACL not supported yet"));
+               cFYI(1, "query POSIX ACL not supported yet");
 #endif /* CONFIG_CIFS_POSIX */
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
                          strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
@@ -299,18 +299,18 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                                cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 #else
-               cFYI(1, ("query POSIX default ACL not supported yet"));
+               cFYI(1, "query POSIX default ACL not supported yet");
 #endif
        } else if (strncmp(ea_name,
                  CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
-               cFYI(1, ("Trusted xattr namespace not supported yet"));
+               cFYI(1, "Trusted xattr namespace not supported yet");
        } else if (strncmp(ea_name,
                  CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
-               cFYI(1, ("Security xattr namespace not supported yet"));
+               cFYI(1, "Security xattr namespace not supported yet");
        } else
                cFYI(1,
-                   ("illegal xattr request %s (only user namespace supported)",
-                       ea_name));
+                   "illegal xattr request %s (only user namespace supported)",
+                    ea_name);
 
        /* We could add an additional check for streams ie
            if proc/fs/cifs/streamstoxattr is set then
index a1695dc..d97f993 100644 (file)
@@ -167,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
                return -EBUSY;
        }
 
+       error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
+       if (error)
+               goto bdi_err;
+
        vc->vc_sb = sb;
 
        sb->s_fs_info = vc;
@@ -175,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_blocksize_bits = 12;
        sb->s_magic = CODA_SUPER_MAGIC;
        sb->s_op = &coda_super_operations;
+       sb->s_bdi = &vc->bdi;
 
        /* get root fid from Venus: this needs the root inode */
        error = venus_rootfid(sb, &fid);
@@ -200,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
         return 0;
 
  error:
+       bdi_destroy(&vc->bdi);
+ bdi_err:
        if (root)
                iput(root);
        if (vc)
@@ -210,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
 
 static void coda_put_super(struct super_block *sb)
 {
+       bdi_destroy(&coda_vcp(sb)->bdi);
        coda_vcp(sb)->vc_sb = NULL;
        sb->s_fs_info = NULL;
 
index 4b6ed03..0544873 100644 (file)
@@ -1531,8 +1531,6 @@ int compat_do_execve(char * filename,
        if (retval < 0)
                goto out;
 
-       current->stack_start = current->mm->start_stack;
-
        /* execve succeeded */
        current->fs->in_exec = 0;
        current->in_execve = 0;
index c32a1b6..641640d 100644 (file)
 #include <linux/nbd.h>
 #include <linux/random.h>
 #include <linux/filter.h>
-#include <linux/pktcdvd.h>
 
 #include <linux/hiddev.h>
 
@@ -1126,8 +1125,6 @@ COMPATIBLE_IOCTL(PPGETMODE)
 COMPATIBLE_IOCTL(PPGETPHASE)
 COMPATIBLE_IOCTL(PPGETFLAGS)
 COMPATIBLE_IOCTL(PPSETFLAGS)
-/* pktcdvd */
-COMPATIBLE_IOCTL(PACKET_CTRL_CMD)
 /* Big A */
 /* sparc only */
 /* Big Q for sound/OSS */
index 8e48b52..0b502f8 100644 (file)
@@ -645,6 +645,7 @@ static void detach_groups(struct config_group *group)
 
                configfs_detach_group(sd->s_element);
                child->d_inode->i_flags |= S_DEAD;
+               dont_mount(child);
 
                mutex_unlock(&child->d_inode->i_mutex);
 
@@ -840,6 +841,7 @@ static int configfs_attach_item(struct config_item *parent_item,
                        mutex_lock(&dentry->d_inode->i_mutex);
                        configfs_remove_dir(item);
                        dentry->d_inode->i_flags |= S_DEAD;
+                       dont_mount(dentry);
                        mutex_unlock(&dentry->d_inode->i_mutex);
                        d_delete(dentry);
                }
@@ -882,6 +884,7 @@ static int configfs_attach_group(struct config_item *parent_item,
                if (ret) {
                        configfs_detach_item(item);
                        dentry->d_inode->i_flags |= S_DEAD;
+                       dont_mount(dentry);
                }
                configfs_adjust_dir_dirent_depth_after_populate(sd);
                mutex_unlock(&dentry->d_inode->i_mutex);
@@ -1725,6 +1728,7 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
        mutex_unlock(&configfs_symlink_mutex);
        configfs_detach_group(&group->cg_item);
        dentry->d_inode->i_flags |= S_DEAD;
+       dont_mount(dentry);
        mutex_unlock(&dentry->d_inode->i_mutex);
 
        d_delete(dentry);
index efb2b94..1cc0876 100644 (file)
@@ -382,8 +382,8 @@ out:
 static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
                                             struct ecryptfs_crypt_stat *crypt_stat)
 {
-       (*offset) = (crypt_stat->num_header_bytes_at_front
-                    + (crypt_stat->extent_size * extent_num));
+       (*offset) = ecryptfs_lower_header_size(crypt_stat)
+                   + (crypt_stat->extent_size * extent_num);
 }
 
 /**
@@ -835,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
        set_extent_mask_and_shift(crypt_stat);
        crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
        if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-               crypt_stat->num_header_bytes_at_front = 0;
+               crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
        else {
                if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
-                       crypt_stat->num_header_bytes_at_front =
+                       crypt_stat->metadata_size =
                                ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
                else
-                       crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE;
+                       crypt_stat->metadata_size = PAGE_CACHE_SIZE;
        }
 }
 
@@ -1108,9 +1108,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written)
        (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
 }
 
-static void
-write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
-                    size_t *written)
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    size_t *written)
 {
        u32 flags = 0;
        int i;
@@ -1238,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt,
 
        header_extent_size = (u32)crypt_stat->extent_size;
        num_header_extents_at_front =
-               (u16)(crypt_stat->num_header_bytes_at_front
-                     / crypt_stat->extent_size);
+               (u16)(crypt_stat->metadata_size / crypt_stat->extent_size);
        put_unaligned_be32(header_extent_size, virt);
        virt += 4;
        put_unaligned_be16(num_header_extents_at_front, virt);
@@ -1292,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
        offset = ECRYPTFS_FILE_SIZE_BYTES;
        write_ecryptfs_marker((page_virt + offset), &written);
        offset += written;
-       write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+       ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat,
+                                       &written);
        offset += written;
        ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
                                       &written);
@@ -1382,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = -EINVAL;
                goto out;
        }
-       virt_len = crypt_stat->num_header_bytes_at_front;
+       virt_len = crypt_stat->metadata_size;
        order = get_order(virt_len);
        /* Released in this function */
        virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
@@ -1428,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
        header_extent_size = get_unaligned_be32(virt);
        virt += sizeof(__be32);
        num_header_extents_at_front = get_unaligned_be16(virt);
-       crypt_stat->num_header_bytes_at_front =
-               (((size_t)num_header_extents_at_front
-                 * (size_t)header_extent_size));
+       crypt_stat->metadata_size = (((size_t)num_header_extents_at_front
+                                    * (size_t)header_extent_size));
        (*bytes_read) = (sizeof(__be32) + sizeof(__be16));
        if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
-           && (crypt_stat->num_header_bytes_at_front
+           && (crypt_stat->metadata_size
                < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
                rc = -EINVAL;
                printk(KERN_WARNING "Invalid header size: [%zd]\n",
-                      crypt_stat->num_header_bytes_at_front);
+                      crypt_stat->metadata_size);
        }
        return rc;
 }
@@ -1452,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
  */
 static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
 {
-       crypt_stat->num_header_bytes_at_front =
-               ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+       crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 }
 
 /**
@@ -1607,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
                                                ecryptfs_dentry,
                                                ECRYPTFS_VALIDATE_HEADER_SIZE);
        if (rc) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
                rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
                if (rc) {
                        printk(KERN_DEBUG "Valid eCryptfs headers not found in "
index 542f625..bfc2e0f 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/scatterlist.h>
 #include <linux/hash.h>
 #include <linux/nsproxy.h>
+#include <linux/backing-dev.h>
 
 /* Version verification for shared data structures w/ userspace */
 #define ECRYPTFS_VERSION_MAJOR 0x00
@@ -273,7 +274,7 @@ struct ecryptfs_crypt_stat {
        u32 flags;
        unsigned int file_version;
        size_t iv_bytes;
-       size_t num_header_bytes_at_front;
+       size_t metadata_size;
        size_t extent_size; /* Data extent size; default is 4096 */
        size_t key_size;
        size_t extent_shift;
@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat {
 struct ecryptfs_sb_info {
        struct super_block *wsi_sb;
        struct ecryptfs_mount_crypt_stat mount_crypt_stat;
+       struct backing_dev_info bdi;
 };
 
 /* file private data. */
@@ -464,6 +466,14 @@ struct ecryptfs_daemon {
 
 extern struct mutex ecryptfs_daemon_hash_mux;
 
+static inline size_t
+ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
+               return 0;
+       return crypt_stat->metadata_size;
+}
+
 static inline struct ecryptfs_file_info *
 ecryptfs_file_to_private(struct file *file)
 {
@@ -651,6 +661,9 @@ int ecryptfs_decrypt_page(struct page *page);
 int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    size_t *written);
 int ecryptfs_read_and_validate_header_region(char *data,
                                             struct inode *ecryptfs_inode);
 int ecryptfs_read_and_validate_xattr_region(char *page_virt,
index d3362fa..e2d4418 100644 (file)
@@ -324,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
        rc = ecryptfs_read_and_validate_header_region(page_virt,
                                                      ecryptfs_dentry->d_inode);
        if (rc) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
                rc = ecryptfs_read_and_validate_xattr_region(page_virt,
                                                             ecryptfs_dentry);
                if (rc) {
@@ -336,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
                ecryptfs_dentry->d_sb)->mount_crypt_stat;
        if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
                if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-                       file_size = (crypt_stat->num_header_bytes_at_front
+                       file_size = (crypt_stat->metadata_size
                                     + i_size_read(lower_dentry->d_inode));
                else
                        file_size = i_size_read(lower_dentry->d_inode);
@@ -388,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
-               printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-                      "lower_dentry = [%s]\n", __func__, rc,
-                      ecryptfs_dentry->d_name.name);
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+                               "[%d] on lower_dentry = [%s]\n", __func__, rc,
+                               encrypted_and_encoded_name);
                goto out_d_drop;
        }
        if (lower_dentry->d_inode)
@@ -417,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
-               printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-                      "lower_dentry = [%s]\n", __func__, rc,
-                      encrypted_and_encoded_name);
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+                               "[%d] on lower_dentry = [%s]\n", __func__, rc,
+                               encrypted_and_encoded_name);
                goto out_d_drop;
        }
 lookup_and_interpose:
@@ -456,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
        rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
        if (rc)
                goto out_lock;
-       fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
-       fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
+       fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
+       fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
        old_dentry->d_inode->i_nlink =
                ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
        i_size_write(new_dentry->d_inode, file_size_save);
@@ -648,38 +649,17 @@ out_lock:
        return rc;
 }
 
-static int
-ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
+                                  size_t *bufsiz)
 {
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
        char *lower_buf;
-       size_t lower_bufsiz;
-       struct dentry *lower_dentry;
-       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
-       char *plaintext_name;
-       size_t plaintext_name_size;
+       size_t lower_bufsiz = PATH_MAX;
        mm_segment_t old_fs;
        int rc;
 
-       lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       if (!lower_dentry->d_inode->i_op->readlink) {
-               rc = -EINVAL;
-               goto out;
-       }
-       mount_crypt_stat = &ecryptfs_superblock_to_private(
-                                               dentry->d_sb)->mount_crypt_stat;
-       /*
-        * If the lower filename is encrypted, it will result in a significantly
-        * longer name.  If needed, truncate the name after decode and decrypt.
-        */
-       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-               lower_bufsiz = PATH_MAX;
-       else
-               lower_bufsiz = bufsiz;
-       /* Released in this function */
        lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
-       if (lower_buf == NULL) {
-               printk(KERN_ERR "%s: Out of memory whilst attempting to "
-                      "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
+       if (!lower_buf) {
                rc = -ENOMEM;
                goto out;
        }
@@ -689,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
                                                   (char __user *)lower_buf,
                                                   lower_bufsiz);
        set_fs(old_fs);
-       if (rc >= 0) {
-               rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
-                                                         &plaintext_name_size,
-                                                         dentry, lower_buf,
-                                                         rc);
-               if (rc) {
-                       printk(KERN_ERR "%s: Error attempting to decode and "
-                              "decrypt filename; rc = [%d]\n", __func__,
-                               rc);
-                       goto out_free_lower_buf;
-               }
-               /* Check for bufsiz <= 0 done in sys_readlinkat() */
-               rc = copy_to_user(buf, plaintext_name,
-                                 min((size_t) bufsiz, plaintext_name_size));
-               if (rc)
-                       rc = -EFAULT;
-               else
-                       rc = plaintext_name_size;
-               kfree(plaintext_name);
-               fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
-       }
-out_free_lower_buf:
+       if (rc < 0)
+               goto out;
+       lower_bufsiz = rc;
+       rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
+                                                 lower_buf, lower_bufsiz);
+out:
        kfree(lower_buf);
+       return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+{
+       char *kbuf;
+       size_t kbufsiz, copied;
+       int rc;
+
+       rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
+       if (rc)
+               goto out;
+       copied = min_t(size_t, bufsiz, kbufsiz);
+       rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
+       kfree(kbuf);
+       fsstack_copy_attr_atime(dentry->d_inode,
+                               ecryptfs_dentry_to_lower(dentry)->d_inode);
 out:
        return rc;
 }
@@ -769,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
 {
        loff_t lower_size;
 
-       lower_size = crypt_stat->num_header_bytes_at_front;
+       lower_size = ecryptfs_lower_header_size(crypt_stat);
        if (upper_size != 0) {
                loff_t num_extents;
 
@@ -1016,6 +998,28 @@ out:
        return rc;
 }
 
+int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+                         struct kstat *stat)
+{
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+       int rc = 0;
+
+       mount_crypt_stat = &ecryptfs_superblock_to_private(
+                                               dentry->d_sb)->mount_crypt_stat;
+       generic_fillattr(dentry->d_inode, stat);
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
+               char *target;
+               size_t targetsiz;
+
+               rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
+               if (!rc) {
+                       kfree(target);
+                       stat->size = targetsiz;
+               }
+       }
+       return rc;
+}
+
 int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
                     struct kstat *stat)
 {
@@ -1040,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->setxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1058,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
        int rc = 0;
 
        if (!lower_dentry->d_inode->i_op->getxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1085,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->listxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1102,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->removexattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1133,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
        .put_link = ecryptfs_put_link,
        .permission = ecryptfs_permission,
        .setattr = ecryptfs_setattr,
+       .getattr = ecryptfs_getattr_link,
        .setxattr = ecryptfs_setxattr,
        .getxattr = ecryptfs_getxattr,
        .listxattr = ecryptfs_listxattr,
index af1a8f0..760983d 100644 (file)
@@ -497,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache;
 static int
 ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
+       struct ecryptfs_sb_info *esi;
        int rc = 0;
 
        /* Released in ecryptfs_put_super() */
        ecryptfs_set_superblock_private(sb,
                                        kmem_cache_zalloc(ecryptfs_sb_info_cache,
                                                         GFP_KERNEL));
-       if (!ecryptfs_superblock_to_private(sb)) {
+       esi = ecryptfs_superblock_to_private(sb);
+       if (!esi) {
                ecryptfs_printk(KERN_WARNING, "Out of memory\n");
                rc = -ENOMEM;
                goto out;
        }
+
+       rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY);
+       if (rc)
+               goto out;
+
+       sb->s_bdi = &esi->bdi;
        sb->s_op = &ecryptfs_sops;
        /* Released through deactivate_super(sb) from get_sb_nodev */
        sb->s_root = d_alloc(NULL, &(const struct qstr) {
index d491237..2ee9a3a 100644 (file)
@@ -83,6 +83,19 @@ out:
        return rc;
 }
 
+static void strip_xattr_flag(char *page_virt,
+                            struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+               size_t written;
+
+               crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR;
+               ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat,
+                                               &written);
+               crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
+       }
+}
+
 /**
  *   Header Extent:
  *     Octets 0-7:        Unencrypted file size (big-endian)
@@ -98,19 +111,6 @@ out:
  *                        (big-endian)
  *     Octet  26:         Begin RFC 2440 authentication token packet set
  */
-static void set_header_info(char *page_virt,
-                           struct ecryptfs_crypt_stat *crypt_stat)
-{
-       size_t written;
-       size_t save_num_header_bytes_at_front =
-               crypt_stat->num_header_bytes_at_front;
-
-       crypt_stat->num_header_bytes_at_front =
-               ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
-       ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
-       crypt_stat->num_header_bytes_at_front =
-               save_num_header_bytes_at_front;
-}
 
 /**
  * ecryptfs_copy_up_encrypted_with_header
@@ -136,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                                           * num_extents_per_page)
                                          + extent_num_in_page);
                size_t num_header_extents_at_front =
-                       (crypt_stat->num_header_bytes_at_front
-                        / crypt_stat->extent_size);
+                       (crypt_stat->metadata_size / crypt_stat->extent_size);
 
                if (view_extent_num < num_header_extents_at_front) {
                        /* This is a header extent */
@@ -147,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                        memset(page_virt, 0, PAGE_CACHE_SIZE);
                        /* TODO: Support more than one header extent */
                        if (view_extent_num == 0) {
+                               size_t written;
+
                                rc = ecryptfs_read_xattr_region(
                                        page_virt, page->mapping->host);
-                               set_header_info(page_virt, crypt_stat);
+                               strip_xattr_flag(page_virt + 16, crypt_stat);
+                               ecryptfs_write_header_metadata(page_virt + 20,
+                                                              crypt_stat,
+                                                              &written);
                        }
                        kunmap_atomic(page_virt, KM_USER0);
                        flush_dcache_page(page);
@@ -162,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                        /* This is an encrypted data extent */
                        loff_t lower_offset =
                                ((view_extent_num * crypt_stat->extent_size)
-                                - crypt_stat->num_header_bytes_at_front);
+                                - crypt_stat->metadata_size);
 
                        rc = ecryptfs_read_lower_page_segment(
                                page, (lower_offset >> PAGE_CACHE_SHIFT),
index fcef41c..0c0ae49 100644 (file)
@@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
                if (lower_dentry->d_inode) {
                        fput(inode_info->lower_file);
                        inode_info->lower_file = NULL;
-                       d_drop(lower_dentry);
                }
        }
        ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
@@ -123,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb)
        lock_kernel();
 
        ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
+       bdi_destroy(&sb_info->bdi);
        kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
        ecryptfs_set_superblock_private(sb, NULL);
 
index bd056a5..3817149 100644 (file)
@@ -1140,8 +1140,7 @@ retry:
                 * ep_poll_callback() when events will become available.
                 */
                init_waitqueue_entry(&wait, current);
-               wait.flags |= WQ_FLAG_EXCLUSIVE;
-               __add_wait_queue(&ep->wq, &wait);
+               __add_wait_queue_exclusive(&ep->wq, &wait);
 
                for (;;) {
                        /*
index 49cdaa1..e6e94c6 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1387,8 +1387,6 @@ int do_execve(char * filename,
        if (retval < 0)
                goto out;
 
-       current->stack_start = current->mm->start_stack;
-
        /* execve succeeded */
        current->fs->in_exec = 0;
        current->in_execve = 0;
index 8442e35..22721b2 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/fs.h>
 #include <linux/time.h>
+#include <linux/backing-dev.h>
 #include "common.h"
 
 /* FIXME: Remove once pnfs hits mainline
@@ -84,6 +85,7 @@ struct exofs_sb_info {
        u32             s_next_generation;      /* next gen # to use          */
        atomic_t        s_curr_pending;         /* number of pending commands */
        uint8_t         s_cred[OSD_CAP_LEN];    /* credential for the fscb    */
+       struct          backing_dev_info bdi;   /* register our bdi with VFS  */
 
        struct pnfs_osd_data_map data_map;      /* Default raid to use
                                                 * FIXME: Needed ?
index 18e57ea..03149b9 100644 (file)
@@ -302,6 +302,7 @@ static void exofs_put_super(struct super_block *sb)
        _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
                            sbi->layout.s_pid);
 
+       bdi_destroy(&sbi->bdi);
        exofs_free_sbi(sbi);
        sb->s_fs_info = NULL;
 }
@@ -546,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        if (!sbi)
                return -ENOMEM;
 
+       ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
+       if (ret)
+               goto free_bdi;
+
        /* use mount options to fill superblock */
        od = osduld_path_lookup(opts->dev_name);
        if (IS_ERR(od)) {
@@ -612,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        }
 
        /* set up operation vectors */
+       sb->s_bdi = &sbi->bdi;
        sb->s_fs_info = sbi;
        sb->s_op = &exofs_sops;
        sb->s_export_op = &exofs_export_ops;
@@ -643,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
        return 0;
 
 free_sbi:
+       bdi_destroy(&sbi->bdi);
+free_bdi:
        EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
                  opts->dev_name, sbi->layout.s_pid, ret);
        exofs_free_sbi(sbi);
index 4e2426e..565cf81 100644 (file)
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .setattr        = ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
 const struct inode_operations ext2_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = ext2_follow_link,
+       .setattr        = ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index ff7b4cc..7c48982 100644 (file)
@@ -34,6 +34,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
@@ -45,6 +46,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
 const struct inode_operations ext3_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = ext3_follow_link,
+       .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index 94c8ee8..236b834 100644 (file)
@@ -3879,6 +3879,7 @@ static int ext4_xattr_fiemap(struct inode *inode,
                physical += offset;
                length = EXT4_SB(inode->i_sb)->s_inode_size - offset;
                flags |= FIEMAP_EXTENT_DATA_INLINE;
+               brelse(iloc.bh);
        } else { /* external block */
                physical = EXT4_I(inode)->i_file_acl << blockbits;
                length = inode->i_sb->s_blocksize;
index 5381802..81d6054 100644 (file)
@@ -5375,7 +5375,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
        } else {
                struct ext4_iloc iloc;
 
-               err = ext4_get_inode_loc(inode, &iloc);
+               err = __ext4_get_inode_loc(inode, &iloc, 0);
                if (err)
                        return err;
                if (wbc->sync_mode == WB_SYNC_ALL)
@@ -5386,6 +5386,7 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
                                   (unsigned long long)iloc.bh->b_blocknr);
                        err = -EIO;
                }
+               brelse(iloc.bh);
        }
        return err;
 }
index bde9d0b..b423a36 100644 (file)
@@ -2535,6 +2535,17 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
                         entry->count, entry->group, entry);
 
+               if (test_opt(sb, DISCARD)) {
+                       ext4_fsblk_t discard_block;
+
+                       discard_block = entry->start_blk +
+                               ext4_group_first_block_no(sb, entry->group);
+                       trace_ext4_discard_blocks(sb,
+                                       (unsigned long long)discard_block,
+                                       entry->count);
+                       sb_issue_discard(sb, discard_block, entry->count);
+               }
+
                err = ext4_mb_load_buddy(sb, entry->group, &e4b);
                /* we expect to find existing buddy because it's pinned */
                BUG_ON(err != 0);
@@ -2556,16 +2567,6 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
                        page_cache_release(e4b.bd_bitmap_page);
                }
                ext4_unlock_group(sb, entry->group);
-               if (test_opt(sb, DISCARD)) {
-                       ext4_fsblk_t discard_block;
-
-                       discard_block = entry->start_blk +
-                               ext4_group_first_block_no(sb, entry->group);
-                       trace_ext4_discard_blocks(sb,
-                                       (unsigned long long)discard_block,
-                                       entry->count);
-                       sb_issue_discard(sb, discard_block, entry->count);
-               }
                kmem_cache_free(ext4_free_ext_cachep, entry);
                ext4_mb_release_desc(&e4b);
        }
index 407bf39..258ec22 100644 (file)
@@ -1205,8 +1205,6 @@ void generic_delete_inode(struct inode *inode)
        inodes_stat.nr_inodes--;
        spin_unlock(&inode_lock);
 
-       security_inode_delete(inode);
-
        if (op->delete_inode) {
                void (*delete)(struct inode *) = op->delete_inode;
                /* Filesystems implementing their own
index 6c75110..7faefb4 100644 (file)
@@ -228,14 +228,23 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
 
 #ifdef CONFIG_BLOCK
 
-#define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits)
-#define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits);
+static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
+{
+       return (offset >> inode->i_blkbits);
+}
+
+static inline loff_t blk_to_logical(struct inode *inode, sector_t blk)
+{
+       return (blk << inode->i_blkbits);
+}
 
 /**
  * __generic_block_fiemap - FIEMAP for block based inodes (no locking)
- * @inode - the inode to map
- * @arg - the pointer to userspace where we copy everything to
- * @get_block - the fs's get_block function
+ * @inode: the inode to map
+ * @fieinfo: the fiemap info struct that will be passed back to userspace
+ * @start: where to start mapping in the inode
+ * @len: how much space to map
+ * @get_block: the fs's get_block function
  *
  * This does FIEMAP for block based inodes.  Basically it will just loop
  * through get_block until we hit the number of extents we want to map, or we
@@ -250,58 +259,63 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg)
  */
 
 int __generic_block_fiemap(struct inode *inode,
-                          struct fiemap_extent_info *fieinfo, u64 start,
-                          u64 len, get_block_t *get_block)
+                          struct fiemap_extent_info *fieinfo, loff_t start,
+                          loff_t len, get_block_t *get_block)
 {
-       struct buffer_head tmp;
-       unsigned long long start_blk;
-       long long length = 0, map_len = 0;
+       struct buffer_head map_bh;
+       sector_t start_blk, last_blk;
+       loff_t isize = i_size_read(inode);
        u64 logical = 0, phys = 0, size = 0;
        u32 flags = FIEMAP_EXTENT_MERGED;
-       int ret = 0, past_eof = 0, whole_file = 0;
+       bool past_eof = false, whole_file = false;
+       int ret = 0;
 
-       if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC)))
+       ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
+       if (ret)
                return ret;
 
-       start_blk = logical_to_blk(inode, start);
-
-       length = (long long)min_t(u64, len, i_size_read(inode));
-       if (length < len)
-               whole_file = 1;
+       /*
+        * Either the i_mutex or other appropriate locking needs to be held
+        * since we expect isize to not change at all through the duration of
+        * this call.
+        */
+       if (len >= isize) {
+               whole_file = true;
+               len = isize;
+       }
 
-       map_len = length;
+       start_blk = logical_to_blk(inode, start);
+       last_blk = logical_to_blk(inode, start + len - 1);
 
        do {
                /*
                 * we set b_size to the total size we want so it will map as
                 * many contiguous blocks as possible at once
                 */
-               memset(&tmp, 0, sizeof(struct buffer_head));
-               tmp.b_size = map_len;
+               memset(&map_bh, 0, sizeof(struct buffer_head));
+               map_bh.b_size = len;
 
-               ret = get_block(inode, start_blk, &tmp, 0);
+               ret = get_block(inode, start_blk, &map_bh, 0);
                if (ret)
                        break;
 
                /* HOLE */
-               if (!buffer_mapped(&tmp)) {
-                       length -= blk_to_logical(inode, 1);
+               if (!buffer_mapped(&map_bh)) {
                        start_blk++;
 
                        /*
-                        * we want to handle the case where there is an
+                        * We want to handle the case where there is an
                         * allocated block at the front of the file, and then
                         * nothing but holes up to the end of the file properly,
                         * to make sure that extent at the front gets properly
                         * marked with FIEMAP_EXTENT_LAST
                         */
                        if (!past_eof &&
-                           blk_to_logical(inode, start_blk) >=
-                           blk_to_logical(inode, 0)+i_size_read(inode))
+                           blk_to_logical(inode, start_blk) >= isize)
                                past_eof = 1;
 
                        /*
-                        * first hole after going past the EOF, this is our
+                        * First hole after going past the EOF, this is our
                         * last extent
                         */
                        if (past_eof && size) {
@@ -309,15 +323,18 @@ int __generic_block_fiemap(struct inode *inode,
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
                                                              flags);
-                               break;
+                       } else if (size) {
+                               ret = fiemap_fill_next_extent(fieinfo, logical,
+                                                             phys, size, flags);
+                               size = 0;
                        }
 
                        /* if we have holes up to/past EOF then we're done */
-                       if (length <= 0 || past_eof)
+                       if (start_blk > last_blk || past_eof || ret)
                                break;
                } else {
                        /*
-                        * we have gone over the length of what we wanted to
+                        * We have gone over the length of what we wanted to
                         * map, and it wasn't the entire file, so add the extent
                         * we got last time and exit.
                         *
@@ -331,7 +348,7 @@ int __generic_block_fiemap(struct inode *inode,
                         * are good to go, just add the extent to the fieinfo
                         * and break
                         */
-                       if (length <= 0 && !whole_file) {
+                       if (start_blk > last_blk && !whole_file) {
                                ret = fiemap_fill_next_extent(fieinfo, logical,
                                                              phys, size,
                                                              flags);
@@ -351,11 +368,10 @@ int __generic_block_fiemap(struct inode *inode,
                        }
 
                        logical = blk_to_logical(inode, start_blk);
-                       phys = blk_to_logical(inode, tmp.b_blocknr);
-                       size = tmp.b_size;
+                       phys = blk_to_logical(inode, map_bh.b_blocknr);
+                       size = map_bh.b_size;
                        flags = FIEMAP_EXTENT_MERGED;
 
-                       length -= tmp.b_size;
                        start_blk += logical_to_blk(inode, size);
 
                        /*
@@ -363,15 +379,13 @@ int __generic_block_fiemap(struct inode *inode,
                         * soon as we find a hole that the last extent we found
                         * is marked with FIEMAP_EXTENT_LAST
                         */
-                       if (!past_eof &&
-                           logical+size >=
-                           blk_to_logical(inode, 0)+i_size_read(inode))
-                               past_eof = 1;
+                       if (!past_eof && logical + size >= isize)
+                               past_eof = true;
                }
                cond_resched();
        } while (1);
 
-       /* if ret is 1 then we just hit the end of the extent array */
+       /* If ret is 1 then we just hit the end of the extent array */
        if (ret == 1)
                ret = 0;
 
index 9dd1262..ed9ba6f 100644 (file)
@@ -61,7 +61,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
                        inode->i_op = &page_symlink_inode_operations;
                        inode->i_mapping->a_ops = &jfs_aops;
                } else {
-                       inode->i_op = &jfs_symlink_inode_operations;
+                       inode->i_op = &jfs_fast_symlink_inode_operations;
                        /*
                         * The inline data should be null-terminated, but
                         * don't let on-disk corruption crash the kernel
index 6c4dfcb..9e2f6a7 100644 (file)
@@ -196,7 +196,7 @@ int dbMount(struct inode *ipbmap)
        bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
        bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
        bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
-       bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth);
+       bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
        bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
        bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
        bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
@@ -288,7 +288,7 @@ int dbSync(struct inode *ipbmap)
        dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag);
        dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref);
        dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel);
-       dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth);
+       dbmp_le->dn_agheight = cpu_to_le32(bmp->db_agheight);
        dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth);
        dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart);
        dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size);
@@ -1441,7 +1441,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
         * tree index of this allocation group within the control page.
         */
        agperlev =
-           (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
+           (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth;
        ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
 
        /* dmap control page trees fan-out by 4 and a single allocation
@@ -1460,7 +1460,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
                 * the subtree to find the leftmost leaf that describes this
                 * free space.
                 */
-               for (k = bmp->db_agheigth; k > 0; k--) {
+               for (k = bmp->db_agheight; k > 0; k--) {
                        for (n = 0, m = (ti << 2) + 1; n < 4; n++) {
                                if (l2nb <= dcp->stree[m + n]) {
                                        ti = m + n;
@@ -3607,7 +3607,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
        }
 
        /*
-        * compute db_aglevel, db_agheigth, db_width, db_agstart:
+        * compute db_aglevel, db_agheight, db_width, db_agstart:
         * an ag is covered in aglevel dmapctl summary tree,
         * at agheight level height (from leaf) with agwidth number of nodes
         * each, which starts at agstart index node of the smmary tree node
@@ -3616,9 +3616,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
        bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
        l2nl =
            bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL);
-       bmp->db_agheigth = l2nl >> 1;
-       bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1));
-       for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0;
+       bmp->db_agheight = l2nl >> 1;
+       bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1));
+       for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0;
             i--) {
                bmp->db_agstart += n;
                n <<= 2;
index 1a6eb41..6dcb906 100644 (file)
@@ -210,7 +210,7 @@ struct dbmap_disk {
        __le32 dn_maxag;        /* 4: max active alloc group number     */
        __le32 dn_agpref;       /* 4: preferred alloc group (hint)      */
        __le32 dn_aglevel;      /* 4: dmapctl level holding the AG      */
-       __le32 dn_agheigth;     /* 4: height in dmapctl of the AG       */
+       __le32 dn_agheight;     /* 4: height in dmapctl of the AG       */
        __le32 dn_agwidth;      /* 4: width in dmapctl of the AG        */
        __le32 dn_agstart;      /* 4: start tree index at AG height     */
        __le32 dn_agl2size;     /* 4: l2 num of blks per alloc group    */
@@ -229,7 +229,7 @@ struct dbmap {
        int dn_maxag;           /* max active alloc group number        */
        int dn_agpref;          /* preferred alloc group (hint)         */
        int dn_aglevel;         /* dmapctl level holding the AG         */
-       int dn_agheigth;        /* height in dmapctl of the AG          */
+       int dn_agheight;        /* height in dmapctl of the AG          */
        int dn_agwidth;         /* width in dmapctl of the AG           */
        int dn_agstart;         /* start tree index at AG height        */
        int dn_agl2size;        /* l2 num of blks per alloc group       */
@@ -255,7 +255,7 @@ struct bmap {
 #define        db_agsize       db_bmap.dn_agsize
 #define        db_agl2size     db_bmap.dn_agl2size
 #define        db_agwidth      db_bmap.dn_agwidth
-#define        db_agheigth     db_bmap.dn_agheigth
+#define        db_agheight     db_bmap.dn_agheight
 #define        db_agstart      db_bmap.dn_agstart
 #define        db_numag        db_bmap.dn_numag
 #define        db_maxlevel     db_bmap.dn_maxlevel
index 79e2c79..9e6bda3 100644 (file)
@@ -48,5 +48,6 @@ extern const struct file_operations jfs_dir_operations;
 extern const struct inode_operations jfs_file_inode_operations;
 extern const struct file_operations jfs_file_operations;
 extern const struct inode_operations jfs_symlink_inode_operations;
+extern const struct inode_operations jfs_fast_symlink_inode_operations;
 extern const struct dentry_operations jfs_ci_dentry_operations;
 #endif                         /* _H_JFS_INODE */
index 4a3e9f3..a9cf8e8 100644 (file)
@@ -956,7 +956,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
         */
 
        if (ssize <= IDATASIZE) {
-               ip->i_op = &jfs_symlink_inode_operations;
+               ip->i_op = &jfs_fast_symlink_inode_operations;
 
                i_fastsymlink = JFS_IP(ip)->i_inline;
                memcpy(i_fastsymlink, name, ssize);
@@ -978,7 +978,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        else {
                jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
 
-               ip->i_op = &page_symlink_inode_operations;
+               ip->i_op = &jfs_symlink_inode_operations;
                ip->i_mapping->a_ops = &jfs_aops;
 
                /*
index 7f24a0b..1aba003 100644 (file)
@@ -81,6 +81,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        struct inode *iplist[1];
        struct jfs_superblock *j_sb, *j_sb2;
        uint old_agsize;
+       int agsizechanged = 0;
        struct buffer_head *bh, *bh2;
 
        /* If the volume hasn't grown, get out now */
@@ -333,6 +334,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         */
        if ((rc = dbExtendFS(ipbmap, XAddress, nblocks)))
                goto error_out;
+
+       agsizechanged |= (bmp->db_agsize != old_agsize);
+
        /*
         * the map now has extended to cover additional nblocks:
         * dn_mapsize = oldMapsize + nblocks;
@@ -432,7 +436,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         * will correctly identify the new ag);
         */
        /* if new AG size the same as old AG size, done! */
-       if (bmp->db_agsize != old_agsize) {
+       if (agsizechanged) {
                if ((rc = diExtendFS(ipimap, ipbmap)))
                        goto error_out;
 
index 157382f..b66832a 100644 (file)
@@ -446,10 +446,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        /* initialize the mount flag and determine the default error handler */
        flag = JFS_ERR_REMOUNT_RO;
 
-       if (!parse_options((char *) data, sb, &newLVSize, &flag)) {
-               kfree(sbi);
-               return -EINVAL;
-       }
+       if (!parse_options((char *) data, sb, &newLVSize, &flag))
+               goto out_kfree;
        sbi->flag = flag;
 
 #ifdef CONFIG_JFS_POSIX_ACL
@@ -458,7 +456,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
 
        if (newLVSize) {
                printk(KERN_ERR "resize option for remount only\n");
-               return -EINVAL;
+               goto out_kfree;
        }
 
        /*
@@ -478,7 +476,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
        inode = new_inode(sb);
        if (inode == NULL) {
                ret = -ENOMEM;
-               goto out_kfree;
+               goto out_unload;
        }
        inode->i_ino = 0;
        inode->i_nlink = 1;
@@ -550,9 +548,10 @@ out_mount_failed:
        make_bad_inode(sbi->direct_inode);
        iput(sbi->direct_inode);
        sbi->direct_inode = NULL;
-out_kfree:
+out_unload:
        if (sbi->nls_tab)
                unload_nls(sbi->nls_tab);
+out_kfree:
        kfree(sbi);
        return ret;
 }
index 4af1a05..205b946 100644 (file)
@@ -29,9 +29,21 @@ static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        return NULL;
 }
 
-const struct inode_operations jfs_symlink_inode_operations = {
+const struct inode_operations jfs_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = jfs_follow_link,
+       .setattr        = jfs_setattr,
+       .setxattr       = jfs_setxattr,
+       .getxattr       = jfs_getxattr,
+       .listxattr      = jfs_listxattr,
+       .removexattr    = jfs_removexattr,
+};
+
+const struct inode_operations jfs_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+       .setattr        = jfs_setattr,
        .setxattr       = jfs_setxattr,
        .getxattr       = jfs_getxattr,
        .listxattr      = jfs_listxattr,
index 243c000..9bd2ce2 100644 (file)
@@ -303,6 +303,11 @@ static void bdev_put_device(struct super_block *sb)
        close_bdev_exclusive(logfs_super(sb)->s_bdev, FMODE_READ|FMODE_WRITE);
 }
 
+static int bdev_can_write_buf(struct super_block *sb, u64 ofs)
+{
+       return 0;
+}
+
 static const struct logfs_device_ops bd_devops = {
        .find_first_sb  = bdev_find_first_sb,
        .find_last_sb   = bdev_find_last_sb,
@@ -310,6 +315,7 @@ static const struct logfs_device_ops bd_devops = {
        .readpage       = bdev_readpage,
        .writeseg       = bdev_writeseg,
        .erase          = bdev_erase,
+       .can_write_buf  = bdev_can_write_buf,
        .sync           = bdev_sync,
        .put_device     = bdev_put_device,
 };
index cafb6ef..a85d47d 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/completion.h>
 #include <linux/mount.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1))
 
@@ -126,7 +127,8 @@ static int mtd_readpage(void *_sb, struct page *page)
 
        err = mtd_read(sb, page->index << PAGE_SHIFT, PAGE_SIZE,
                        page_address(page));
-       if (err == -EUCLEAN) {
+       if (err == -EUCLEAN || err == -EBADMSG) {
+               /* -EBADMSG happens regularly on power failures */
                err = 0;
                /* FIXME: force GC this segment */
        }
@@ -233,12 +235,32 @@ static void mtd_put_device(struct super_block *sb)
        put_mtd_device(logfs_super(sb)->s_mtd);
 }
 
+static int mtd_can_write_buf(struct super_block *sb, u64 ofs)
+{
+       struct logfs_super *super = logfs_super(sb);
+       void *buf;
+       int err;
+
+       buf = kmalloc(super->s_writesize, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       err = mtd_read(sb, ofs, super->s_writesize, buf);
+       if (err)
+               goto out;
+       if (memchr_inv(buf, 0xff, super->s_writesize))
+               err = -EIO;
+       kfree(buf);
+out:
+       return err;
+}
+
 static const struct logfs_device_ops mtd_devops = {
        .find_first_sb  = mtd_find_first_sb,
        .find_last_sb   = mtd_find_last_sb,
        .readpage       = mtd_readpage,
        .writeseg       = mtd_writeseg,
        .erase          = mtd_erase,
+       .can_write_buf  = mtd_can_write_buf,
        .sync           = mtd_sync,
        .put_device     = mtd_put_device,
 };
@@ -250,5 +272,7 @@ int logfs_get_sb_mtd(struct file_system_type *type, int flags,
        const struct logfs_device_ops *devops = &mtd_devops;
 
        mtd = get_mtd_device(NULL, mtdnr);
+       if (IS_ERR(mtd))
+               return PTR_ERR(mtd);
        return logfs_get_sb_device(type, flags, mtd, NULL, devops, mnt);
 }
index 370f367..0de5240 100644 (file)
@@ -161,7 +161,17 @@ static int logfs_writepage(struct page *page, struct writeback_control *wbc)
 
 static void logfs_invalidatepage(struct page *page, unsigned long offset)
 {
-       move_page_to_btree(page);
+       struct logfs_block *block = logfs_block(page);
+
+       if (block->reserved_bytes) {
+               struct super_block *sb = page->mapping->host->i_sb;
+               struct logfs_super *super = logfs_super(sb);
+
+               super->s_dirty_pages -= block->reserved_bytes;
+               block->ops->free_block(sb, block);
+               BUG_ON(bitmap_weight(block->alias_map, LOGFS_BLOCK_FACTOR));
+       } else
+               move_page_to_btree(page);
        BUG_ON(PagePrivate(page) || page->private);
 }
 
@@ -212,10 +222,8 @@ int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 int logfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
        struct super_block *sb = dentry->d_inode->i_sb;
-       struct logfs_super *super = logfs_super(sb);
 
-       /* FIXME: write anchor */
-       super->s_devops->sync(sb);
+       logfs_write_anchor(sb);
        return 0;
 }
 
index 84e36f5..caa4419 100644 (file)
@@ -122,7 +122,7 @@ static void logfs_cleanse_block(struct super_block *sb, u64 ofs, u64 ino,
        logfs_safe_iput(inode, cookie);
 }
 
-static u32 logfs_gc_segment(struct super_block *sb, u32 segno, u8 dist)
+static u32 logfs_gc_segment(struct super_block *sb, u32 segno)
 {
        struct logfs_super *super = logfs_super(sb);
        struct logfs_segment_header sh;
@@ -401,7 +401,7 @@ static int __logfs_gc_once(struct super_block *sb, struct gc_candidate *cand)
                        segno, (u64)segno << super->s_segshift,
                        dist, no_free_segments(sb), valid,
                        super->s_free_bytes);
-       cleaned = logfs_gc_segment(sb, segno, dist);
+       cleaned = logfs_gc_segment(sb, segno);
        log_gc("GC segment #%02x complete - now %x valid\n", segno,
                        valid - cleaned);
        BUG_ON(cleaned != valid);
@@ -459,6 +459,14 @@ static void __logfs_gc_pass(struct super_block *sb, int target)
        struct logfs_block *block;
        int round, progress, last_progress = 0;
 
+       /*
+        * Doing too many changes to the segfile at once would result
+        * in a large number of aliases.  Write the journal before
+        * things get out of hand.
+        */
+       if (super->s_shadow_tree.no_shadowed_segments >= MAX_OBJ_ALIASES)
+               logfs_write_anchor(sb);
+
        if (no_free_segments(sb) >= target &&
                        super->s_no_object_aliases < MAX_OBJ_ALIASES)
                return;
@@ -624,38 +632,31 @@ static int check_area(struct super_block *sb, int i)
 {
        struct logfs_super *super = logfs_super(sb);
        struct logfs_area *area = super->s_area[i];
-       struct logfs_object_header oh;
+       gc_level_t gc_level;
+       u32 cleaned, valid, ec;
        u32 segno = area->a_segno;
-       u32 ofs = area->a_used_bytes;
-       __be32 crc;
-       int err;
+       u64 ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
 
        if (!area->a_is_open)
                return 0;
 
-       for (ofs = area->a_used_bytes;
-            ofs <= super->s_segsize - sizeof(oh);
-            ofs += (u32)be16_to_cpu(oh.len) + sizeof(oh)) {
-               err = wbuf_read(sb, dev_ofs(sb, segno, ofs), sizeof(oh), &oh);
-               if (err)
-                       return err;
-
-               if (!memchr_inv(&oh, 0xff, sizeof(oh)))
-                       break;
+       if (super->s_devops->can_write_buf(sb, ofs) == 0)
+               return 0;
 
-               crc = logfs_crc32(&oh, sizeof(oh) - 4, 4);
-               if (crc != oh.crc) {
-                       printk(KERN_INFO "interrupted header at %llx\n",
-                                       dev_ofs(sb, segno, ofs));
-                       return 0;
-               }
-       }
-       if (ofs != area->a_used_bytes) {
-               printk(KERN_INFO "%x bytes unaccounted data found at %llx\n",
-                               ofs - area->a_used_bytes,
-                               dev_ofs(sb, segno, area->a_used_bytes));
-               area->a_used_bytes = ofs;
-       }
+       printk(KERN_INFO"LogFS: Possibly incomplete write at %llx\n", ofs);
+       /*
+        * The device cannot write back the write buffer.  Most likely the
+        * wbuf was already written out and the system crashed at some point
+        * before the journal commit happened.  In that case we wouldn't have
+        * to do anything.  But if the crash happened before the wbuf was
+        * written out correctly, we must GC this segment.  So assume the
+        * worst and always do the GC run.
+        */
+       area->a_is_open = 0;
+       valid = logfs_valid_bytes(sb, segno, &ec, &gc_level);
+       cleaned = logfs_gc_segment(sb, segno);
+       if (cleaned != valid)
+               return -EIO;
        return 0;
 }
 
index 14ed272..755a92e 100644 (file)
@@ -193,6 +193,7 @@ static void logfs_init_inode(struct super_block *sb, struct inode *inode)
        inode->i_ctime  = CURRENT_TIME;
        inode->i_mtime  = CURRENT_TIME;
        inode->i_nlink  = 1;
+       li->li_refcount = 1;
        INIT_LIST_HEAD(&li->li_freeing_list);
 
        for (i = 0; i < LOGFS_EMBEDDED_FIELDS; i++)
@@ -326,7 +327,7 @@ static void logfs_set_ino_generation(struct super_block *sb,
        u64 ino;
 
        mutex_lock(&super->s_journal_mutex);
-       ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino);
+       ino = logfs_seek_hole(super->s_master_inode, super->s_last_ino + 1);
        super->s_last_ino = ino;
        super->s_inos_till_wrap--;
        if (super->s_inos_till_wrap < 0) {
@@ -386,8 +387,7 @@ static void logfs_init_once(void *_li)
 
 static int logfs_sync_fs(struct super_block *sb, int wait)
 {
-       /* FIXME: write anchor */
-       logfs_super(sb)->s_devops->sync(sb);
+       logfs_write_anchor(sb);
        return 0;
 }
 
index 33bd260..4b0e061 100644 (file)
@@ -132,10 +132,9 @@ static int read_area(struct super_block *sb, struct logfs_je_area *a)
 
        ofs = dev_ofs(sb, area->a_segno, area->a_written_bytes);
        if (super->s_writesize > 1)
-               logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
+               return logfs_buf_recover(area, ofs, a + 1, super->s_writesize);
        else
-               logfs_buf_recover(area, ofs, NULL, 0);
-       return 0;
+               return logfs_buf_recover(area, ofs, NULL, 0);
 }
 
 static void *unpack(void *from, void *to)
@@ -245,7 +244,7 @@ static int read_je(struct super_block *sb, u64 ofs)
                read_erasecount(sb, unpack(jh, scratch));
                break;
        case JE_AREA:
-               read_area(sb, unpack(jh, scratch));
+               err = read_area(sb, unpack(jh, scratch));
                break;
        case JE_OBJ_ALIAS:
                err = logfs_load_object_aliases(sb, unpack(jh, scratch),
@@ -389,7 +388,10 @@ static void journal_get_erase_count(struct logfs_area *area)
 static int journal_erase_segment(struct logfs_area *area)
 {
        struct super_block *sb = area->a_sb;
-       struct logfs_segment_header sh;
+       union {
+               struct logfs_segment_header sh;
+               unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)];
+       } u;
        u64 ofs;
        int err;
 
@@ -397,20 +399,21 @@ static int journal_erase_segment(struct logfs_area *area)
        if (err)
                return err;
 
-       sh.pad = 0;
-       sh.type = SEG_JOURNAL;
-       sh.level = 0;
-       sh.segno = cpu_to_be32(area->a_segno);
-       sh.ec = cpu_to_be32(area->a_erase_count);
-       sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
-       sh.crc = logfs_crc32(&sh, sizeof(sh), 4);
+       memset(&u, 0, sizeof(u));
+       u.sh.pad = 0;
+       u.sh.type = SEG_JOURNAL;
+       u.sh.level = 0;
+       u.sh.segno = cpu_to_be32(area->a_segno);
+       u.sh.ec = cpu_to_be32(area->a_erase_count);
+       u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
+       u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4);
 
        /* This causes a bug in segment.c.  Not yet. */
        //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0);
 
        ofs = dev_ofs(sb, area->a_segno, 0);
-       area->a_used_bytes = ALIGN(sizeof(sh), 16);
-       logfs_buf_write(area, ofs, &sh, sizeof(sh));
+       area->a_used_bytes = sizeof(u);
+       logfs_buf_write(area, ofs, &u, sizeof(u));
        return 0;
 }
 
@@ -494,6 +497,8 @@ static void account_shadows(struct super_block *sb)
 
        btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
        btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);
+       btree_grim_visitor32(&tree->segment_map, 0, NULL);
+       tree->no_shadowed_segments = 0;
 
        if (li->li_block) {
                /*
@@ -607,9 +612,9 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
        if (len == 0)
                return logfs_write_header(super, header, 0, type);
 
+       BUG_ON(len > sb->s_blocksize);
        compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
        if (compr_len < 0 || type == JE_ANCHOR) {
-               BUG_ON(len > sb->s_blocksize);
                memcpy(data, buf, len);
                compr_len = len;
                compr = COMPR_NONE;
@@ -661,6 +666,7 @@ static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type,
        if (ofs < 0)
                return ofs;
        logfs_buf_write(area, ofs, super->s_compressed_je, len);
+       BUG_ON(super->s_no_je >= MAX_JOURNAL_ENTRIES);
        super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs);
        return 0;
 }
index b84b0ee..93b55f3 100644 (file)
@@ -144,6 +144,7 @@ struct logfs_area_ops {
  * @erase:                     erase one segment
  * @read:                      read from the device
  * @erase:                     erase part of the device
+ * @can_write_buf:             decide whether wbuf can be written to ofs
  */
 struct logfs_device_ops {
        struct page *(*find_first_sb)(struct super_block *sb, u64 *ofs);
@@ -153,6 +154,7 @@ struct logfs_device_ops {
        void (*writeseg)(struct super_block *sb, u64 ofs, size_t len);
        int (*erase)(struct super_block *sb, loff_t ofs, size_t len,
                        int ensure_write);
+       int (*can_write_buf)(struct super_block *sb, u64 ofs);
        void (*sync)(struct super_block *sb);
        void (*put_device)(struct super_block *sb);
 };
@@ -257,10 +259,14 @@ struct logfs_shadow {
  * struct shadow_tree
  * @new:                       shadows where old_ofs==0, indexed by new_ofs
  * @old:                       shadows where old_ofs!=0, indexed by old_ofs
+ * @segment_map:               bitfield of segments containing shadows
+ * @no_shadowed_segment:       number of segments containing shadows
  */
 struct shadow_tree {
        struct btree_head64 new;
        struct btree_head64 old;
+       struct btree_head32 segment_map;
+       int no_shadowed_segments;
 };
 
 struct object_alias_item {
@@ -305,13 +311,14 @@ typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix,
                level_t level, int child_no, __be64 val);
 struct logfs_block_ops {
        void    (*write_block)(struct logfs_block *block);
-       gc_level_t      (*block_level)(struct logfs_block *block);
        void    (*free_block)(struct super_block *sb, struct logfs_block*block);
        int     (*write_alias)(struct super_block *sb,
                        struct logfs_block *block,
                        write_alias_t *write_one_alias);
 };
 
+#define MAX_JOURNAL_ENTRIES 256
+
 struct logfs_super {
        struct mtd_info *s_mtd;                 /* underlying device */
        struct block_device *s_bdev;            /* underlying device */
@@ -378,7 +385,7 @@ struct logfs_super {
        u32      s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */
        u64      s_last_version;
        struct logfs_area *s_journal_area;      /* open journal segment */
-       __be64  s_je_array[64];
+       __be64  s_je_array[MAX_JOURNAL_ENTRIES];
        int     s_no_je;
 
        int      s_sum_index;                   /* for the 12 summaries */
@@ -389,6 +396,7 @@ struct logfs_super {
        int      s_lock_count;
        mempool_t *s_block_pool;                /* struct logfs_block pool */
        mempool_t *s_shadow_pool;               /* struct logfs_shadow pool */
+       struct list_head s_writeback_list;      /* writeback pages */
        /*
         * Space accounting:
         * - s_used_bytes specifies space used to store valid data objects.
@@ -593,19 +601,19 @@ void freeseg(struct super_block *sb, u32 segno);
 int logfs_init_areas(struct super_block *sb);
 void logfs_cleanup_areas(struct super_block *sb);
 int logfs_open_area(struct logfs_area *area, size_t bytes);
-void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
+int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                int use_filler);
 
-static inline void logfs_buf_write(struct logfs_area *area, u64 ofs,
+static inline int logfs_buf_write(struct logfs_area *area, u64 ofs,
                void *buf, size_t len)
 {
-       __logfs_buf_write(area, ofs, buf, len, 0);
+       return __logfs_buf_write(area, ofs, buf, len, 0);
 }
 
-static inline void logfs_buf_recover(struct logfs_area *area, u64 ofs,
+static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs,
                void *buf, size_t len)
 {
-       __logfs_buf_write(area, ofs, buf, len, 1);
+       return __logfs_buf_write(area, ofs, buf, len, 1);
 }
 
 /* super.c */
@@ -722,4 +730,10 @@ static inline struct logfs_area *get_area(struct super_block *sb,
        return logfs_super(sb)->s_area[(__force u8)gc_level];
 }
 
+static inline void logfs_mempool_destroy(mempool_t *pool)
+{
+       if (pool)
+               mempool_destroy(pool);
+}
+
 #endif
index bff4025..0718d11 100644 (file)
@@ -430,25 +430,6 @@ static void inode_write_block(struct logfs_block *block)
        }
 }
 
-static gc_level_t inode_block_level(struct logfs_block *block)
-{
-       BUG_ON(block->inode->i_ino == LOGFS_INO_MASTER);
-       return GC_LEVEL(LOGFS_MAX_LEVELS);
-}
-
-static gc_level_t indirect_block_level(struct logfs_block *block)
-{
-       struct page *page;
-       struct inode *inode;
-       u64 bix;
-       level_t level;
-
-       page = block->page;
-       inode = page->mapping->host;
-       logfs_unpack_index(page->index, &bix, &level);
-       return expand_level(inode->i_ino, level);
-}
-
 /*
  * This silences a false, yet annoying gcc warning.  I hate it when my editor
  * jumps into bitops.h each time I recompile this file.
@@ -587,14 +568,12 @@ static void indirect_free_block(struct super_block *sb,
 
 static struct logfs_block_ops inode_block_ops = {
        .write_block = inode_write_block,
-       .block_level = inode_block_level,
        .free_block = inode_free_block,
        .write_alias = inode_write_alias,
 };
 
 struct logfs_block_ops indirect_block_ops = {
        .write_block = indirect_write_block,
-       .block_level = indirect_block_level,
        .free_block = indirect_free_block,
        .write_alias = indirect_write_alias,
 };
@@ -913,6 +892,8 @@ u64 logfs_seek_hole(struct inode *inode, u64 bix)
                return bix;
        else if (li->li_data[INDIRECT_INDEX] & LOGFS_FULLY_POPULATED)
                bix = maxbix(li->li_height);
+       else if (bix >= maxbix(li->li_height))
+               return bix;
        else {
                bix = seek_holedata_loop(inode, bix, 0);
                if (bix < maxbix(li->li_height))
@@ -1114,17 +1095,25 @@ static int logfs_reserve_bytes(struct inode *inode, int bytes)
 int get_page_reserve(struct inode *inode, struct page *page)
 {
        struct logfs_super *super = logfs_super(inode->i_sb);
+       struct logfs_block *block = logfs_block(page);
        int ret;
 
-       if (logfs_block(page) && logfs_block(page)->reserved_bytes)
+       if (block && block->reserved_bytes)
                return 0;
 
        logfs_get_wblocks(inode->i_sb, page, WF_LOCK);
-       ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE);
+       while ((ret = logfs_reserve_bytes(inode, 6 * LOGFS_MAX_OBJECTSIZE)) &&
+                       !list_empty(&super->s_writeback_list)) {
+               block = list_entry(super->s_writeback_list.next,
+                               struct logfs_block, alias_list);
+               block->ops->write_block(block);
+       }
        if (!ret) {
                alloc_data_block(inode, page);
-               logfs_block(page)->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE;
+               block = logfs_block(page);
+               block->reserved_bytes += 6 * LOGFS_MAX_OBJECTSIZE;
                super->s_dirty_pages += 6 * LOGFS_MAX_OBJECTSIZE;
+               list_move_tail(&block->alias_list, &super->s_writeback_list);
        }
        logfs_put_wblocks(inode->i_sb, page, WF_LOCK);
        return ret;
@@ -1241,6 +1230,18 @@ static void free_shadow(struct inode *inode, struct logfs_shadow *shadow)
        mempool_free(shadow, super->s_shadow_pool);
 }
 
+static void mark_segment(struct shadow_tree *tree, u32 segno)
+{
+       int err;
+
+       if (!btree_lookup32(&tree->segment_map, segno)) {
+               err = btree_insert32(&tree->segment_map, segno, (void *)1,
+                               GFP_NOFS);
+               BUG_ON(err);
+               tree->no_shadowed_segments++;
+       }
+}
+
 /**
  * fill_shadow_tree - Propagate shadow tree changes due to a write
  * @inode:     Inode owning the page
@@ -1288,6 +1289,8 @@ static void fill_shadow_tree(struct inode *inode, struct page *page,
 
                super->s_dirty_used_bytes += shadow->new_len;
                super->s_dirty_free_bytes += shadow->old_len;
+               mark_segment(tree, shadow->old_ofs >> super->s_segshift);
+               mark_segment(tree, shadow->new_ofs >> super->s_segshift);
        }
 }
 
@@ -1845,19 +1848,37 @@ static int __logfs_truncate(struct inode *inode, u64 size)
        return logfs_truncate_direct(inode, size);
 }
 
-int logfs_truncate(struct inode *inode, u64 size)
+/*
+ * Truncate, by changing the segment file, can consume a fair amount
+ * of resources.  So back off from time to time and do some GC.
+ * 8 or 2048 blocks should be well within safety limits even if
+ * every single block resided in a different segment.
+ */
+#define TRUNCATE_STEP  (8 * 1024 * 1024)
+int logfs_truncate(struct inode *inode, u64 target)
 {
        struct super_block *sb = inode->i_sb;
-       int err;
+       u64 size = i_size_read(inode);
+       int err = 0;
 
-       logfs_get_wblocks(sb, NULL, 1);
-       err = __logfs_truncate(inode, size);
-       if (!err)
-               err = __logfs_write_inode(inode, 0);
-       logfs_put_wblocks(sb, NULL, 1);
+       size = ALIGN(size, TRUNCATE_STEP);
+       while (size > target) {
+               if (size > TRUNCATE_STEP)
+                       size -= TRUNCATE_STEP;
+               else
+                       size = 0;
+               if (size < target)
+                       size = target;
+
+               logfs_get_wblocks(sb, NULL, 1);
+               err = __logfs_truncate(inode, size);
+               if (!err)
+                       err = __logfs_write_inode(inode, 0);
+               logfs_put_wblocks(sb, NULL, 1);
+       }
 
        if (!err)
-               err = vmtruncate(inode, size);
+               err = vmtruncate(inode, target);
 
        /* I don't trust error recovery yet. */
        WARN_ON(err);
@@ -2238,6 +2259,7 @@ int logfs_init_rw(struct super_block *sb)
        int min_fill = 3 * super->s_no_blocks;
 
        INIT_LIST_HEAD(&super->s_object_alias);
+       INIT_LIST_HEAD(&super->s_writeback_list);
        mutex_init(&super->s_write_mutex);
        super->s_block_pool = mempool_create_kmalloc_pool(min_fill,
                        sizeof(struct logfs_block));
@@ -2251,8 +2273,6 @@ void logfs_cleanup_rw(struct super_block *sb)
        struct logfs_super *super = logfs_super(sb);
 
        destroy_meta_inode(super->s_segfile_inode);
-       if (super->s_block_pool)
-               mempool_destroy(super->s_block_pool);
-       if (super->s_shadow_pool)
-               mempool_destroy(super->s_shadow_pool);
+       logfs_mempool_destroy(super->s_block_pool);
+       logfs_mempool_destroy(super->s_shadow_pool);
 }
index 801a3a1..a9657af 100644 (file)
@@ -67,7 +67,7 @@ static struct page *get_mapping_page(struct super_block *sb, pgoff_t index,
        return page;
 }
 
-void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
+int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                int use_filler)
 {
        pgoff_t index = ofs >> PAGE_SHIFT;
@@ -81,8 +81,10 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                copylen = min((ulong)len, PAGE_SIZE - offset);
 
                page = get_mapping_page(area->a_sb, index, use_filler);
-               SetPageUptodate(page);
+               if (IS_ERR(page))
+                       return PTR_ERR(page);
                BUG_ON(!page); /* FIXME: reserve a pool */
+               SetPageUptodate(page);
                memcpy(page_address(page) + offset, buf, copylen);
                SetPagePrivate(page);
                page_cache_release(page);
@@ -92,6 +94,7 @@ void __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len,
                offset = 0;
                index++;
        } while (len);
+       return 0;
 }
 
 static void pad_partial_page(struct logfs_area *area)
@@ -183,14 +186,8 @@ static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
        return 0;
 }
 
-static gc_level_t btree_block_level(struct logfs_block *block)
-{
-       return expand_level(block->ino, block->level);
-}
-
 static struct logfs_block_ops btree_block_ops = {
        .write_block    = btree_write_block,
-       .block_level    = btree_block_level,
        .free_block     = __free_block,
        .write_alias    = btree_write_alias,
 };
@@ -919,7 +916,7 @@ err:
        for (i--; i >= 0; i--)
                free_area(super->s_area[i]);
        free_area(super->s_journal_area);
-       mempool_destroy(super->s_alias_pool);
+       logfs_mempool_destroy(super->s_alias_pool);
        return -ENOMEM;
 }
 
index b60bfac..d651e10 100644 (file)
@@ -12,6 +12,7 @@
 #include "logfs.h"
 #include <linux/bio.h>
 #include <linux/slab.h>
+#include <linux/blkdev.h>
 #include <linux/mtd/mtd.h>
 #include <linux/statfs.h>
 #include <linux/buffer_head.h>
@@ -137,6 +138,14 @@ static int logfs_sb_set(struct super_block *sb, void *_super)
        sb->s_fs_info = super;
        sb->s_mtd = super->s_mtd;
        sb->s_bdev = super->s_bdev;
+#ifdef CONFIG_BLOCK
+       if (sb->s_bdev)
+               sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info;
+#endif
+#ifdef CONFIG_MTD
+       if (sb->s_mtd)
+               sb->s_bdi = sb->s_mtd->backing_dev_info;
+#endif
        return 0;
 }
 
@@ -328,27 +337,27 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
                goto fail;
 
        sb->s_root = d_alloc_root(rootdir);
-       if (!sb->s_root)
-               goto fail2;
+       if (!sb->s_root) {
+               iput(rootdir);
+               goto fail;
+       }
 
        super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
        if (!super->s_erase_page)
-               goto fail2;
+               goto fail;
        memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE);
 
        /* FIXME: check for read-only mounts */
        err = logfs_make_writeable(sb);
        if (err)
-               goto fail3;
+               goto fail1;
 
        log_super("LogFS: Finished mounting\n");
        simple_set_mnt(mnt, sb);
        return 0;
 
-fail3:
+fail1:
        __free_page(super->s_erase_page);
-fail2:
-       iput(rootdir);
 fail:
        iput(logfs_super(sb)->s_master_inode);
        return -EIO;
@@ -377,7 +386,7 @@ static struct page *find_super_block(struct super_block *sb)
        if (!first || IS_ERR(first))
                return NULL;
        last = super->s_devops->find_last_sb(sb, &super->s_sb_ofs[1]);
-       if (!last || IS_ERR(first)) {
+       if (!last || IS_ERR(last)) {
                page_cache_release(first);
                return NULL;
        }
@@ -408,7 +417,7 @@ static int __logfs_read_sb(struct super_block *sb)
 
        page = find_super_block(sb);
        if (!page)
-               return -EIO;
+               return -EINVAL;
 
        ds = page_address(page);
        super->s_size = be64_to_cpu(ds->ds_filesystem_size);
@@ -452,6 +461,8 @@ static int logfs_read_sb(struct super_block *sb, int read_only)
 
        btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool);
        btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool);
+       btree_init_mempool32(&super->s_shadow_tree.segment_map,
+                       super->s_btree_pool);
 
        ret = logfs_init_mapping(sb);
        if (ret)
@@ -516,8 +527,8 @@ static void logfs_kill_sb(struct super_block *sb)
        if (super->s_erase_page)
                __free_page(super->s_erase_page);
        super->s_devops->put_device(sb);
-       mempool_destroy(super->s_btree_pool);
-       mempool_destroy(super->s_alias_pool);
+       logfs_mempool_destroy(super->s_btree_pool);
+       logfs_mempool_destroy(super->s_alias_pool);
        kfree(super);
        log_super("LogFS: Finished unmounting\n");
 }
index a7dce91..b86b96f 100644 (file)
@@ -1641,7 +1641,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        if (nd->last.name[nd->last.len]) {
                if (open_flag & O_CREAT)
                        goto exit;
-               nd->flags |= LOOKUP_DIRECTORY;
+               nd->flags |= LOOKUP_DIRECTORY | LOOKUP_FOLLOW;
        }
 
        /* just plain open? */
@@ -1830,6 +1830,8 @@ reval:
        }
        if (open_flag & O_DIRECTORY)
                nd.flags |= LOOKUP_DIRECTORY;
+       if (!(open_flag & O_NOFOLLOW))
+               nd.flags |= LOOKUP_FOLLOW;
        filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
        while (unlikely(!filp)) { /* trailing symlink */
                struct path holder;
@@ -1837,7 +1839,7 @@ reval:
                void *cookie;
                error = -ELOOP;
                /* S_ISDIR part is a temporary automount kludge */
-               if ((open_flag & O_NOFOLLOW) && !S_ISDIR(inode->i_mode))
+               if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(inode->i_mode))
                        goto exit_dput;
                if (count++ == 32)
                        goto exit_dput;
@@ -2174,8 +2176,10 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
                error = security_inode_rmdir(dir, dentry);
                if (!error) {
                        error = dir->i_op->rmdir(dir, dentry);
-                       if (!error)
+                       if (!error) {
                                dentry->d_inode->i_flags |= S_DEAD;
+                               dont_mount(dentry);
+                       }
                }
        }
        mutex_unlock(&dentry->d_inode->i_mutex);
@@ -2259,7 +2263,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
                if (!error) {
                        error = dir->i_op->unlink(dir, dentry);
                        if (!error)
-                               dentry->d_inode->i_flags |= S_DEAD;
+                               dont_mount(dentry);
                }
        }
        mutex_unlock(&dentry->d_inode->i_mutex);
@@ -2570,17 +2574,20 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
                return error;
 
        target = new_dentry->d_inode;
-       if (target) {
+       if (target)
                mutex_lock(&target->i_mutex);
-               dentry_unhash(new_dentry);
-       }
        if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
                error = -EBUSY;
-       else 
+       else {
+               if (target)
+                       dentry_unhash(new_dentry);
                error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
+       }
        if (target) {
-               if (!error)
+               if (!error) {
                        target->i_flags |= S_DEAD;
+                       dont_mount(new_dentry);
+               }
                mutex_unlock(&target->i_mutex);
                if (d_unhashed(new_dentry))
                        d_rehash(new_dentry);
@@ -2612,7 +2619,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
                error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
        if (!error) {
                if (target)
-                       target->i_flags |= S_DEAD;
+                       dont_mount(new_dentry);
                if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
                        d_move(old_dentry, new_dentry);
        }
index 8174c8a..88058de 100644 (file)
@@ -628,7 +628,6 @@ repeat:
                mnt->mnt_pinned = 0;
                spin_unlock(&vfsmount_lock);
                acct_auto_close_mnt(mnt);
-               security_sb_umount_close(mnt);
                goto repeat;
        }
 }
@@ -1117,8 +1116,6 @@ static int do_umount(struct vfsmount *mnt, int flags)
                retval = 0;
        }
        spin_unlock(&vfsmount_lock);
-       if (retval)
-               security_sb_umount_busy(mnt);
        up_write(&namespace_sem);
        release_mounts(&umount_list);
        return retval;
@@ -1432,20 +1429,13 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
 
        err = -ENOENT;
        mutex_lock(&path->dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(path->dentry->d_inode))
-               goto out_unlock;
-
-       err = security_sb_check_sb(mnt, path);
-       if (err)
+       if (cant_mount(path->dentry))
                goto out_unlock;
 
-       err = -ENOENT;
        if (!d_unlinked(path->dentry))
                err = attach_recursive_mnt(mnt, path, NULL);
 out_unlock:
        mutex_unlock(&path->dentry->d_inode->i_mutex);
-       if (!err)
-               security_sb_post_addmount(mnt, path);
        return err;
 }
 
@@ -1581,8 +1571,6 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
        }
        up_write(&sb->s_umount);
        if (!err) {
-               security_sb_post_remount(path->mnt, flags, data);
-
                spin_lock(&vfsmount_lock);
                touch_mnt_namespace(path->mnt->mnt_ns);
                spin_unlock(&vfsmount_lock);
@@ -1623,7 +1611,7 @@ static int do_move_mount(struct path *path, char *old_name)
 
        err = -ENOENT;
        mutex_lock(&path->dentry->d_inode->i_mutex);
-       if (IS_DEADDIR(path->dentry->d_inode))
+       if (cant_mount(path->dentry))
                goto out1;
 
        if (d_unlinked(path->dentry))
@@ -2234,7 +2222,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
        if (!check_mnt(root.mnt))
                goto out2;
        error = -ENOENT;
-       if (IS_DEADDIR(new.dentry->d_inode))
+       if (cant_mount(old.dentry))
                goto out2;
        if (d_unlinked(new.dentry))
                goto out2;
@@ -2277,7 +2265,6 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
        touch_mnt_namespace(current->nsproxy->mnt_ns);
        spin_unlock(&vfsmount_lock);
        chroot_fs_refs(&root, &new);
-       security_sb_post_pivotroot(&root, &new);
        error = 0;
        path_put(&root_parent);
        path_put(&parent_path);
index cf98da1..fa33851 100644 (file)
@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
        sb->s_blocksize_bits = 10;
        sb->s_magic = NCP_SUPER_MAGIC;
        sb->s_op = &ncp_sops;
+       sb->s_bdi = &server->bdi;
 
        server = NCP_SBP(sb);
        memset(server, 0, sizeof(*server));
 
+       error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
+       if (error)
+               goto out_bdi;
+
        server->ncp_filp = ncp_filp;
        server->ncp_sock = sock;
        
@@ -719,6 +724,8 @@ out_fput2:
        if (server->info_filp)
                fput(server->info_filp);
 out_fput:
+       bdi_destroy(&server->bdi);
+out_bdi:
        /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
         * 
         * The previously used put_filp(ncp_filp); was bogous, since
@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb)
        kill_pid(server->m.wdog_pid, SIGTERM, 1);
        put_pid(server->m.wdog_pid);
 
+       bdi_destroy(&server->bdi);
        kfree(server->priv.data);
        kfree(server->auth.object_name);
        vfree(server->rxbuf);
index 2a3d352..7ec9b34 100644 (file)
@@ -934,7 +934,6 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
        }
 
        fsinfo.fattr = fattr;
-       nfs_fattr_init(fattr);
        error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);
        if (error < 0)
                goto out_error;
@@ -966,6 +965,8 @@ out_error:
 static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source)
 {
        target->flags = source->flags;
+       target->rsize = source->rsize;
+       target->wsize = source->wsize;
        target->acregmin = source->acregmin;
        target->acregmax = source->acregmax;
        target->acdirmin = source->acdirmin;
@@ -1045,13 +1046,18 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
                                     struct nfs_fh *mntfh)
 {
        struct nfs_server *server;
-       struct nfs_fattr fattr;
+       struct nfs_fattr *fattr;
        int error;
 
        server = nfs_alloc_server();
        if (!server)
                return ERR_PTR(-ENOMEM);
 
+       error = -ENOMEM;
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto error;
+
        /* Get a client representation */
        error = nfs_init_server(server, data);
        if (error < 0)
@@ -1062,7 +1068,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
        BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
 
        /* Probe the root fh to retrieve its FSID */
-       error = nfs_probe_fsinfo(server, mntfh, &fattr);
+       error = nfs_probe_fsinfo(server, mntfh, fattr);
        if (error < 0)
                goto error;
        if (server->nfs_client->rpc_ops->version == 3) {
@@ -1075,14 +1081,14 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
                        server->namelen = NFS2_MAXNAMLEN;
        }
 
-       if (!(fattr.valid & NFS_ATTR_FATTR)) {
-               error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
+       if (!(fattr->valid & NFS_ATTR_FATTR)) {
+               error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
                if (error < 0) {
                        dprintk("nfs_create_server: getattr error = %d\n", -error);
                        goto error;
                }
        }
-       memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
+       memcpy(&server->fsid, &fattr->fsid, sizeof(server->fsid));
 
        dprintk("Server FSID: %llx:%llx\n",
                (unsigned long long) server->fsid.major,
@@ -1094,9 +1100,11 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
        spin_unlock(&nfs_client_lock);
 
        server->mount_time = jiffies;
+       nfs_free_fattr(fattr);
        return server;
 
 error:
+       nfs_free_fattr(fattr);
        nfs_free_server(server);
        return ERR_PTR(error);
 }
@@ -1294,7 +1302,8 @@ static int nfs4_init_server(struct nfs_server *server,
 
        /* Initialise the client representation from the mount data */
        server->flags = data->flags;
-       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
+       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|
+               NFS_CAP_POSIX_LOCK;
        server->options = data->options;
 
        /* Get a client record */
@@ -1337,7 +1346,7 @@ error:
 struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
                                      struct nfs_fh *mntfh)
 {
-       struct nfs_fattr fattr;
+       struct nfs_fattr *fattr;
        struct nfs_server *server;
        int error;
 
@@ -1347,6 +1356,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
+       error = -ENOMEM;
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto error;
+
        /* set up the general RPC client */
        error = nfs4_init_server(server, data);
        if (error < 0)
@@ -1361,7 +1375,7 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
                goto error;
 
        /* Probe the root fh to retrieve its FSID */
-       error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
+       error = nfs4_get_rootfh(server, mntfh);
        if (error < 0)
                goto error;
 
@@ -1372,7 +1386,7 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
 
        nfs4_session_set_rwsize(server);
 
-       error = nfs_probe_fsinfo(server, mntfh, &fattr);
+       error = nfs_probe_fsinfo(server, mntfh, fattr);
        if (error < 0)
                goto error;
 
@@ -1386,9 +1400,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
 
        server->mount_time = jiffies;
        dprintk("<-- nfs4_create_server() = %p\n", server);
+       nfs_free_fattr(fattr);
        return server;
 
 error:
+       nfs_free_fattr(fattr);
        nfs_free_server(server);
        dprintk("<-- nfs4_create_server() = error %d\n", error);
        return ERR_PTR(error);
@@ -1402,7 +1418,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 {
        struct nfs_client *parent_client;
        struct nfs_server *server, *parent_server;
-       struct nfs_fattr fattr;
+       struct nfs_fattr *fattr;
        int error;
 
        dprintk("--> nfs4_create_referral_server()\n");
@@ -1411,6 +1427,11 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
+       error = -ENOMEM;
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto error;
+
        parent_server = NFS_SB(data->sb);
        parent_client = parent_server->nfs_client;
 
@@ -1440,12 +1461,12 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
 
        /* Probe the root fh to retrieve its FSID and filehandle */
-       error = nfs4_path_walk(server, mntfh, data->mnt_path);
+       error = nfs4_get_rootfh(server, mntfh);
        if (error < 0)
                goto error;
 
        /* probe the filesystem info for this server filesystem */
-       error = nfs_probe_fsinfo(server, mntfh, &fattr);
+       error = nfs_probe_fsinfo(server, mntfh, fattr);
        if (error < 0)
                goto error;
 
@@ -1463,10 +1484,12 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 
        server->mount_time = jiffies;
 
+       nfs_free_fattr(fattr);
        dprintk("<-- nfs_create_referral_server() = %p\n", server);
        return server;
 
 error:
+       nfs_free_fattr(fattr);
        nfs_free_server(server);
        dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
        return ERR_PTR(error);
@@ -1482,7 +1505,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
                                    struct nfs_fattr *fattr)
 {
        struct nfs_server *server;
-       struct nfs_fattr fattr_fsinfo;
+       struct nfs_fattr *fattr_fsinfo;
        int error;
 
        dprintk("--> nfs_clone_server(,%llx:%llx,)\n",
@@ -1493,6 +1516,11 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
+       error = -ENOMEM;
+       fattr_fsinfo = nfs_alloc_fattr();
+       if (fattr_fsinfo == NULL)
+               goto out_free_server;
+
        /* Copy data from the source */
        server->nfs_client = source->nfs_client;
        atomic_inc(&server->nfs_client->cl_count);
@@ -1509,7 +1537,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
                nfs_init_server_aclclient(server);
 
        /* probe the filesystem info for this server filesystem */
-       error = nfs_probe_fsinfo(server, fh, &fattr_fsinfo);
+       error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
        if (error < 0)
                goto out_free_server;
 
@@ -1531,10 +1559,12 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
 
        server->mount_time = jiffies;
 
+       nfs_free_fattr(fattr_fsinfo);
        dprintk("<-- nfs_clone_server() = %p\n", server);
        return server;
 
 out_free_server:
+       nfs_free_fattr(fattr_fsinfo);
        nfs_free_server(server);
        dprintk("<-- nfs_clone_server() = error %d\n", error);
        return ERR_PTR(error);
index 1567124..3016345 100644 (file)
@@ -24,6 +24,8 @@
 
 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
 {
+       if (delegation->cred)
+               put_rpccred(delegation->cred);
        kfree(delegation);
 }
 
@@ -36,13 +38,7 @@ static void nfs_free_delegation_callback(struct rcu_head *head)
 
 static void nfs_free_delegation(struct nfs_delegation *delegation)
 {
-       struct rpc_cred *cred;
-
-       cred = rcu_dereference(delegation->cred);
-       rcu_assign_pointer(delegation->cred, NULL);
        call_rcu(&delegation->rcu, nfs_free_delegation_callback);
-       if (cred)
-               put_rpccred(cred);
 }
 
 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
@@ -129,21 +125,35 @@ again:
  */
 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
 {
-       struct nfs_delegation *delegation = NFS_I(inode)->delegation;
-       struct rpc_cred *oldcred;
+       struct nfs_delegation *delegation;
+       struct rpc_cred *oldcred = NULL;
 
-       if (delegation == NULL)
-               return;
-       memcpy(delegation->stateid.data, res->delegation.data,
-                       sizeof(delegation->stateid.data));
-       delegation->type = res->delegation_type;
-       delegation->maxsize = res->maxsize;
-       oldcred = delegation->cred;
-       delegation->cred = get_rpccred(cred);
-       clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
-       NFS_I(inode)->delegation_state = delegation->type;
-       smp_wmb();
-       put_rpccred(oldcred);
+       rcu_read_lock();
+       delegation = rcu_dereference(NFS_I(inode)->delegation);
+       if (delegation != NULL) {
+               spin_lock(&delegation->lock);
+               if (delegation->inode != NULL) {
+                       memcpy(delegation->stateid.data, res->delegation.data,
+                              sizeof(delegation->stateid.data));
+                       delegation->type = res->delegation_type;
+                       delegation->maxsize = res->maxsize;
+                       oldcred = delegation->cred;
+                       delegation->cred = get_rpccred(cred);
+                       clear_bit(NFS_DELEGATION_NEED_RECLAIM,
+                                 &delegation->flags);
+                       NFS_I(inode)->delegation_state = delegation->type;
+                       spin_unlock(&delegation->lock);
+                       put_rpccred(oldcred);
+                       rcu_read_unlock();
+               } else {
+                       /* We appear to have raced with a delegation return. */
+                       spin_unlock(&delegation->lock);
+                       rcu_read_unlock();
+                       nfs_inode_set_delegation(inode, cred, res);
+               }
+       } else {
+               rcu_read_unlock();
+       }
 }
 
 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
@@ -166,9 +176,13 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation
        return inode;
 }
 
-static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, const nfs4_stateid *stateid)
+static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi,
+                                                          const nfs4_stateid *stateid,
+                                                          struct nfs_client *clp)
 {
-       struct nfs_delegation *delegation = rcu_dereference(nfsi->delegation);
+       struct nfs_delegation *delegation =
+               rcu_dereference_protected(nfsi->delegation,
+                                         lockdep_is_held(&clp->cl_lock));
 
        if (delegation == NULL)
                goto nomatch;
@@ -195,11 +209,11 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
 {
        struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
        struct nfs_inode *nfsi = NFS_I(inode);
-       struct nfs_delegation *delegation;
+       struct nfs_delegation *delegation, *old_delegation;
        struct nfs_delegation *freeme = NULL;
        int status = 0;
 
-       delegation = kmalloc(sizeof(*delegation), GFP_KERNEL);
+       delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
        if (delegation == NULL)
                return -ENOMEM;
        memcpy(delegation->stateid.data, res->delegation.data,
@@ -213,10 +227,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
        spin_lock_init(&delegation->lock);
 
        spin_lock(&clp->cl_lock);
-       if (rcu_dereference(nfsi->delegation) != NULL) {
-               if (memcmp(&delegation->stateid, &nfsi->delegation->stateid,
-                                       sizeof(delegation->stateid)) == 0 &&
-                               delegation->type == nfsi->delegation->type) {
+       old_delegation = rcu_dereference_protected(nfsi->delegation,
+                                                  lockdep_is_held(&clp->cl_lock));
+       if (old_delegation != NULL) {
+               if (memcmp(&delegation->stateid, &old_delegation->stateid,
+                                       sizeof(old_delegation->stateid)) == 0 &&
+                               delegation->type == old_delegation->type) {
                        goto out;
                }
                /*
@@ -226,12 +242,12 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
                dfprintk(FILE, "%s: server %s handed out "
                                "a duplicate delegation!\n",
                                __func__, clp->cl_hostname);
-               if (delegation->type <= nfsi->delegation->type) {
+               if (delegation->type <= old_delegation->type) {
                        freeme = delegation;
                        delegation = NULL;
                        goto out;
                }
-               freeme = nfs_detach_delegation_locked(nfsi, NULL);
+               freeme = nfs_detach_delegation_locked(nfsi, NULL, clp);
        }
        list_add_rcu(&delegation->super_list, &clp->cl_delegations);
        nfsi->delegation_state = delegation->type;
@@ -301,7 +317,7 @@ restart:
                if (inode == NULL)
                        continue;
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
                spin_unlock(&clp->cl_lock);
                rcu_read_unlock();
                if (delegation != NULL) {
@@ -330,9 +346,9 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode)
        struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs_delegation *delegation;
 
-       if (rcu_dereference(nfsi->delegation) != NULL) {
+       if (rcu_access_pointer(nfsi->delegation) != NULL) {
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(nfsi, NULL);
+               delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
                spin_unlock(&clp->cl_lock);
                if (delegation != NULL)
                        nfs_do_return_delegation(inode, delegation, 0);
@@ -346,9 +362,9 @@ int nfs_inode_return_delegation(struct inode *inode)
        struct nfs_delegation *delegation;
        int err = 0;
 
-       if (rcu_dereference(nfsi->delegation) != NULL) {
+       if (rcu_access_pointer(nfsi->delegation) != NULL) {
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(nfsi, NULL);
+               delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
                spin_unlock(&clp->cl_lock);
                if (delegation != NULL) {
                        nfs_msync_inode(inode);
@@ -526,7 +542,7 @@ restart:
                if (inode == NULL)
                        continue;
                spin_lock(&clp->cl_lock);
-               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
+               delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
                spin_unlock(&clp->cl_lock);
                rcu_read_unlock();
                if (delegation != NULL)
index c6f2750..ee9a179 100644 (file)
@@ -530,9 +530,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        nfs_readdir_descriptor_t my_desc,
                        *desc = &my_desc;
        struct nfs_entry my_entry;
-       struct nfs_fh    fh;
-       struct nfs_fattr fattr;
-       long            res;
+       int res = -ENOMEM;
 
        dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -554,9 +552,11 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 
        my_entry.cookie = my_entry.prev_cookie = 0;
        my_entry.eof = 0;
-       my_entry.fh = &fh;
-       my_entry.fattr = &fattr;
-       nfs_fattr_init(&fattr);
+       my_entry.fh = nfs_alloc_fhandle();
+       my_entry.fattr = nfs_alloc_fattr();
+       if (my_entry.fh == NULL || my_entry.fattr == NULL)
+               goto out_alloc_failed;
+
        desc->entry = &my_entry;
 
        nfs_block_sillyrename(dentry);
@@ -598,7 +598,10 @@ out:
        nfs_unblock_sillyrename(dentry);
        if (res > 0)
                res = 0;
-       dfprintk(FILE, "NFS: readdir(%s/%s) returns %ld\n",
+out_alloc_failed:
+       nfs_free_fattr(my_entry.fattr);
+       nfs_free_fhandle(my_entry.fh);
+       dfprintk(FILE, "NFS: readdir(%s/%s) returns %d\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
                        res);
        return res;
@@ -776,9 +779,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
        struct inode *dir;
        struct inode *inode;
        struct dentry *parent;
+       struct nfs_fh *fhandle = NULL;
+       struct nfs_fattr *fattr = NULL;
        int error;
-       struct nfs_fh fhandle;
-       struct nfs_fattr fattr;
 
        parent = dget_parent(dentry);
        dir = parent->d_inode;
@@ -811,14 +814,22 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
        if (NFS_STALE(inode))
                goto out_bad;
 
-       error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+       error = -ENOMEM;
+       fhandle = nfs_alloc_fhandle();
+       fattr = nfs_alloc_fattr();
+       if (fhandle == NULL || fattr == NULL)
+               goto out_error;
+
+       error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
        if (error)
                goto out_bad;
-       if (nfs_compare_fh(NFS_FH(inode), &fhandle))
+       if (nfs_compare_fh(NFS_FH(inode), fhandle))
                goto out_bad;
-       if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
+       if ((error = nfs_refresh_inode(inode, fattr)) != 0)
                goto out_bad;
 
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fhandle);
 out_set_verifier:
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
  out_valid:
@@ -837,14 +848,26 @@ out_zap_parent:
                /* If we have submounts, don't unhash ! */
                if (have_submounts(dentry))
                        goto out_valid;
+               if (dentry->d_flags & DCACHE_DISCONNECTED)
+                       goto out_valid;
                shrink_dcache_parent(dentry);
        }
        d_drop(dentry);
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fhandle);
        dput(parent);
        dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n",
                        __func__, dentry->d_parent->d_name.name,
                        dentry->d_name.name);
        return 0;
+out_error:
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fhandle);
+       dput(parent);
+       dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) lookup returned error %d\n",
+                       __func__, dentry->d_parent->d_name.name,
+                       dentry->d_name.name, error);
+       return error;
 }
 
 /*
@@ -909,9 +932,9 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
        struct dentry *res;
        struct dentry *parent;
        struct inode *inode = NULL;
+       struct nfs_fh *fhandle = NULL;
+       struct nfs_fattr *fattr = NULL;
        int error;
-       struct nfs_fh fhandle;
-       struct nfs_fattr fattr;
 
        dfprintk(VFS, "NFS: lookup(%s/%s)\n",
                dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -921,7 +944,6 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
        if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
                goto out;
 
-       res = ERR_PTR(-ENOMEM);
        dentry->d_op = NFS_PROTO(dir)->dentry_ops;
 
        /*
@@ -934,17 +956,23 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
                goto out;
        }
 
+       res = ERR_PTR(-ENOMEM);
+       fhandle = nfs_alloc_fhandle();
+       fattr = nfs_alloc_fattr();
+       if (fhandle == NULL || fattr == NULL)
+               goto out;
+
        parent = dentry->d_parent;
        /* Protect against concurrent sillydeletes */
        nfs_block_sillyrename(parent);
-       error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+       error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
        if (error == -ENOENT)
                goto no_entry;
        if (error < 0) {
                res = ERR_PTR(error);
                goto out_unblock_sillyrename;
        }
-       inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
+       inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
        res = (struct dentry *)inode;
        if (IS_ERR(res))
                goto out_unblock_sillyrename;
@@ -960,6 +988,8 @@ no_entry:
 out_unblock_sillyrename:
        nfs_unblock_sillyrename(parent);
 out:
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fhandle);
        return res;
 }
 
@@ -1025,12 +1055,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
+                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
-                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                goto out;
@@ -1050,7 +1080,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
        struct inode *dir;
        int openflags, ret = 0;
 
-       if (!is_atomic_open(nd))
+       if (!is_atomic_open(nd) || d_mountpoint(dentry))
                goto no_open;
        parent = dget_parent(dentry);
        dir = parent->d_inode;
@@ -1667,28 +1697,33 @@ static void nfs_access_free_entry(struct nfs_access_entry *entry)
        smp_mb__after_atomic_dec();
 }
 
+static void nfs_access_free_list(struct list_head *head)
+{
+       struct nfs_access_entry *cache;
+
+       while (!list_empty(head)) {
+               cache = list_entry(head->next, struct nfs_access_entry, lru);
+               list_del(&cache->lru);
+               nfs_access_free_entry(cache);
+       }
+}
+
 int nfs_access_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
 {
        LIST_HEAD(head);
        struct nfs_inode *nfsi;
        struct nfs_access_entry *cache;
 
-restart:
+       if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
+               return (nr_to_scan == 0) ? 0 : -1;
+
        spin_lock(&nfs_access_lru_lock);
        list_for_each_entry(nfsi, &nfs_access_lru_list, access_cache_inode_lru) {
-               struct rw_semaphore *s_umount;
                struct inode *inode;
 
                if (nr_to_scan-- == 0)
                        break;
-               s_umount = &nfsi->vfs_inode.i_sb->s_umount;
-               if (!down_read_trylock(s_umount))
-                       continue;
-               inode = igrab(&nfsi->vfs_inode);
-               if (inode == NULL) {
-                       up_read(s_umount);
-                       continue;
-               }
+               inode = &nfsi->vfs_inode;
                spin_lock(&inode->i_lock);
                if (list_empty(&nfsi->access_cache_entry_lru))
                        goto remove_lru_entry;
@@ -1702,61 +1737,47 @@ restart:
                else {
 remove_lru_entry:
                        list_del_init(&nfsi->access_cache_inode_lru);
+                       smp_mb__before_clear_bit();
                        clear_bit(NFS_INO_ACL_LRU_SET, &nfsi->flags);
+                       smp_mb__after_clear_bit();
                }
-               spin_unlock(&inode->i_lock);
-               spin_unlock(&nfs_access_lru_lock);
-               iput(inode);
-               up_read(s_umount);
-               goto restart;
        }
        spin_unlock(&nfs_access_lru_lock);
-       while (!list_empty(&head)) {
-               cache = list_entry(head.next, struct nfs_access_entry, lru);
-               list_del(&cache->lru);
-               nfs_access_free_entry(cache);
-       }
+       nfs_access_free_list(&head);
        return (atomic_long_read(&nfs_access_nr_entries) / 100) * sysctl_vfs_cache_pressure;
 }
 
-static void __nfs_access_zap_cache(struct inode *inode)
+static void __nfs_access_zap_cache(struct nfs_inode *nfsi, struct list_head *head)
 {
-       struct nfs_inode *nfsi = NFS_I(inode);
        struct rb_root *root_node = &nfsi->access_cache;
-       struct rb_node *n, *dispose = NULL;
+       struct rb_node *n;
        struct nfs_access_entry *entry;
 
        /* Unhook entries from the cache */
        while ((n = rb_first(root_node)) != NULL) {
                entry = rb_entry(n, struct nfs_access_entry, rb_node);
                rb_erase(n, root_node);
-               list_del(&entry->lru);
-               n->rb_left = dispose;
-               dispose = n;
+               list_move(&entry->lru, head);
        }
        nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
-       spin_unlock(&inode->i_lock);
-
-       /* Now kill them all! */
-       while (dispose != NULL) {
-               n = dispose;
-               dispose = n->rb_left;
-               nfs_access_free_entry(rb_entry(n, struct nfs_access_entry, rb_node));
-       }
 }
 
 void nfs_access_zap_cache(struct inode *inode)
 {
+       LIST_HEAD(head);
+
+       if (test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags) == 0)
+               return;
        /* Remove from global LRU init */
-       if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) {
-               spin_lock(&nfs_access_lru_lock);
+       spin_lock(&nfs_access_lru_lock);
+       if (test_and_clear_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
                list_del_init(&NFS_I(inode)->access_cache_inode_lru);
-               spin_unlock(&nfs_access_lru_lock);
-       }
 
        spin_lock(&inode->i_lock);
-       /* This will release the spinlock */
-       __nfs_access_zap_cache(inode);
+       __nfs_access_zap_cache(NFS_I(inode), &head);
+       spin_unlock(&inode->i_lock);
+       spin_unlock(&nfs_access_lru_lock);
+       nfs_access_free_list(&head);
 }
 
 static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
@@ -1807,8 +1828,8 @@ out_stale:
        nfs_access_free_entry(cache);
        return -ENOENT;
 out_zap:
-       /* This will release the spinlock */
-       __nfs_access_zap_cache(inode);
+       spin_unlock(&inode->i_lock);
+       nfs_access_zap_cache(inode);
        return -ENOENT;
 }
 
@@ -1863,9 +1884,11 @@ static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *s
        smp_mb__after_atomic_inc();
 
        /* Add inode to global LRU list */
-       if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) {
+       if (!test_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags)) {
                spin_lock(&nfs_access_lru_lock);
-               list_add_tail(&NFS_I(inode)->access_cache_inode_lru, &nfs_access_lru_list);
+               if (!test_and_set_bit(NFS_INO_ACL_LRU_SET, &NFS_I(inode)->flags))
+                       list_add_tail(&NFS_I(inode)->access_cache_inode_lru,
+                                       &nfs_access_lru_list);
                spin_unlock(&nfs_access_lru_lock);
        }
 }
index 8d965bd..cac96bc 100644 (file)
@@ -161,14 +161,17 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
        struct nfs_server *server = NFS_SERVER(inode);
        struct nfs_inode *nfsi = NFS_I(inode);
 
-       if (server->flags & NFS_MOUNT_NOAC)
-               goto force_reval;
+       if (nfs_have_delegated_attributes(inode))
+               goto out_noreval;
+
        if (filp->f_flags & O_DIRECT)
                goto force_reval;
-       if (nfsi->npages != 0)
-               return 0;
-       if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
-               return 0;
+       if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
+               goto force_reval;
+       if (nfs_attribute_timeout(inode))
+               goto force_reval;
+out_noreval:
+       return 0;
 force_reval:
        return __nfs_revalidate_inode(server, inode);
 }
index a6b16ed..ce153a6 100644 (file)
@@ -467,7 +467,8 @@ int __nfs_readpages_from_fscache(struct nfs_open_context *ctx,
                                 struct list_head *pages,
                                 unsigned *nr_pages)
 {
-       int ret, npages = *nr_pages;
+       unsigned npages = *nr_pages;
+       int ret;
 
        dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
                 NFS_I(inode)->fscache, npages, inode);
index b35d2a6..7428f7d 100644 (file)
@@ -78,159 +78,94 @@ struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh)
 {
        struct nfs_server *server = NFS_SB(sb);
        struct nfs_fsinfo fsinfo;
-       struct nfs_fattr fattr;
-       struct dentry *mntroot;
+       struct dentry *ret;
        struct inode *inode;
        int error;
 
        /* get the actual root for this mount */
-       fsinfo.fattr = &fattr;
+       fsinfo.fattr = nfs_alloc_fattr();
+       if (fsinfo.fattr == NULL)
+               return ERR_PTR(-ENOMEM);
 
        error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
        if (error < 0) {
                dprintk("nfs_get_root: getattr error = %d\n", -error);
-               return ERR_PTR(error);
+               ret = ERR_PTR(error);
+               goto out;
        }
 
        inode = nfs_fhget(sb, mntfh, fsinfo.fattr);
        if (IS_ERR(inode)) {
                dprintk("nfs_get_root: get root inode failed\n");
-               return ERR_CAST(inode);
+               ret = ERR_CAST(inode);
+               goto out;
        }
 
        error = nfs_superblock_set_dummy_root(sb, inode);
-       if (error != 0)
-               return ERR_PTR(error);
+       if (error != 0) {
+               ret = ERR_PTR(error);
+               goto out;
+       }
 
        /* root dentries normally start off anonymous and get spliced in later
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       mntroot = d_obtain_alias(inode);
-       if (IS_ERR(mntroot)) {
+       ret = d_obtain_alias(inode);
+       if (IS_ERR(ret)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               return mntroot;
+               goto out;
        }
 
-       security_d_instantiate(mntroot, inode);
-
-       if (!mntroot->d_op)
-               mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops;
+       security_d_instantiate(ret, inode);
 
-       return mntroot;
+       if (ret->d_op == NULL)
+               ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
+out:
+       nfs_free_fattr(fsinfo.fattr);
+       return ret;
 }
 
 #ifdef CONFIG_NFS_V4
 
-/*
- * Do a simple pathwalk from the root FH of the server to the nominated target
- * of the mountpoint
- * - give error on symlinks
- * - give error on ".." occurring in the path
- * - follow traversals
- */
-int nfs4_path_walk(struct nfs_server *server,
-                  struct nfs_fh *mntfh,
-                  const char *path)
+int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh)
 {
        struct nfs_fsinfo fsinfo;
-       struct nfs_fattr fattr;
-       struct nfs_fh lastfh;
-       struct qstr name;
-       int ret;
+       int ret = -ENOMEM;
 
-       dprintk("--> nfs4_path_walk(,,%s)\n", path);
+       dprintk("--> nfs4_get_rootfh()\n");
 
-       fsinfo.fattr = &fattr;
-       nfs_fattr_init(&fattr);
-
-       /* Eat leading slashes */
-       while (*path == '/')
-               path++;
+       fsinfo.fattr = nfs_alloc_fattr();
+       if (fsinfo.fattr == NULL)
+               goto out;
 
        /* Start by getting the root filehandle from the server */
        ret = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
        if (ret < 0) {
-               dprintk("nfs4_get_root: getroot error = %d\n", -ret);
-               return ret;
+               dprintk("nfs4_get_rootfh: getroot error = %d\n", -ret);
+               goto out;
        }
 
-       if (!S_ISDIR(fattr.mode)) {
-               printk(KERN_ERR "nfs4_get_root:"
+       if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE)
+                       || !S_ISDIR(fsinfo.fattr->mode)) {
+               printk(KERN_ERR "nfs4_get_rootfh:"
                       " getroot encountered non-directory\n");
-               return -ENOTDIR;
+               ret = -ENOTDIR;
+               goto out;
        }
 
-       /* FIXME: It is quite valid for the server to return a referral here */
-       if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
-               printk(KERN_ERR "nfs4_get_root:"
+       if (fsinfo.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
+               printk(KERN_ERR "nfs4_get_rootfh:"
                       " getroot obtained referral\n");
-               return -EREMOTE;
-       }
-
-next_component:
-       dprintk("Next: %s\n", path);
-
-       /* extract the next bit of the path */
-       if (!*path)
-               goto path_walk_complete;
-
-       name.name = path;
-       while (*path && *path != '/')
-               path++;
-       name.len = path - (const char *) name.name;
-
-       if (name.len > NFS4_MAXNAMLEN)
-               return -ENAMETOOLONG;
-
-eat_dot_dir:
-       while (*path == '/')
-               path++;
-
-       if (path[0] == '.' && (path[1] == '/' || !path[1])) {
-               path += 2;
-               goto eat_dot_dir;
-       }
-
-       /* FIXME: Why shouldn't the user be able to use ".." in the path? */
-       if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || !path[2])
-           ) {
-               printk(KERN_ERR "nfs4_get_root:"
-                      " Mount path contains reference to \"..\"\n");
-               return -EINVAL;
+               ret = -EREMOTE;
+               goto out;
        }
 
-       /* lookup the next FH in the sequence */
-       memcpy(&lastfh, mntfh, sizeof(lastfh));
-
-       dprintk("LookupFH: %*.*s [%s]\n", name.len, name.len, name.name, path);
-
-       ret = server->nfs_client->rpc_ops->lookupfh(server, &lastfh, &name,
-                                                   mntfh, &fattr);
-       if (ret < 0) {
-               dprintk("nfs4_get_root: getroot error = %d\n", -ret);
-               return ret;
-       }
-
-       if (!S_ISDIR(fattr.mode)) {
-               printk(KERN_ERR "nfs4_get_root:"
-                      " lookupfh encountered non-directory\n");
-               return -ENOTDIR;
-       }
-
-       /* FIXME: Referrals are quite valid here too */
-       if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL) {
-               printk(KERN_ERR "nfs4_get_root:"
-                      " lookupfh obtained referral\n");
-               return -EREMOTE;
-       }
-
-       goto next_component;
-
-path_walk_complete:
-       memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));
-       dprintk("<-- nfs4_path_walk() = 0\n");
-       return 0;
+       memcpy(&server->fsid, &fsinfo.fattr->fsid, sizeof(server->fsid));
+out:
+       nfs_free_fattr(fsinfo.fattr);
+       dprintk("<-- nfs4_get_rootfh() = %d\n", ret);
+       return ret;
 }
 
 /*
@@ -239,8 +174,8 @@ path_walk_complete:
 struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
 {
        struct nfs_server *server = NFS_SB(sb);
-       struct nfs_fattr fattr;
-       struct dentry *mntroot;
+       struct nfs_fattr *fattr = NULL;
+       struct dentry *ret;
        struct inode *inode;
        int error;
 
@@ -254,40 +189,50 @@ struct dentry *nfs4_get_root(struct super_block *sb, struct nfs_fh *mntfh)
                return ERR_PTR(error);
        }
 
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               return ERR_PTR(-ENOMEM);;
+
        /* get the actual root for this mount */
-       error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);
+       error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr);
        if (error < 0) {
                dprintk("nfs_get_root: getattr error = %d\n", -error);
-               return ERR_PTR(error);
+               ret = ERR_PTR(error);
+               goto out;
        }
 
-       inode = nfs_fhget(sb, mntfh, &fattr);
+       inode = nfs_fhget(sb, mntfh, fattr);
        if (IS_ERR(inode)) {
                dprintk("nfs_get_root: get root inode failed\n");
-               return ERR_CAST(inode);
+               ret = ERR_CAST(inode);
+               goto out;
        }
 
        error = nfs_superblock_set_dummy_root(sb, inode);
-       if (error != 0)
-               return ERR_PTR(error);
+       if (error != 0) {
+               ret = ERR_PTR(error);
+               goto out;
+       }
 
        /* root dentries normally start off anonymous and get spliced in later
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       mntroot = d_obtain_alias(inode);
-       if (IS_ERR(mntroot)) {
+       ret = d_obtain_alias(inode);
+       if (IS_ERR(ret)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               return mntroot;
+               goto out;
        }
 
-       security_d_instantiate(mntroot, inode);
+       security_d_instantiate(ret, inode);
 
-       if (!mntroot->d_op)
-               mntroot->d_op = server->nfs_client->rpc_ops->dentry_ops;
+       if (ret->d_op == NULL)
+               ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
 
+out:
+       nfs_free_fattr(fattr);
        dprintk("<-- nfs4_get_root()\n");
-       return mntroot;
+       return ret;
 }
 
 #endif /* CONFIG_NFS_V4 */
index 737128f..099b351 100644 (file)
@@ -393,8 +393,8 @@ int
 nfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
-       struct nfs_fattr fattr;
-       int error;
+       struct nfs_fattr *fattr;
+       int error = -ENOMEM;
 
        nfs_inc_stats(inode, NFSIOS_VFSSETATTR);
 
@@ -417,14 +417,20 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
                filemap_write_and_wait(inode->i_mapping);
                nfs_wb_all(inode);
        }
+
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto out;
        /*
         * Return any delegations if we're going to change ACLs
         */
        if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
                nfs_inode_return_delegation(inode);
-       error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
+       error = NFS_PROTO(inode)->setattr(dentry, fattr, attr);
        if (error == 0)
-               nfs_refresh_inode(inode, &fattr);
+               nfs_refresh_inode(inode, fattr);
+       nfs_free_fattr(fattr);
+out:
        return error;
 }
 
@@ -623,10 +629,10 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
        list_for_each_entry(pos, &nfsi->open_files, list) {
                if (cred != NULL && pos->cred != cred)
                        continue;
-               if ((pos->mode & mode) == mode) {
-                       ctx = get_nfs_open_context(pos);
-                       break;
-               }
+               if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
+                       continue;
+               ctx = get_nfs_open_context(pos);
+               break;
        }
        spin_unlock(&inode->i_lock);
        return ctx;
@@ -682,7 +688,7 @@ int
 __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
        int              status = -ESTALE;
-       struct nfs_fattr fattr;
+       struct nfs_fattr *fattr = NULL;
        struct nfs_inode *nfsi = NFS_I(inode);
 
        dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
@@ -693,8 +699,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        if (NFS_STALE(inode))
                goto out;
 
+       status = -ENOMEM;
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto out;
+
        nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
-       status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
+       status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), fattr);
        if (status != 0) {
                dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
                         inode->i_sb->s_id,
@@ -707,7 +718,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
                goto out;
        }
 
-       status = nfs_refresh_inode(inode, &fattr);
+       status = nfs_refresh_inode(inode, fattr);
        if (status) {
                dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
                         inode->i_sb->s_id,
@@ -723,6 +734,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
                (long long)NFS_FILEID(inode));
 
  out:
+       nfs_free_fattr(fattr);
        return status;
 }
 
@@ -730,9 +742,14 @@ int nfs_attribute_timeout(struct inode *inode)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
 
+       return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+}
+
+static int nfs_attribute_cache_expired(struct inode *inode)
+{
        if (nfs_have_delegated_attributes(inode))
                return 0;
-       return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
+       return nfs_attribute_timeout(inode);
 }
 
 /**
@@ -745,7 +762,7 @@ int nfs_attribute_timeout(struct inode *inode)
 int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
        if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR)
-                       && !nfs_attribute_timeout(inode))
+                       && !nfs_attribute_cache_expired(inode))
                return NFS_STALE(inode) ? -ESTALE : 0;
        return __nfs_revalidate_inode(server, inode);
 }
@@ -782,7 +799,8 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
        int ret = 0;
 
        if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
-                       || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
+                       || nfs_attribute_cache_expired(inode)
+                       || NFS_STALE(inode)) {
                ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
                if (ret < 0)
                        goto out;
@@ -916,6 +934,26 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
        fattr->gencount = nfs_inc_attr_generation_counter();
 }
 
+struct nfs_fattr *nfs_alloc_fattr(void)
+{
+       struct nfs_fattr *fattr;
+
+       fattr = kmalloc(sizeof(*fattr), GFP_NOFS);
+       if (fattr != NULL)
+               nfs_fattr_init(fattr);
+       return fattr;
+}
+
+struct nfs_fh *nfs_alloc_fhandle(void)
+{
+       struct nfs_fh *fh;
+
+       fh = kmalloc(sizeof(struct nfs_fh), GFP_NOFS);
+       if (fh != NULL)
+               fh->size = 0;
+       return fh;
+}
+
 /**
  * nfs_inode_attrs_need_update - check if the inode attributes need updating
  * @inode - pointer to inode
index 11f82f0..d8bd619 100644 (file)
@@ -244,9 +244,7 @@ extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *);
 #ifdef CONFIG_NFS_V4
 extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *);
 
-extern int nfs4_path_walk(struct nfs_server *server,
-                         struct nfs_fh *mntfh,
-                         const char *path);
+extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh);
 #endif
 
 /* read.c */
index 1d8d5c8..c583248 100644 (file)
@@ -36,14 +36,14 @@ static inline void nfs_inc_stats(const struct inode *inode,
 
 static inline void nfs_add_server_stats(const struct nfs_server *server,
                                        enum nfs_stat_bytecounters stat,
-                                       unsigned long addend)
+                                       long addend)
 {
        this_cpu_add(server->io_stats->bytes[stat], addend);
 }
 
 static inline void nfs_add_stats(const struct inode *inode,
                                 enum nfs_stat_bytecounters stat,
-                                unsigned long addend)
+                                long addend)
 {
        nfs_add_server_stats(NFS_SERVER(inode), stat, addend);
 }
@@ -51,7 +51,7 @@ static inline void nfs_add_stats(const struct inode *inode,
 #ifdef CONFIG_NFS_FSCACHE
 static inline void nfs_add_fscache_stats(struct inode *inode,
                                         enum nfs_stat_fscachecounters stat,
-                                        unsigned long addend)
+                                        long addend)
 {
        this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend);
 }
index 7888cf3..db6aa36 100644 (file)
@@ -105,8 +105,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        struct vfsmount *mnt;
        struct nfs_server *server = NFS_SERVER(dentry->d_inode);
        struct dentry *parent;
-       struct nfs_fh fh;
-       struct nfs_fattr fattr;
+       struct nfs_fh *fh = NULL;
+       struct nfs_fattr *fattr = NULL;
        int err;
 
        dprintk("--> nfs_follow_mountpoint()\n");
@@ -115,6 +115,12 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        if (IS_ROOT(dentry))
                goto out_err;
 
+       err = -ENOMEM;
+       fh = nfs_alloc_fhandle();
+       fattr = nfs_alloc_fattr();
+       if (fh == NULL || fattr == NULL)
+               goto out_err;
+
        dprintk("%s: enter\n", __func__);
        dput(nd->path.dentry);
        nd->path.dentry = dget(dentry);
@@ -123,16 +129,16 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        parent = dget_parent(nd->path.dentry);
        err = server->nfs_client->rpc_ops->lookup(parent->d_inode,
                                                  &nd->path.dentry->d_name,
-                                                 &fh, &fattr);
+                                                 fh, fattr);
        dput(parent);
        if (err != 0)
                goto out_err;
 
-       if (fattr.valid & NFS_ATTR_FATTR_V4_REFERRAL)
+       if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL)
                mnt = nfs_do_refmount(nd->path.mnt, nd->path.dentry);
        else
-               mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, &fh,
-                                     &fattr);
+               mnt = nfs_do_submount(nd->path.mnt, nd->path.dentry, fh,
+                                     fattr);
        err = PTR_ERR(mnt);
        if (IS_ERR(mnt))
                goto out_err;
@@ -151,6 +157,8 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
        nd->path.dentry = dget(mnt->mnt_root);
        schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
 out:
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fh);
        dprintk("%s: done, returned %d\n", __func__, err);
 
        dprintk("<-- nfs_follow_mountpoint() = %d\n", err);
index d150ae0..9f88c5f 100644 (file)
@@ -185,7 +185,6 @@ static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
 struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
 {
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs_fattr fattr;
        struct page *pages[NFSACL_MAXPAGES] = { };
        struct nfs3_getaclargs args = {
                .fh = NFS_FH(inode),
@@ -193,7 +192,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
                .pages = pages,
        };
        struct nfs3_getaclres res = {
-               .fattr =        &fattr,
+               0
        };
        struct rpc_message msg = {
                .rpc_argp       = &args,
@@ -228,7 +227,10 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
 
        dprintk("NFS call getacl\n");
        msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL];
-       nfs_fattr_init(&fattr);
+       res.fattr = nfs_alloc_fattr();
+       if (res.fattr == NULL)
+               return ERR_PTR(-ENOMEM);
+
        status = rpc_call_sync(server->client_acl, &msg, 0);
        dprintk("NFS reply getacl: %d\n", status);
 
@@ -238,7 +240,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
 
        switch (status) {
                case 0:
-                       status = nfs_refresh_inode(inode, &fattr);
+                       status = nfs_refresh_inode(inode, res.fattr);
                        break;
                case -EPFNOSUPPORT:
                case -EPROTONOSUPPORT:
@@ -278,6 +280,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
 getout:
        posix_acl_release(res.acl_access);
        posix_acl_release(res.acl_default);
+       nfs_free_fattr(res.fattr);
 
        if (status != 0) {
                posix_acl_release(acl);
@@ -290,7 +293,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
                  struct posix_acl *dfacl)
 {
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs_fattr fattr;
+       struct nfs_fattr *fattr;
        struct page *pages[NFSACL_MAXPAGES];
        struct nfs3_setaclargs args = {
                .inode = inode,
@@ -335,8 +338,13 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
        }
 
        dprintk("NFS call setacl\n");
+       status = -ENOMEM;
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto out_freepages;
+
        msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
-       nfs_fattr_init(&fattr);
+       msg.rpc_resp = fattr;
        status = rpc_call_sync(server->client_acl, &msg, 0);
        nfs_access_zap_cache(inode);
        nfs_zap_acl_cache(inode);
@@ -344,7 +352,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
 
        switch (status) {
                case 0:
-                       status = nfs_refresh_inode(inode, &fattr);
+                       status = nfs_refresh_inode(inode, fattr);
                        nfs3_cache_acls(inode, acl, dfacl);
                        break;
                case -EPFNOSUPPORT:
@@ -355,6 +363,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
                case -ENOTSUPP:
                        status = -EOPNOTSUPP;
        }
+       nfs_free_fattr(fattr);
 out_freepages:
        while (args.npages != 0) {
                args.npages--;
index e701002..fabb4f2 100644 (file)
@@ -144,14 +144,12 @@ static int
 nfs3_proc_lookup(struct inode *dir, struct qstr *name,
                 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
-       struct nfs_fattr        dir_attr;
        struct nfs3_diropargs   arg = {
                .fh             = NFS_FH(dir),
                .name           = name->name,
                .len            = name->len
        };
        struct nfs3_diropres    res = {
-               .dir_attr       = &dir_attr,
                .fh             = fhandle,
                .fattr          = fattr
        };
@@ -163,29 +161,30 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name,
        int                     status;
 
        dprintk("NFS call  lookup %s\n", name->name);
-       nfs_fattr_init(&dir_attr);
+       res.dir_attr = nfs_alloc_fattr();
+       if (res.dir_attr == NULL)
+               return -ENOMEM;
+
        nfs_fattr_init(fattr);
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
-       nfs_refresh_inode(dir, &dir_attr);
+       nfs_refresh_inode(dir, res.dir_attr);
        if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
                msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
                msg.rpc_argp = fhandle;
                msg.rpc_resp = fattr;
                status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        }
+       nfs_free_fattr(res.dir_attr);
        dprintk("NFS reply lookup: %d\n", status);
        return status;
 }
 
 static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 {
-       struct nfs_fattr        fattr;
        struct nfs3_accessargs  arg = {
                .fh             = NFS_FH(inode),
        };
-       struct nfs3_accessres   res = {
-               .fattr          = &fattr,
-       };
+       struct nfs3_accessres   res;
        struct rpc_message msg = {
                .rpc_proc       = &nfs3_procedures[NFS3PROC_ACCESS],
                .rpc_argp       = &arg,
@@ -193,7 +192,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
                .rpc_cred       = entry->cred,
        };
        int mode = entry->mask;
-       int status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  access\n");
 
@@ -210,9 +209,13 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
                if (mode & MAY_EXEC)
                        arg.access |= NFS3_ACCESS_EXECUTE;
        }
-       nfs_fattr_init(&fattr);
+
+       res.fattr = nfs_alloc_fattr();
+       if (res.fattr == NULL)
+               goto out;
+
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
-       nfs_refresh_inode(inode, &fattr);
+       nfs_refresh_inode(inode, res.fattr);
        if (status == 0) {
                entry->mask = 0;
                if (res.access & NFS3_ACCESS_READ)
@@ -222,6 +225,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
                if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
                        entry->mask |= MAY_EXEC;
        }
+       nfs_free_fattr(res.fattr);
+out:
        dprintk("NFS reply access: %d\n", status);
        return status;
 }
@@ -229,7 +234,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 static int nfs3_proc_readlink(struct inode *inode, struct page *page,
                unsigned int pgbase, unsigned int pglen)
 {
-       struct nfs_fattr        fattr;
+       struct nfs_fattr        *fattr;
        struct nfs3_readlinkargs args = {
                .fh             = NFS_FH(inode),
                .pgbase         = pgbase,
@@ -239,14 +244,19 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page,
        struct rpc_message msg = {
                .rpc_proc       = &nfs3_procedures[NFS3PROC_READLINK],
                .rpc_argp       = &args,
-               .rpc_resp       = &fattr,
        };
-       int                     status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  readlink\n");
-       nfs_fattr_init(&fattr);
+       fattr = nfs_alloc_fattr();
+       if (fattr == NULL)
+               goto out;
+       msg.rpc_resp = fattr;
+
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
-       nfs_refresh_inode(inode, &fattr);
+       nfs_refresh_inode(inode, fattr);
+       nfs_free_fattr(fattr);
+out:
        dprintk("NFS reply readlink: %d\n", status);
        return status;
 }
@@ -396,12 +406,17 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name)
                .rpc_argp = &arg,
                .rpc_resp = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  remove %s\n", name->name);
-       nfs_fattr_init(&res.dir_attr);
+       res.dir_attr = nfs_alloc_fattr();
+       if (res.dir_attr == NULL)
+               goto out;
+
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
-       nfs_post_op_update_inode(dir, &res.dir_attr);
+       nfs_post_op_update_inode(dir, res.dir_attr);
+       nfs_free_fattr(res.dir_attr);
+out:
        dprintk("NFS reply remove: %d\n", status);
        return status;
 }
@@ -419,7 +434,7 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
        if (nfs3_async_handle_jukebox(task, dir))
                return 0;
        res = task->tk_msg.rpc_resp;
-       nfs_post_op_update_inode(dir, &res->dir_attr);
+       nfs_post_op_update_inode(dir, res->dir_attr);
        return 1;
 }
 
@@ -427,7 +442,6 @@ static int
 nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
                 struct inode *new_dir, struct qstr *new_name)
 {
-       struct nfs_fattr        old_dir_attr, new_dir_attr;
        struct nfs3_renameargs  arg = {
                .fromfh         = NFS_FH(old_dir),
                .fromname       = old_name->name,
@@ -436,23 +450,27 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
                .toname         = new_name->name,
                .tolen          = new_name->len
        };
-       struct nfs3_renameres   res = {
-               .fromattr       = &old_dir_attr,
-               .toattr         = &new_dir_attr
-       };
+       struct nfs3_renameres res;
        struct rpc_message msg = {
                .rpc_proc       = &nfs3_procedures[NFS3PROC_RENAME],
                .rpc_argp       = &arg,
                .rpc_resp       = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
-       nfs_fattr_init(&old_dir_attr);
-       nfs_fattr_init(&new_dir_attr);
+
+       res.fromattr = nfs_alloc_fattr();
+       res.toattr = nfs_alloc_fattr();
+       if (res.fromattr == NULL || res.toattr == NULL)
+               goto out;
+
        status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
-       nfs_post_op_update_inode(old_dir, &old_dir_attr);
-       nfs_post_op_update_inode(new_dir, &new_dir_attr);
+       nfs_post_op_update_inode(old_dir, res.fromattr);
+       nfs_post_op_update_inode(new_dir, res.toattr);
+out:
+       nfs_free_fattr(res.toattr);
+       nfs_free_fattr(res.fromattr);
        dprintk("NFS reply rename: %d\n", status);
        return status;
 }
@@ -460,30 +478,32 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
 static int
 nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
 {
-       struct nfs_fattr        dir_attr, fattr;
        struct nfs3_linkargs    arg = {
                .fromfh         = NFS_FH(inode),
                .tofh           = NFS_FH(dir),
                .toname         = name->name,
                .tolen          = name->len
        };
-       struct nfs3_linkres     res = {
-               .dir_attr       = &dir_attr,
-               .fattr          = &fattr
-       };
+       struct nfs3_linkres     res;
        struct rpc_message msg = {
                .rpc_proc       = &nfs3_procedures[NFS3PROC_LINK],
                .rpc_argp       = &arg,
                .rpc_resp       = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  link %s\n", name->name);
-       nfs_fattr_init(&dir_attr);
-       nfs_fattr_init(&fattr);
+       res.fattr = nfs_alloc_fattr();
+       res.dir_attr = nfs_alloc_fattr();
+       if (res.fattr == NULL || res.dir_attr == NULL)
+               goto out;
+
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
-       nfs_post_op_update_inode(dir, &dir_attr);
-       nfs_post_op_update_inode(inode, &fattr);
+       nfs_post_op_update_inode(dir, res.dir_attr);
+       nfs_post_op_update_inode(inode, res.fattr);
+out:
+       nfs_free_fattr(res.dir_attr);
+       nfs_free_fattr(res.fattr);
        dprintk("NFS reply link: %d\n", status);
        return status;
 }
@@ -554,7 +574,7 @@ out:
 static int
 nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
 {
-       struct nfs_fattr        dir_attr;
+       struct nfs_fattr        *dir_attr;
        struct nfs3_diropargs   arg = {
                .fh             = NFS_FH(dir),
                .name           = name->name,
@@ -563,14 +583,19 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
        struct rpc_message msg = {
                .rpc_proc       = &nfs3_procedures[NFS3PROC_RMDIR],
                .rpc_argp       = &arg,
-               .rpc_resp       = &dir_attr,
        };
-       int                     status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  rmdir %s\n", name->name);
-       nfs_fattr_init(&dir_attr);
+       dir_attr = nfs_alloc_fattr();
+       if (dir_attr == NULL)
+               goto out;
+
+       msg.rpc_resp = dir_attr;
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
-       nfs_post_op_update_inode(dir, &dir_attr);
+       nfs_post_op_update_inode(dir, dir_attr);
+       nfs_free_fattr(dir_attr);
+out:
        dprintk("NFS reply rmdir: %d\n", status);
        return status;
 }
@@ -589,7 +614,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                  u64 cookie, struct page *page, unsigned int count, int plus)
 {
        struct inode            *dir = dentry->d_inode;
-       struct nfs_fattr        dir_attr;
        __be32                  *verf = NFS_COOKIEVERF(dir);
        struct nfs3_readdirargs arg = {
                .fh             = NFS_FH(dir),
@@ -600,7 +624,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                .pages          = &page
        };
        struct nfs3_readdirres  res = {
-               .dir_attr       = &dir_attr,
                .verf           = verf,
                .plus           = plus
        };
@@ -610,7 +633,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                .rpc_resp       = &res,
                .rpc_cred       = cred
        };
-       int                     status;
+       int status = -ENOMEM;
 
        if (plus)
                msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
@@ -618,12 +641,17 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
        dprintk("NFS call  readdir%s %d\n",
                        plus? "plus" : "", (unsigned int) cookie);
 
-       nfs_fattr_init(&dir_attr);
+       res.dir_attr = nfs_alloc_fattr();
+       if (res.dir_attr == NULL)
+               goto out;
+
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
 
        nfs_invalidate_atime(dir);
+       nfs_refresh_inode(dir, res.dir_attr);
 
-       nfs_refresh_inode(dir, &dir_attr);
+       nfs_free_fattr(res.dir_attr);
+out:
        dprintk("NFS reply readdir: %d\n", status);
        return status;
 }
index 56a86f6..75dcfc7 100644 (file)
@@ -762,7 +762,7 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 static int
 nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
 {
-       return nfs3_xdr_wccstat(req, p, &res->dir_attr);
+       return nfs3_xdr_wccstat(req, p, res->dir_attr);
 }
 
 /*
index a187200..c538c61 100644 (file)
@@ -206,14 +206,14 @@ extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
 
 
 /* nfs4proc.c */
-extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *);
-extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
+extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
+extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
 extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
 extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
 extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
 extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
+extern int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait);
 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
@@ -286,7 +286,7 @@ extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
 extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
 extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
 
-extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter);
+extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
 extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
 extern void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid);
 extern void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid);
index f071d12..3c2a172 100644 (file)
@@ -115,6 +115,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
                                     char *page, char *page2,
                                     const struct nfs4_fs_location *location)
 {
+       const size_t addr_bufsize = sizeof(struct sockaddr_storage);
        struct vfsmount *mnt = ERR_PTR(-ENOENT);
        char *mnt_path;
        unsigned int maxbuflen;
@@ -126,9 +127,12 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
        mountdata->mnt_path = mnt_path;
        maxbuflen = mnt_path - 1 - page2;
 
+       mountdata->addr = kmalloc(addr_bufsize, GFP_KERNEL);
+       if (mountdata->addr == NULL)
+               return ERR_PTR(-ENOMEM);
+
        for (s = 0; s < location->nservers; s++) {
                const struct nfs4_string *buf = &location->servers[s];
-               struct sockaddr_storage addr;
 
                if (buf->len <= 0 || buf->len >= maxbuflen)
                        continue;
@@ -137,11 +141,10 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
                        continue;
 
                mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
-                               (struct sockaddr *)&addr, sizeof(addr));
+                               mountdata->addr, addr_bufsize);
                if (mountdata->addrlen == 0)
                        continue;
 
-               mountdata->addr = (struct sockaddr *)&addr;
                rpc_set_port(mountdata->addr, NFS_PORT);
 
                memcpy(page2, buf->data, buf->len);
@@ -156,6 +159,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
                if (!IS_ERR(mnt))
                        break;
        }
+       kfree(mountdata->addr);
        return mnt;
 }
 
@@ -221,8 +225,8 @@ out:
 
 /*
  * nfs_do_refmount - handle crossing a referral on server
+ * @mnt_parent - mountpoint of referral
  * @dentry - dentry of referral
- * @nd - nameidata info
  *
  */
 struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
index fe0cd9e..70015dd 100644 (file)
@@ -70,6 +70,9 @@ static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *);
 static int _nfs4_proc_lookup(struct inode *dir, const struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
 static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr);
+static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
+                           struct nfs_fattr *fattr, struct iattr *sattr,
+                           struct nfs4_state *state);
 
 /* Prevent leaks of NFSv4 errors into userland */
 static int nfs4_map_errors(int err)
@@ -714,17 +717,18 @@ static void nfs4_init_opendata_res(struct nfs4_opendata *p)
 
 static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
                struct nfs4_state_owner *sp, fmode_t fmode, int flags,
-               const struct iattr *attrs)
+               const struct iattr *attrs,
+               gfp_t gfp_mask)
 {
        struct dentry *parent = dget_parent(path->dentry);
        struct inode *dir = parent->d_inode;
        struct nfs_server *server = NFS_SERVER(dir);
        struct nfs4_opendata *p;
 
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), gfp_mask);
        if (p == NULL)
                goto err;
-       p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+       p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid, gfp_mask);
        if (p->o_arg.seqid == NULL)
                goto err_free;
        path_get(path);
@@ -1060,7 +1064,7 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
 {
        struct nfs4_opendata *opendata;
 
-       opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL);
+       opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, 0, NULL, GFP_NOFS);
        if (opendata == NULL)
                return ERR_PTR(-ENOMEM);
        opendata->state = state;
@@ -1523,6 +1527,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
                nfs_post_op_update_inode(dir, o_res->dir_attr);
        } else
                nfs_refresh_inode(dir, o_res->dir_attr);
+       if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
+               server->caps &= ~NFS_CAP_POSIX_LOCK;
        if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
                status = _nfs4_proc_open_confirm(data);
                if (status != 0)
@@ -1646,7 +1652,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
        if (path->dentry->d_inode != NULL)
                nfs4_return_incompatible_delegation(path->dentry->d_inode, fmode);
        status = -ENOMEM;
-       opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr);
+       opendata = nfs4_opendata_alloc(path, sp, fmode, flags, sattr, GFP_KERNEL);
        if (opendata == NULL)
                goto err_put_state_owner;
 
@@ -1657,15 +1663,24 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
        if (status != 0)
                goto err_opendata_put;
 
-       if (opendata->o_arg.open_flags & O_EXCL)
-               nfs4_exclusive_attrset(opendata, sattr);
-
        state = nfs4_opendata_to_nfs4_state(opendata);
        status = PTR_ERR(state);
        if (IS_ERR(state))
                goto err_opendata_put;
-       if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+       if (server->caps & NFS_CAP_POSIX_LOCK)
                set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
+
+       if (opendata->o_arg.open_flags & O_EXCL) {
+               nfs4_exclusive_attrset(opendata, sattr);
+
+               nfs_fattr_init(opendata->o_res.f_attr);
+               status = nfs4_do_setattr(state->inode, cred,
+                               opendata->o_res.f_attr, sattr,
+                               state);
+               if (status == 0)
+                       nfs_setattr_update_inode(state->inode, sattr);
+               nfs_post_op_update_inode(state->inode, opendata->o_res.f_attr);
+       }
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
        *res = state;
@@ -1912,7 +1927,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
  *
  * NOTE: Caller must be holding the sp->so_owner semaphore!
  */
-int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
+int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, int wait)
 {
        struct nfs_server *server = NFS_SERVER(state->inode);
        struct nfs4_closedata *calldata;
@@ -1931,7 +1946,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
        };
        int status = -ENOMEM;
 
-       calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
+       calldata = kzalloc(sizeof(*calldata), gfp_mask);
        if (calldata == NULL)
                goto out;
        calldata->inode = state->inode;
@@ -1939,7 +1954,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
        calldata->arg.fh = NFS_FH(state->inode);
        calldata->arg.stateid = &state->open_stateid;
        /* Serialization for the sequence id */
-       calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid);
+       calldata->arg.seqid = nfs_alloc_seqid(&state->owner->so_seqid, gfp_mask);
        if (calldata->arg.seqid == NULL)
                goto out_free_calldata;
        calldata->arg.fmode = 0;
@@ -2402,14 +2417,12 @@ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 {
        struct nfs_server *server = NFS_SERVER(inode);
-       struct nfs_fattr fattr;
        struct nfs4_accessargs args = {
                .fh = NFS_FH(inode),
                .bitmask = server->attr_bitmask,
        };
        struct nfs4_accessres res = {
                .server = server,
-               .fattr = &fattr,
        };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
@@ -2436,7 +2449,11 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
                if (mode & MAY_EXEC)
                        args.access |= NFS4_ACCESS_EXECUTE;
        }
-       nfs_fattr_init(&fattr);
+
+       res.fattr = nfs_alloc_fattr();
+       if (res.fattr == NULL)
+               return -ENOMEM;
+
        status = nfs4_call_sync(server, &msg, &args, &res, 0);
        if (!status) {
                entry->mask = 0;
@@ -2446,8 +2463,9 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
                        entry->mask |= MAY_WRITE;
                if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
                        entry->mask |= MAY_EXEC;
-               nfs_refresh_inode(inode, &fattr);
+               nfs_refresh_inode(inode, res.fattr);
        }
+       nfs_free_fattr(res.fattr);
        return status;
 }
 
@@ -2560,13 +2578,6 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
        }
        d_add(dentry, igrab(state->inode));
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
-       if (flags & O_EXCL) {
-               struct nfs_fattr fattr;
-               status = nfs4_do_setattr(state->inode, cred, &fattr, sattr, state);
-               if (status == 0)
-                       nfs_setattr_update_inode(state->inode, sattr);
-               nfs_post_op_update_inode(state->inode, &fattr);
-       }
        if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
                status = nfs4_intent_set_file(nd, &path, state, fmode);
        else
@@ -2594,14 +2605,19 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
+
+       res.dir_attr = nfs_alloc_fattr();
+       if (res.dir_attr == NULL)
+               goto out;
 
-       nfs_fattr_init(&res.dir_attr);
        status = nfs4_call_sync(server, &msg, &args, &res, 1);
        if (status == 0) {
                update_changeattr(dir, &res.cinfo);
-               nfs_post_op_update_inode(dir, &res.dir_attr);
+               nfs_post_op_update_inode(dir, res.dir_attr);
        }
+       nfs_free_fattr(res.dir_attr);
+out:
        return status;
 }
 
@@ -2636,7 +2652,7 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
        if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
                return 0;
        update_changeattr(dir, &res->cinfo);
-       nfs_post_op_update_inode(dir, &res->dir_attr);
+       nfs_post_op_update_inode(dir, res->dir_attr);
        return 1;
 }
 
@@ -2651,29 +2667,31 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
                .new_name = new_name,
                .bitmask = server->attr_bitmask,
        };
-       struct nfs_fattr old_fattr, new_fattr;
        struct nfs4_rename_res res = {
                .server = server,
-               .old_fattr = &old_fattr,
-               .new_fattr = &new_fattr,
        };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RENAME],
                .rpc_argp = &arg,
                .rpc_resp = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
        
-       nfs_fattr_init(res.old_fattr);
-       nfs_fattr_init(res.new_fattr);
-       status = nfs4_call_sync(server, &msg, &arg, &res, 1);
+       res.old_fattr = nfs_alloc_fattr();
+       res.new_fattr = nfs_alloc_fattr();
+       if (res.old_fattr == NULL || res.new_fattr == NULL)
+               goto out;
 
+       status = nfs4_call_sync(server, &msg, &arg, &res, 1);
        if (!status) {
                update_changeattr(old_dir, &res.old_cinfo);
                nfs_post_op_update_inode(old_dir, res.old_fattr);
                update_changeattr(new_dir, &res.new_cinfo);
                nfs_post_op_update_inode(new_dir, res.new_fattr);
        }
+out:
+       nfs_free_fattr(res.new_fattr);
+       nfs_free_fattr(res.old_fattr);
        return status;
 }
 
@@ -2700,28 +2718,30 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
                .name   = name,
                .bitmask = server->attr_bitmask,
        };
-       struct nfs_fattr fattr, dir_attr;
        struct nfs4_link_res res = {
                .server = server,
-               .fattr = &fattr,
-               .dir_attr = &dir_attr,
        };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
                .rpc_argp = &arg,
                .rpc_resp = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
+
+       res.fattr = nfs_alloc_fattr();
+       res.dir_attr = nfs_alloc_fattr();
+       if (res.fattr == NULL || res.dir_attr == NULL)
+               goto out;
 
-       nfs_fattr_init(res.fattr);
-       nfs_fattr_init(res.dir_attr);
        status = nfs4_call_sync(server, &msg, &arg, &res, 1);
        if (!status) {
                update_changeattr(dir, &res.cinfo);
                nfs_post_op_update_inode(dir, res.dir_attr);
                nfs_post_op_update_inode(inode, res.fattr);
        }
-
+out:
+       nfs_free_fattr(res.dir_attr);
+       nfs_free_fattr(res.fattr);
        return status;
 }
 
@@ -3144,23 +3164,31 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
        msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT];
 }
 
+struct nfs4_renewdata {
+       struct nfs_client       *client;
+       unsigned long           timestamp;
+};
+
 /*
  * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
  * standalone procedure for queueing an asynchronous RENEW.
  */
-static void nfs4_renew_release(void *data)
+static void nfs4_renew_release(void *calldata)
 {
-       struct nfs_client *clp = data;
+       struct nfs4_renewdata *data = calldata;
+       struct nfs_client *clp = data->client;
 
        if (atomic_read(&clp->cl_count) > 1)
                nfs4_schedule_state_renewal(clp);
        nfs_put_client(clp);
+       kfree(data);
 }
 
-static void nfs4_renew_done(struct rpc_task *task, void *data)
+static void nfs4_renew_done(struct rpc_task *task, void *calldata)
 {
-       struct nfs_client *clp = data;
-       unsigned long timestamp = task->tk_start;
+       struct nfs4_renewdata *data = calldata;
+       struct nfs_client *clp = data->client;
+       unsigned long timestamp = data->timestamp;
 
        if (task->tk_status < 0) {
                /* Unless we're shutting down, schedule state recovery! */
@@ -3186,11 +3214,17 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred)
                .rpc_argp       = clp,
                .rpc_cred       = cred,
        };
+       struct nfs4_renewdata *data;
 
        if (!atomic_inc_not_zero(&clp->cl_count))
                return -EIO;
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       if (data == NULL)
+               return -ENOMEM;
+       data->client = clp;
+       data->timestamp = jiffies;
        return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
-                       &nfs4_renew_ops, clp);
+                       &nfs4_renew_ops, data);
 }
 
 int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
@@ -3492,7 +3526,9 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
        return _nfs4_async_handle_error(task, server, server->nfs_client, state);
 }
 
-int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
+int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
+               unsigned short port, struct rpc_cred *cred,
+               struct nfs4_setclientid_res *res)
 {
        nfs4_verifier sc_verifier;
        struct nfs4_setclientid setclientid = {
@@ -3502,7 +3538,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
                .rpc_argp = &setclientid,
-               .rpc_resp = clp,
+               .rpc_resp = res,
                .rpc_cred = cred,
        };
        __be32 *p;
@@ -3545,12 +3581,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, unsigned short po
        return status;
 }
 
-static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+               struct nfs4_setclientid_res *arg,
+               struct rpc_cred *cred)
 {
        struct nfs_fsinfo fsinfo;
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
-               .rpc_argp = clp,
+               .rpc_argp = arg,
                .rpc_resp = &fsinfo,
                .rpc_cred = cred,
        };
@@ -3568,12 +3606,14 @@ static int _nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cre
        return status;
 }
 
-int nfs4_proc_setclientid_confirm(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
+               struct nfs4_setclientid_res *arg,
+               struct rpc_cred *cred)
 {
        long timeout = 0;
        int err;
        do {
-               err = _nfs4_proc_setclientid_confirm(clp, cred);
+               err = _nfs4_proc_setclientid_confirm(clp, arg, cred);
                switch (err) {
                        case 0:
                                return err;
@@ -3665,7 +3705,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
        };
        int status = 0;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_NOFS);
        if (data == NULL)
                return -ENOMEM;
        data->args.fhandle = &data->fh;
@@ -3821,7 +3861,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
        struct nfs4_unlockdata *p;
        struct inode *inode = lsp->ls_state->inode;
 
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), GFP_NOFS);
        if (p == NULL)
                return NULL;
        p->arg.fh = NFS_FH(inode);
@@ -3959,7 +3999,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
        if (test_bit(NFS_DELEGATED_STATE, &state->flags))
                goto out;
        lsp = request->fl_u.nfs4_fl.owner;
-       seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+       seqid = nfs_alloc_seqid(&lsp->ls_seqid, GFP_KERNEL);
        status = -ENOMEM;
        if (seqid == NULL)
                goto out;
@@ -3987,22 +4027,23 @@ struct nfs4_lockdata {
 };
 
 static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
-               struct nfs_open_context *ctx, struct nfs4_lock_state *lsp)
+               struct nfs_open_context *ctx, struct nfs4_lock_state *lsp,
+               gfp_t gfp_mask)
 {
        struct nfs4_lockdata *p;
        struct inode *inode = lsp->ls_state->inode;
        struct nfs_server *server = NFS_SERVER(inode);
 
-       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), gfp_mask);
        if (p == NULL)
                return NULL;
 
        p->arg.fh = NFS_FH(inode);
        p->arg.fl = &p->fl;
-       p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid);
+       p->arg.open_seqid = nfs_alloc_seqid(&lsp->ls_state->owner->so_seqid, gfp_mask);
        if (p->arg.open_seqid == NULL)
                goto out_free;
-       p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+       p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid, gfp_mask);
        if (p->arg.lock_seqid == NULL)
                goto out_free_seqid;
        p->arg.lock_stateid = &lsp->ls_stateid;
@@ -4156,7 +4197,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
 
        dprintk("%s: begin!\n", __func__);
        data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file),
-                       fl->fl_u.nfs4_fl.owner);
+                       fl->fl_u.nfs4_fl.owner,
+                       recovery_type == NFS_LOCK_NEW ? GFP_KERNEL : GFP_NOFS);
        if (data == NULL)
                return -ENOMEM;
        if (IS_SETLKW(cmd))
@@ -4645,7 +4687,7 @@ static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
        if (max_reqs != tbl->max_slots) {
                ret = -ENOMEM;
                new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
-                             GFP_KERNEL);
+                             GFP_NOFS);
                if (!new)
                        goto out;
                ret = 0;
@@ -4710,7 +4752,7 @@ static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
 
        dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
 
-       slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_KERNEL);
+       slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
        if (!slot)
                goto out;
        ret = 0;
@@ -4759,7 +4801,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
        struct nfs4_session *session;
        struct nfs4_slot_table *tbl;
 
-       session = kzalloc(sizeof(struct nfs4_session), GFP_KERNEL);
+       session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS);
        if (!session)
                return NULL;
 
@@ -5103,8 +5145,8 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp,
 
        if (!atomic_inc_not_zero(&clp->cl_count))
                return -EIO;
-       args = kzalloc(sizeof(*args), GFP_KERNEL);
-       res = kzalloc(sizeof(*res), GFP_KERNEL);
+       args = kzalloc(sizeof(*args), GFP_NOFS);
+       res = kzalloc(sizeof(*res), GFP_NOFS);
        if (!args || !res) {
                kfree(args);
                kfree(res);
@@ -5205,7 +5247,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
        int status = -ENOMEM;
 
        dprintk("--> %s\n", __func__);
-       calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
+       calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
        if (calldata == NULL)
                goto out;
        calldata->clp = clp;
@@ -5216,9 +5258,12 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp)
        msg.rpc_resp = &calldata->res;
        task_setup_data.callback_data = calldata;
        task = rpc_run_task(&task_setup_data);
-       if (IS_ERR(task))
+       if (IS_ERR(task)) {
                status = PTR_ERR(task);
+               goto out;
+       }
        rpc_put_task(task);
+       return 0;
 out:
        dprintk("<-- %s status=%d\n", __func__, status);
        return status;
index 6c5ed51..34acf59 100644 (file)
@@ -62,6 +62,7 @@ static LIST_HEAD(nfs4_clientid_list);
 
 int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
 {
+       struct nfs4_setclientid_res clid;
        unsigned short port;
        int status;
 
@@ -69,11 +70,15 @@ int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
        if (clp->cl_addr.ss_family == AF_INET6)
                port = nfs_callback_tcpport6;
 
-       status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred);
-       if (status == 0)
-               status = nfs4_proc_setclientid_confirm(clp, cred);
-       if (status == 0)
-               nfs4_schedule_state_renewal(clp);
+       status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
+       if (status != 0)
+               goto out;
+       status = nfs4_proc_setclientid_confirm(clp, &clid, cred);
+       if (status != 0)
+               goto out;
+       clp->cl_clientid = clid.clientid;
+       nfs4_schedule_state_renewal(clp);
+out:
        return status;
 }
 
@@ -361,7 +366,7 @@ nfs4_alloc_state_owner(void)
 {
        struct nfs4_state_owner *sp;
 
-       sp = kzalloc(sizeof(*sp),GFP_KERNEL);
+       sp = kzalloc(sizeof(*sp),GFP_NOFS);
        if (!sp)
                return NULL;
        spin_lock_init(&sp->so_lock);
@@ -435,7 +440,7 @@ nfs4_alloc_open_state(void)
 {
        struct nfs4_state *state;
 
-       state = kzalloc(sizeof(*state), GFP_KERNEL);
+       state = kzalloc(sizeof(*state), GFP_NOFS);
        if (!state)
                return NULL;
        atomic_set(&state->count, 1);
@@ -537,7 +542,8 @@ void nfs4_put_open_state(struct nfs4_state *state)
 /*
  * Close the current file.
  */
-static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fmode, int wait)
+static void __nfs4_close(struct path *path, struct nfs4_state *state,
+               fmode_t fmode, gfp_t gfp_mask, int wait)
 {
        struct nfs4_state_owner *owner = state->owner;
        int call_close = 0;
@@ -578,17 +584,17 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state, fmode_t fm
                nfs4_put_open_state(state);
                nfs4_put_state_owner(owner);
        } else
-               nfs4_do_close(path, state, wait);
+               nfs4_do_close(path, state, gfp_mask, wait);
 }
 
 void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
 {
-       __nfs4_close(path, state, fmode, 0);
+       __nfs4_close(path, state, fmode, GFP_NOFS, 0);
 }
 
 void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode)
 {
-       __nfs4_close(path, state, fmode, 1);
+       __nfs4_close(path, state, fmode, GFP_KERNEL, 1);
 }
 
 /*
@@ -618,7 +624,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
        struct nfs4_lock_state *lsp;
        struct nfs_client *clp = state->owner->so_client;
 
-       lsp = kzalloc(sizeof(*lsp), GFP_KERNEL);
+       lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
        if (lsp == NULL)
                return NULL;
        rpc_init_wait_queue(&lsp->ls_sequence.wait, "lock_seqid_waitqueue");
@@ -754,11 +760,11 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
        nfs4_put_lock_state(lsp);
 }
 
-struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
+struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask)
 {
        struct nfs_seqid *new;
 
-       new = kmalloc(sizeof(*new), GFP_KERNEL);
+       new = kmalloc(sizeof(*new), gfp_mask);
        if (new != NULL) {
                new->sequence = counter;
                INIT_LIST_HEAD(&new->list);
@@ -1347,7 +1353,7 @@ static int nfs4_recall_slot(struct nfs_client *clp)
 
        nfs4_begin_drain_session(clp);
        new = kmalloc(fc_tbl->target_max_slots * sizeof(struct nfs4_slot),
-                     GFP_KERNEL);
+                     GFP_NOFS);
         if (!new)
                return -ENOMEM;
 
index 38f3b58..6bdef28 100644 (file)
@@ -1504,14 +1504,14 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
        hdr->replen += decode_setclientid_maxsz;
 }
 
-static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
+static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
 {
        __be32 *p;
 
        p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE);
        *p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM);
-       p = xdr_encode_hyper(p, client_state->cl_clientid);
-       xdr_encode_opaque_fixed(p, client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
+       p = xdr_encode_hyper(p, arg->clientid);
+       xdr_encode_opaque_fixed(p, arg->confirm.data, NFS4_VERIFIER_SIZE);
        hdr->nops++;
        hdr->replen += decode_setclientid_confirm_maxsz;
 }
@@ -2324,7 +2324,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
 /*
  * a SETCLIENTID_CONFIRM request
  */
-static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
+static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid_res *arg)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr = {
@@ -2334,7 +2334,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
 
        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
        encode_compound_hdr(&xdr, req, &hdr);
-       encode_setclientid_confirm(&xdr, clp, &hdr);
+       encode_setclientid_confirm(&xdr, arg, &hdr);
        encode_putrootfh(&xdr, &hdr);
        encode_fsinfo(&xdr, lease_bitmap, &hdr);
        encode_nops(&hdr);
@@ -4397,7 +4397,7 @@ out_overflow:
        return -EIO;
 }
 
-static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
+static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res)
 {
        __be32 *p;
        uint32_t opnum;
@@ -4417,8 +4417,8 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
                p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE);
                if (unlikely(!p))
                        goto out_overflow;
-               p = xdr_decode_hyper(p, &clp->cl_clientid);
-               memcpy(clp->cl_confirm.data, p, NFS4_VERIFIER_SIZE);
+               p = xdr_decode_hyper(p, &res->clientid);
+               memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE);
        } else if (nfserr == NFSERR_CLID_INUSE) {
                uint32_t len;
 
@@ -4815,7 +4815,7 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem
                goto out;
        if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
                goto out;
-       decode_getfattr(&xdr, &res->dir_attr, res->server,
+       decode_getfattr(&xdr, res->dir_attr, res->server,
                        !RPC_IS_ASYNC(rqstp->rq_task));
 out:
        return status;
@@ -5498,7 +5498,7 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
  * Decode SETCLIENTID response
  */
 static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
-               struct nfs_client *clp)
+               struct nfs4_setclientid_res *res)
 {
        struct xdr_stream xdr;
        struct compound_hdr hdr;
@@ -5507,7 +5507,7 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
        status = decode_compound_hdr(&xdr, &hdr);
        if (!status)
-               status = decode_setclientid(&xdr, clp);
+               status = decode_setclientid(&xdr, res);
        return status;
 }
 
index 8c55b27..6bd19d8 100644 (file)
@@ -488,7 +488,6 @@ static int __init root_nfs_ports(void)
  */
 static int __init root_nfs_get_handle(void)
 {
-       struct nfs_fh fh;
        struct sockaddr_in sin;
        unsigned int auth_flav_len = 0;
        struct nfs_mount_request request = {
@@ -499,21 +498,24 @@ static int __init root_nfs_get_handle(void)
                                        NFS_MNT3_VERSION : NFS_MNT_VERSION,
                .protocol       = (nfs_data.flags & NFS_MOUNT_TCP) ?
                                        XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP,
-               .fh             = &fh,
                .auth_flav_len  = &auth_flav_len,
        };
-       int status;
+       int status = -ENOMEM;
 
+       request.fh = nfs_alloc_fhandle();
+       if (!request.fh)
+               goto out;
        set_sockaddr(&sin, servaddr, htons(mount_port));
        status = nfs_mount(&request);
        if (status < 0)
                printk(KERN_ERR "Root-NFS: Server returned error %d "
                                "while mounting %s\n", status, nfs_export_path);
        else {
-               nfs_data.root.size = fh.size;
-               memcpy(nfs_data.root.data, fh.data, fh.size);
+               nfs_data.root.size = request.fh->size;
+               memcpy(&nfs_data.root.data, request.fh->data, request.fh->size);
        }
-
+       nfs_free_fhandle(request.fh);
+out:
        return status;
 }
 
index 29d9d36..a3654e5 100644 (file)
@@ -60,16 +60,10 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
 {
        struct nfs_page         *req;
 
-       for (;;) {
-               /* try to allocate the request struct */
-               req = nfs_page_alloc();
-               if (req != NULL)
-                       break;
-
-               if (fatal_signal_pending(current))
-                       return ERR_PTR(-ERESTARTSYS);
-               yield();
-       }
+       /* try to allocate the request struct */
+       req = nfs_page_alloc();
+       if (req == NULL)
+               return ERR_PTR(-ENOMEM);
 
        /* Initialize the request struct. Initially, we assume a
         * long write-back delay. This will be adjusted in
index 0288be8..611bec2 100644 (file)
@@ -224,35 +224,60 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page,
        return status;
 }
 
+struct nfs_createdata {
+       struct nfs_createargs arg;
+       struct nfs_diropok res;
+       struct nfs_fh fhandle;
+       struct nfs_fattr fattr;
+};
+
+static struct nfs_createdata *nfs_alloc_createdata(struct inode *dir,
+               struct dentry *dentry, struct iattr *sattr)
+{
+       struct nfs_createdata *data;
+
+       data = kmalloc(sizeof(*data), GFP_KERNEL);
+
+       if (data != NULL) {
+               data->arg.fh = NFS_FH(dir);
+               data->arg.name = dentry->d_name.name;
+               data->arg.len = dentry->d_name.len;
+               data->arg.sattr = sattr;
+               nfs_fattr_init(&data->fattr);
+               data->fhandle.size = 0;
+               data->res.fh = &data->fhandle;
+               data->res.fattr = &data->fattr;
+       }
+       return data;
+};
+
+static void nfs_free_createdata(const struct nfs_createdata *data)
+{
+       kfree(data);
+}
+
 static int
 nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                int flags, struct nameidata *nd)
 {
-       struct nfs_fh           fhandle;
-       struct nfs_fattr        fattr;
-       struct nfs_createargs   arg = {
-               .fh             = NFS_FH(dir),
-               .name           = dentry->d_name.name,
-               .len            = dentry->d_name.len,
-               .sattr          = sattr
-       };
-       struct nfs_diropok      res = {
-               .fh             = &fhandle,
-               .fattr          = &fattr
-       };
+       struct nfs_createdata *data;
        struct rpc_message msg = {
                .rpc_proc       = &nfs_procedures[NFSPROC_CREATE],
-               .rpc_argp       = &arg,
-               .rpc_resp       = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
 
-       nfs_fattr_init(&fattr);
        dprintk("NFS call  create %s\n", dentry->d_name.name);
+       data = nfs_alloc_createdata(dir, dentry, sattr);
+       if (data == NULL)
+               goto out;
+       msg.rpc_argp = &data->arg;
+       msg.rpc_resp = &data->res;
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
        if (status == 0)
-               status = nfs_instantiate(dentry, &fhandle, &fattr);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
+       nfs_free_createdata(data);
+out:
        dprintk("NFS reply create: %d\n", status);
        return status;
 }
@@ -264,24 +289,12 @@ static int
 nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
               dev_t rdev)
 {
-       struct nfs_fh fhandle;
-       struct nfs_fattr fattr;
-       struct nfs_createargs   arg = {
-               .fh             = NFS_FH(dir),
-               .name           = dentry->d_name.name,
-               .len            = dentry->d_name.len,
-               .sattr          = sattr
-       };
-       struct nfs_diropok      res = {
-               .fh             = &fhandle,
-               .fattr          = &fattr
-       };
+       struct nfs_createdata *data;
        struct rpc_message msg = {
                .rpc_proc       = &nfs_procedures[NFSPROC_CREATE],
-               .rpc_argp       = &arg,
-               .rpc_resp       = &res,
        };
-       int status, mode;
+       umode_t mode;
+       int status = -ENOMEM;
 
        dprintk("NFS call  mknod %s\n", dentry->d_name.name);
 
@@ -294,17 +307,24 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
        }
 
-       nfs_fattr_init(&fattr);
+       data = nfs_alloc_createdata(dir, dentry, sattr);
+       if (data == NULL)
+               goto out;
+       msg.rpc_argp = &data->arg;
+       msg.rpc_resp = &data->res;
+
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
 
        if (status == -EINVAL && S_ISFIFO(mode)) {
                sattr->ia_mode = mode;
-               nfs_fattr_init(&fattr);
+               nfs_fattr_init(data->res.fattr);
                status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        }
        if (status == 0)
-               status = nfs_instantiate(dentry, &fhandle, &fattr);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
+       nfs_free_createdata(data);
+out:
        dprintk("NFS reply mknod: %d\n", status);
        return status;
 }
@@ -398,8 +418,8 @@ static int
 nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
                 unsigned int len, struct iattr *sattr)
 {
-       struct nfs_fh fhandle;
-       struct nfs_fattr fattr;
+       struct nfs_fh *fh;
+       struct nfs_fattr *fattr;
        struct nfs_symlinkargs  arg = {
                .fromfh         = NFS_FH(dir),
                .fromname       = dentry->d_name.name,
@@ -412,12 +432,18 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
                .rpc_proc       = &nfs_procedures[NFSPROC_SYMLINK],
                .rpc_argp       = &arg,
        };
-       int                     status;
+       int status = -ENAMETOOLONG;
+
+       dprintk("NFS call  symlink %s\n", dentry->d_name.name);
 
        if (len > NFS2_MAXPATHLEN)
-               return -ENAMETOOLONG;
+               goto out;
 
-       dprintk("NFS call  symlink %s\n", dentry->d_name.name);
+       fh = nfs_alloc_fhandle();
+       fattr = nfs_alloc_fattr();
+       status = -ENOMEM;
+       if (fh == NULL || fattr == NULL)
+               goto out;
 
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
@@ -427,12 +453,12 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
         * filehandle size to zero indicates to nfs_instantiate that it
         * should fill in the data with a LOOKUP call on the wire.
         */
-       if (status == 0) {
-               nfs_fattr_init(&fattr);
-               fhandle.size = 0;
-               status = nfs_instantiate(dentry, &fhandle, &fattr);
-       }
+       if (status == 0)
+               status = nfs_instantiate(dentry, fh, fattr);
 
+       nfs_free_fattr(fattr);
+       nfs_free_fhandle(fh);
+out:
        dprintk("NFS reply symlink: %d\n", status);
        return status;
 }
@@ -440,31 +466,25 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
 static int
 nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
 {
-       struct nfs_fh fhandle;
-       struct nfs_fattr fattr;
-       struct nfs_createargs   arg = {
-               .fh             = NFS_FH(dir),
-               .name           = dentry->d_name.name,
-               .len            = dentry->d_name.len,
-               .sattr          = sattr
-       };
-       struct nfs_diropok      res = {
-               .fh             = &fhandle,
-               .fattr          = &fattr
-       };
+       struct nfs_createdata *data;
        struct rpc_message msg = {
                .rpc_proc       = &nfs_procedures[NFSPROC_MKDIR],
-               .rpc_argp       = &arg,
-               .rpc_resp       = &res,
        };
-       int                     status;
+       int status = -ENOMEM;
 
        dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
-       nfs_fattr_init(&fattr);
+       data = nfs_alloc_createdata(dir, dentry, sattr);
+       if (data == NULL)
+               goto out;
+       msg.rpc_argp = &data->arg;
+       msg.rpc_resp = &data->res;
+
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
        nfs_mark_for_revalidate(dir);
        if (status == 0)
-               status = nfs_instantiate(dentry, &fhandle, &fattr);
+               status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
+       nfs_free_createdata(data);
+out:
        dprintk("NFS reply mkdir: %d\n", status);
        return status;
 }
index db9b360..6e2b06e 100644 (file)
@@ -40,7 +40,7 @@ static mempool_t *nfs_rdata_mempool;
 
 struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
 {
-       struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS);
+       struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_KERNEL);
 
        if (p) {
                memset(p, 0, sizeof(*p));
@@ -50,7 +50,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
                if (pagecount <= ARRAY_SIZE(p->page_array))
                        p->pagevec = p->page_array;
                else {
-                       p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_NOFS);
+                       p->pagevec = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
                        if (!p->pagevec) {
                                mempool_free(p, nfs_rdata_mempool);
                                p = NULL;
index e016372..2f8b115 100644 (file)
@@ -141,7 +141,6 @@ static const match_table_t nfs_mount_option_tokens = {
        { Opt_resvport, "resvport" },
        { Opt_noresvport, "noresvport" },
        { Opt_fscache, "fsc" },
-       { Opt_fscache_uniq, "fsc=%s" },
        { Opt_nofscache, "nofsc" },
 
        { Opt_port, "port=%s" },
@@ -171,6 +170,7 @@ static const match_table_t nfs_mount_option_tokens = {
        { Opt_mountaddr, "mountaddr=%s" },
 
        { Opt_lookupcache, "lookupcache=%s" },
+       { Opt_fscache_uniq, "fsc=%s" },
 
        { Opt_err, NULL }
 };
@@ -423,15 +423,19 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        unsigned char blockbits;
        unsigned long blockres;
        struct nfs_fh *fh = NFS_FH(dentry->d_inode);
-       struct nfs_fattr fattr;
-       struct nfs_fsstat res = {
-                       .fattr = &fattr,
-       };
-       int error;
+       struct nfs_fsstat res;
+       int error = -ENOMEM;
+
+       res.fattr = nfs_alloc_fattr();
+       if (res.fattr == NULL)
+               goto out_err;
 
        error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
+
+       nfs_free_fattr(res.fattr);
        if (error < 0)
                goto out_err;
+
        buf->f_type = NFS_SUPER_MAGIC;
 
        /*
@@ -1046,14 +1050,6 @@ static int nfs_parse_mount_options(char *raw,
                        kfree(mnt->fscache_uniq);
                        mnt->fscache_uniq = NULL;
                        break;
-               case Opt_fscache_uniq:
-                       string = match_strdup(args);
-                       if (!string)
-                               goto out_nomem;
-                       kfree(mnt->fscache_uniq);
-                       mnt->fscache_uniq = string;
-                       mnt->options |= NFS_OPTION_FSCACHE;
-                       break;
 
                /*
                 * options that take numeric values
@@ -1384,6 +1380,14 @@ static int nfs_parse_mount_options(char *raw,
                                        return 0;
                        };
                        break;
+               case Opt_fscache_uniq:
+                       string = match_strdup(args);
+                       if (string == NULL)
+                               goto out_nomem;
+                       kfree(mnt->fscache_uniq);
+                       mnt->fscache_uniq = string;
+                       mnt->options |= NFS_OPTION_FSCACHE;
+                       break;
 
                /*
                 * Special options
@@ -2172,7 +2176,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        int error = -ENOMEM;
 
        data = nfs_alloc_parsed_mount_data(3);
-       mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+       mntfh = nfs_alloc_fhandle();
        if (data == NULL || mntfh == NULL)
                goto out_free_fh;
 
@@ -2187,6 +2191,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        if (data->version == 4) {
                error = nfs4_try_mount(flags, dev_name, data, mnt);
                kfree(data->client_address);
+               kfree(data->nfs_server.export_path);
                goto out;
        }
 #endif /* CONFIG_NFS_V4 */
@@ -2246,7 +2251,7 @@ out:
        kfree(data->fscache_uniq);
        security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
-       kfree(mntfh);
+       nfs_free_fhandle(mntfh);
        kfree(data);
        return error;
 
@@ -2555,7 +2560,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
        };
        int error = -ENOMEM;
 
-       mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+       mntfh = nfs_alloc_fhandle();
        if (data == NULL || mntfh == NULL)
                goto out_free_fh;
 
@@ -2613,7 +2618,7 @@ static int nfs4_remote_get_sb(struct file_system_type *fs_type,
 out:
        security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
-       kfree(mntfh);
+       nfs_free_fhandle(mntfh);
        return error;
 
 out_free:
@@ -2657,7 +2662,7 @@ static void nfs_fix_devname(const struct path *path, struct vfsmount *mnt)
        devname = nfs_path(path->mnt->mnt_devname,
                        path->mnt->mnt_root, path->dentry,
                        page, PAGE_SIZE);
-       if (devname == NULL)
+       if (IS_ERR(devname))
                goto out_freepage;
        tmp = kstrdup(devname, GFP_KERNEL);
        if (tmp == NULL)
@@ -2668,41 +2673,120 @@ out_freepage:
        free_page((unsigned long)page);
 }
 
+struct nfs_referral_count {
+       struct list_head list;
+       const struct task_struct *task;
+       unsigned int referral_count;
+};
+
+static LIST_HEAD(nfs_referral_count_list);
+static DEFINE_SPINLOCK(nfs_referral_count_list_lock);
+
+static struct nfs_referral_count *nfs_find_referral_count(void)
+{
+       struct nfs_referral_count *p;
+
+       list_for_each_entry(p, &nfs_referral_count_list, list) {
+               if (p->task == current)
+                       return p;
+       }
+       return NULL;
+}
+
+#define NFS_MAX_NESTED_REFERRALS 2
+
+static int nfs_referral_loop_protect(void)
+{
+       struct nfs_referral_count *p, *new;
+       int ret = -ENOMEM;
+
+       new = kmalloc(sizeof(*new), GFP_KERNEL);
+       if (!new)
+               goto out;
+       new->task = current;
+       new->referral_count = 1;
+
+       ret = 0;
+       spin_lock(&nfs_referral_count_list_lock);
+       p = nfs_find_referral_count();
+       if (p != NULL) {
+               if (p->referral_count >= NFS_MAX_NESTED_REFERRALS)
+                       ret = -ELOOP;
+               else
+                       p->referral_count++;
+       } else {
+               list_add(&new->list, &nfs_referral_count_list);
+               new = NULL;
+       }
+       spin_unlock(&nfs_referral_count_list_lock);
+       kfree(new);
+out:
+       return ret;
+}
+
+static void nfs_referral_loop_unprotect(void)
+{
+       struct nfs_referral_count *p;
+
+       spin_lock(&nfs_referral_count_list_lock);
+       p = nfs_find_referral_count();
+       p->referral_count--;
+       if (p->referral_count == 0)
+               list_del(&p->list);
+       else
+               p = NULL;
+       spin_unlock(&nfs_referral_count_list_lock);
+       kfree(p);
+}
+
 static int nfs_follow_remote_path(struct vfsmount *root_mnt,
                const char *export_path, struct vfsmount *mnt_target)
 {
+       struct nameidata *nd = NULL;
        struct mnt_namespace *ns_private;
-       struct nameidata nd;
        struct super_block *s;
        int ret;
 
+       nd = kmalloc(sizeof(*nd), GFP_KERNEL);
+       if (nd == NULL)
+               return -ENOMEM;
+
        ns_private = create_mnt_ns(root_mnt);
        ret = PTR_ERR(ns_private);
        if (IS_ERR(ns_private))
                goto out_mntput;
 
+       ret = nfs_referral_loop_protect();
+       if (ret != 0)
+               goto out_put_mnt_ns;
+
        ret = vfs_path_lookup(root_mnt->mnt_root, root_mnt,
-                       export_path, LOOKUP_FOLLOW, &nd);
+                       export_path, LOOKUP_FOLLOW, nd);
 
+       nfs_referral_loop_unprotect();
        put_mnt_ns(ns_private);
 
        if (ret != 0)
                goto out_err;
 
-       s = nd.path.mnt->mnt_sb;
+       s = nd->path.mnt->mnt_sb;
        atomic_inc(&s->s_active);
        mnt_target->mnt_sb = s;
-       mnt_target->mnt_root = dget(nd.path.dentry);
+       mnt_target->mnt_root = dget(nd->path.dentry);
 
        /* Correct the device pathname */
-       nfs_fix_devname(&nd.path, mnt_target);
+       nfs_fix_devname(&nd->path, mnt_target);
 
-       path_put(&nd.path);
+       path_put(&nd->path);
+       kfree(nd);
        down_write(&s->s_umount);
        return 0;
+out_put_mnt_ns:
+       put_mnt_ns(ns_private);
 out_mntput:
        mntput(root_mnt);
 out_err:
+       kfree(nd);
        return ret;
 }
 
@@ -2873,17 +2957,21 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
        struct super_block *s;
        struct nfs_server *server;
        struct dentry *mntroot;
-       struct nfs_fh mntfh;
+       struct nfs_fh *mntfh;
        int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
        struct nfs_sb_mountdata sb_mntdata = {
                .mntflags = flags,
        };
-       int error;
+       int error = -ENOMEM;
 
        dprintk("--> nfs4_referral_get_sb()\n");
 
+       mntfh = nfs_alloc_fhandle();
+       if (mntfh == NULL)
+               goto out_err_nofh;
+
        /* create a new volume representation */
-       server = nfs4_create_referral_server(data, &mntfh);
+       server = nfs4_create_referral_server(data, mntfh);
        if (IS_ERR(server)) {
                error = PTR_ERR(server);
                goto out_err_noserver;
@@ -2915,7 +3003,7 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
                nfs_fscache_get_super_cookie(s, NULL, data);
        }
 
-       mntroot = nfs4_get_root(s, &mntfh);
+       mntroot = nfs4_get_root(s, mntfh);
        if (IS_ERR(mntroot)) {
                error = PTR_ERR(mntroot);
                goto error_splat_super;
@@ -2932,12 +3020,15 @@ static int nfs4_remote_referral_get_sb(struct file_system_type *fs_type,
 
        security_sb_clone_mnt_opts(data->sb, s);
 
+       nfs_free_fhandle(mntfh);
        dprintk("<-- nfs4_referral_get_sb() = 0\n");
        return 0;
 
 out_err_nosb:
        nfs_free_server(server);
 out_err_noserver:
+       nfs_free_fhandle(mntfh);
+out_err_nofh:
        dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
        return error;
 
@@ -2946,6 +3037,7 @@ error_splat_super:
                bdi_unregister(&server->backing_dev_info);
 error_splat_bdi:
        deactivate_locked_super(s);
+       nfs_free_fhandle(mntfh);
        dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
        return error;
 }
index 6da3d3f..a2242af 100644 (file)
@@ -23,6 +23,7 @@ struct nfs_unlinkdata {
        struct nfs_removeres res;
        struct inode *dir;
        struct rpc_cred *cred;
+       struct nfs_fattr dir_attr;
 };
 
 /**
@@ -169,7 +170,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n
        }
        nfs_sb_active(dir->i_sb);
        data->args.fh = NFS_FH(dir);
-       nfs_fattr_init(&data->res.dir_attr);
+       nfs_fattr_init(data->res.dir_attr);
 
        NFS_PROTO(dir)->unlink_setup(&msg, dir);
 
@@ -259,6 +260,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry)
                goto out_free;
        }
        data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
+       data->res.dir_attr = &data->dir_attr;
 
        status = -EBUSY;
        spin_lock(&dentry->d_lock);
index 53ff70e..3aea3ca 100644 (file)
@@ -201,6 +201,7 @@ static int nfs_set_page_writeback(struct page *page)
                struct inode *inode = page->mapping->host;
                struct nfs_server *nfss = NFS_SERVER(inode);
 
+               page_cache_get(page);
                if (atomic_long_inc_return(&nfss->writeback) >
                                NFS_CONGESTION_ON_THRESH) {
                        set_bdi_congested(&nfss->backing_dev_info,
@@ -216,6 +217,7 @@ static void nfs_end_page_writeback(struct page *page)
        struct nfs_server *nfss = NFS_SERVER(inode);
 
        end_page_writeback(page);
+       page_cache_release(page);
        if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
                clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
 }
@@ -421,6 +423,7 @@ static void
 nfs_mark_request_dirty(struct nfs_page *req)
 {
        __set_page_dirty_nobuffers(req->wb_page);
+       __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
 }
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -660,9 +663,11 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
        req = nfs_setup_write_request(ctx, page, offset, count);
        if (IS_ERR(req))
                return PTR_ERR(req);
+       nfs_mark_request_dirty(req);
        /* Update file length */
        nfs_grow_file(page, offset, count);
        nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
+       nfs_mark_request_dirty(req);
        nfs_clear_page_tag_locked(req);
        return 0;
 }
@@ -739,8 +744,6 @@ int nfs_updatepage(struct file *file, struct page *page,
        status = nfs_writepage_setup(ctx, page, offset, count);
        if (status < 0)
                nfs_set_pageerror(page);
-       else
-               __set_page_dirty_nobuffers(page);
 
        dprintk("NFS:       nfs_updatepage returns %d (isize %lld)\n",
                        status, (long long)i_size_read(inode));
@@ -749,13 +752,12 @@ int nfs_updatepage(struct file *file, struct page *page,
 
 static void nfs_writepage_release(struct nfs_page *req)
 {
+       struct page *page = req->wb_page;
 
-       if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
-               nfs_end_page_writeback(req->wb_page);
+       if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req))
                nfs_inode_remove_request(req);
-       } else
-               nfs_end_page_writeback(req->wb_page);
        nfs_clear_page_tag_locked(req);
+       nfs_end_page_writeback(page);
 }
 
 static int flush_task_priority(int how)
@@ -779,7 +781,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                int how)
 {
        struct inode *inode = req->wb_context->path.dentry->d_inode;
-       int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
@@ -794,9 +795,10 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                .callback_ops = call_ops,
                .callback_data = data,
                .workqueue = nfsiod_workqueue,
-               .flags = flags,
+               .flags = RPC_TASK_ASYNC,
                .priority = priority,
        };
+       int ret = 0;
 
        /* Set up the RPC argument and reply structs
         * NB: take care not to mess about with data->commit et al. */
@@ -835,10 +837,18 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                (unsigned long long)data->args.offset);
 
        task = rpc_run_task(&task_setup_data);
-       if (IS_ERR(task))
-               return PTR_ERR(task);
+       if (IS_ERR(task)) {
+               ret = PTR_ERR(task);
+               goto out;
+       }
+       if (how & FLUSH_SYNC) {
+               ret = rpc_wait_for_completion_task(task);
+               if (ret == 0)
+                       ret = task->tk_status;
+       }
        rpc_put_task(task);
-       return 0;
+out:
+       return ret;
 }
 
 /* If a nfs_flush_* function fails, it should remove reqs from @head and
@@ -847,9 +857,11 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
  */
 static void nfs_redirty_request(struct nfs_page *req)
 {
+       struct page *page = req->wb_page;
+
        nfs_mark_request_dirty(req);
-       nfs_end_page_writeback(req->wb_page);
        nfs_clear_page_tag_locked(req);
+       nfs_end_page_writeback(page);
 }
 
 /*
@@ -1084,16 +1096,15 @@ static void nfs_writeback_release_full(void *calldata)
                if (nfs_write_need_commit(data)) {
                        memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
                        nfs_mark_request_commit(req);
-                       nfs_end_page_writeback(page);
                        dprintk(" marked for commit\n");
                        goto next;
                }
                dprintk(" OK\n");
 remove_request:
-               nfs_end_page_writeback(page);
                nfs_inode_remove_request(req);
        next:
                nfs_clear_page_tag_locked(req);
+               nfs_end_page_writeback(page);
        }
        nfs_writedata_release(calldata);
 }
@@ -1190,6 +1201,25 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
 
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
+static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
+{
+       if (!test_and_set_bit(NFS_INO_COMMIT, &nfsi->flags))
+               return 1;
+       if (may_wait && !out_of_line_wait_on_bit_lock(&nfsi->flags,
+                               NFS_INO_COMMIT, nfs_wait_bit_killable,
+                               TASK_KILLABLE))
+               return 1;
+       return 0;
+}
+
+static void nfs_commit_clear_lock(struct nfs_inode *nfsi)
+{
+       clear_bit(NFS_INO_COMMIT, &nfsi->flags);
+       smp_mb__after_clear_bit();
+       wake_up_bit(&nfsi->flags, NFS_INO_COMMIT);
+}
+
+
 static void nfs_commitdata_release(void *data)
 {
        struct nfs_write_data *wdata = data;
@@ -1207,7 +1237,6 @@ static int nfs_commit_rpcsetup(struct list_head *head,
 {
        struct nfs_page *first = nfs_list_entry(head->next);
        struct inode *inode = first->wb_context->path.dentry->d_inode;
-       int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
@@ -1222,7 +1251,7 @@ static int nfs_commit_rpcsetup(struct list_head *head,
                .callback_ops = &nfs_commit_ops,
                .callback_data = data,
                .workqueue = nfsiod_workqueue,
-               .flags = flags,
+               .flags = RPC_TASK_ASYNC,
                .priority = priority,
        };
 
@@ -1282,6 +1311,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
                                BDI_RECLAIMABLE);
                nfs_clear_page_tag_locked(req);
        }
+       nfs_commit_clear_lock(NFS_I(inode));
        return -ENOMEM;
 }
 
@@ -1337,6 +1367,7 @@ static void nfs_commit_release(void *calldata)
        next:
                nfs_clear_page_tag_locked(req);
        }
+       nfs_commit_clear_lock(NFS_I(data->inode));
        nfs_commitdata_release(calldata);
 }
 
@@ -1351,8 +1382,11 @@ static const struct rpc_call_ops nfs_commit_ops = {
 static int nfs_commit_inode(struct inode *inode, int how)
 {
        LIST_HEAD(head);
-       int res;
+       int may_wait = how & FLUSH_SYNC;
+       int res = 0;
 
+       if (!nfs_commit_set_lock(NFS_I(inode), may_wait))
+               goto out;
        spin_lock(&inode->i_lock);
        res = nfs_scan_commit(inode, &head, 0, 0);
        spin_unlock(&inode->i_lock);
@@ -1360,7 +1394,13 @@ static int nfs_commit_inode(struct inode *inode, int how)
                int error = nfs_commit_list(inode, &head, how);
                if (error < 0)
                        return error;
-       }
+               if (may_wait)
+                       wait_on_bit(&NFS_I(inode)->flags, NFS_INO_COMMIT,
+                                       nfs_wait_bit_killable,
+                                       TASK_KILLABLE);
+       } else
+               nfs_commit_clear_lock(NFS_I(inode));
+out:
        return res;
 }
 
@@ -1432,6 +1472,7 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page)
 
        BUG_ON(!PageLocked(page));
        for (;;) {
+               wait_on_page_writeback(page);
                req = nfs_page_find_request(page);
                if (req == NULL)
                        break;
@@ -1466,30 +1507,18 @@ int nfs_wb_page(struct inode *inode, struct page *page)
                .range_start = range_start,
                .range_end = range_end,
        };
-       struct nfs_page *req;
-       int need_commit;
        int ret;
 
        while(PagePrivate(page)) {
+               wait_on_page_writeback(page);
                if (clear_page_dirty_for_io(page)) {
                        ret = nfs_writepage_locked(page, &wbc);
                        if (ret < 0)
                                goto out_error;
                }
-               req = nfs_find_and_lock_request(page);
-               if (!req)
-                       break;
-               if (IS_ERR(req)) {
-                       ret = PTR_ERR(req);
+               ret = sync_inode(inode, &wbc);
+               if (ret < 0)
                        goto out_error;
-               }
-               need_commit = test_bit(PG_CLEAN, &req->wb_flags);
-               nfs_clear_page_tag_locked(req);
-               if (need_commit) {
-                       ret = nfs_commit_inode(inode, FLUSH_SYNC);
-                       if (ret < 0)
-                               goto out_error;
-               }
        }
        return 0;
 out_error:
index 872a5ef..c2a4f71 100644 (file)
@@ -259,10 +259,9 @@ static struct cache_detail svc_expkey_cache = {
        .alloc          = expkey_alloc,
 };
 
-static struct svc_expkey *
-svc_expkey_lookup(struct svc_expkey *item)
+static int
+svc_expkey_hash(struct svc_expkey *item)
 {
-       struct cache_head *ch;
        int hash = item->ek_fsidtype;
        char * cp = (char*)item->ek_fsid;
        int len = key_len(item->ek_fsidtype);
@@ -270,6 +269,14 @@ svc_expkey_lookup(struct svc_expkey *item)
        hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
        hash ^= hash_ptr(item->ek_client, EXPKEY_HASHBITS);
        hash &= EXPKEY_HASHMASK;
+       return hash;
+}
+
+static struct svc_expkey *
+svc_expkey_lookup(struct svc_expkey *item)
+{
+       struct cache_head *ch;
+       int hash = svc_expkey_hash(item);
 
        ch = sunrpc_cache_lookup(&svc_expkey_cache, &item->h,
                                 hash);
@@ -283,13 +290,7 @@ static struct svc_expkey *
 svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)
 {
        struct cache_head *ch;
-       int hash = new->ek_fsidtype;
-       char * cp = (char*)new->ek_fsid;
-       int len = key_len(new->ek_fsidtype);
-
-       hash ^= hash_mem(cp, len, EXPKEY_HASHBITS);
-       hash ^= hash_ptr(new->ek_client, EXPKEY_HASHBITS);
-       hash &= EXPKEY_HASHMASK;
+       int hash = svc_expkey_hash(new);
 
        ch = sunrpc_cache_update(&svc_expkey_cache, &new->h,
                                 &old->h, hash);
@@ -738,14 +739,22 @@ struct cache_detail svc_export_cache = {
        .alloc          = svc_export_alloc,
 };
 
-static struct svc_export *
-svc_export_lookup(struct svc_export *exp)
+static int
+svc_export_hash(struct svc_export *exp)
 {
-       struct cache_head *ch;
        int hash;
+
        hash = hash_ptr(exp->ex_client, EXPORT_HASHBITS);
        hash ^= hash_ptr(exp->ex_path.dentry, EXPORT_HASHBITS);
        hash ^= hash_ptr(exp->ex_path.mnt, EXPORT_HASHBITS);
+       return hash;
+}
+
+static struct svc_export *
+svc_export_lookup(struct svc_export *exp)
+{
+       struct cache_head *ch;
+       int hash = svc_export_hash(exp);
 
        ch = sunrpc_cache_lookup(&svc_export_cache, &exp->h,
                                 hash);
@@ -759,10 +768,7 @@ static struct svc_export *
 svc_export_update(struct svc_export *new, struct svc_export *old)
 {
        struct cache_head *ch;
-       int hash;
-       hash = hash_ptr(old->ex_client, EXPORT_HASHBITS);
-       hash ^= hash_ptr(old->ex_path.dentry, EXPORT_HASHBITS);
-       hash ^= hash_ptr(old->ex_path.mnt, EXPORT_HASHBITS);
+       int hash = svc_export_hash(old);
 
        ch = sunrpc_cache_update(&svc_export_cache, &new->h,
                                 &old->h,
@@ -1071,9 +1077,9 @@ exp_export(struct nfsctl_export *nxp)
                err = 0;
 finish:
        kfree(new.ex_pathname);
-       if (exp)
+       if (!IS_ERR_OR_NULL(exp))
                exp_put(exp);
-       if (fsid_key && !IS_ERR(fsid_key))
+       if (!IS_ERR_OR_NULL(fsid_key))
                cache_put(&fsid_key->h, &svc_expkey_cache);
        path_put(&path);
 out_put_clp:
index 7e32bd3..eb78e7e 100644 (file)
@@ -32,6 +32,7 @@
  */
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/svc_xprt.h>
 #include <linux/slab.h>
 #include "nfsd.h"
 #include "state.h"
@@ -79,11 +80,6 @@ enum nfs_cb_opnum4 {
                                        cb_sequence_dec_sz +            \
                                        op_dec_sz)
 
-struct nfs4_rpc_args {
-       void                            *args_op;
-       struct nfsd4_cb_sequence        args_seq;
-};
-
 /*
 * Generic encode routines from fs/nfs/nfs4xdr.c
 */
@@ -428,13 +424,19 @@ static struct rpc_procinfo     nfs4_cb_procedures[] = {
 };
 
 static struct rpc_version       nfs_cb_version4 = {
+/*
+ * Note on the callback rpc program version number: despite language in rfc
+ * 5661 section 18.36.3 requiring servers to use 4 in this field, the
+ * official xdr descriptions for both 4.0 and 4.1 specify version 1, and
+ * in practice that appears to be what implementations use.  The section
+ * 18.36.3 language is expected to be fixed in an erratum.
+ */
         .number                 = 1,
         .nrprocs                = ARRAY_SIZE(nfs4_cb_procedures),
         .procs                  = nfs4_cb_procedures
 };
 
 static struct rpc_version *    nfs_cb_version[] = {
-       NULL,
        &nfs_cb_version4,
 };
 
@@ -456,15 +458,14 @@ static struct rpc_program cb_program = {
 
 static int max_cb_time(void)
 {
-       return max(NFSD_LEASE_TIME/10, (time_t)1) * HZ;
+       return max(nfsd4_lease/10, (time_t)1) * HZ;
 }
 
 /* Reference counting, callback cleanup, etc., all look racy as heck.
- * And why is cb_set an atomic? */
+ * And why is cl_cb_set an atomic? */
 
-int setup_callback_client(struct nfs4_client *clp)
+int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *cb)
 {
-       struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
        struct rpc_timeout      timeparms = {
                .to_initval     = max_cb_time(),
                .to_retries     = 0,
@@ -476,7 +477,7 @@ int setup_callback_client(struct nfs4_client *clp)
                .timeout        = &timeparms,
                .program        = &cb_program,
                .prognumber     = cb->cb_prog,
-               .version        = nfs_cb_version[1]->number,
+               .version        = 0,
                .authflavor     = clp->cl_flavor,
                .flags          = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
                .client_name    = clp->cl_principal,
@@ -486,7 +487,7 @@ int setup_callback_client(struct nfs4_client *clp)
        if (!clp->cl_principal && (clp->cl_flavor >= RPC_AUTH_GSS_KRB5))
                return -EINVAL;
        if (cb->cb_minorversion) {
-               args.bc_xprt = clp->cl_cb_xprt;
+               args.bc_xprt = cb->cb_xprt;
                args.protocol = XPRT_TRANSPORT_BC_TCP;
        }
        /* Create RPC client */
@@ -496,7 +497,7 @@ int setup_callback_client(struct nfs4_client *clp)
                        PTR_ERR(client));
                return PTR_ERR(client);
        }
-       cb->cb_client = client;
+       nfsd4_set_callback_client(clp, client);
        return 0;
 
 }
@@ -514,8 +515,7 @@ static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
        if (task->tk_status)
                warn_no_callback_path(clp, task->tk_status);
        else
-               atomic_set(&clp->cl_cb_conn.cb_set, 1);
-       put_nfs4_client(clp);
+               atomic_set(&clp->cl_cb_set, 1);
 }
 
 static const struct rpc_call_ops nfsd4_cb_probe_ops = {
@@ -537,7 +537,6 @@ int set_callback_cred(void)
 
 void do_probe_callback(struct nfs4_client *clp)
 {
-       struct nfs4_cb_conn *cb = &clp->cl_cb_conn;
        struct rpc_message msg = {
                .rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
                .rpc_argp       = clp,
@@ -545,34 +544,27 @@ void do_probe_callback(struct nfs4_client *clp)
        };
        int status;
 
-       status = rpc_call_async(cb->cb_client, &msg,
+       status = rpc_call_async(clp->cl_cb_client, &msg,
                                RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
                                &nfsd4_cb_probe_ops, (void *)clp);
-       if (status) {
+       if (status)
                warn_no_callback_path(clp, status);
-               put_nfs4_client(clp);
-       }
 }
 
 /*
  * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
  */
-void
-nfsd4_probe_callback(struct nfs4_client *clp)
+void nfsd4_probe_callback(struct nfs4_client *clp, struct nfs4_cb_conn *cb)
 {
        int status;
 
-       BUG_ON(atomic_read(&clp->cl_cb_conn.cb_set));
+       BUG_ON(atomic_read(&clp->cl_cb_set));
 
-       status = setup_callback_client(clp);
+       status = setup_callback_client(clp, cb);
        if (status) {
                warn_no_callback_path(clp, status);
                return;
        }
-
-       /* the task holds a reference to the nfs4_client struct */
-       atomic_inc(&clp->cl_count);
-
        do_probe_callback(clp);
 }
 
@@ -658,18 +650,32 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
        }
 }
 
+
 static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
 {
        struct nfs4_delegation *dp = calldata;
        struct nfs4_client *clp = dp->dl_client;
+       struct rpc_clnt *current_rpc_client = clp->cl_cb_client;
 
        nfsd4_cb_done(task, calldata);
 
+       if (current_rpc_client == NULL) {
+               /* We're shutting down; give up. */
+               /* XXX: err, or is it ok just to fall through
+                * and rpc_restart_call? */
+               return;
+       }
+
        switch (task->tk_status) {
        case -EIO:
                /* Network partition? */
-               atomic_set(&clp->cl_cb_conn.cb_set, 0);
+               atomic_set(&clp->cl_cb_set, 0);
                warn_no_callback_path(clp, task->tk_status);
+               if (current_rpc_client != task->tk_client) {
+                       /* queue a callback on the new connection: */
+                       nfsd4_cb_recall(dp);
+                       return;
+               }
        case -EBADHANDLE:
        case -NFS4ERR_BAD_STATEID:
                /* Race: client probably got cb_recall
@@ -677,7 +683,7 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
                break;
        default:
                /* success, or error we can't handle */
-               goto done;
+               return;
        }
        if (dp->dl_retries--) {
                rpc_delay(task, 2*HZ);
@@ -685,20 +691,16 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
                rpc_restart_call(task);
                return;
        } else {
-               atomic_set(&clp->cl_cb_conn.cb_set, 0);
+               atomic_set(&clp->cl_cb_set, 0);
                warn_no_callback_path(clp, task->tk_status);
        }
-done:
-       kfree(task->tk_msg.rpc_argp);
 }
 
 static void nfsd4_cb_recall_release(void *calldata)
 {
        struct nfs4_delegation *dp = calldata;
-       struct nfs4_client *clp = dp->dl_client;
 
        nfs4_put_delegation(dp);
-       put_nfs4_client(clp);
 }
 
 static const struct rpc_call_ops nfsd4_cb_recall_ops = {
@@ -707,33 +709,75 @@ static const struct rpc_call_ops nfsd4_cb_recall_ops = {
        .rpc_release = nfsd4_cb_recall_release,
 };
 
+static struct workqueue_struct *callback_wq;
+
+int nfsd4_create_callback_queue(void)
+{
+       callback_wq = create_singlethread_workqueue("nfsd4_callbacks");
+       if (!callback_wq)
+               return -ENOMEM;
+       return 0;
+}
+
+void nfsd4_destroy_callback_queue(void)
+{
+       destroy_workqueue(callback_wq);
+}
+
+/* must be called under the state lock */
+void nfsd4_set_callback_client(struct nfs4_client *clp, struct rpc_clnt *new)
+{
+       struct rpc_clnt *old = clp->cl_cb_client;
+
+       clp->cl_cb_client = new;
+       /*
+        * After this, any work that saw the old value of cl_cb_client will
+        * be gone:
+        */
+       flush_workqueue(callback_wq);
+       /* So we can safely shut it down: */
+       if (old)
+               rpc_shutdown_client(old);
+}
+
 /*
  * called with dp->dl_count inc'ed.
  */
-void
-nfsd4_cb_recall(struct nfs4_delegation *dp)
+static void _nfsd4_cb_recall(struct nfs4_delegation *dp)
 {
        struct nfs4_client *clp = dp->dl_client;
-       struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
-       struct nfs4_rpc_args *args;
+       struct rpc_clnt *clnt = clp->cl_cb_client;
+       struct nfs4_rpc_args *args = &dp->dl_recall.cb_args;
        struct rpc_message msg = {
                .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
                .rpc_cred = callback_cred
        };
-       int status = -ENOMEM;
+       int status;
+
+       if (clnt == NULL)
+               return; /* Client is shutting down; give up. */
 
-       args = kzalloc(sizeof(*args), GFP_KERNEL);
-       if (!args)
-               goto out;
        args->args_op = dp;
        msg.rpc_argp = args;
        dp->dl_retries = 1;
        status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
                                &nfsd4_cb_recall_ops, dp);
-out:
-       if (status) {
-               kfree(args);
-               put_nfs4_client(clp);
+       if (status)
                nfs4_put_delegation(dp);
-       }
+}
+
+void nfsd4_do_callback_rpc(struct work_struct *w)
+{
+       /* XXX: for now, just send off delegation recall. */
+       /* In future, generalize to handle any sort of callback. */
+       struct nfsd4_callback *c = container_of(w, struct nfsd4_callback, cb_work);
+       struct nfs4_delegation *dp = container_of(c, struct nfs4_delegation, dl_recall);
+
+       _nfsd4_cb_recall(dp);
+}
+
+
+void nfsd4_cb_recall(struct nfs4_delegation *dp)
+{
+       queue_work(callback_wq, &dp->dl_recall.cb_work);
 }
index 2ab9e85..59ec449 100644 (file)
@@ -969,20 +969,36 @@ static struct nfsd4_operation nfsd4_ops[];
 static const char *nfsd4_op_name(unsigned opnum);
 
 /*
- * Enforce NFSv4.1 COMPOUND ordering rules.
+ * Enforce NFSv4.1 COMPOUND ordering rules:
  *
- * TODO:
- * - enforce NFS4ERR_NOT_ONLY_OP,
- * - DESTROY_SESSION MUST be the final operation in the COMPOUND request.
+ * Also note, enforced elsewhere:
+ *     - SEQUENCE other than as first op results in
+ *       NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
+ *     - BIND_CONN_TO_SESSION must be the only op in its compound
+ *       (Will be enforced in nfsd4_bind_conn_to_session().)
+ *     - DESTROY_SESSION must be the final operation in a compound, if
+ *       sessionid's in SEQUENCE and DESTROY_SESSION are the same.
+ *       (Enforced in nfsd4_destroy_session().)
  */
-static bool nfs41_op_ordering_ok(struct nfsd4_compoundargs *args)
+static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
 {
-       if (args->minorversion && args->opcnt > 0) {
-               struct nfsd4_op *op = &args->ops[0];
-               return (op->status == nfserr_op_illegal) ||
-                      (nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP);
-       }
-       return true;
+       struct nfsd4_op *op = &args->ops[0];
+
+       /* These ordering requirements don't apply to NFSv4.0: */
+       if (args->minorversion == 0)
+               return nfs_ok;
+       /* This is weird, but OK, not our problem: */
+       if (args->opcnt == 0)
+               return nfs_ok;
+       if (op->status == nfserr_op_illegal)
+               return nfs_ok;
+       if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
+               return nfserr_op_not_in_session;
+       if (op->opnum == OP_SEQUENCE)
+               return nfs_ok;
+       if (args->opcnt != 1)
+               return nfserr_not_only_op;
+       return nfs_ok;
 }
 
 /*
@@ -1012,6 +1028,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
        resp->rqstp = rqstp;
        resp->cstate.minorversion = args->minorversion;
        resp->cstate.replay_owner = NULL;
+       resp->cstate.session = NULL;
        fh_init(&resp->cstate.current_fh, NFS4_FHSIZE);
        fh_init(&resp->cstate.save_fh, NFS4_FHSIZE);
        /* Use the deferral mechanism only for NFSv4.0 compounds */
@@ -1024,13 +1041,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
        if (args->minorversion > nfsd_supported_minorversion)
                goto out;
 
-       if (!nfs41_op_ordering_ok(args)) {
+       status = nfs41_check_op_ordering(args);
+       if (status) {
                op = &args->ops[0];
-               op->status = nfserr_sequence_pos;
+               op->status = status;
                goto encode_op;
        }
 
-       status = nfs_ok;
        while (!status && resp->opcnt < args->opcnt) {
                op = &args->ops[resp->opcnt++];
 
@@ -1295,6 +1312,11 @@ static struct nfsd4_operation nfsd4_ops[] = {
                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
                .op_name = "OP_SEQUENCE",
        },
+       [OP_RECLAIM_COMPLETE] = {
+               .op_func = (nfsd4op_func)nfsd4_reclaim_complete,
+               .op_flags = ALLOWED_WITHOUT_FH,
+               .op_name = "OP_RECLAIM_COMPLETE",
+       },
 };
 
 static const char *nfsd4_op_name(unsigned opnum)
index 6a8feda..12f7109 100644 (file)
@@ -45,8 +45,8 @@
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
 /* Globals */
-static time_t lease_time = 90;     /* default lease time */
-static time_t user_lease_time = 90;
+time_t nfsd4_lease = 90;     /* default lease time */
+time_t nfsd4_grace = 90;
 static time_t boot_time;
 static u32 current_ownerid = 1;
 static u32 current_fileid = 1;
@@ -190,7 +190,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
        dp->dl_vfs_file = stp->st_vfs_file;
        dp->dl_type = type;
        dp->dl_ident = cb->cb_ident;
-       dp->dl_stateid.si_boot = get_seconds();
+       dp->dl_stateid.si_boot = boot_time;
        dp->dl_stateid.si_stateownerid = current_delegid++;
        dp->dl_stateid.si_fileid = 0;
        dp->dl_stateid.si_generation = 0;
@@ -199,6 +199,7 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f
        atomic_set(&dp->dl_count, 1);
        list_add(&dp->dl_perfile, &fp->fi_delegations);
        list_add(&dp->dl_perclnt, &clp->cl_delegations);
+       INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc);
        return dp;
 }
 
@@ -249,6 +250,9 @@ unhash_delegation(struct nfs4_delegation *dp)
  * SETCLIENTID state 
  */
 
+/* client_lock protects the client lru list and session hash table */
+static DEFINE_SPINLOCK(client_lock);
+
 /* Hash tables for nfs4_clientid state */
 #define CLIENT_HASH_BITS                 4
 #define CLIENT_HASH_SIZE                (1 << CLIENT_HASH_BITS)
@@ -367,7 +371,6 @@ static void release_openowner(struct nfs4_stateowner *sop)
        nfs4_put_stateowner(sop);
 }
 
-static DEFINE_SPINLOCK(sessionid_lock);
 #define SESSION_HASH_SIZE      512
 static struct list_head sessionid_hashtbl[SESSION_HASH_SIZE];
 
@@ -565,10 +568,10 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
 
        new->se_flags = cses->flags;
        kref_init(&new->se_ref);
-       spin_lock(&sessionid_lock);
+       spin_lock(&client_lock);
        list_add(&new->se_hash, &sessionid_hashtbl[idx]);
        list_add(&new->se_perclnt, &clp->cl_sessions);
-       spin_unlock(&sessionid_lock);
+       spin_unlock(&client_lock);
 
        status = nfs_ok;
 out:
@@ -579,7 +582,7 @@ out_free:
        goto out;
 }
 
-/* caller must hold sessionid_lock */
+/* caller must hold client_lock */
 static struct nfsd4_session *
 find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
 {
@@ -602,7 +605,7 @@ find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
        return NULL;
 }
 
-/* caller must hold sessionid_lock */
+/* caller must hold client_lock */
 static void
 unhash_session(struct nfsd4_session *ses)
 {
@@ -610,15 +613,6 @@ unhash_session(struct nfsd4_session *ses)
        list_del(&ses->se_perclnt);
 }
 
-static void
-release_session(struct nfsd4_session *ses)
-{
-       spin_lock(&sessionid_lock);
-       unhash_session(ses);
-       spin_unlock(&sessionid_lock);
-       nfsd4_put_session(ses);
-}
-
 void
 free_session(struct kref *kref)
 {
@@ -634,9 +628,18 @@ free_session(struct kref *kref)
        kfree(ses);
 }
 
+/* must be called under the client_lock */
 static inline void
-renew_client(struct nfs4_client *clp)
+renew_client_locked(struct nfs4_client *clp)
 {
+       if (is_client_expired(clp)) {
+               dprintk("%s: client (clientid %08x/%08x) already expired\n",
+                       __func__,
+                       clp->cl_clientid.cl_boot,
+                       clp->cl_clientid.cl_id);
+               return;
+       }
+
        /*
        * Move client to the end to the LRU list.
        */
@@ -647,6 +650,14 @@ renew_client(struct nfs4_client *clp)
        clp->cl_time = get_seconds();
 }
 
+static inline void
+renew_client(struct nfs4_client *clp)
+{
+       spin_lock(&client_lock);
+       renew_client_locked(clp);
+       spin_unlock(&client_lock);
+}
+
 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
 static int
 STALE_CLIENTID(clientid_t *clid)
@@ -680,27 +691,9 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
        return clp;
 }
 
-static void
-shutdown_callback_client(struct nfs4_client *clp)
-{
-       struct rpc_clnt *clnt = clp->cl_cb_conn.cb_client;
-
-       if (clnt) {
-               /*
-                * Callback threads take a reference on the client, so there
-                * should be no outstanding callbacks at this point.
-                */
-               clp->cl_cb_conn.cb_client = NULL;
-               rpc_shutdown_client(clnt);
-       }
-}
-
 static inline void
 free_client(struct nfs4_client *clp)
 {
-       shutdown_callback_client(clp);
-       if (clp->cl_cb_xprt)
-               svc_xprt_put(clp->cl_cb_xprt);
        if (clp->cl_cred.cr_group_info)
                put_group_info(clp->cl_cred.cr_group_info);
        kfree(clp->cl_principal);
@@ -709,10 +702,34 @@ free_client(struct nfs4_client *clp)
 }
 
 void
-put_nfs4_client(struct nfs4_client *clp)
+release_session_client(struct nfsd4_session *session)
 {
-       if (atomic_dec_and_test(&clp->cl_count))
+       struct nfs4_client *clp = session->se_client;
+
+       if (!atomic_dec_and_lock(&clp->cl_refcount, &client_lock))
+               return;
+       if (is_client_expired(clp)) {
                free_client(clp);
+               session->se_client = NULL;
+       } else
+               renew_client_locked(clp);
+       spin_unlock(&client_lock);
+       nfsd4_put_session(session);
+}
+
+/* must be called under the client_lock */
+static inline void
+unhash_client_locked(struct nfs4_client *clp)
+{
+       mark_client_expired(clp);
+       list_del(&clp->cl_lru);
+       while (!list_empty(&clp->cl_sessions)) {
+               struct nfsd4_session  *ses;
+               ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
+                                se_perclnt);
+               unhash_session(ses);
+               nfsd4_put_session(ses);
+       }
 }
 
 static void
@@ -722,9 +739,6 @@ expire_client(struct nfs4_client *clp)
        struct nfs4_delegation *dp;
        struct list_head reaplist;
 
-       dprintk("NFSD: expire_client cl_count %d\n",
-                           atomic_read(&clp->cl_count));
-
        INIT_LIST_HEAD(&reaplist);
        spin_lock(&recall_lock);
        while (!list_empty(&clp->cl_delegations)) {
@@ -740,20 +754,20 @@ expire_client(struct nfs4_client *clp)
                list_del_init(&dp->dl_recall_lru);
                unhash_delegation(dp);
        }
-       list_del(&clp->cl_idhash);
-       list_del(&clp->cl_strhash);
-       list_del(&clp->cl_lru);
        while (!list_empty(&clp->cl_openowners)) {
                sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient);
                release_openowner(sop);
        }
-       while (!list_empty(&clp->cl_sessions)) {
-               struct nfsd4_session  *ses;
-               ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
-                                se_perclnt);
-               release_session(ses);
-       }
-       put_nfs4_client(clp);
+       nfsd4_set_callback_client(clp, NULL);
+       if (clp->cl_cb_conn.cb_xprt)
+               svc_xprt_put(clp->cl_cb_conn.cb_xprt);
+       list_del(&clp->cl_idhash);
+       list_del(&clp->cl_strhash);
+       spin_lock(&client_lock);
+       unhash_client_locked(clp);
+       if (atomic_read(&clp->cl_refcount) == 0)
+               free_client(clp);
+       spin_unlock(&client_lock);
 }
 
 static void copy_verf(struct nfs4_client *target, nfs4_verifier *source)
@@ -839,14 +853,15 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
        }
 
        memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
-       atomic_set(&clp->cl_count, 1);
-       atomic_set(&clp->cl_cb_conn.cb_set, 0);
+       atomic_set(&clp->cl_refcount, 0);
+       atomic_set(&clp->cl_cb_set, 0);
        INIT_LIST_HEAD(&clp->cl_idhash);
        INIT_LIST_HEAD(&clp->cl_strhash);
        INIT_LIST_HEAD(&clp->cl_openowners);
        INIT_LIST_HEAD(&clp->cl_delegations);
        INIT_LIST_HEAD(&clp->cl_sessions);
        INIT_LIST_HEAD(&clp->cl_lru);
+       clp->cl_time = get_seconds();
        clear_bit(0, &clp->cl_cb_slot_busy);
        rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
        copy_verf(clp, verf);
@@ -877,8 +892,7 @@ add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
        list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
        idhashval = clientid_hashval(clp->cl_clientid.cl_id);
        list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
-       list_add_tail(&clp->cl_lru, &client_lru);
-       clp->cl_time = get_seconds();
+       renew_client(clp);
 }
 
 static void
@@ -888,10 +902,9 @@ move_to_confirmed(struct nfs4_client *clp)
        unsigned int strhashval;
 
        dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp);
-       list_del_init(&clp->cl_strhash);
        list_move(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
        strhashval = clientstr_hashval(clp->cl_recdir);
-       list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
+       list_move(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
        renew_client(clp);
 }
 
@@ -1327,15 +1340,9 @@ nfsd4_create_session(struct svc_rqst *rqstp,
                cs_slot->sl_seqid++; /* from 0 to 1 */
                move_to_confirmed(unconf);
 
-               /*
-                * We do not support RDMA or persistent sessions
-                */
-               cr_ses->flags &= ~SESSION4_PERSIST;
-               cr_ses->flags &= ~SESSION4_RDMA;
-
                if (cr_ses->flags & SESSION4_BACK_CHAN) {
-                       unconf->cl_cb_xprt = rqstp->rq_xprt;
-                       svc_xprt_get(unconf->cl_cb_xprt);
+                       unconf->cl_cb_conn.cb_xprt = rqstp->rq_xprt;
+                       svc_xprt_get(rqstp->rq_xprt);
                        rpc_copy_addr(
                                (struct sockaddr *)&unconf->cl_cb_conn.cb_addr,
                                sa);
@@ -1344,7 +1351,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
                                cstate->minorversion;
                        unconf->cl_cb_conn.cb_prog = cr_ses->callback_prog;
                        unconf->cl_cb_seq_nr = 1;
-                       nfsd4_probe_callback(unconf);
+                       nfsd4_probe_callback(unconf, &unconf->cl_cb_conn);
                }
                conf = unconf;
        } else {
@@ -1352,6 +1359,12 @@ nfsd4_create_session(struct svc_rqst *rqstp,
                goto out;
        }
 
+       /*
+        * We do not support RDMA or persistent sessions
+        */
+       cr_ses->flags &= ~SESSION4_PERSIST;
+       cr_ses->flags &= ~SESSION4_RDMA;
+
        status = alloc_init_session(rqstp, conf, cr_ses);
        if (status)
                goto out;
@@ -1369,6 +1382,21 @@ out:
        return status;
 }
 
+static bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
+{
+       struct nfsd4_compoundres *resp = rqstp->rq_resp;
+       struct nfsd4_compoundargs *argp = rqstp->rq_argp;
+
+       return argp->opcnt == resp->opcnt;
+}
+
+static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
+{
+       if (!session)
+               return 0;
+       return !memcmp(sid, &session->se_sessionid, sizeof(*sid));
+}
+
 __be32
 nfsd4_destroy_session(struct svc_rqst *r,
                      struct nfsd4_compound_state *cstate,
@@ -1384,19 +1412,25 @@ nfsd4_destroy_session(struct svc_rqst *r,
         * - Do we need to clear any callback info from previous session?
         */
 
+       if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
+               if (!nfsd4_last_compound_op(r))
+                       return nfserr_not_only_op;
+       }
        dump_sessionid(__func__, &sessionid->sessionid);
-       spin_lock(&sessionid_lock);
+       spin_lock(&client_lock);
        ses = find_in_sessionid_hashtbl(&sessionid->sessionid);
        if (!ses) {
-               spin_unlock(&sessionid_lock);
+               spin_unlock(&client_lock);
                goto out;
        }
 
        unhash_session(ses);
-       spin_unlock(&sessionid_lock);
+       spin_unlock(&client_lock);
 
+       nfs4_lock_state();
        /* wait for callbacks */
-       shutdown_callback_client(ses->se_client);
+       nfsd4_set_callback_client(ses->se_client, NULL);
+       nfs4_unlock_state();
        nfsd4_put_session(ses);
        status = nfs_ok;
 out:
@@ -1417,7 +1451,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        if (resp->opcnt != 1)
                return nfserr_sequence_pos;
 
-       spin_lock(&sessionid_lock);
+       spin_lock(&client_lock);
        status = nfserr_badsession;
        session = find_in_sessionid_hashtbl(&seq->sessionid);
        if (!session)
@@ -1456,22 +1490,46 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        cstate->slot = slot;
        cstate->session = session;
 
-       /* Hold a session reference until done processing the compound:
-        * nfsd4_put_session called only if the cstate slot is set.
-        */
-       nfsd4_get_session(session);
 out:
-       spin_unlock(&sessionid_lock);
-       /* Renew the clientid on success and on replay */
+       /* Hold a session reference until done processing the compound. */
        if (cstate->session) {
-               nfs4_lock_state();
-               renew_client(session->se_client);
-               nfs4_unlock_state();
+               nfsd4_get_session(cstate->session);
+               atomic_inc(&session->se_client->cl_refcount);
        }
+       spin_unlock(&client_lock);
        dprintk("%s: return %d\n", __func__, ntohl(status));
        return status;
 }
 
+__be32
+nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
+{
+       if (rc->rca_one_fs) {
+               if (!cstate->current_fh.fh_dentry)
+                       return nfserr_nofilehandle;
+               /*
+                * We don't take advantage of the rca_one_fs case.
+                * That's OK, it's optional, we can safely ignore it.
+                */
+                return nfs_ok;
+       }
+       nfs4_lock_state();
+       if (is_client_expired(cstate->session->se_client)) {
+               nfs4_unlock_state();
+               /*
+                * The following error isn't really legal.
+                * But we only get here if the client just explicitly
+                * destroyed the client.  Surely it no longer cares what
+                * error it gets back on an operation for the dead
+                * client.
+                */
+               return nfserr_stale_clientid;
+       }
+       nfsd4_create_clid_dir(cstate->session->se_client);
+       nfs4_unlock_state();
+       return nfs_ok;
+}
+
 __be32
 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                  struct nfsd4_setclientid *setclid)
@@ -1631,9 +1689,8 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                if (!same_creds(&conf->cl_cred, &unconf->cl_cred))
                        status = nfserr_clid_inuse;
                else {
-                       /* XXX: We just turn off callbacks until we can handle
-                         * change request correctly. */
-                       atomic_set(&conf->cl_cb_conn.cb_set, 0);
+                       atomic_set(&conf->cl_cb_set, 0);
+                       nfsd4_probe_callback(conf, &unconf->cl_cb_conn);
                        expire_client(unconf);
                        status = nfs_ok;
 
@@ -1667,7 +1724,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                        }
                        move_to_confirmed(unconf);
                        conf = unconf;
-                       nfsd4_probe_callback(conf);
+                       nfsd4_probe_callback(conf, &conf->cl_cb_conn);
                        status = nfs_ok;
                }
        } else if ((!conf || (conf && !same_verf(&conf->cl_confirm, &confirm)))
@@ -1700,12 +1757,12 @@ alloc_init_file(struct inode *ino)
                INIT_LIST_HEAD(&fp->fi_hash);
                INIT_LIST_HEAD(&fp->fi_stateids);
                INIT_LIST_HEAD(&fp->fi_delegations);
-               spin_lock(&recall_lock);
-               list_add(&fp->fi_hash, &file_hashtbl[hashval]);
-               spin_unlock(&recall_lock);
                fp->fi_inode = igrab(ino);
                fp->fi_id = current_fileid++;
                fp->fi_had_conflict = false;
+               spin_lock(&recall_lock);
+               list_add(&fp->fi_hash, &file_hashtbl[hashval]);
+               spin_unlock(&recall_lock);
                return fp;
        }
        return NULL;
@@ -1827,7 +1884,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
        stp->st_stateowner = sop;
        get_nfs4_file(fp);
        stp->st_file = fp;
-       stp->st_stateid.si_boot = get_seconds();
+       stp->st_stateid.si_boot = boot_time;
        stp->st_stateid.si_stateownerid = sop->so_id;
        stp->st_stateid.si_fileid = fp->fi_id;
        stp->st_stateid.si_generation = 0;
@@ -2028,7 +2085,6 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
         * lock) we know the server hasn't removed the lease yet, we know
         * it's safe to take a reference: */
        atomic_inc(&dp->dl_count);
-       atomic_inc(&dp->dl_client->cl_count);
 
        spin_lock(&recall_lock);
        list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
@@ -2347,7 +2403,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
 {
        struct nfs4_delegation *dp;
        struct nfs4_stateowner *sop = stp->st_stateowner;
-       struct nfs4_cb_conn *cb = &sop->so_client->cl_cb_conn;
+       int cb_up = atomic_read(&sop->so_client->cl_cb_set);
        struct file_lock fl, *flp = &fl;
        int status, flag = 0;
 
@@ -2355,7 +2411,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
        open->op_recall = 0;
        switch (open->op_claim_type) {
                case NFS4_OPEN_CLAIM_PREVIOUS:
-                       if (!atomic_read(&cb->cb_set))
+                       if (!cb_up)
                                open->op_recall = 1;
                        flag = open->op_delegate_type;
                        if (flag == NFS4_OPEN_DELEGATE_NONE)
@@ -2366,7 +2422,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta
                         * had the chance to reclaim theirs.... */
                        if (locks_in_grace())
                                goto out;
-                       if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
+                       if (!cb_up || !sop->so_confirmed)
                                goto out;
                        if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
                                flag = NFS4_OPEN_DELEGATE_WRITE;
@@ -2483,10 +2539,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
        }
        memcpy(&open->op_stateid, &stp->st_stateid, sizeof(stateid_t));
 
-       if (nfsd4_has_session(&resp->cstate)) {
+       if (nfsd4_has_session(&resp->cstate))
                open->op_stateowner->so_confirmed = 1;
-               nfsd4_create_clid_dir(open->op_stateowner->so_client);
-       }
 
        /*
        * Attempt to hand out a delegation. No error return, because the
@@ -2537,7 +2591,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        renew_client(clp);
        status = nfserr_cb_path_down;
        if (!list_empty(&clp->cl_delegations)
-                       && !atomic_read(&clp->cl_cb_conn.cb_set))
+                       && !atomic_read(&clp->cl_cb_set))
                goto out;
        status = nfs_ok;
 out:
@@ -2554,6 +2608,12 @@ nfsd4_end_grace(void)
        dprintk("NFSD: end of grace period\n");
        nfsd4_recdir_purge_old();
        locks_end_grace(&nfsd4_manager);
+       /*
+        * Now that every NFSv4 client has had the chance to recover and
+        * to see the (possibly new, possibly shorter) lease time, we
+        * can safely set the next grace time to the current lease time:
+        */
+       nfsd4_grace = nfsd4_lease;
 }
 
 static time_t
@@ -2563,15 +2623,17 @@ nfs4_laundromat(void)
        struct nfs4_stateowner *sop;
        struct nfs4_delegation *dp;
        struct list_head *pos, *next, reaplist;
-       time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
-       time_t t, clientid_val = NFSD_LEASE_TIME;
-       time_t u, test_val = NFSD_LEASE_TIME;
+       time_t cutoff = get_seconds() - nfsd4_lease;
+       time_t t, clientid_val = nfsd4_lease;
+       time_t u, test_val = nfsd4_lease;
 
        nfs4_lock_state();
 
        dprintk("NFSD: laundromat service - starting\n");
        if (locks_in_grace())
                nfsd4_end_grace();
+       INIT_LIST_HEAD(&reaplist);
+       spin_lock(&client_lock);
        list_for_each_safe(pos, next, &client_lru) {
                clp = list_entry(pos, struct nfs4_client, cl_lru);
                if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -2580,12 +2642,22 @@ nfs4_laundromat(void)
                                clientid_val = t;
                        break;
                }
+               if (atomic_read(&clp->cl_refcount)) {
+                       dprintk("NFSD: client in use (clientid %08x)\n",
+                               clp->cl_clientid.cl_id);
+                       continue;
+               }
+               unhash_client_locked(clp);
+               list_add(&clp->cl_lru, &reaplist);
+       }
+       spin_unlock(&client_lock);
+       list_for_each_safe(pos, next, &reaplist) {
+               clp = list_entry(pos, struct nfs4_client, cl_lru);
                dprintk("NFSD: purging unused client (clientid %08x)\n",
                        clp->cl_clientid.cl_id);
                nfsd4_remove_clid_dir(clp);
                expire_client(clp);
        }
-       INIT_LIST_HEAD(&reaplist);
        spin_lock(&recall_lock);
        list_for_each_safe(pos, next, &del_recall_lru) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
@@ -2605,7 +2677,7 @@ nfs4_laundromat(void)
                list_del_init(&dp->dl_recall_lru);
                unhash_delegation(dp);
        }
-       test_val = NFSD_LEASE_TIME;
+       test_val = nfsd4_lease;
        list_for_each_safe(pos, next, &close_lru) {
                sop = list_entry(pos, struct nfs4_stateowner, so_close_lru);
                if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) {
@@ -2661,39 +2733,11 @@ nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp)
 static int
 STALE_STATEID(stateid_t *stateid)
 {
-       if (time_after((unsigned long)boot_time,
-                       (unsigned long)stateid->si_boot)) {
-               dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
-                       STATEID_VAL(stateid));
-               return 1;
-       }
-       return 0;
-}
-
-static int
-EXPIRED_STATEID(stateid_t *stateid)
-{
-       if (time_before((unsigned long)boot_time,
-                       ((unsigned long)stateid->si_boot)) &&
-           time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) {
-               dprintk("NFSD: expired stateid " STATEID_FMT "!\n",
-                       STATEID_VAL(stateid));
-               return 1;
-       }
-       return 0;
-}
-
-static __be32
-stateid_error_map(stateid_t *stateid)
-{
-       if (STALE_STATEID(stateid))
-               return nfserr_stale_stateid;
-       if (EXPIRED_STATEID(stateid))
-               return nfserr_expired;
-
-       dprintk("NFSD: bad stateid " STATEID_FMT "!\n",
+       if (stateid->si_boot == boot_time)
+               return 0;
+       dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
                STATEID_VAL(stateid));
-       return nfserr_bad_stateid;
+       return 1;
 }
 
 static inline int
@@ -2817,10 +2861,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
        status = nfserr_bad_stateid;
        if (is_delegation_stateid(stateid)) {
                dp = find_delegation_stateid(ino, stateid);
-               if (!dp) {
-                       status = stateid_error_map(stateid);
+               if (!dp)
                        goto out;
-               }
                status = check_stateid_generation(stateid, &dp->dl_stateid,
                                                  flags);
                if (status)
@@ -2833,10 +2875,8 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate,
                        *filpp = dp->dl_vfs_file;
        } else { /* open or lock stateid */
                stp = find_stateid(stateid, flags);
-               if (!stp) {
-                       status = stateid_error_map(stateid);
+               if (!stp)
                        goto out;
-               }
                if (nfs4_check_fh(current_fh, stp))
                        goto out;
                if (!stp->st_stateowner->so_confirmed)
@@ -2908,7 +2948,7 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
                 */
                sop = search_close_lru(stateid->si_stateownerid, flags);
                if (sop == NULL)
-                       return stateid_error_map(stateid);
+                       return nfserr_bad_stateid;
                *sopp = sop;
                goto check_replay;
        }
@@ -3175,10 +3215,8 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (!is_delegation_stateid(stateid))
                goto out;
        dp = find_delegation_stateid(inode, stateid);
-       if (!dp) {
-               status = stateid_error_map(stateid);
+       if (!dp)
                goto out;
-       }
        status = check_stateid_generation(stateid, &dp->dl_stateid, flags);
        if (status)
                goto out;
@@ -3404,7 +3442,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
        stp->st_stateowner = sop;
        get_nfs4_file(fp);
        stp->st_file = fp;
-       stp->st_stateid.si_boot = get_seconds();
+       stp->st_stateid.si_boot = boot_time;
        stp->st_stateid.si_stateownerid = sop->so_id;
        stp->st_stateid.si_fileid = fp->fi_id;
        stp->st_stateid.si_generation = 0;
@@ -3976,12 +4014,6 @@ nfsd4_load_reboot_recovery_data(void)
                printk("NFSD: Failure reading reboot recovery data\n");
 }
 
-unsigned long
-get_nfs4_grace_period(void)
-{
-       return max(user_lease_time, lease_time) * HZ;
-}
-
 /*
  * Since the lifetime of a delegation isn't limited to that of an open, a
  * client may quite reasonably hang on to a delegation as long as it has
@@ -4008,20 +4040,27 @@ set_max_delegations(void)
 static int
 __nfs4_state_start(void)
 {
-       unsigned long grace_time;
+       int ret;
 
        boot_time = get_seconds();
-       grace_time = get_nfs4_grace_period();
-       lease_time = user_lease_time;
        locks_start_grace(&nfsd4_manager);
        printk(KERN_INFO "NFSD: starting %ld-second grace period\n",
-              grace_time/HZ);
+              nfsd4_grace);
+       ret = set_callback_cred();
+       if (ret)
+               return -ENOMEM;
        laundry_wq = create_singlethread_workqueue("nfsd4");
        if (laundry_wq == NULL)
                return -ENOMEM;
-       queue_delayed_work(laundry_wq, &laundromat_work, grace_time);
+       ret = nfsd4_create_callback_queue();
+       if (ret)
+               goto out_free_laundry;
+       queue_delayed_work(laundry_wq, &laundromat_work, nfsd4_grace * HZ);
        set_max_delegations();
-       return set_callback_cred();
+       return 0;
+out_free_laundry:
+       destroy_workqueue(laundry_wq);
+       return ret;
 }
 
 int
@@ -4039,12 +4078,6 @@ nfs4_state_start(void)
        return 0;
 }
 
-time_t
-nfs4_lease_time(void)
-{
-       return lease_time;
-}
-
 static void
 __nfs4_state_shutdown(void)
 {
@@ -4089,6 +4122,7 @@ nfs4_state_shutdown(void)
        nfs4_lock_state();
        nfs4_release_reclaim();
        __nfs4_state_shutdown();
+       nfsd4_destroy_callback_queue();
        nfs4_unlock_state();
 }
 
@@ -4128,21 +4162,3 @@ nfs4_recoverydir(void)
 {
        return user_recovery_dirname;
 }
-
-/*
- * Called when leasetime is changed.
- *
- * The only way the protocol gives us to handle on-the-fly lease changes is to
- * simulate a reboot.  Instead of doing that, we just wait till the next time
- * we start to register any changes in lease time.  If the administrator
- * really wants to change the lease time *now*, they can go ahead and bring
- * nfsd down and then back up again after changing the lease time.
- *
- * user_lease_time is protected by nfsd_mutex since it's only really accessed
- * when nfsd is starting
- */
-void
-nfs4_reset_lease(time_t leasetime)
-{
-       user_lease_time = leasetime;
-}
index e170317..ac17a70 100644 (file)
@@ -161,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
        argp->p = page_address(argp->pagelist[0]);
        argp->pagelist++;
        if (argp->pagelen < PAGE_SIZE) {
-               argp->end = p + (argp->pagelen>>2);
+               argp->end = argp->p + (argp->pagelen>>2);
                argp->pagelen = 0;
        } else {
-               argp->end = p + (PAGE_SIZE>>2);
+               argp->end = argp->p + (PAGE_SIZE>>2);
                argp->pagelen -= PAGE_SIZE;
        }
        memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
@@ -1234,6 +1234,16 @@ nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
        DECODE_TAIL;
 }
 
+static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
+{
+       DECODE_HEAD;
+
+       READ_BUF(4);
+       READ32(rc->rca_one_fs);
+
+       DECODE_TAIL;
+}
+
 static __be32
 nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
 {
@@ -1346,7 +1356,7 @@ static nfsd4_dec nfsd41_dec_ops[] = {
        [OP_TEST_STATEID]       = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_WANT_DELEGATION]    = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_DESTROY_CLIENTID]   = (nfsd4_dec)nfsd4_decode_notsupp,
-       [OP_RECLAIM_COMPLETE]   = (nfsd4_dec)nfsd4_decode_notsupp,
+       [OP_RECLAIM_COMPLETE]   = (nfsd4_dec)nfsd4_decode_reclaim_complete,
 };
 
 struct nfsd4_minorversion_ops {
@@ -1426,10 +1436,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
                        argp->p = page_address(argp->pagelist[0]);
                        argp->pagelist++;
                        if (argp->pagelen < PAGE_SIZE) {
-                               argp->end = p + (argp->pagelen>>2);
+                               argp->end = argp->p + (argp->pagelen>>2);
                                argp->pagelen = 0;
                        } else {
-                               argp->end = p + (PAGE_SIZE>>2);
+                               argp->end = argp->p + (PAGE_SIZE>>2);
                                argp->pagelen -= PAGE_SIZE;
                        }
                }
@@ -1900,7 +1910,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
        if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
                if ((buflen -= 4) < 0)
                        goto out_resource;
-               WRITE32(NFSD_LEASE_TIME);
+               WRITE32(nfsd4_lease);
        }
        if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
                if ((buflen -= 4) < 0)
@@ -3307,11 +3317,14 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
                iov = &rqstp->rq_res.head[0];
        iov->iov_len = ((char*)resp->p) - (char*)iov->iov_base;
        BUG_ON(iov->iov_len > PAGE_SIZE);
-       if (nfsd4_has_session(cs) && cs->status != nfserr_replay_cache) {
-               nfsd4_store_cache_entry(resp);
-               dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
-               resp->cstate.slot->sl_inuse = false;
-               nfsd4_put_session(resp->cstate.session);
+       if (nfsd4_has_session(cs)) {
+               if (cs->status != nfserr_replay_cache) {
+                       nfsd4_store_cache_entry(resp);
+                       dprintk("%s: SET SLOT STATE TO AVAILABLE\n", __func__);
+                       cs->slot->sl_inuse = false;
+               }
+               /* Renew the clientid on success and on replay */
+               release_session_client(cs->session);
        }
        return 1;
 }
index e359107..bc3194e 100644 (file)
@@ -46,6 +46,7 @@ enum {
         */
 #ifdef CONFIG_NFSD_V4
        NFSD_Leasetime,
+       NFSD_Gracetime,
        NFSD_RecoveryDir,
 #endif
 };
@@ -70,6 +71,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size);
 static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
 #ifdef CONFIG_NFSD_V4
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
+static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
 #endif
 
@@ -91,6 +93,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_MaxBlkSize] = write_maxblksize,
 #ifdef CONFIG_NFSD_V4
        [NFSD_Leasetime] = write_leasetime,
+       [NFSD_Gracetime] = write_gracetime,
        [NFSD_RecoveryDir] = write_recoverydir,
 #endif
 };
@@ -1204,29 +1207,45 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
 }
 
 #ifdef CONFIG_NFSD_V4
-extern time_t nfs4_leasetime(void);
-
-static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
+static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time)
 {
-       /* if size > 10 seconds, call
-        * nfs4_reset_lease() then write out the new lease (seconds) as reply
-        */
        char *mesg = buf;
-       int rv, lease;
+       int rv, i;
 
        if (size > 0) {
                if (nfsd_serv)
                        return -EBUSY;
-               rv = get_int(&mesg, &lease);
+               rv = get_int(&mesg, &i);
                if (rv)
                        return rv;
-               if (lease < 10 || lease > 3600)
+               /*
+                * Some sanity checking.  We don't have a reason for
+                * these particular numbers, but problems with the
+                * extremes are:
+                *      - Too short: the briefest network outage may
+                *        cause clients to lose all their locks.  Also,
+                *        the frequent polling may be wasteful.
+                *      - Too long: do you really want reboot recovery
+                *        to take more than an hour?  Or to make other
+                *        clients wait an hour before being able to
+                *        revoke a dead client's locks?
+                */
+               if (i < 10 || i > 3600)
                        return -EINVAL;
-               nfs4_reset_lease(lease);
+               *time = i;
        }
 
-       return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n",
-                                                       nfs4_lease_time());
+       return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
+}
+
+static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, time_t *time)
+{
+       ssize_t rv;
+
+       mutex_lock(&nfsd_mutex);
+       rv = __nfsd4_write_time(file, buf, size, time);
+       mutex_unlock(&nfsd_mutex);
+       return rv;
 }
 
 /**
@@ -1252,12 +1271,22 @@ static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
  */
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
 {
-       ssize_t rv;
+       return nfsd4_write_time(file, buf, size, &nfsd4_lease);
+}
 
-       mutex_lock(&nfsd_mutex);
-       rv = __write_leasetime(file, buf, size);
-       mutex_unlock(&nfsd_mutex);
-       return rv;
+/**
+ * write_gracetime - Set or report current NFSv4 grace period time
+ *
+ * As above, but sets the time of the NFSv4 grace period.
+ *
+ * Note this should never be set to less than the *previous*
+ * lease-period time, but we don't try to enforce this.  (In the common
+ * case (a new boot), we don't know what the previous lease time was
+ * anyway.)
+ */
+static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
+{
+       return nfsd4_write_time(file, buf, size, &nfsd4_grace);
 }
 
 extern char *nfs4_recoverydir(void);
@@ -1351,6 +1380,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
 #ifdef CONFIG_NFSD_V4
                [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
+               [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
 #endif
                /* last one */ {""}
index e942a1a..7237776 100644 (file)
@@ -82,7 +82,6 @@ int nfs4_state_init(void);
 void nfsd4_free_slabs(void);
 int nfs4_state_start(void);
 void nfs4_state_shutdown(void);
-time_t nfs4_lease_time(void);
 void nfs4_reset_lease(time_t leasetime);
 int nfs4_reset_recoverydir(char *recdir);
 #else
@@ -90,7 +89,6 @@ static inline int nfs4_state_init(void) { return 0; }
 static inline void nfsd4_free_slabs(void) { }
 static inline int nfs4_state_start(void) { return 0; }
 static inline void nfs4_state_shutdown(void) { }
-static inline time_t nfs4_lease_time(void) { return 0; }
 static inline void nfs4_reset_lease(time_t leasetime) { }
 static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
 #endif
@@ -229,6 +227,9 @@ extern struct timeval       nfssvc_boot;
 
 #ifdef CONFIG_NFSD_V4
 
+extern time_t nfsd4_lease;
+extern time_t nfsd4_grace;
+
 /* before processing a COMPOUND operation, we have to check that there
  * is enough space in the buffer for XDR encode to succeed.  otherwise,
  * we might process an operation with side effects, and be unable to
@@ -247,7 +248,6 @@ extern struct timeval       nfssvc_boot;
 #define        COMPOUND_SLACK_SPACE            140    /* OP_GETFH */
 #define COMPOUND_ERR_SLACK_SPACE       12     /* OP_SETATTR */
 
-#define NFSD_LEASE_TIME                 (nfs4_lease_time())
 #define NFSD_LAUNDROMAT_MINTIMEOUT      10   /* seconds */
 
 /*
index 171699e..06b2a26 100644 (file)
@@ -120,7 +120,7 @@ u32 nfsd_supported_minorversion;
 int nfsd_vers(int vers, enum vers_op change)
 {
        if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS)
-               return -1;
+               return 0;
        switch(change) {
        case NFSD_SET:
                nfsd_versions[vers] = nfsd_version[vers];
index fefeae2..006c842 100644 (file)
@@ -70,6 +70,16 @@ struct nfsd4_cb_sequence {
        struct nfs4_client      *cbs_clp;
 };
 
+struct nfs4_rpc_args {
+       void                            *args_op;
+       struct nfsd4_cb_sequence        args_seq;
+};
+
+struct nfsd4_callback {
+       struct nfs4_rpc_args cb_args;
+       struct work_struct cb_work;
+};
+
 struct nfs4_delegation {
        struct list_head        dl_perfile;
        struct list_head        dl_perclnt;
@@ -86,6 +96,7 @@ struct nfs4_delegation {
        stateid_t               dl_stateid;
        struct knfsd_fh         dl_fh;
        int                     dl_retries;
+       struct nfsd4_callback   dl_recall;
 };
 
 /* client delegation callback info */
@@ -96,9 +107,7 @@ struct nfs4_cb_conn {
        u32                     cb_prog;
        u32                     cb_minorversion;
        u32                     cb_ident;       /* minorversion 0 only */
-       /* RPC client info */
-       atomic_t                cb_set;     /* successful CB_NULL call */
-       struct rpc_clnt *       cb_client;
+       struct svc_xprt         *cb_xprt;       /* minorversion 1 only */
 };
 
 /* Maximum number of slots per session. 160 is useful for long haul TCP */
@@ -157,7 +166,7 @@ struct nfsd4_session {
        struct list_head        se_hash;        /* hash by sessionid */
        struct list_head        se_perclnt;
        u32                     se_flags;
-       struct nfs4_client      *se_client;     /* for expire_client */
+       struct nfs4_client      *se_client;
        struct nfs4_sessionid   se_sessionid;
        struct nfsd4_channel_attrs se_fchannel;
        struct nfsd4_channel_attrs se_bchannel;
@@ -212,25 +221,41 @@ struct nfs4_client {
        struct svc_cred         cl_cred;        /* setclientid principal */
        clientid_t              cl_clientid;    /* generated by server */
        nfs4_verifier           cl_confirm;     /* generated by server */
-       struct nfs4_cb_conn     cl_cb_conn;     /* callback info */
-       atomic_t                cl_count;       /* ref count */
        u32                     cl_firststate;  /* recovery dir creation */
 
+       /* for v4.0 and v4.1 callbacks: */
+       struct nfs4_cb_conn     cl_cb_conn;
+       struct rpc_clnt         *cl_cb_client;
+       atomic_t                cl_cb_set;
+
        /* for nfs41 */
        struct list_head        cl_sessions;
        struct nfsd4_clid_slot  cl_cs_slot;     /* create_session slot */
        u32                     cl_exchange_flags;
        struct nfs4_sessionid   cl_sessionid;
+       /* number of rpc's in progress over an associated session: */
+       atomic_t                cl_refcount;
 
        /* for nfs41 callbacks */
        /* We currently support a single back channel with a single slot */
        unsigned long           cl_cb_slot_busy;
        u32                     cl_cb_seq_nr;
-       struct svc_xprt         *cl_cb_xprt;    /* 4.1 callback transport */
        struct rpc_wait_queue   cl_cb_waitq;    /* backchannel callers may */
                                                /* wait here for slots */
 };
 
+static inline void
+mark_client_expired(struct nfs4_client *clp)
+{
+       clp->cl_time = 0;
+}
+
+static inline bool
+is_client_expired(struct nfs4_client *clp)
+{
+       return clp->cl_time == 0;
+}
+
 /* struct nfs4_client_reset
  * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl
  * upon lease reset, or from upcall to state_daemon (to read in state
@@ -377,11 +402,14 @@ extern void nfs4_lock_state(void);
 extern void nfs4_unlock_state(void);
 extern int nfs4_in_grace(void);
 extern __be32 nfs4_check_open_reclaim(clientid_t *clid);
-extern void put_nfs4_client(struct nfs4_client *clp);
 extern void nfs4_free_stateowner(struct kref *kref);
 extern int set_callback_cred(void);
-extern void nfsd4_probe_callback(struct nfs4_client *clp);
+extern void nfsd4_probe_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
+extern void nfsd4_do_callback_rpc(struct work_struct *);
 extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
+extern int nfsd4_create_callback_queue(void);
+extern void nfsd4_destroy_callback_queue(void);
+extern void nfsd4_set_callback_client(struct nfs4_client *, struct rpc_clnt *);
 extern void nfs4_put_delegation(struct nfs4_delegation *dp);
 extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
 extern void nfsd4_init_recdir(char *recdir_name);
@@ -392,6 +420,7 @@ extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id);
 extern void nfsd4_recdir_purge_old(void);
 extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
 extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
+extern void release_session_client(struct nfsd4_session *);
 
 static inline void
 nfs4_put_stateowner(struct nfs4_stateowner *so)
index 6dd5f19..23c06f7 100644 (file)
@@ -724,7 +724,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        struct inode    *inode;
        int             flags = O_RDONLY|O_LARGEFILE;
        __be32          err;
-       int             host_err;
+       int             host_err = 0;
 
        validate_process_creds();
 
@@ -761,7 +761,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
         * Check to see if there are any leases on this file.
         * This may block while leases are broken.
         */
-       host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
+       if (!(access & NFSD_MAY_NOT_BREAK_LEASE))
+               host_err = break_lease(inode, O_NONBLOCK | ((access & NFSD_MAY_WRITE) ? O_WRONLY : 0));
        if (host_err == -EWOULDBLOCK)
                host_err = -ETIMEDOUT;
        if (host_err) /* NOMEM or WOULDBLOCK */
@@ -1169,7 +1170,8 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
                        goto out;
        }
 
-       err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file);
+       err = nfsd_open(rqstp, fhp, S_IFREG,
+                       NFSD_MAY_WRITE|NFSD_MAY_NOT_BREAK_LEASE, &file);
        if (err)
                goto out;
        if (EX_ISSYNC(fhp->fh_export)) {
index 4b1de0a..217a62c 100644 (file)
@@ -20,6 +20,7 @@
 #define NFSD_MAY_OWNER_OVERRIDE        64
 #define NFSD_MAY_LOCAL_ACCESS  128 /* IRIX doing local access check on device special file*/
 #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256
+#define NFSD_MAY_NOT_BREAK_LEASE 512
 
 #define NFSD_MAY_CREATE                (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
 #define NFSD_MAY_REMOVE                (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
index efa3377..4d476ff 100644 (file)
@@ -381,6 +381,10 @@ struct nfsd4_destroy_session {
        struct nfs4_sessionid   sessionid;
 };
 
+struct nfsd4_reclaim_complete {
+       u32 rca_one_fs;
+};
+
 struct nfsd4_op {
        int                                     opnum;
        __be32                                  status;
@@ -421,6 +425,7 @@ struct nfsd4_op {
                struct nfsd4_create_session     create_session;
                struct nfsd4_destroy_session    destroy_session;
                struct nfsd4_sequence           sequence;
+               struct nfsd4_reclaim_complete   reclaim_complete;
        } u;
        struct nfs4_replay *                    replay;
 };
@@ -513,9 +518,8 @@ extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp);
 extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp,
                struct nfsd4_sequence *seq);
 extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp,
-               struct nfsd4_compound_state *,
-struct nfsd4_exchange_id *);
-               extern __be32 nfsd4_create_session(struct svc_rqst *,
+               struct nfsd4_compound_state *, struct nfsd4_exchange_id *);
+extern __be32 nfsd4_create_session(struct svc_rqst *,
                struct nfsd4_compound_state *,
                struct nfsd4_create_session *);
 extern __be32 nfsd4_sequence(struct svc_rqst *,
@@ -524,6 +528,7 @@ extern __be32 nfsd4_sequence(struct svc_rqst *,
 extern __be32 nfsd4_destroy_session(struct svc_rqst *,
                struct nfsd4_compound_state *,
                struct nfsd4_destroy_session *);
+__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *);
 extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *,
                struct nfsd4_open *open);
 extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp,
index 8d6356a..7cfb87e 100644 (file)
@@ -426,7 +426,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
        bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
        if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
                                    group_offset, bitmap))
-               printk(KERN_WARNING "%s: entry numer %llu already freed\n",
+               printk(KERN_WARNING "%s: entry number %llu already freed\n",
                       __func__, (unsigned long long)req->pr_entry_nr);
 
        nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
index 7cdd98b..76c38e3 100644 (file)
@@ -1879,7 +1879,7 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
                                   struct nilfs_btree_path *path,
                                   int level, struct buffer_head *bh)
 {
-       int maxlevel, ret;
+       int maxlevel = 0, ret;
        struct nilfs_btree_node *parent;
        struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
        __u64 ptr;
index c2ff1b3..f90a33d 100644 (file)
@@ -649,7 +649,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
 long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = filp->f_dentry->d_inode;
-       void __user *argp = (void __user *)arg;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case NILFS_IOCTL_CHANGE_CPMODE:
index 0cdbc5e..48145f5 100644 (file)
@@ -749,6 +749,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
        sb->s_export_op = &nilfs_export_ops;
        sb->s_root = NULL;
        sb->s_time_gran = 1;
+       sb->s_bdi = nilfs->ns_bdi;
 
        err = load_nilfs(nilfs, sbi);
        if (err)
index 3e56dbf..b3a159b 100644 (file)
@@ -15,6 +15,7 @@ config INOTIFY
 
 config INOTIFY_USER
        bool "Inotify support for userspace"
+       select ANON_INODES
        select FSNOTIFY
        default y
        ---help---
index 1afb0a1..e27960c 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/path.h> /* struct path */
 #include <linux/slab.h> /* kmem_* */
 #include <linux/types.h>
+#include <linux/sched.h>
 
 #include "inotify.h"
 
@@ -146,6 +147,7 @@ static void inotify_free_group_priv(struct fsnotify_group *group)
        idr_for_each(&group->inotify_data.idr, idr_callback, group);
        idr_remove_all(&group->inotify_data.idr);
        idr_destroy(&group->inotify_data.idr);
+       free_uid(group->inotify_data.user);
 }
 
 void inotify_free_event_priv(struct fsnotify_event_private_data *fsn_event_priv)
index 472cdf2..e46ca68 100644 (file)
@@ -546,21 +546,24 @@ retry:
        if (unlikely(!idr_pre_get(&group->inotify_data.idr, GFP_KERNEL)))
                goto out_err;
 
+       /* we are putting the mark on the idr, take a reference */
+       fsnotify_get_mark(&tmp_ientry->fsn_entry);
+
        spin_lock(&group->inotify_data.idr_lock);
        ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,
                                group->inotify_data.last_wd+1,
                                &tmp_ientry->wd);
        spin_unlock(&group->inotify_data.idr_lock);
        if (ret) {
+               /* we didn't get on the idr, drop the idr reference */
+               fsnotify_put_mark(&tmp_ientry->fsn_entry);
+
                /* idr was out of memory allocate and try again */
                if (ret == -EAGAIN)
                        goto retry;
                goto out_err;
        }
 
-       /* we put the mark on the idr, take a reference */
-       fsnotify_get_mark(&tmp_ientry->fsn_entry);
-
        /* we are on the idr, now get on the inode */
        ret = fsnotify_add_mark(&tmp_ientry->fsn_entry, group, inode);
        if (ret) {
@@ -578,16 +581,13 @@ retry:
        /* return the watch descriptor for this new entry */
        ret = tmp_ientry->wd;
 
-       /* match the ref from fsnotify_init_markentry() */
-       fsnotify_put_mark(&tmp_ientry->fsn_entry);
-
        /* if this mark added a new event update the group mask */
        if (mask & ~group->mask)
                fsnotify_recalc_group_mask(group);
 
 out_err:
-       if (ret < 0)
-               kmem_cache_free(inotify_inode_mark_cachep, tmp_ientry);
+       /* match the ref from fsnotify_init_markentry() */
+       fsnotify_put_mark(&tmp_ientry->fsn_entry);
 
        return ret;
 }
index ecebb22..f9d5d3f 100644 (file)
@@ -406,6 +406,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
                                struct buffer_head *bh)
 {
        int ret = 0;
+       struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
 
        mlog_entry_void();
 
@@ -425,6 +426,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
 
        get_bh(bh); /* for end_buffer_write_sync() */
        bh->b_end_io = end_buffer_write_sync;
+       ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &di->i_check);
        submit_bh(WRITE, bh);
 
        wait_on_buffer(bh);
index a795eb9..12d5eb7 100644 (file)
@@ -184,9 +184,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
        BUG_ON(!lksb);
 
        /* only updates if this node masters the lockres */
+       spin_lock(&res->spinlock);
        if (res->owner == dlm->node_num) {
-
-               spin_lock(&res->spinlock);
                /* check the lksb flags for the direction */
                if (lksb->flags & DLM_LKSB_GET_LVB) {
                        mlog(0, "getting lvb from lockres for %s node\n",
@@ -201,8 +200,8 @@ static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
                 * here. In the future we might want to clear it at the time
                 * the put is actually done.
                 */
-               spin_unlock(&res->spinlock);
        }
+       spin_unlock(&res->spinlock);
 
        /* reset any lvb flags on the lksb */
        lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB);
index 1b0de15..b83d610 100644 (file)
@@ -112,20 +112,20 @@ MODULE_PARM_DESC(capabilities, DLMFS_CAPABILITIES);
  * O_RDONLY -> PRMODE level
  * O_WRONLY -> EXMODE level
  *
- * O_NONBLOCK -> LKM_NOQUEUE
+ * O_NONBLOCK -> NOQUEUE
  */
 static int dlmfs_decode_open_flags(int open_flags,
                                   int *level,
                                   int *flags)
 {
        if (open_flags & (O_WRONLY|O_RDWR))
-               *level = LKM_EXMODE;
+               *level = DLM_LOCK_EX;
        else
-               *level = LKM_PRMODE;
+               *level = DLM_LOCK_PR;
 
        *flags = 0;
        if (open_flags & O_NONBLOCK)
-               *flags |= LKM_NOQUEUE;
+               *flags |= DLM_LKF_NOQUEUE;
 
        return 0;
 }
@@ -166,7 +166,7 @@ static int dlmfs_file_open(struct inode *inode,
                 * to be able userspace to be able to distinguish a
                 * valid lock request from one that simply couldn't be
                 * granted. */
-               if (flags & LKM_NOQUEUE && status == -EAGAIN)
+               if (flags & DLM_LKF_NOQUEUE && status == -EAGAIN)
                        status = -ETXTBSY;
                kfree(fp);
                goto bail;
@@ -193,7 +193,7 @@ static int dlmfs_file_release(struct inode *inode,
        status = 0;
        if (fp) {
                level = fp->fp_lock_level;
-               if (level != LKM_IVMODE)
+               if (level != DLM_LOCK_IV)
                        user_dlm_cluster_unlock(&ip->ip_lockres, level);
 
                kfree(fp);
@@ -262,7 +262,7 @@ static ssize_t dlmfs_file_read(struct file *filp,
        if ((count + *ppos) > i_size_read(inode))
                readlen = i_size_read(inode) - *ppos;
        else
-               readlen = count - *ppos;
+               readlen = count;
 
        lvb_buf = kmalloc(readlen, GFP_NOFS);
        if (!lvb_buf)
index 17947dc..a5fbd9c 100644 (file)
@@ -684,6 +684,7 @@ restarted_transaction:
                if (why == RESTART_META) {
                        mlog(0, "restarting function.\n");
                        restart_func = 1;
+                       status = 0;
                } else {
                        BUG_ON(why != RESTART_TRANS);
 
@@ -1981,18 +1982,18 @@ relock:
        /* communicate with ocfs2_dio_end_io */
        ocfs2_iocb_set_rw_locked(iocb, rw_level);
 
-       if (direct_io) {
-               ret = generic_segment_checks(iov, &nr_segs, &ocount,
-                                            VERIFY_READ);
-               if (ret)
-                       goto out_dio;
+       ret = generic_segment_checks(iov, &nr_segs, &ocount,
+                                    VERIFY_READ);
+       if (ret)
+               goto out_dio;
 
-               count = ocount;
-               ret = generic_write_checks(file, ppos, &count,
-                                          S_ISBLK(inode->i_mode));
-               if (ret)
-                       goto out_dio;
+       count = ocount;
+       ret = generic_write_checks(file, ppos, &count,
+                                  S_ISBLK(inode->i_mode));
+       if (ret)
+               goto out_dio;
 
+       if (direct_io) {
                written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
                                                    ppos, count, ocount);
                if (written < 0) {
@@ -2007,7 +2008,10 @@ relock:
                        goto out_dio;
                }
        } else {
-               written = __generic_file_aio_write(iocb, iov, nr_segs, ppos);
+               current->backing_dev_info = file->f_mapping->backing_dev_info;
+               written = generic_file_buffered_write(iocb, iov, nr_segs, *ppos,
+                                                     ppos, count, 0);
+               current->backing_dev_info = NULL;
        }
 
 out_dio:
@@ -2021,9 +2025,9 @@ out_dio:
                if (ret < 0)
                        written = ret;
 
-               if (!ret && (old_size != i_size_read(inode) ||
-                   old_clusters != OCFS2_I(inode)->ip_clusters ||
-                   has_refcount)) {
+               if (!ret && ((old_size != i_size_read(inode)) ||
+                            (old_clusters != OCFS2_I(inode)->ip_clusters) ||
+                            has_refcount)) {
                        ret = jbd2_journal_force_commit(osb->journal->j_journal);
                        if (ret < 0)
                                written = ret;
index 07cc8bb..af18988 100644 (file)
@@ -558,6 +558,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
                handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
                if (IS_ERR(handle)) {
                        status = PTR_ERR(handle);
+                       handle = NULL;
                        mlog_errno(status);
                        goto out;
                }
@@ -639,11 +640,13 @@ static int ocfs2_remove_inode(struct inode *inode,
                goto bail_unlock;
        }
 
-       status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
-                                 orphan_dir_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail_commit;
+       if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
+               status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
+                                         orphan_dir_bh);
+               if (status < 0) {
+                       mlog_errno(status);
+                       goto bail_commit;
+               }
        }
 
        /* set the inodes dtime */
@@ -722,38 +725,39 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb,
 static int ocfs2_wipe_inode(struct inode *inode,
                            struct buffer_head *di_bh)
 {
-       int status, orphaned_slot;
+       int status, orphaned_slot = -1;
        struct inode *orphan_dir_inode = NULL;
        struct buffer_head *orphan_dir_bh = NULL;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
-       struct ocfs2_dinode *di;
+       struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
 
-       di = (struct ocfs2_dinode *) di_bh->b_data;
-       orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
+       if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
+               orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
 
-       status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
-       if (status)
-               return status;
+               status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
+               if (status)
+                       return status;
 
-       orphan_dir_inode = ocfs2_get_system_file_inode(osb,
-                                                      ORPHAN_DIR_SYSTEM_INODE,
-                                                      orphaned_slot);
-       if (!orphan_dir_inode) {
-               status = -EEXIST;
-               mlog_errno(status);
-               goto bail;
-       }
+               orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+                                                              ORPHAN_DIR_SYSTEM_INODE,
+                                                              orphaned_slot);
+               if (!orphan_dir_inode) {
+                       status = -EEXIST;
+                       mlog_errno(status);
+                       goto bail;
+               }
 
-       /* Lock the orphan dir. The lock will be held for the entire
-        * delete_inode operation. We do this now to avoid races with
-        * recovery completion on other nodes. */
-       mutex_lock(&orphan_dir_inode->i_mutex);
-       status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
-       if (status < 0) {
-               mutex_unlock(&orphan_dir_inode->i_mutex);
+               /* Lock the orphan dir. The lock will be held for the entire
+                * delete_inode operation. We do this now to avoid races with
+                * recovery completion on other nodes. */
+               mutex_lock(&orphan_dir_inode->i_mutex);
+               status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
+               if (status < 0) {
+                       mutex_unlock(&orphan_dir_inode->i_mutex);
 
-               mlog_errno(status);
-               goto bail;
+                       mlog_errno(status);
+                       goto bail;
+               }
        }
 
        /* we do this while holding the orphan dir lock because we
@@ -794,6 +798,9 @@ static int ocfs2_wipe_inode(struct inode *inode,
                mlog_errno(status);
 
 bail_unlock_dir:
+       if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
+               return status;
+
        ocfs2_inode_unlock(orphan_dir_inode, 1);
        mutex_unlock(&orphan_dir_inode->i_mutex);
        brelse(orphan_dir_bh);
@@ -889,7 +896,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
 
        /* Do some basic inode verification... */
        di = (struct ocfs2_dinode *) di_bh->b_data;
-       if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
+       if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) &&
+           !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
                /*
                 * Inodes in the orphan dir must have ORPHANED_FL.  The only
                 * inodes that come back out of the orphan dir are reflink
index ba4fe07..0b28e19 100644 (file)
@@ -100,6 +100,8 @@ struct ocfs2_inode_info
 #define OCFS2_INODE_MAYBE_ORPHANED     0x00000020
 /* Does someone have the file open O_DIRECT */
 #define OCFS2_INODE_OPEN_DIRECT                0x00000040
+/* Tell the inode wipe code it's not in orphan dir */
+#define OCFS2_INODE_SKIP_ORPHAN_DIR     0x00000080
 
 static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
 {
index b1eb50a..4cbb18f 100644 (file)
@@ -408,23 +408,28 @@ static int ocfs2_mknod(struct inode *dir,
                }
        }
 
-       status = ocfs2_add_entry(handle, dentry, inode,
-                                OCFS2_I(inode)->ip_blkno, parent_fe_bh,
-                                &lookup);
-       if (status < 0) {
+       /*
+        * Do this before adding the entry to the directory. We add
+        * also set d_op after success so that ->d_iput() will cleanup
+        * the dentry lock even if ocfs2_add_entry() fails below.
+        */
+       status = ocfs2_dentry_attach_lock(dentry, inode,
+                                         OCFS2_I(dir)->ip_blkno);
+       if (status) {
                mlog_errno(status);
                goto leave;
        }
+       dentry->d_op = &ocfs2_dentry_ops;
 
-       status = ocfs2_dentry_attach_lock(dentry, inode,
-                                         OCFS2_I(dir)->ip_blkno);
-       if (status) {
+       status = ocfs2_add_entry(handle, dentry, inode,
+                                OCFS2_I(inode)->ip_blkno, parent_fe_bh,
+                                &lookup);
+       if (status < 0) {
                mlog_errno(status);
                goto leave;
        }
 
        insert_inode_hash(inode);
-       dentry->d_op = &ocfs2_dentry_ops;
        d_instantiate(dentry, inode);
        status = 0;
 leave:
@@ -445,11 +450,6 @@ leave:
 
        ocfs2_free_dir_lookup_result(&lookup);
 
-       if ((status < 0) && inode) {
-               clear_nlink(inode);
-               iput(inode);
-       }
-
        if (inode_ac)
                ocfs2_free_alloc_context(inode_ac);
 
@@ -459,6 +459,17 @@ leave:
        if (meta_ac)
                ocfs2_free_alloc_context(meta_ac);
 
+       /*
+        * We should call iput after the i_mutex of the bitmap been
+        * unlocked in ocfs2_free_alloc_context, or the
+        * ocfs2_delete_inode will mutex_lock again.
+        */
+       if ((status < 0) && inode) {
+               OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
+               clear_nlink(inode);
+               iput(inode);
+       }
+
        mlog_exit(status);
 
        return status;
@@ -1771,22 +1782,27 @@ static int ocfs2_symlink(struct inode *dir,
                }
        }
 
-       status = ocfs2_add_entry(handle, dentry, inode,
-                                le64_to_cpu(fe->i_blkno), parent_fe_bh,
-                                &lookup);
-       if (status < 0) {
+       /*
+        * Do this before adding the entry to the directory. We add
+        * also set d_op after success so that ->d_iput() will cleanup
+        * the dentry lock even if ocfs2_add_entry() fails below.
+        */
+       status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
+       if (status) {
                mlog_errno(status);
                goto bail;
        }
+       dentry->d_op = &ocfs2_dentry_ops;
 
-       status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
-       if (status) {
+       status = ocfs2_add_entry(handle, dentry, inode,
+                                le64_to_cpu(fe->i_blkno), parent_fe_bh,
+                                &lookup);
+       if (status < 0) {
                mlog_errno(status);
                goto bail;
        }
 
        insert_inode_hash(inode);
-       dentry->d_op = &ocfs2_dentry_ops;
        d_instantiate(dentry, inode);
 bail:
        if (status < 0 && did_quota)
@@ -1811,6 +1827,7 @@ bail:
        if (xattr_ac)
                ocfs2_free_alloc_context(xattr_ac);
        if ((status < 0) && inode) {
+               OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
                clear_nlink(inode);
                iput(inode);
        }
@@ -1976,6 +1993,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
        }
 
        le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
+       OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
 
        /* Record which orphan dir our inode now resides
         * in. delete_inode will use this to determine which orphan
index bd96f6c..5cbcd0f 100644 (file)
@@ -4083,6 +4083,9 @@ static int ocfs2_complete_reflink(struct inode *s_inode,
        di->i_attr = s_di->i_attr;
 
        if (preserve) {
+               t_inode->i_uid = s_inode->i_uid;
+               t_inode->i_gid = s_inode->i_gid;
+               t_inode->i_mode = s_inode->i_mode;
                di->i_uid = s_di->i_uid;
                di->i_gid = s_di->i_gid;
                di->i_mode = s_di->i_mode;
index e51f2ec..885ab55 100644 (file)
@@ -81,7 +81,6 @@
 #include <linux/pid_namespace.h>
 #include <linux/ptrace.h>
 #include <linux/tracehook.h>
-#include <linux/swapops.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -495,7 +494,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
                rsslim,
                mm ? mm->start_code : 0,
                mm ? mm->end_code : 0,
-               (permitted && mm) ? task->stack_start : 0,
+               (permitted && mm) ? mm->start_stack : 0,
                esp,
                eip,
                /* The signal information here is obsolete.
index 7621db8..c7f9f23 100644 (file)
@@ -730,6 +730,7 @@ out_no_task:
 
 static const struct file_operations proc_info_file_operations = {
        .read           = proc_info_read,
+       .llseek         = generic_file_llseek,
 };
 
 static int proc_single_show(struct seq_file *m, void *v)
@@ -987,6 +988,7 @@ out_no_task:
 
 static const struct file_operations proc_environ_operations = {
        .read           = environ_read,
+       .llseek         = generic_file_llseek,
 };
 
 static ssize_t oom_adjust_read(struct file *file, char __user *buf,
@@ -1060,6 +1062,7 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
 static const struct file_operations proc_oom_adjust_operations = {
        .read           = oom_adjust_read,
        .write          = oom_adjust_write,
+       .llseek         = generic_file_llseek,
 };
 
 #ifdef CONFIG_AUDITSYSCALL
@@ -1131,6 +1134,7 @@ out_free_page:
 static const struct file_operations proc_loginuid_operations = {
        .read           = proc_loginuid_read,
        .write          = proc_loginuid_write,
+       .llseek         = generic_file_llseek,
 };
 
 static ssize_t proc_sessionid_read(struct file * file, char __user * buf,
@@ -1151,6 +1155,7 @@ static ssize_t proc_sessionid_read(struct file * file, char __user * buf,
 
 static const struct file_operations proc_sessionid_operations = {
        .read           = proc_sessionid_read,
+       .llseek         = generic_file_llseek,
 };
 #endif
 
@@ -1202,6 +1207,7 @@ static ssize_t proc_fault_inject_write(struct file * file,
 static const struct file_operations proc_fault_inject_operations = {
        .read           = proc_fault_inject_read,
        .write          = proc_fault_inject_write,
+       .llseek         = generic_file_llseek,
 };
 #endif
 
@@ -1943,7 +1949,7 @@ static ssize_t proc_fdinfo_read(struct file *file, char __user *buf,
 }
 
 static const struct file_operations proc_fdinfo_file_operations = {
-       .open           = nonseekable_open,
+       .open           = nonseekable_open,
        .read           = proc_fdinfo_read,
 };
 
@@ -2227,6 +2233,7 @@ out_no_task:
 static const struct file_operations proc_pid_attr_operations = {
        .read           = proc_pid_attr_read,
        .write          = proc_pid_attr_write,
+       .llseek         = generic_file_llseek,
 };
 
 static const struct pid_entry attr_dir_stuff[] = {
@@ -2347,6 +2354,7 @@ static ssize_t proc_coredump_filter_write(struct file *file,
 static const struct file_operations proc_coredump_filter_operations = {
        .read           = proc_coredump_filter_read,
        .write          = proc_coredump_filter_write,
+       .llseek         = generic_file_llseek,
 };
 #endif
 
@@ -2909,7 +2917,7 @@ out_no_task:
  */
 static const struct pid_entry tid_base_stuff[] = {
        DIR("fd",        S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
-       DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations),
+       DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
        REG("environ",   S_IRUSR, proc_environ_operations),
        INF("auxv",      S_IRUSR, proc_pid_auxv),
        ONE("status",    S_IRUGO, proc_pid_status),
index d35b232..aea8502 100644 (file)
@@ -232,9 +232,9 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
                if (rv == -ENOIOCTLCMD)
                        rv = -EINVAL;
        } else if (ioctl) {
-               lock_kernel();
+               WARN_ONCE(1, "Procfs ioctl handlers must use unlocked_ioctl, "
+                         "%pf will be called without the Bkl held\n", ioctl);
                rv = ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
-               unlock_kernel();
        }
 
        pde_users_dec(pde);
index 19979a2..c837a77 100644 (file)
@@ -558,6 +558,7 @@ static int open_kcore(struct inode *inode, struct file *filp)
 static const struct file_operations proc_kcore_operations = {
        .read           = read_kcore,
        .open           = open_kcore,
+       .llseek         = generic_file_llseek,
 };
 
 #ifdef CONFIG_MEMORY_HOTPLUG
index cfe90a4..bd4b5a7 100644 (file)
@@ -53,6 +53,7 @@ static const struct file_operations proc_kmsg_operations = {
        .poll           = kmsg_poll,
        .open           = kmsg_open,
        .release        = kmsg_release,
+       .llseek         = generic_file_llseek,
 };
 
 static int __init proc_kmsg_init(void)
index 0705534..47f5b14 100644 (file)
@@ -247,25 +247,6 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
                                } else if (vma->vm_start <= mm->start_stack &&
                                           vma->vm_end >= mm->start_stack) {
                                        name = "[stack]";
-                               } else {
-                                       unsigned long stack_start;
-                                       struct proc_maps_private *pmp;
-
-                                       pmp = m->private;
-                                       stack_start = pmp->task->stack_start;
-
-                                       if (vma->vm_start <= stack_start &&
-                                           vma->vm_end >= stack_start) {
-                                               pad_len_spaces(m, len);
-                                               seq_printf(m,
-                                                "[threadstack:%08lx]",
-#ifdef CONFIG_STACK_GROWSUP
-                                                vma->vm_end - stack_start
-#else
-                                                stack_start - vma->vm_start
-#endif
-                                               );
-                                       }
                                }
                        } else {
                                name = "[vdso]";
index 9fbc99e..91c817f 100644 (file)
@@ -163,6 +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,
 };
 
 static struct vmcore* __init get_new_element(void)
index dad7fb2..3e21b1e 100644 (file)
@@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING
          Note that this behavior is currently deprecated and may go away in
          future. Please use notification via netlink socket instead.
 
+config QUOTA_DEBUG
+       bool "Additional quota sanity checks"
+       depends on QUOTA
+       default n
+       help
+         If you say Y here, quota subsystem will perform some additional
+         sanity checks of quota internal structures. If unsure, say N.
+
 # Generic support for tree structured quota files. Selected when needed.
 config QUOTA_TREE
         tristate
index e0b870f..788b580 100644 (file)
@@ -80,8 +80,6 @@
 
 #include <asm/uaccess.h>
 
-#define __DQUOT_PARANOIA
-
 /*
  * There are three quota SMP locks. dq_list_lock protects all lists with quotas
  * and quota formats, dqstats structure containing statistics about the lists
@@ -695,7 +693,7 @@ void dqput(struct dquot *dquot)
 
        if (!dquot)
                return;
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        if (!atomic_read(&dquot->dq_count)) {
                printk("VFS: dqput: trying to free free dquot\n");
                printk("VFS: device %s, dquot of %s %d\n",
@@ -748,7 +746,7 @@ we_slept:
                goto we_slept;
        }
        atomic_dec(&dquot->dq_count);
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        /* sanity check */
        BUG_ON(!list_empty(&dquot->dq_free));
 #endif
@@ -845,7 +843,7 @@ we_slept:
                dquot = NULL;
                goto out;
        }
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        BUG_ON(!dquot->dq_sb);  /* Has somebody invalidated entry under us? */
 #endif
 out:
@@ -874,14 +872,18 @@ static int dqinit_needed(struct inode *inode, int type)
 static void add_dquot_ref(struct super_block *sb, int type)
 {
        struct inode *inode, *old_inode = NULL;
+#ifdef CONFIG_QUOTA_DEBUG
        int reserved = 0;
+#endif
 
        spin_lock(&inode_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
                if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
                        continue;
+#ifdef CONFIG_QUOTA_DEBUG
                if (unlikely(inode_get_rsv_space(inode) > 0))
                        reserved = 1;
+#endif
                if (!atomic_read(&inode->i_writecount))
                        continue;
                if (!dqinit_needed(inode, type))
@@ -903,11 +905,13 @@ static void add_dquot_ref(struct super_block *sb, int type)
        spin_unlock(&inode_lock);
        iput(old_inode);
 
+#ifdef CONFIG_QUOTA_DEBUG
        if (reserved) {
                printk(KERN_WARNING "VFS (%s): Writes happened before quota"
                        " was turned on thus quota information is probably "
                        "inconsistent. Please run quotacheck(8).\n", sb->s_id);
        }
+#endif
 }
 
 /*
@@ -934,7 +938,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
        inode->i_dquot[type] = NULL;
        if (dquot) {
                if (dqput_blocks(dquot)) {
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
                        if (atomic_read(&dquot->dq_count) != 1)
                                printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
 #endif
@@ -2322,34 +2326,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
        if (di->dqb_valid & QIF_SPACE) {
                dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_BLIMITS) {
                dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
                dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_INODES) {
                dm->dqb_curinodes = di->dqb_curinodes;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_ILIMITS) {
                dm->dqb_isoftlimit = di->dqb_isoftlimit;
                dm->dqb_ihardlimit = di->dqb_ihardlimit;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_BTIME) {
                dm->dqb_btime = di->dqb_btime;
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_ITIME) {
                dm->dqb_itime = di->dqb_itime;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
        }
 
        if (check_blim) {
index f8a6075..0793044 100644 (file)
@@ -46,8 +46,6 @@ static inline bool is_privroot_deh(struct dentry *dir,
                                   struct reiserfs_de_head *deh)
 {
        struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root;
-       if (reiserfs_expose_privroot(dir->d_sb))
-               return 0;
        return (dir == dir->d_parent && privroot->d_inode &&
                deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid);
 }
index 4f9586b..e7cc00e 100644 (file)
@@ -554,7 +554,7 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
        if (!err && new_size < i_size_read(dentry->d_inode)) {
                struct iattr newattrs = {
                        .ia_ctime = current_fs_time(inode->i_sb),
-                       .ia_size = buffer_size,
+                       .ia_size = new_size,
                        .ia_valid = ATTR_SIZE | ATTR_CTIME,
                };
 
@@ -973,21 +973,13 @@ int reiserfs_permission(struct inode *inode, int mask)
        return generic_permission(inode, mask, NULL);
 }
 
-/* This will catch lookups from the fs root to .reiserfs_priv */
-static int
-xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
+static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
-       struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
-       if (container_of(q1, struct dentry, d_name) == priv_root)
-               return -ENOENT;
-       if (q1->len == name->len &&
-                  !memcmp(q1->name, name->name, name->len))
-               return 0;
-       return 1;
+       return -EPERM;
 }
 
 static const struct dentry_operations xattr_lookup_poison_ops = {
-       .d_compare = xattr_lookup_poison,
+       .d_revalidate = xattr_hide_revalidate,
 };
 
 int reiserfs_lookup_privroot(struct super_block *s)
@@ -1001,8 +993,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
                                strlen(PRIVROOT_NAME));
        if (!IS_ERR(dentry)) {
                REISERFS_SB(s)->priv_root = dentry;
-               if (!reiserfs_expose_privroot(s))
-                       s->s_root->d_op = &xattr_lookup_poison_ops;
+               dentry->d_op = &xattr_lookup_poison_ops;
                if (dentry->d_inode)
                        dentry->d_inode->i_flags |= S_PRIVATE;
        } else
index 1c4c8f0..dfa1d67 100644 (file)
@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb)
        if (server->conn_pid)
                kill_pid(server->conn_pid, SIGTERM, 1);
 
+       bdi_destroy(&server->bdi);
        kfree(server->ops);
        smb_unload_nls(server);
        sb->s_fs_info = NULL;
@@ -525,6 +526,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
        if (!server)
                goto out_no_server;
        sb->s_fs_info = server;
+       
+       if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY))
+               goto out_bdi;
+
+       sb->s_bdi = &server->bdi;
 
        server->super_block = sb;
        server->mnt = NULL;
@@ -624,6 +630,8 @@ out_no_smbiod:
 out_bad_option:
        kfree(mem);
 out_no_mem:
+       bdi_destroy(&server->bdi);
+out_bdi:
        if (!server->mnt)
                printk(KERN_ERR "smb_fill_super: allocation failure\n");
        sb->s_fs_info = NULL;
index 1cb0d81..653c030 100644 (file)
@@ -87,9 +87,8 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index,
        u64 cur_index = index >> msblk->devblksize_log2;
        int bytes, compressed, b = 0, k = 0, page = 0, avail;
 
-
-       bh = kcalloc((msblk->block_size >> msblk->devblksize_log2) + 1,
-                               sizeof(*bh), GFP_KERNEL);
+       bh = kcalloc(((srclength + msblk->devblksize - 1)
+               >> msblk->devblksize_log2) + 1, sizeof(*bh), GFP_KERNEL);
        if (bh == NULL)
                return -ENOMEM;
 
index 3550aec..48b6f4a 100644 (file)
@@ -275,7 +275,8 @@ allocate_root:
 
        err = squashfs_read_inode(root, root_inode);
        if (err) {
-               iget_failed(root);
+               make_bad_inode(root);
+               iput(root);
                goto failed_mount;
        }
        insert_inode_hash(root);
@@ -353,6 +354,7 @@ static void squashfs_put_super(struct super_block *sb)
                kfree(sbi->id_table);
                kfree(sbi->fragment_index);
                kfree(sbi->meta_index);
+               kfree(sbi->inode_lookup_table);
                kfree(sb->s_fs_info);
                sb->s_fs_info = NULL;
        }
index 15a03d0..7a60387 100644 (file)
@@ -128,8 +128,9 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
                goto release_mutex;
        }
 
+       length = stream->total_out;
        mutex_unlock(&msblk->read_data_mutex);
-       return stream->total_out;
+       return length;
 
 release_mutex:
        mutex_unlock(&msblk->read_data_mutex);
index f35ac60..1527e6a 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/kobject.h>
 #include <linux/mutex.h>
 #include <linux/file.h>
+#include <linux/backing-dev.h>
 #include <asm/uaccess.h>
 #include "internal.h"
 
@@ -693,6 +694,7 @@ int set_anon_super(struct super_block *s, void *data)
                return -EMFILE;
        }
        s->s_dev = MKDEV(0, dev & MINORMASK);
+       s->s_bdi = &noop_backing_dev_info;
        return 0;
 }
 
@@ -954,10 +956,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
        if (error < 0)
                goto out_free_secdata;
        BUG_ON(!mnt->mnt_sb);
+       WARN_ON(!mnt->mnt_sb->s_bdi);
 
-       error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
-       if (error)
-               goto out_sb;
+       error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
+       if (error)
+               goto out_sb;
 
        /*
         * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE
index fc5c3d7..92b2281 100644 (file)
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -14,6 +14,7 @@
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
+#include <linux/backing-dev.h>
 #include "internal.h"
 
 #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
@@ -32,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
         * This should be safe, as we require bdi backing to actually
         * write out data in the first place
         */
-       if (!sb->s_bdi)
+       if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
                return 0;
 
        if (sb->s_qcop && sb->s_qcop->quota_sync)
index 4e50286..1dabed2 100644 (file)
@@ -164,8 +164,8 @@ struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct page **res_
                                                        name, de->name))
                                        goto found;
                        }
+                       dir_put_page(page);
                }
-               dir_put_page(page);
 
                if (++n >= npages)
                        n = 0;
index 19626e2..9a9378b 100644 (file)
@@ -125,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-       if (bloc->logicalBlockNum < 0 ||
-           (bloc->logicalBlockNum + count) >
-               partmap->s_partition_len) {
+       if (bloc->logicalBlockNum + count < count ||
+           (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
                udf_debug("%d < %d || %d + %d > %d\n",
                          bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
                          count, partmap->s_partition_len);
@@ -393,9 +392,8 @@ static void udf_table_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-       if (bloc->logicalBlockNum < 0 ||
-           (bloc->logicalBlockNum + count) >
-               partmap->s_partition_len) {
+       if (bloc->logicalBlockNum + count < count ||
+           (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
                udf_debug("%d < %d || %d + %d > %d\n",
                          bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count,
                          partmap->s_partition_len);
index 1eb0677..4b6a46c 100644 (file)
@@ -218,7 +218,7 @@ const struct file_operations udf_file_operations = {
        .llseek                 = generic_file_llseek,
 };
 
-static int udf_setattr(struct dentry *dentry, struct iattr *iattr)
+int udf_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        struct inode *inode = dentry->d_inode;
        int error;
index bb863fe..8a3fbd1 100644 (file)
@@ -1314,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                break;
        case ICBTAG_FILE_TYPE_SYMLINK:
                inode->i_data.a_ops = &udf_symlink_aops;
-               inode->i_op = &page_symlink_inode_operations;
+               inode->i_op = &udf_symlink_inode_operations;
                inode->i_mode = S_IFLNK | S_IRWXUGO;
                break;
        case ICBTAG_FILE_TYPE_MAIN:
index db423ab..7581602 100644 (file)
@@ -925,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        iinfo = UDF_I(inode);
        inode->i_mode = S_IFLNK | S_IRWXUGO;
        inode->i_data.a_ops = &udf_symlink_aops;
-       inode->i_op = &page_symlink_inode_operations;
+       inode->i_op = &udf_symlink_inode_operations;
 
        if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
                struct kernel_lb_addr eloc;
@@ -1393,6 +1393,7 @@ const struct export_operations udf_export_ops = {
 const struct inode_operations udf_dir_inode_operations = {
        .lookup                         = udf_lookup,
        .create                         = udf_create,
+       .setattr                        = udf_setattr,
        .link                           = udf_link,
        .unlink                         = udf_unlink,
        .symlink                        = udf_symlink,
@@ -1401,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = {
        .mknod                          = udf_mknod,
        .rename                         = udf_rename,
 };
+const struct inode_operations udf_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+       .setattr        = udf_setattr,
+};
index 4223ac8..702a114 100644 (file)
@@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations;
 extern const struct file_operations udf_dir_operations;
 extern const struct inode_operations udf_file_inode_operations;
 extern const struct file_operations udf_file_operations;
+extern const struct inode_operations udf_symlink_inode_operations;
 extern const struct address_space_operations udf_aops;
 extern const struct address_space_operations udf_adinicb_aops;
 extern const struct address_space_operations udf_symlink_aops;
@@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
 /* file.c */
 extern int udf_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
-
+extern int udf_setattr(struct dentry *dentry, struct iattr *iattr);
 /* inode.c */
 extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
 extern int udf_sync_inode(struct inode *);
index 52e06b4..29f1edc 100644 (file)
@@ -1209,6 +1209,7 @@ xfs_fs_put_super(
 
        xfs_unmountfs(mp);
        xfs_freesb(mp);
+       xfs_inode_shrinker_unregister(mp);
        xfs_icsb_destroy_counters(mp);
        xfs_close_devices(mp);
        xfs_dmops_put(mp);
@@ -1622,6 +1623,8 @@ xfs_fs_fill_super(
        if (error)
                goto fail_vnrele;
 
+       xfs_inode_shrinker_register(mp);
+
        kfree(mtpt);
        return 0;
 
@@ -1867,6 +1870,7 @@ init_xfs_fs(void)
                goto out_cleanup_procfs;
 
        vfs_initquota();
+       xfs_inode_shrinker_init();
 
        error = register_filesystem(&xfs_fs_type);
        if (error)
@@ -1894,6 +1898,7 @@ exit_xfs_fs(void)
 {
        vfs_exitquota();
        unregister_filesystem(&xfs_fs_type);
+       xfs_inode_shrinker_destroy();
        xfs_sysctl_unregister();
        xfs_cleanup_procfs();
        xfs_buf_terminate();
index 05cd853..a427c63 100644 (file)
@@ -95,7 +95,8 @@ xfs_inode_ag_walk(
                                           struct xfs_perag *pag, int flags),
        int                     flags,
        int                     tag,
-       int                     exclusive)
+       int                     exclusive,
+       int                     *nr_to_scan)
 {
        uint32_t                first_index;
        int                     last_error = 0;
@@ -134,7 +135,7 @@ restart:
                if (error == EFSCORRUPTED)
                        break;
 
-       } while (1);
+       } while ((*nr_to_scan)--);
 
        if (skipped) {
                delay(1);
@@ -150,12 +151,15 @@ xfs_inode_ag_iterator(
                                           struct xfs_perag *pag, int flags),
        int                     flags,
        int                     tag,
-       int                     exclusive)
+       int                     exclusive,
+       int                     *nr_to_scan)
 {
        int                     error = 0;
        int                     last_error = 0;
        xfs_agnumber_t          ag;
+       int                     nr;
 
+       nr = nr_to_scan ? *nr_to_scan : INT_MAX;
        for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
                struct xfs_perag        *pag;
 
@@ -165,14 +169,18 @@ xfs_inode_ag_iterator(
                        continue;
                }
                error = xfs_inode_ag_walk(mp, pag, execute, flags, tag,
-                                               exclusive);
+                                               exclusive, &nr);
                xfs_perag_put(pag);
                if (error) {
                        last_error = error;
                        if (error == EFSCORRUPTED)
                                break;
                }
+               if (nr <= 0)
+                       break;
        }
+       if (nr_to_scan)
+               *nr_to_scan = nr;
        return XFS_ERROR(last_error);
 }
 
@@ -291,7 +299,7 @@ xfs_sync_data(
        ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
 
        error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags,
-                                     XFS_ICI_NO_TAG, 0);
+                                     XFS_ICI_NO_TAG, 0, NULL);
        if (error)
                return XFS_ERROR(error);
 
@@ -310,7 +318,7 @@ xfs_sync_attr(
        ASSERT((flags & ~SYNC_WAIT) == 0);
 
        return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags,
-                                    XFS_ICI_NO_TAG, 0);
+                                    XFS_ICI_NO_TAG, 0, NULL);
 }
 
 STATIC int
@@ -673,6 +681,7 @@ __xfs_inode_set_reclaim_tag(
        radix_tree_tag_set(&pag->pag_ici_root,
                           XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
                           XFS_ICI_RECLAIM_TAG);
+       pag->pag_ici_reclaimable++;
 }
 
 /*
@@ -705,6 +714,7 @@ __xfs_inode_clear_reclaim_tag(
 {
        radix_tree_tag_clear(&pag->pag_ici_root,
                        XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
+       pag->pag_ici_reclaimable--;
 }
 
 /*
@@ -820,10 +830,10 @@ xfs_reclaim_inode(
         * call into reclaim to find it in a clean state instead of waiting for
         * it now. We also don't return errors here - if the error is transient
         * then the next reclaim pass will flush the inode, and if the error
-        * is permanent then the next sync reclaim will relcaim the inode and
+        * is permanent then the next sync reclaim will reclaim the inode and
         * pass on the error.
         */
-       if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+       if (error && error != EAGAIN && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                        "inode 0x%llx background reclaim flush failed with %d",
                        (long long)ip->i_ino, error);
@@ -854,5 +864,93 @@ xfs_reclaim_inodes(
        int             mode)
 {
        return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode,
-                                       XFS_ICI_RECLAIM_TAG, 1);
+                                       XFS_ICI_RECLAIM_TAG, 1, NULL);
+}
+
+/*
+ * Shrinker infrastructure.
+ *
+ * This is all far more complex than it needs to be. It adds a global list of
+ * mounts because the shrinkers can only call a global context. We need to make
+ * the shrinkers pass a context to avoid the need for global state.
+ */
+static LIST_HEAD(xfs_mount_list);
+static struct rw_semaphore xfs_mount_list_lock;
+
+static int
+xfs_reclaim_inode_shrink(
+       int             nr_to_scan,
+       gfp_t           gfp_mask)
+{
+       struct xfs_mount *mp;
+       struct xfs_perag *pag;
+       xfs_agnumber_t  ag;
+       int             reclaimable = 0;
+
+       if (nr_to_scan) {
+               if (!(gfp_mask & __GFP_FS))
+                       return -1;
+
+               down_read(&xfs_mount_list_lock);
+               list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
+                       xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0,
+                                       XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan);
+                       if (nr_to_scan <= 0)
+                               break;
+               }
+               up_read(&xfs_mount_list_lock);
+       }
+
+       down_read(&xfs_mount_list_lock);
+       list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
+               for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
+
+                       pag = xfs_perag_get(mp, ag);
+                       if (!pag->pag_ici_init) {
+                               xfs_perag_put(pag);
+                               continue;
+                       }
+                       reclaimable += pag->pag_ici_reclaimable;
+                       xfs_perag_put(pag);
+               }
+       }
+       up_read(&xfs_mount_list_lock);
+       return reclaimable;
+}
+
+static struct shrinker xfs_inode_shrinker = {
+       .shrink = xfs_reclaim_inode_shrink,
+       .seeks = DEFAULT_SEEKS,
+};
+
+void __init
+xfs_inode_shrinker_init(void)
+{
+       init_rwsem(&xfs_mount_list_lock);
+       register_shrinker(&xfs_inode_shrinker);
+}
+
+void
+xfs_inode_shrinker_destroy(void)
+{
+       ASSERT(list_empty(&xfs_mount_list));
+       unregister_shrinker(&xfs_inode_shrinker);
+}
+
+void
+xfs_inode_shrinker_register(
+       struct xfs_mount        *mp)
+{
+       down_write(&xfs_mount_list_lock);
+       list_add_tail(&mp->m_mplist, &xfs_mount_list);
+       up_write(&xfs_mount_list_lock);
+}
+
+void
+xfs_inode_shrinker_unregister(
+       struct xfs_mount        *mp)
+{
+       down_write(&xfs_mount_list_lock);
+       list_del(&mp->m_mplist);
+       up_write(&xfs_mount_list_lock);
 }
index d480c34..cdcbaac 100644 (file)
@@ -53,6 +53,11 @@ void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
 int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag);
 int xfs_inode_ag_iterator(struct xfs_mount *mp,
        int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
-       int flags, int tag, int write_lock);
+       int flags, int tag, int write_lock, int *nr_to_scan);
+
+void xfs_inode_shrinker_init(void);
+void xfs_inode_shrinker_destroy(void);
+void xfs_inode_shrinker_register(struct xfs_mount *mp);
+void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
 
 #endif
index 5d0ee8d..50bee07 100644 (file)
@@ -891,7 +891,8 @@ xfs_qm_dqrele_all_inodes(
        uint             flags)
 {
        ASSERT(mp->m_quotainfo);
-       xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0);
+       xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags,
+                               XFS_ICI_NO_TAG, 0, NULL);
 }
 
 /*------------------------------------------------------------------------*/
index b1a5a1f..abb8222 100644 (file)
@@ -223,6 +223,7 @@ typedef struct xfs_perag {
        int             pag_ici_init;   /* incore inode cache initialised */
        rwlock_t        pag_ici_lock;   /* incore inode lock */
        struct radix_tree_root pag_ici_root;    /* incore inode cache root */
+       int             pag_ici_reclaimable;    /* reclaimable inodes */
 #endif
        int             pagb_count;     /* pagb slots in use */
        xfs_perag_busy_t pagb_list[XFS_PAGB_NUM_SLOTS]; /* unstable blocks */
index cd27c9d..5bba29a 100644 (file)
@@ -177,16 +177,26 @@ xfs_swap_extents_check_format(
            XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > tip->i_df.if_ext_max)
                return EINVAL;
 
-       /* Check root block of temp in btree form to max in target */
+       /*
+        * If we are in a btree format, check that the temp root block will fit
+        * in the target and that it has enough extents to be in btree format
+        * in the target.
+        *
+        * Note that we have to be careful to allow btree->extent conversions
+        * (a common defrag case) which will occur when the temp inode is in
+        * extent format...
+        */
        if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
-           XFS_IFORK_BOFF(ip) &&
-           tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip))
+           ((XFS_IFORK_BOFF(ip) &&
+             tip->i_df.if_broot_bytes > XFS_IFORK_BOFF(ip)) ||
+            XFS_IFORK_NEXTENTS(tip, XFS_DATA_FORK) <= ip->i_df.if_ext_max))
                return EINVAL;
 
-       /* Check root block of target in btree form to max in temp */
+       /* Reciprocal target->temp btree format checks */
        if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE &&
-           XFS_IFORK_BOFF(tip) &&
-           ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip))
+           ((XFS_IFORK_BOFF(tip) &&
+             ip->i_df.if_broot_bytes > XFS_IFORK_BOFF(tip)) ||
+            XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) <= tip->i_df.if_ext_max))
                return EINVAL;
 
        return 0;
index e8fba92..2be0191 100644 (file)
@@ -745,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t      *mp,
 
 /*
  * Determine if we have a transaction that has gone to disk
- * that needs to be covered. Log activity needs to be idle (no AIL and
- * nothing in the iclogs). And, we need to be in the right state indicating
- * something has gone out.
+ * that needs to be covered. To begin the transition to the idle state
+ * firstly the log needs to be idle (no AIL and nothing in the iclogs).
+ * If we are then in a state where covering is needed, the caller is informed
+ * that dummy transactions are required to move the log into the idle state.
+ *
+ * Because this is called as part of the sync process, we should also indicate
+ * that dummy transactions should be issued in anything but the covered or
+ * idle states. This ensures that the log tail is accurately reflected in
+ * the log at the end of the sync, hence if a crash occurrs avoids replay
+ * of transactions where the metadata is already on disk.
  */
 int
 xfs_log_need_covered(xfs_mount_t *mp)
@@ -759,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp)
                return 0;
 
        spin_lock(&log->l_icloglock);
-       if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
-               (log->l_covered_state == XLOG_STATE_COVER_NEED2))
-                       && !xfs_trans_ail_tail(log->l_ailp)
-                       && xlog_iclogs_empty(log)) {
-               if (log->l_covered_state == XLOG_STATE_COVER_NEED)
-                       log->l_covered_state = XLOG_STATE_COVER_DONE;
-               else {
-                       ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2);
-                       log->l_covered_state = XLOG_STATE_COVER_DONE2;
+       switch (log->l_covered_state) {
+       case XLOG_STATE_COVER_DONE:
+       case XLOG_STATE_COVER_DONE2:
+       case XLOG_STATE_COVER_IDLE:
+               break;
+       case XLOG_STATE_COVER_NEED:
+       case XLOG_STATE_COVER_NEED2:
+               if (!xfs_trans_ail_tail(log->l_ailp) &&
+                   xlog_iclogs_empty(log)) {
+                       if (log->l_covered_state == XLOG_STATE_COVER_NEED)
+                               log->l_covered_state = XLOG_STATE_COVER_DONE;
+                       else
+                               log->l_covered_state = XLOG_STATE_COVER_DONE2;
                }
+               /* FALLTHRU */
+       default:
                needed = 1;
+               break;
        }
        spin_unlock(&log->l_icloglock);
        return needed;
index 4fa0bc7..9ff48a1 100644 (file)
@@ -259,6 +259,7 @@ typedef struct xfs_mount {
        wait_queue_head_t       m_wait_single_sync_task;
        __int64_t               m_update_flags; /* sb flags we need to update
                                                   on the next remount,rw */
+       struct list_head        m_mplist;       /* inode shrinker mount list */
 } xfs_mount_t;
 
 /*
index c99c64d..c33749f 100644 (file)
@@ -33,7 +33,7 @@
  * Atomically reads the value of @v.  Note that the guaranteed
  * useful range of an atomic_t is only 24 bits.
  */
-#define atomic_read(v) ((v)->counter)
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
 
 /**
  * atomic_set - set atomic variable
diff --git a/include/asm-generic/bitops/arch_hweight.h b/include/asm-generic/bitops/arch_hweight.h
new file mode 100644 (file)
index 0000000..6a211f4
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_
+
+#include <asm/types.h>
+
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+       return __sw_hweight32(w);
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+       return __sw_hweight16(w);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+       return __sw_hweight8(w);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+       return __sw_hweight64(w);
+}
+#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
diff --git a/include/asm-generic/bitops/const_hweight.h b/include/asm-generic/bitops/const_hweight.h
new file mode 100644 (file)
index 0000000..fa2a50b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_
+
+/*
+ * Compile time versions of __arch_hweightN()
+ */
+#define __const_hweight8(w)            \
+      (        (!!((w) & (1ULL << 0))) +       \
+       (!!((w) & (1ULL << 1))) +       \
+       (!!((w) & (1ULL << 2))) +       \
+       (!!((w) & (1ULL << 3))) +       \
+       (!!((w) & (1ULL << 4))) +       \
+       (!!((w) & (1ULL << 5))) +       \
+       (!!((w) & (1ULL << 6))) +       \
+       (!!((w) & (1ULL << 7))) )
+
+#define __const_hweight16(w) (__const_hweight8(w)  + __const_hweight8((w)  >> 8 ))
+#define __const_hweight32(w) (__const_hweight16(w) + __const_hweight16((w) >> 16))
+#define __const_hweight64(w) (__const_hweight32(w) + __const_hweight32((w) >> 32))
+
+/*
+ * Generic interface.
+ */
+#define hweight8(w)  (__builtin_constant_p(w) ? __const_hweight8(w)  : __arch_hweight8(w))
+#define hweight16(w) (__builtin_constant_p(w) ? __const_hweight16(w) : __arch_hweight16(w))
+#define hweight32(w) (__builtin_constant_p(w) ? __const_hweight32(w) : __arch_hweight32(w))
+#define hweight64(w) (__builtin_constant_p(w) ? __const_hweight64(w) : __arch_hweight64(w))
+
+/*
+ * Interface for known constant arguments
+ */
+#define HWEIGHT8(w)  (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight8(w))
+#define HWEIGHT16(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight16(w))
+#define HWEIGHT32(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight32(w))
+#define HWEIGHT64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_hweight64(w))
+
+/*
+ * Type invariant interface to the compile time constant hweight functions.
+ */
+#define HWEIGHT(w)   HWEIGHT64((u64)w)
+
+#endif /* _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ */
index fbbc383..a94d651 100644 (file)
@@ -1,11 +1,7 @@
 #ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
 #define _ASM_GENERIC_BITOPS_HWEIGHT_H_
 
-#include <asm/types.h>
-
-extern unsigned int hweight32(unsigned int w);
-extern unsigned int hweight16(unsigned int w);
-extern unsigned int hweight8(unsigned int w);
-extern unsigned long hweight64(__u64 w);
+#include <asm-generic/bitops/arch_hweight.h>
+#include <asm-generic/bitops/const_hweight.h>
 
 #endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
index e694263..6920695 100644 (file)
@@ -131,7 +131,7 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev,
                debug_dma_sync_single_range_for_cpu(dev, addr, offset, size, dir);
 
        } else
-               dma_sync_single_for_cpu(dev, addr, size, dir);
+               dma_sync_single_for_cpu(dev, addr + offset, size, dir);
 }
 
 static inline void dma_sync_single_range_for_device(struct device *dev,
@@ -148,7 +148,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev,
                debug_dma_sync_single_range_for_device(dev, addr, offset, size, dir);
 
        } else
-               dma_sync_single_for_device(dev, addr, size, dir);
+               dma_sync_single_for_device(dev, addr + offset, size, dir);
 }
 
 static inline void
index 04a6ebc..2d428b0 100644 (file)
@@ -6,6 +6,7 @@
        {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
index e929c27..6b9db91 100644 (file)
@@ -789,34 +789,6 @@ extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
 extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo,
                                  bool interruptible);
 
-/**
- * ttm_bo_block_reservation
- *
- * @bo: A pointer to a struct ttm_buffer_object.
- * @interruptible: Use interruptible sleep when waiting.
- * @no_wait: Don't sleep, but rather return -EBUSY.
- *
- * Block reservation for validation by simply reserving the buffer.
- * This is intended for single buffer use only without eviction,
- * and thus needs no deadlock protection.
- *
- * Returns:
- * -EBUSY: If no_wait == 1 and the buffer is already reserved.
- * -ERESTARTSYS: If interruptible == 1 and the process received a signal
- * while sleeping.
- */
-extern int ttm_bo_block_reservation(struct ttm_buffer_object *bo,
-                                   bool interruptible, bool no_wait);
-
-/**
- * ttm_bo_unblock_reservation
- *
- * @bo: A pointer to a struct ttm_buffer_object.
- *
- * Unblocks reservation leaving lru lists untouched.
- */
-extern void ttm_bo_unblock_reservation(struct ttm_buffer_object *bo);
-
 /*
  * ttm_bo_util.c
  */
index b926afe..3da73f5 100644 (file)
@@ -116,11 +116,12 @@ extern unsigned long acpi_realmode_flags;
 
 int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
 
 #ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
 #else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
 #endif
 /*
  * This function undoes the effect of one call to acpi_register_gsi().
index 6b42417..7e466fe 100644 (file)
@@ -6,8 +6,29 @@
 
 #include <linux/mmc/host.h>
 
+/**
+ * struct mmci_platform_data - platform configuration for the MMCI
+ * (also known as PL180) block.
+ * @f_max: the maximum operational frequency for this host in this
+ * platform configuration. When this is specified it takes precedence
+ * over the module parameter for the same frequency.
+ * @ocr_mask: available voltages on the 4 pins from the block, this
+ * is ignored if a regulator is used, see the MMC_VDD_* masks in
+ * mmc/host.h
+ * @translate_vdd: a callback function to translate a MMC_VDD_*
+ * mask into a value to be binary or:ed and written into the
+ * MMCIPWR register of the block
+ * @status: if no GPIO read function was given to the block in
+ * gpio_wp (below) this function will be called to determine
+ * whether a card is present in the MMC slot or not
+ * @gpio_wp: read this GPIO pin to see if the card is write protected
+ * @gpio_cd: read this GPIO pin to detect card insertion
+ * @capabilities: the capabilities of the block as implemented in
+ * this platform, signify anything MMC_CAP_* from mmc/host.h
+ */
 struct mmci_platform_data {
-       unsigned int ocr_mask;                  /* available voltages */
+       unsigned int f_max;
+       unsigned int ocr_mask;
        u32 (*translate_vdd)(struct device *, unsigned int);
        unsigned int (*status)(struct device *);
        int     gpio_wp;
index fcbc26a..bd0e3c6 100644 (file)
@@ -101,6 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
                const char *fmt, ...);
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
 void bdi_unregister(struct backing_dev_info *bdi);
+int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
 void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
                                long nr_pages);
 int bdi_writeback_task(struct bdi_writeback *wb);
@@ -246,6 +247,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
 #endif
 
 extern struct backing_dev_info default_backing_dev_info;
+extern struct backing_dev_info noop_backing_dev_info;
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
 
 int writeback_in_progress(struct backing_dev_info *bdi);
index b796eab..fc68053 100644 (file)
 #define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 #endif
 
+extern unsigned int __sw_hweight8(unsigned int w);
+extern unsigned int __sw_hweight16(unsigned int w);
+extern unsigned int __sw_hweight32(unsigned int w);
+extern unsigned long __sw_hweight64(__u64 w);
+
 /*
  * Include this here because some architectures need generic_ffs/fls in
  * scope
@@ -44,31 +49,6 @@ static inline unsigned long hweight_long(unsigned long w)
        return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
 }
 
-/*
- * Clearly slow versions of the hweightN() functions, their benefit is
- * of course compile time evaluation of constant arguments.
- */
-#define HWEIGHT8(w)                                    \
-      (        BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) +   \
-       (!!((w) & (1ULL << 0))) +                       \
-       (!!((w) & (1ULL << 1))) +                       \
-       (!!((w) & (1ULL << 2))) +                       \
-       (!!((w) & (1ULL << 3))) +                       \
-       (!!((w) & (1ULL << 4))) +                       \
-       (!!((w) & (1ULL << 5))) +                       \
-       (!!((w) & (1ULL << 6))) +                       \
-       (!!((w) & (1ULL << 7))) )
-
-#define HWEIGHT16(w) (HWEIGHT8(w)  + HWEIGHT8((w) >> 8))
-#define HWEIGHT32(w) (HWEIGHT16(w) + HWEIGHT16((w) >> 16))
-#define HWEIGHT64(w) (HWEIGHT32(w) + HWEIGHT32((w) >> 32))
-
-/*
- * Type invariant version that simply casts things to the
- * largest type.
- */
-#define HWEIGHT(w)   HWEIGHT64((u64)(w))
-
 /**
  * rol32 - rotate a 32-bit value left
  * @word: value to rotate
index b8ad1ea..8f78073 100644 (file)
@@ -530,6 +530,7 @@ static inline struct cgroup_subsys_state *task_subsys_state(
 {
        return rcu_dereference_check(task->cgroups->subsys[subsys_id],
                                     rcu_read_lock_held() ||
+                                    lockdep_is_held(&task->alloc_lock) ||
                                     cgroup_lock_is_held());
 }
 
index 4bca8b6..5ea3c60 100644 (file)
@@ -273,7 +273,6 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
 }
 
 
-/* used to install a new clocksource */
 extern int clocksource_register(struct clocksource*);
 extern void clocksource_unregister(struct clocksource*);
 extern void clocksource_touch_watchdog(void);
@@ -287,6 +286,24 @@ extern void clocksource_mark_unstable(struct clocksource *cs);
 extern void
 clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
 
+/*
+ * Don't call __clocksource_register_scale directly, use
+ * clocksource_register_hz/khz
+ */
+extern int
+__clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
+
+static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
+{
+       return __clocksource_register_scale(cs, 1, hz);
+}
+
+static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
+{
+       return __clocksource_register_scale(cs, 1000, khz);
+}
+
+
 static inline void
 clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
 {
index 5b5d473..8859e2e 100644 (file)
@@ -7,6 +7,8 @@
 #define MAX_CODADEVS  5           /* how many do we allow */
 
 #ifdef __KERNEL__
+#include <linux/backing-dev.h>
+
 struct kstatfs;
 
 /* communication pending/processing queues */
@@ -17,6 +19,7 @@ struct venus_comm {
        struct list_head    vc_processing;
        int                 vc_inuse;
        struct super_block *vc_sb;
+       struct backing_dev_info bdi;
 };
 
 
index 4de02b1..9f15150 100644 (file)
@@ -278,6 +278,27 @@ struct freq_attr {
        ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
 };
 
+#define cpufreq_freq_attr_ro(_name)            \
+static struct freq_attr _name =                        \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+#define cpufreq_freq_attr_ro_perm(_name, _perm)        \
+static struct freq_attr _name =                        \
+__ATTR(_name, _perm, show_##_name, NULL)
+
+#define cpufreq_freq_attr_ro_old(_name)                \
+static struct freq_attr _name##_old =          \
+__ATTR(_name, 0444, show_##_name##_old, NULL)
+
+#define cpufreq_freq_attr_rw(_name)            \
+static struct freq_attr _name =                        \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+#define cpufreq_freq_attr_rw_old(_name)                \
+static struct freq_attr _name##_old =          \
+__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
+
+
 struct global_attr {
        struct attribute attr;
        ssize_t (*show)(struct kobject *kobj,
@@ -286,6 +307,15 @@ struct global_attr {
                         const char *c, size_t count);
 };
 
+#define define_one_global_ro(_name)            \
+static struct global_attr _name =              \
+__ATTR(_name, 0444, show_##_name, NULL)
+
+#define define_one_global_rw(_name)            \
+static struct global_attr _name =              \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+
 /*********************************************************************
  *                        CPUFREQ 2.6. INTERFACE                     *
  *********************************************************************/
index a5740fc..a73454a 100644 (file)
@@ -21,8 +21,7 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
 extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask);
-extern void cpuset_cpus_allowed_locked(struct task_struct *p,
-                                      struct cpumask *mask);
+extern int cpuset_cpus_allowed_fallback(struct task_struct *p);
 extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
 #define cpuset_current_mems_allowed (current->mems_allowed)
 void cpuset_init_current_mems_allowed(void);
@@ -69,9 +68,6 @@ struct seq_file;
 extern void cpuset_task_status_allowed(struct seq_file *m,
                                        struct task_struct *task);
 
-extern void cpuset_lock(void);
-extern void cpuset_unlock(void);
-
 extern int cpuset_mem_spread_node(void);
 
 static inline int cpuset_do_page_mem_spread(void)
@@ -105,10 +101,11 @@ static inline void cpuset_cpus_allowed(struct task_struct *p,
 {
        cpumask_copy(mask, cpu_possible_mask);
 }
-static inline void cpuset_cpus_allowed_locked(struct task_struct *p,
-                                             struct cpumask *mask)
+
+static inline int cpuset_cpus_allowed_fallback(struct task_struct *p)
 {
-       cpumask_copy(mask, cpu_possible_mask);
+       cpumask_copy(&p->cpus_allowed, cpu_possible_mask);
+       return cpumask_any(cpu_active_mask);
 }
 
 static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
@@ -157,9 +154,6 @@ static inline void cpuset_task_status_allowed(struct seq_file *m,
 {
 }
 
-static inline void cpuset_lock(void) {}
-static inline void cpuset_unlock(void) {}
-
 static inline int cpuset_mem_spread_node(void)
 {
        return 0;
index 30b93b2..eebb617 100644 (file)
@@ -186,6 +186,8 @@ d_iput:             no              no              no       yes
 
 #define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 /* Parent inode is watched by some fsnotify listener */
 
+#define DCACHE_CANT_MOUNT      0x0100
+
 extern spinlock_t dcache_lock;
 extern seqlock_t rename_lock;
 
@@ -358,6 +360,18 @@ static inline int d_unlinked(struct dentry *dentry)
        return d_unhashed(dentry) && !IS_ROOT(dentry);
 }
 
+static inline int cant_mount(struct dentry *dentry)
+{
+       return (dentry->d_flags & DCACHE_CANT_MOUNT);
+}
+
+static inline void dont_mount(struct dentry *dentry)
+{
+       spin_lock(&dentry->d_lock);
+       dentry->d_flags |= DCACHE_CANT_MOUNT;
+       spin_unlock(&dentry->d_lock);
+}
+
 static inline struct dentry *dget_parent(struct dentry *dentry)
 {
        struct dentry *ret;
index 8c243aa..597692f 100644 (file)
@@ -20,12 +20,14 @@ struct debug_obj_descr;
  * struct debug_obj - representaion of an tracked object
  * @node:      hlist node to link the object into the tracker list
  * @state:     tracked object state
+ * @astate:    current active state
  * @object:    pointer to the real object
  * @descr:     pointer to an object type specific debug description structure
  */
 struct debug_obj {
        struct hlist_node       node;
        enum debug_obj_state    state;
+       unsigned int            astate;
        void                    *object;
        struct debug_obj_descr  *descr;
 };
@@ -60,6 +62,15 @@ extern void debug_object_deactivate(void *addr, struct debug_obj_descr *descr);
 extern void debug_object_destroy   (void *addr, struct debug_obj_descr *descr);
 extern void debug_object_free      (void *addr, struct debug_obj_descr *descr);
 
+/*
+ * Active state:
+ * - Set at 0 upon initialization.
+ * - Must return to 0 before deactivation.
+ */
+extern void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+                         unsigned int expect, unsigned int next);
+
 extern void debug_objects_early_init(void);
 extern void debug_objects_mem_init(void);
 #else
index 1821928..241b96b 100644 (file)
@@ -451,6 +451,10 @@ struct device {
 
 static inline const char *dev_name(const struct device *dev)
 {
+       /* Use the init name until the kobject becomes available */
+       if (dev->init_name)
+               return dev->init_name;
+
        return kobject_name(&dev->kobj);
 }
 
index 5978584..4d60801 100644 (file)
@@ -394,6 +394,7 @@ typedef struct elf64_shdr {
 #define NT_S390_TODPREG        0x303           /* s390 TOD programmable register */
 #define NT_S390_CTRS   0x304           /* s390 control registers */
 #define NT_S390_PREFIX 0x305           /* s390 prefix register */
+#define NT_S390_LAST_BREAK     0x306   /* s390 breaking event address */
 
 
 /* Note header in a PT_NOTE section */
index 40b1101..68f883b 100644 (file)
@@ -1,21 +1,26 @@
 /*
  * Char device interface.
  *
- * Copyright (C) 2005-2006  Kristian Hoegsberg <krh@bitplanet.net>
- *
- * 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.
+ * Copyright (C) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  */
 
 #ifndef _LINUX_FIREWIRE_CDEV_H
@@ -438,7 +443,7 @@ struct fw_cdev_remove_descriptor {
  * @type:      %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE
  * @header_size: Header size to strip for receive contexts
  * @channel:   Channel to bind to
- * @speed:     Speed to transmit at
+ * @speed:     Speed for transmit contexts
  * @closure:   To be returned in &fw_cdev_event_iso_interrupt
  * @handle:    Handle to context, written back by kernel
  *
@@ -451,6 +456,9 @@ struct fw_cdev_remove_descriptor {
  * If a context was successfully created, the kernel writes back a handle to the
  * context, which must be passed in for subsequent operations on that context.
  *
+ * For receive contexts, @header_size must be at least 4 and must be a multiple
+ * of 4.
+ *
  * Note that the effect of a @header_size > 4 depends on
  * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt.
  */
@@ -481,10 +489,34 @@ struct fw_cdev_create_iso_context {
  *
  * &struct fw_cdev_iso_packet is used to describe isochronous packet queues.
  *
- * Use the FW_CDEV_ISO_ macros to fill in @control.  The sy and tag fields are
- * specified by IEEE 1394a and IEC 61883.
- *
- * FIXME - finish this documentation
+ * Use the FW_CDEV_ISO_ macros to fill in @control.
+ *
+ * For transmit packets, the header length must be a multiple of 4 and specifies
+ * the numbers of bytes in @header that will be prepended to the packet's
+ * payload; these bytes are copied into the kernel and will not be accessed
+ * after the ioctl has returned.  The sy and tag fields are copied to the iso
+ * packet header (these fields are specified by IEEE 1394a and IEC 61883-1).
+ * The skip flag specifies that no packet is to be sent in a frame; when using
+ * this, all other fields except the interrupt flag must be zero.
+ *
+ * For receive packets, the header length must be a multiple of the context's
+ * header size; if the header length is larger than the context's header size,
+ * multiple packets are queued for this entry.  The sy and tag fields are
+ * ignored.  If the sync flag is set, the context drops all packets until
+ * a packet with a matching sy field is received (the sync value to wait for is
+ * specified in the &fw_cdev_start_iso structure).  The payload length defines
+ * how many payload bytes can be received for one packet (in addition to payload
+ * quadlets that have been defined as headers and are stripped and returned in
+ * the &fw_cdev_event_iso_interrupt structure).  If more bytes are received, the
+ * additional bytes are dropped.  If less bytes are received, the remaining
+ * bytes in this part of the payload buffer will not be written to, not even by
+ * the next packet, i.e., packets received in consecutive frames will not
+ * necessarily be consecutive in memory.  If an entry has queued multiple
+ * packets, the payload length is divided equally among them.
+ *
+ * When a packet with the interrupt flag set has been completed, the
+ * &fw_cdev_event_iso_interrupt event will be sent.  An entry that has queued
+ * multiple receive packets is completed when its last packet is completed.
  */
 struct fw_cdev_iso_packet {
        __u32 control;
@@ -501,7 +533,7 @@ struct fw_cdev_iso_packet {
  * Queue a number of isochronous packets for reception or transmission.
  * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs,
  * which describe how to transmit from or receive into a contiguous region
- * of a mmap()'ed payload buffer.  As part of the packet descriptors,
+ * of a mmap()'ed payload buffer.  As part of transmit packet descriptors,
  * a series of headers can be supplied, which will be prepended to the
  * payload during DMA.
  *
@@ -620,8 +652,8 @@ struct fw_cdev_get_cycle_timer2 {
  * instead of allocated.
  * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation.
  *
- * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources
- * for the lifetime of the fd or handle.
+ * To summarize, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE allocates iso resources
+ * for the lifetime of the fd or @handle.
  * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources
  * for the duration of a bus generation.
  *
index b316770..9b4bb5f 100644 (file)
@@ -1,3 +1,28 @@
+/*
+ * IEEE 1394 constants.
+ *
+ * Copyright (C) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifndef _LINUX_FIREWIRE_CONSTANTS_H
 #define _LINUX_FIREWIRE_CONSTANTS_H
 
@@ -21,7 +46,7 @@
 #define EXTCODE_WRAP_ADD               0x6
 #define EXTCODE_VENDOR_DEPENDENT       0x7
 
-/* Juju specific tcodes */
+/* Linux firewire-core (Juju) specific tcodes */
 #define TCODE_LOCK_MASK_SWAP           (0x10 | EXTCODE_MASK_SWAP)
 #define TCODE_LOCK_COMPARE_SWAP                (0x10 | EXTCODE_COMPARE_SWAP)
 #define TCODE_LOCK_FETCH_ADD           (0x10 | EXTCODE_FETCH_ADD)
@@ -36,7 +61,7 @@
 #define RCODE_TYPE_ERROR               0x6
 #define RCODE_ADDRESS_ERROR            0x7
 
-/* Juju specific rcodes */
+/* Linux firewire-core (Juju) specific rcodes */
 #define RCODE_SEND_ERROR               0x10
 #define RCODE_CANCELLED                        0x11
 #define RCODE_BUSY                     0x12
index 39d57bc..44f35ae 100644 (file)
@@ -2315,8 +2315,9 @@ extern int vfs_fstatat(int , char __user *, struct kstat *, int);
 extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
                    unsigned long arg);
 extern int __generic_block_fiemap(struct inode *inode,
-                                 struct fiemap_extent_info *fieinfo, u64 start,
-                                 u64 len, get_block_t *get_block);
+                                 struct fiemap_extent_info *fieinfo,
+                                 loff_t start, loff_t len,
+                                 get_block_t *get_block);
 extern int generic_block_fiemap(struct inode *inode,
                                struct fiemap_extent_info *fieinfo, u64 start,
                                u64 len, get_block_t *get_block);
index 01e6ade..41e4633 100644 (file)
@@ -82,9 +82,13 @@ void clear_ftrace_function(void);
 extern void ftrace_stub(unsigned long a0, unsigned long a1);
 
 #else /* !CONFIG_FUNCTION_TRACER */
-# define register_ftrace_function(ops) do { } while (0)
-# define unregister_ftrace_function(ops) do { } while (0)
-# define clear_ftrace_function(ops) do { } while (0)
+/*
+ * (un)register_ftrace_function must be a macro since the ops parameter
+ * must not be evaluated.
+ */
+#define register_ftrace_function(ops) ({ 0; })
+#define unregister_ftrace_function(ops) ({ 0; })
+static inline void clear_ftrace_function(void) { }
 static inline void ftrace_kill(void) { }
 static inline void ftrace_stop(void) { }
 static inline void ftrace_start(void) { }
@@ -237,11 +241,13 @@ extern int skip_trace(unsigned long ip);
 extern void ftrace_disable_daemon(void);
 extern void ftrace_enable_daemon(void);
 #else
-# define skip_trace(ip)                                ({ 0; })
-# define ftrace_force_update()                 ({ 0; })
-# define ftrace_set_filter(buf, len, reset)    do { } while (0)
-# define ftrace_disable_daemon()               do { } while (0)
-# define ftrace_enable_daemon()                        do { } while (0)
+static inline int skip_trace(unsigned long ip) { return 0; }
+static inline int ftrace_force_update(void) { return 0; }
+static inline void ftrace_set_filter(unsigned char *buf, int len, int reset)
+{
+}
+static inline void ftrace_disable_daemon(void) { }
+static inline void ftrace_enable_daemon(void) { }
 static inline void ftrace_release_mod(struct module *mod) {}
 static inline int register_ftrace_command(struct ftrace_func_command *cmd)
 {
@@ -314,16 +320,16 @@ static inline void __ftrace_enabled_restore(int enabled)
   extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
   extern void time_hardirqs_off(unsigned long a0, unsigned long a1);
 #else
-# define time_hardirqs_on(a0, a1)              do { } while (0)
-# define time_hardirqs_off(a0, a1)             do { } while (0)
+  static inline void time_hardirqs_on(unsigned long a0, unsigned long a1) { }
+  static inline void time_hardirqs_off(unsigned long a0, unsigned long a1) { }
 #endif
 
 #ifdef CONFIG_PREEMPT_TRACER
   extern void trace_preempt_on(unsigned long a0, unsigned long a1);
   extern void trace_preempt_off(unsigned long a0, unsigned long a1);
 #else
-# define trace_preempt_on(a0, a1)              do { } while (0)
-# define trace_preempt_off(a0, a1)             do { } while (0)
+  static inline void trace_preempt_on(unsigned long a0, unsigned long a1) { }
+  static inline void trace_preempt_off(unsigned long a0, unsigned long a1) { }
 #endif
 
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
@@ -352,6 +358,10 @@ struct ftrace_graph_ret {
        int depth;
 };
 
+/* Type of the callback handlers for tracing function graph*/
+typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
+typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
+
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 
 /* for init task */
@@ -400,10 +410,6 @@ extern char __irqentry_text_end[];
 
 #define FTRACE_RETFUNC_DEPTH 50
 #define FTRACE_RETSTACK_ALLOC_SIZE 32
-/* Type of the callback handlers for tracing function graph*/
-typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
-typedef int (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
-
 extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
                                trace_func_graph_ent_t entryfunc);
 
@@ -441,6 +447,13 @@ static inline void unpause_graph_tracing(void)
 static inline void ftrace_graph_init_task(struct task_struct *t) { }
 static inline void ftrace_graph_exit_task(struct task_struct *t) { }
 
+static inline int register_ftrace_graph(trace_func_graph_ret_t retfunc,
+                         trace_func_graph_ent_t entryfunc)
+{
+       return -1;
+}
+static inline void unregister_ftrace_graph(void) { }
+
 static inline int task_curr_ret_stack(struct task_struct *tsk)
 {
        return -1;
@@ -492,7 +505,9 @@ static inline int test_tsk_trace_graph(struct task_struct *tsk)
        return tsk->trace & TSK_TRACE_FL_GRAPH;
 }
 
-extern int ftrace_dump_on_oops;
+enum ftrace_dump_mode;
+
+extern enum ftrace_dump_mode ftrace_dump_on_oops;
 
 #ifdef CONFIG_PREEMPT
 #define INIT_TRACE_RECURSION           .trace_recursion = 0,
@@ -504,18 +519,6 @@ extern int ftrace_dump_on_oops;
 #define INIT_TRACE_RECURSION
 #endif
 
-#ifdef CONFIG_HW_BRANCH_TRACER
-
-void trace_hw_branch(u64 from, u64 to);
-void trace_hw_branch_oops(void);
-
-#else /* CONFIG_HW_BRANCH_TRACER */
-
-static inline void trace_hw_branch(u64 from, u64 to) {}
-static inline void trace_hw_branch_oops(void) {}
-
-#endif /* CONFIG_HW_BRANCH_TRACER */
-
 #ifdef CONFIG_FTRACE_SYSCALLS
 
 unsigned long arch_syscall_addr(int nr);
index c0f4b36..39e71b0 100644 (file)
@@ -58,6 +58,7 @@ struct trace_iterator {
        /* The below is zeroed out in pipe_read */
        struct trace_seq        seq;
        struct trace_entry      *ent;
+       unsigned long           lost_events;
        int                     leftover;
        int                     cpu;
        u64                     ts;
index 5d86fb2..fd0c1b8 100644 (file)
@@ -422,6 +422,8 @@ extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
 
 extern int schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
                                                const enum hrtimer_mode mode);
+extern int schedule_hrtimeout_range_clock(ktime_t *expires,
+               unsigned long delta, const enum hrtimer_mode mode, int clock);
 extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
 
 /* Soft interrupt function to run the hrtimer queues: */
index c70d27a..a2d6ea4 100644 (file)
@@ -9,9 +9,22 @@ enum {
 };
 
 enum {
-       HW_BREAKPOINT_R = 1,
-       HW_BREAKPOINT_W = 2,
-       HW_BREAKPOINT_X = 4,
+       HW_BREAKPOINT_EMPTY     = 0,
+       HW_BREAKPOINT_R         = 1,
+       HW_BREAKPOINT_W         = 2,
+       HW_BREAKPOINT_RW        = HW_BREAKPOINT_R | HW_BREAKPOINT_W,
+       HW_BREAKPOINT_X         = 4,
+       HW_BREAKPOINT_INVALID   = HW_BREAKPOINT_RW | HW_BREAKPOINT_X,
+};
+
+enum bp_type_idx {
+       TYPE_INST       = 0,
+#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS
+       TYPE_DATA       = 0,
+#else
+       TYPE_DATA       = 1,
+#endif
+       TYPE_MAX
 };
 
 #ifdef __KERNEL__
@@ -34,6 +47,12 @@ static inline void hw_breakpoint_init(struct perf_event_attr *attr)
        attr->sample_period = 1;
 }
 
+static inline void ptrace_breakpoint_init(struct perf_event_attr *attr)
+{
+       hw_breakpoint_init(attr);
+       attr->exclude_kernel = 1;
+}
+
 static inline unsigned long hw_breakpoint_addr(struct perf_event *bp)
 {
        return bp->attr.bp_addr;
index 0a5da63..6ed1d59 100644 (file)
@@ -355,6 +355,8 @@ struct i2c_adapter {
        int nr;
        char name[48];
        struct completion dev_released;
+
+       struct list_head userspace_clients;
 };
 #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
 
index c9bf92c..d94963b 100644 (file)
@@ -79,10 +79,7 @@ enum {
        IFLA_NET_NS_PID,
        IFLA_IFALIAS,
        IFLA_NUM_VF,            /* Number of VFs if device is SR-IOV PF */
-       IFLA_VF_MAC,            /* Hardware queue specific attributes */
-       IFLA_VF_VLAN,
-       IFLA_VF_TX_RATE,        /* TX Bandwidth Allocation */
-       IFLA_VFINFO,
+       IFLA_VFINFO_LIST,
        __IFLA_MAX
 };
 
@@ -203,6 +200,24 @@ enum macvlan_mode {
 
 /* SR-IOV virtual function managment section */
 
+enum {
+       IFLA_VF_INFO_UNSPEC,
+       IFLA_VF_INFO,
+       __IFLA_VF_INFO_MAX,
+};
+
+#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1)
+
+enum {
+       IFLA_VF_UNSPEC,
+       IFLA_VF_MAC,            /* Hardware queue specific attributes */
+       IFLA_VF_VLAN,
+       IFLA_VF_TX_RATE,        /* TX Bandwidth Allocation */
+       __IFLA_VF_MAX,
+};
+
+#define IFLA_VF_MAX (__IFLA_VF_MAX - 1)
+
 struct ifla_vf_mac {
        __u32 vf;
        __u8 mac[32]; /* MAX_ADDR_LEN */
index b1ed1cd..7996fc2 100644 (file)
@@ -49,7 +49,6 @@ extern struct group_info init_groups;
                { .first = &init_task.pids[PIDTYPE_PGID].node },        \
                { .first = &init_task.pids[PIDTYPE_SID].node },         \
        },                                                              \
-       .rcu            = RCU_HEAD_INIT,                                \
        .level          = 0,                                            \
        .numbers        = { {                                           \
                .nr             = 0,                                    \
index 3bd018b..c964cd7 100644 (file)
@@ -44,6 +44,7 @@ struct matrix_keymap_data {
  * @active_low: gpio polarity
  * @wakeup: controls whether the device should be set up as wakeup
  *     source
+ * @no_autorepeat: disable key autorepeat
  *
  * This structure represents platform-specific data that use used by
  * matrix_keypad driver to perform proper initialization.
@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data {
 
        bool            active_low;
        bool            wakeup;
+       bool            no_autorepeat;
 };
 
 /**
index 75f3f00..5137db3 100644 (file)
@@ -39,7 +39,8 @@
  * These flags used only by the kernel as part of the
  * irq handling routines.
  *
- * IRQF_DISABLED - keep irqs disabled when calling the action handler
+ * IRQF_DISABLED - keep irqs disabled when calling the action handler.
+ *                 DEPRECATED. This flag is a NOOP and scheduled to be removed
  * IRQF_SAMPLE_RANDOM - irq is used to feed the random generator
  * IRQF_SHARED - allow sharing the irq among several devices
  * IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur
@@ -77,6 +78,18 @@ enum {
        IRQTF_AFFINITY,
 };
 
+/**
+ * These values can be returned by request_any_context_irq() and
+ * describe the context the interrupt will be run in.
+ *
+ * IRQC_IS_HARDIRQ - interrupt runs in hardirq context
+ * IRQC_IS_NESTED - interrupt runs in a nested threaded context
+ */
+enum {
+       IRQC_IS_HARDIRQ = 0,
+       IRQC_IS_NESTED,
+};
+
 typedef irqreturn_t (*irq_handler_t)(int, void *);
 
 /**
@@ -120,6 +133,10 @@ request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
        return request_threaded_irq(irq, handler, NULL, flags, name, dev);
 }
 
+extern int __must_check
+request_any_context_irq(unsigned int irq, irq_handler_t handler,
+                       unsigned long flags, const char *name, void *dev_id);
+
 extern void exit_irq_thread(void);
 #else
 
@@ -141,6 +158,13 @@ request_threaded_irq(unsigned int irq, irq_handler_t handler,
        return request_irq(irq, handler, flags, name, dev);
 }
 
+static inline int __must_check
+request_any_context_irq(unsigned int irq, irq_handler_t handler,
+                       unsigned long flags, const char *name, void *dev_id)
+{
+       return request_irq(irq, handler, flags, name, dev_id);
+}
+
 static inline void exit_irq_thread(void) { }
 #endif
 
@@ -209,6 +233,7 @@ extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
 extern int irq_can_set_affinity(unsigned int irq);
 extern int irq_select_affinity(unsigned int irq);
 
+extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
 #else /* CONFIG_SMP */
 
 static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m)
@@ -223,6 +248,11 @@ static inline int irq_can_set_affinity(unsigned int irq)
 
 static inline int irq_select_affinity(unsigned int irq)  { return 0; }
 
+static inline int irq_set_affinity_hint(unsigned int irq,
+                                        const struct cpumask *m)
+{
+       return -EINVAL;
+}
 #endif /* CONFIG_SMP && CONFIG_GENERIC_HARDIRQS */
 
 #ifdef CONFIG_GENERIC_HARDIRQS
index 3af4ffd..be22ad8 100644 (file)
@@ -37,9 +37,9 @@ struct iommu_ops {
        int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
        void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
        int (*map)(struct iommu_domain *domain, unsigned long iova,
-                  phys_addr_t paddr, size_t size, int prot);
-       void (*unmap)(struct iommu_domain *domain, unsigned long iova,
-                     size_t size);
+                  phys_addr_t paddr, int gfp_order, int prot);
+       int (*unmap)(struct iommu_domain *domain, unsigned long iova,
+                    int gfp_order);
        phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
                                    unsigned long iova);
        int (*domain_has_cap)(struct iommu_domain *domain,
@@ -56,10 +56,10 @@ extern int iommu_attach_device(struct iommu_domain *domain,
                               struct device *dev);
 extern void iommu_detach_device(struct iommu_domain *domain,
                                struct device *dev);
-extern int iommu_map_range(struct iommu_domain *domain, unsigned long iova,
-                          phys_addr_t paddr, size_t size, int prot);
-extern void iommu_unmap_range(struct iommu_domain *domain, unsigned long iova,
-                             size_t size);
+extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
+                    phys_addr_t paddr, int gfp_order, int prot);
+extern int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+                      int gfp_order);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
                                      unsigned long iova);
 extern int iommu_domain_has_cap(struct iommu_domain *domain,
@@ -96,16 +96,16 @@ static inline void iommu_detach_device(struct iommu_domain *domain,
 {
 }
 
-static inline int iommu_map_range(struct iommu_domain *domain,
-                                 unsigned long iova, phys_addr_t paddr,
-                                 size_t size, int prot)
+static inline int iommu_map(struct iommu_domain *domain, unsigned long iova,
+                           phys_addr_t paddr, int gfp_order, int prot)
 {
        return -ENODEV;
 }
 
-static inline void iommu_unmap_range(struct iommu_domain *domain,
-                                    unsigned long iova, size_t size)
+static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+                             int gfp_order)
 {
+       return -ENODEV;
 }
 
 static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
index 707ab12..c03243a 100644 (file)
@@ -195,6 +195,7 @@ struct irq_desc {
        raw_spinlock_t          lock;
 #ifdef CONFIG_SMP
        cpumask_var_t           affinity;
+       const struct cpumask    *affinity_hint;
        unsigned int            node;
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        cpumask_var_t           pending_mask;
index 9365227..9fb1c12 100644 (file)
@@ -490,6 +490,13 @@ static inline void tracing_off(void) { }
 static inline void tracing_off_permanent(void) { }
 static inline int tracing_is_on(void) { return 0; }
 #endif
+
+enum ftrace_dump_mode {
+       DUMP_NONE,
+       DUMP_ALL,
+       DUMP_ORIG,
+};
+
 #ifdef CONFIG_TRACING
 extern void tracing_start(void);
 extern void tracing_stop(void);
@@ -571,7 +578,7 @@ __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
 extern int
 __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
 
-extern void ftrace_dump(void);
+extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
 #else
 static inline void
 ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
@@ -592,7 +599,7 @@ ftrace_vprintk(const char *fmt, va_list ap)
 {
        return 0;
 }
-static inline void ftrace_dump(void) { }
+static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 #endif /* CONFIG_TRACING */
 
 /*
index ce59832..e1ceaa9 100644 (file)
@@ -130,7 +130,7 @@ static inline ktime_t timeval_to_ktime(struct timeval tv)
 /* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */
 #define ktime_to_ns(kt)                        ((kt).tv64)
 
-#else
+#else  /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */
 
 /*
  * Helper macros/inlines to get the ktime_t math right in the timespec
@@ -275,7 +275,7 @@ static inline s64 ktime_to_ns(const ktime_t kt)
        return (s64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec;
 }
 
-#endif
+#endif /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */
 
 /**
  * ktime_equal - Compares two ktime_t variables to see if they are equal
@@ -295,6 +295,12 @@ static inline s64 ktime_to_us(const ktime_t kt)
        return (s64) tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
 }
 
+static inline s64 ktime_to_ms(const ktime_t kt)
+{
+       struct timeval tv = ktime_to_timeval(kt);
+       return (s64) tv.tv_sec * MSEC_PER_SEC + tv.tv_usec / USEC_PER_MSEC;
+}
+
 static inline s64 ktime_us_delta(const ktime_t later, const ktime_t earlier)
 {
        return ktime_to_us(ktime_sub(later, earlier));
index a3fd0f9..169d077 100644 (file)
@@ -54,7 +54,7 @@ extern struct kmem_cache *kvm_vcpu_cache;
  */
 struct kvm_io_bus {
        int                   dev_count;
-#define NR_IOBUS_DEVS 6
+#define NR_IOBUS_DEVS 200
        struct kvm_io_device *devs[NR_IOBUS_DEVS];
 };
 
@@ -119,6 +119,11 @@ struct kvm_memory_slot {
        int user_alloc;
 };
 
+static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
+{
+       return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+}
+
 struct kvm_kernel_irq_routing_entry {
        u32 gsi;
        u32 type;
index f78f83d..6907251 100644 (file)
@@ -33,7 +33,7 @@ struct common_audit_data {
 #define LSM_AUDIT_DATA_IPC     4
 #define LSM_AUDIT_DATA_TASK    5
 #define LSM_AUDIT_DATA_KEY     6
-#define LSM_AUDIT_NO_AUDIT     7
+#define LSM_AUDIT_DATA_NONE    7
 #define LSM_AUDIT_DATA_KMOD    8
        struct task_struct *tsk;
        union   {
index 462acaf..fb19bb9 100644 (file)
@@ -19,7 +19,6 @@ struct anon_vma;
 struct file_ra_state;
 struct user_struct;
 struct writeback_control;
-struct rlimit;
 
 #ifndef CONFIG_DISCONTIGMEM          /* Don't use mapnrs, do it properly */
 extern unsigned long max_mapnr;
@@ -1449,9 +1448,6 @@ int vmemmap_populate_basepages(struct page *start_page,
 int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
 void vmemmap_populate_print_last(void);
 
-extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
-                                size_t size);
-extern void refund_locked_memory(struct mm_struct *mm, size_t size);
 
 enum mf_flags {
        MF_COUNT_INCREASED = 1 << 0,
index f58e9d8..56fde43 100644 (file)
@@ -474,4 +474,13 @@ struct platform_device_id {
                        __attribute__((aligned(sizeof(kernel_ulong_t))));
 };
 
+struct zorro_device_id {
+       __u32 id;                       /* Device ID or ZORRO_WILDCARD */
+       kernel_ulong_t driver_data;     /* Data private to the driver */
+};
+
+#define ZORRO_WILDCARD                 (0xffffffff)    /* not official */
+
+#define ZORRO_DEVICE_MODALIAS_FMT      "zorro:i%08X"
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
index 515d53a..6914fca 100644 (file)
@@ -465,8 +465,7 @@ static inline void __module_get(struct module *module)
        if (module) {
                preempt_disable();
                __this_cpu_inc(module->refptr->incs);
-               trace_module_get(module, _THIS_IP_,
-                                __this_cpu_read(module->refptr->incs));
+               trace_module_get(module, _THIS_IP_);
                preempt_enable();
        }
 }
@@ -480,8 +479,7 @@ static inline int try_module_get(struct module *module)
 
                if (likely(module_is_live(module))) {
                        __this_cpu_inc(module->refptr->incs);
-                       trace_module_get(module, _THIS_IP_,
-                               __this_cpu_read(module->refptr->incs));
+                       trace_module_get(module, _THIS_IP_);
                } else
                        ret = 0;
 
index 6330fc7..5ec9ca6 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/ncp_mount.h>
 #include <linux/net.h>
 #include <linux/mutex.h>
+#include <linux/backing-dev.h>
 
 #ifdef __KERNEL__
 
@@ -127,6 +128,7 @@ struct ncp_server {
                size_t len;
                __u8 data[128];
        } unexpected_packet;
+       struct backing_dev_info bdi;
 };
 
 extern void ncp_tcp_rcv_proc(struct work_struct *work);
index 1a0b85a..77c2ae5 100644 (file)
@@ -209,6 +209,7 @@ struct nfs_inode {
 #define NFS_INO_FLUSHING       (4)             /* inode is flushing out data */
 #define NFS_INO_FSCACHE                (5)             /* inode can be cached by FS-Cache */
 #define NFS_INO_FSCACHE_LOCK   (6)             /* FS-Cache cookie management lock */
+#define NFS_INO_COMMIT         (7)             /* inode is committing unstable writes */
 
 static inline struct nfs_inode *NFS_I(const struct inode *inode)
 {
@@ -355,6 +356,20 @@ extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struc
 extern u64 nfs_compat_user_ino64(u64 fileid);
 extern void nfs_fattr_init(struct nfs_fattr *fattr);
 
+extern struct nfs_fattr *nfs_alloc_fattr(void);
+
+static inline void nfs_free_fattr(const struct nfs_fattr *fattr)
+{
+       kfree(fattr);
+}
+
+extern struct nfs_fh *nfs_alloc_fhandle(void);
+
+static inline void nfs_free_fhandle(const struct nfs_fh *fh)
+{
+       kfree(fh);
+}
+
 /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
 extern __be32 root_nfs_parse_addr(char *name); /*__init*/
 extern unsigned long nfs_inc_attr_generation_counter(void);
index 717a5e5..d6e10a4 100644 (file)
@@ -44,7 +44,6 @@ struct nfs_client {
 
 #ifdef CONFIG_NFS_V4
        u64                     cl_clientid;    /* constant */
-       nfs4_verifier           cl_confirm;
        unsigned long           cl_state;
 
        struct rb_root          cl_openowner_id;
@@ -176,6 +175,7 @@ struct nfs_server {
 #define NFS_CAP_ATIME          (1U << 11)
 #define NFS_CAP_CTIME          (1U << 12)
 #define NFS_CAP_MTIME          (1U << 13)
+#define NFS_CAP_POSIX_LOCK     (1U << 14)
 
 
 /* maximum number of slots to use */
index 89b2881..51914d7 100644 (file)
@@ -386,8 +386,8 @@ struct nfs_removeargs {
 
 struct nfs_removeres {
        const struct nfs_server *server;
+       struct nfs_fattr        *dir_attr;
        struct nfs4_change_info cinfo;
-       struct nfs_fattr        dir_attr;
        struct nfs4_sequence_res        seq_res;
 };
 
@@ -824,6 +824,11 @@ struct nfs4_setclientid {
        u32                             sc_cb_ident;
 };
 
+struct nfs4_setclientid_res {
+       u64                             clientid;
+       nfs4_verifier                   confirm;
+};
+
 struct nfs4_statfs_arg {
        const struct nfs_fh *           fh;
        const u32 *                     bitmask;
index 65e333a..80d55bb 100644 (file)
@@ -40,12 +40,12 @@ struct nfs_fhbase_old {
  * This is the new flexible, extensible style NFSv2/v3 file handle.
  * by Neil Brown <neilb@cse.unsw.edu.au> - March 2000
  *
- * The file handle is seens as a list of 4byte words.
- * The first word contains a version number (1) and four descriptor bytes
+ * The file handle starts with a sequence of four-byte words.
+ * The first word contains a version number (1) and three descriptor bytes
  * that tell how the remaining 3 variable length fields should be handled.
  * These three bytes are auth_type, fsid_type and fileid_type.
  *
- * All 4byte values are in host-byte-order.
+ * All four-byte values are in host-byte-order.
  *
  * The auth_type field specifies how the filehandle can be authenticated
  * This might allow a file to be confirmed to be in a writable part of a
index c8e3754..3fd5c82 100644 (file)
@@ -203,8 +203,19 @@ struct perf_event_attr {
                                enable_on_exec :  1, /* next exec enables     */
                                task           :  1, /* trace fork/exit       */
                                watermark      :  1, /* wakeup_watermark      */
-
-                               __reserved_1   : 49;
+                               /*
+                                * precise_ip:
+                                *
+                                *  0 - SAMPLE_IP can have arbitrary skid
+                                *  1 - SAMPLE_IP must have constant skid
+                                *  2 - SAMPLE_IP requested to have 0 skid
+                                *  3 - SAMPLE_IP must have 0 skid
+                                *
+                                *  See also PERF_RECORD_MISC_EXACT_IP
+                                */
+                               precise_ip     :  2, /* skid constraint       */
+
+                               __reserved_1   : 47;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
@@ -287,11 +298,24 @@ struct perf_event_mmap_page {
        __u64   data_tail;              /* user-space written tail */
 };
 
-#define PERF_RECORD_MISC_CPUMODE_MASK          (3 << 0)
+#define PERF_RECORD_MISC_CPUMODE_MASK          (7 << 0)
 #define PERF_RECORD_MISC_CPUMODE_UNKNOWN       (0 << 0)
 #define PERF_RECORD_MISC_KERNEL                        (1 << 0)
 #define PERF_RECORD_MISC_USER                  (2 << 0)
 #define PERF_RECORD_MISC_HYPERVISOR            (3 << 0)
+#define PERF_RECORD_MISC_GUEST_KERNEL          (4 << 0)
+#define PERF_RECORD_MISC_GUEST_USER            (5 << 0)
+
+/*
+ * Indicates that the content of PERF_SAMPLE_IP points to
+ * the actual instruction that triggered the event. See also
+ * perf_event_attr::precise_ip.
+ */
+#define PERF_RECORD_MISC_EXACT_IP              (1 << 14)
+/*
+ * Reserve the last bit to indicate some extended misc field
+ */
+#define PERF_RECORD_MISC_EXT_RESERVED          (1 << 15)
 
 struct perf_event_header {
        __u32   type;
@@ -439,6 +463,12 @@ enum perf_callchain_context {
 # include <asm/perf_event.h>
 #endif
 
+struct perf_guest_info_callbacks {
+       int (*is_in_guest) (void);
+       int (*is_user_mode) (void);
+       unsigned long (*get_guest_ip) (void);
+};
+
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 #include <asm/hw_breakpoint.h>
 #endif
@@ -468,6 +498,17 @@ struct perf_raw_record {
        void                            *data;
 };
 
+struct perf_branch_entry {
+       __u64                           from;
+       __u64                           to;
+       __u64                           flags;
+};
+
+struct perf_branch_stack {
+       __u64                           nr;
+       struct perf_branch_entry        entries[0];
+};
+
 struct task_struct;
 
 /**
@@ -506,6 +547,8 @@ struct hw_perf_event {
 
 struct perf_event;
 
+#define PERF_EVENT_TXN_STARTED 1
+
 /**
  * struct pmu - generic performance monitoring unit
  */
@@ -516,6 +559,16 @@ struct pmu {
        void (*stop)                    (struct perf_event *event);
        void (*read)                    (struct perf_event *event);
        void (*unthrottle)              (struct perf_event *event);
+
+       /*
+        * group events scheduling is treated as a transaction,
+        * add group events as a whole and perform one schedulability test.
+        * If test fails, roll back the whole group
+        */
+
+       void (*start_txn)       (const struct pmu *pmu);
+       void (*cancel_txn)      (const struct pmu *pmu);
+       int  (*commit_txn)      (const struct pmu *pmu);
 };
 
 /**
@@ -571,6 +624,14 @@ enum perf_group_flag {
        PERF_GROUP_SOFTWARE = 0x1,
 };
 
+#define SWEVENT_HLIST_BITS     8
+#define SWEVENT_HLIST_SIZE     (1 << SWEVENT_HLIST_BITS)
+
+struct swevent_hlist {
+       struct hlist_head       heads[SWEVENT_HLIST_SIZE];
+       struct rcu_head         rcu_head;
+};
+
 /**
  * struct perf_event - performance event kernel representation:
  */
@@ -579,6 +640,7 @@ struct perf_event {
        struct list_head                group_entry;
        struct list_head                event_entry;
        struct list_head                sibling_list;
+       struct hlist_node               hlist_entry;
        int                             nr_siblings;
        int                             group_flags;
        struct perf_event               *group_leader;
@@ -726,6 +788,9 @@ struct perf_cpu_context {
        int                             active_oncpu;
        int                             max_pertask;
        int                             exclusive;
+       struct swevent_hlist            *swevent_hlist;
+       struct mutex                    hlist_mutex;
+       int                             hlist_refcount;
 
        /*
         * Recursion avoidance:
@@ -769,9 +834,6 @@ extern void perf_disable(void);
 extern void perf_enable(void);
 extern int perf_event_task_disable(void);
 extern int perf_event_task_enable(void);
-extern int hw_perf_group_sched_in(struct perf_event *group_leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx);
 extern void perf_event_update_userpage(struct perf_event *event);
 extern int perf_event_release_kernel(struct perf_event *event);
 extern struct perf_event *
@@ -902,6 +964,10 @@ static inline void perf_event_mmap(struct vm_area_struct *vma)
                __perf_event_mmap(vma);
 }
 
+extern struct perf_guest_info_callbacks *perf_guest_cbs;
+extern int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+extern int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *callbacks);
+
 extern void perf_event_comm(struct task_struct *tsk);
 extern void perf_event_fork(struct task_struct *tsk);
 
@@ -971,6 +1037,11 @@ perf_sw_event(u32 event_id, u64 nr, int nmi,
 static inline void
 perf_bp_event(struct perf_event *event, void *data)                    { }
 
+static inline int perf_register_guest_info_callbacks
+(struct perf_guest_info_callbacks *callbacks) { return 0; }
+static inline int perf_unregister_guest_info_callbacks
+(struct perf_guest_info_callbacks *callbacks) { return 0; }
+
 static inline void perf_event_mmap(struct vm_area_struct *vma)         { }
 static inline void perf_event_comm(struct task_struct *tsk)            { }
 static inline void perf_event_fork(struct task_struct *tsk)            { }
index 212da17..5417944 100644 (file)
@@ -44,12 +44,14 @@ extern int platform_get_irq_byname(struct platform_device *, const char *);
 extern int platform_add_devices(struct platform_device **, int);
 
 extern struct platform_device *platform_device_register_simple(const char *, int id,
-                                       struct resource *, unsigned int);
+                                       const struct resource *, unsigned int);
 extern struct platform_device *platform_device_register_data(struct device *,
                const char *, int, const void *, size_t);
 
 extern struct platform_device *platform_device_alloc(const char *name, int id);
-extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
+extern int platform_device_add_resources(struct platform_device *pdev,
+                                        const struct resource *res,
+                                        unsigned int num);
 extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size);
 extern int platform_device_add(struct platform_device *pdev);
 extern void platform_device_del(struct platform_device *pdev);
index 2110a81..34066ff 100644 (file)
 #define POISON_FREE    0x6b    /* for use-after-free poisoning */
 #define        POISON_END      0xa5    /* end-byte of poisoning */
 
+/********** mm/hugetlb.c **********/
+/*
+ * Private mappings of hugetlb pages use this poisoned value for
+ * page->mapping. The core VM should not be doing anything with this mapping
+ * but futex requires the existence of some page->mapping value even though it
+ * is unused if PAGE_MAPPING_ANON is set.
+ */
+#define HUGETLB_POISON ((void *)(0x00300300 + POISON_POINTER_DELTA + PAGE_MAPPING_ANON))
+
 /********** arch/$ARCH/mm/init.c **********/
 #define POISON_FREE_INITMEM    0xcc
 
index e1fb607..4272521 100644 (file)
@@ -345,18 +345,6 @@ static inline void user_single_step_siginfo(struct task_struct *tsk,
 #define arch_ptrace_stop(code, info)           do { } while (0)
 #endif
 
-#ifndef arch_ptrace_untrace
-/*
- * Do machine-specific work before untracing child.
- *
- * This is called for a normal detach as well as from ptrace_exit()
- * when the tracing task dies.
- *
- * Called with write_lock(&tasklist_lock) held.
- */
-#define arch_ptrace_untrace(task)              do { } while (0)
-#endif
-
 extern int task_current_syscall(struct task_struct *target, long *callno,
                                unsigned long args[6], unsigned int maxargs,
                                unsigned long *sp, unsigned long *pc);
index 5210a5c..fe1872e 100644 (file)
@@ -110,6 +110,7 @@ struct rb_node
 struct rb_root
 {
        struct rb_node *rb_node;
+       void (*augment_cb)(struct rb_node *node);
 };
 
 
@@ -129,7 +130,9 @@ static inline void rb_set_color(struct rb_node *rb, int color)
        rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
 }
 
-#define RB_ROOT        (struct rb_root) { NULL, }
+#define RB_ROOT        (struct rb_root) { NULL, NULL, }
+#define RB_AUGMENT_ROOT(x)     (struct rb_root) { NULL, x}
+
 #define        rb_entry(ptr, type, member) container_of(ptr, type, member)
 
 #define RB_EMPTY_ROOT(root)    ((root)->rb_node == NULL)
index 872a98e..b653b4a 100644 (file)
@@ -56,8 +56,6 @@ struct rcu_head {
 };
 
 /* Exported common interfaces */
-extern void synchronize_rcu_bh(void);
-extern void synchronize_sched(void);
 extern void rcu_barrier(void);
 extern void rcu_barrier_bh(void);
 extern void rcu_barrier_sched(void);
@@ -66,8 +64,6 @@ extern int sched_expedited_torture_stats(char *page);
 
 /* Internal to kernel */
 extern void rcu_init(void);
-extern int rcu_scheduler_active;
-extern void rcu_scheduler_starting(void);
 
 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
 #include <linux/rcutree.h>
@@ -83,6 +79,14 @@ extern void rcu_scheduler_starting(void);
        (ptr)->next = NULL; (ptr)->func = NULL; \
 } while (0)
 
+static inline void init_rcu_head_on_stack(struct rcu_head *head)
+{
+}
+
+static inline void destroy_rcu_head_on_stack(struct rcu_head *head)
+{
+}
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
 extern struct lockdep_map rcu_lock_map;
@@ -101,20 +105,18 @@ extern struct lockdep_map rcu_sched_lock_map;
 # define rcu_read_release_sched() \
                lock_release(&rcu_sched_lock_map, 1, _THIS_IP_)
 
-static inline int debug_lockdep_rcu_enabled(void)
-{
-       return likely(rcu_scheduler_active && debug_locks);
-}
+extern int debug_lockdep_rcu_enabled(void);
 
 /**
  * rcu_read_lock_held - might we be in RCU read-side critical section?
  *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in
- * an RCU read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an RCU
+ * read-side critical section.  In absence of CONFIG_DEBUG_LOCK_ALLOC,
  * this assumes we are in an RCU read-side critical section unless it can
  * prove otherwise.
  *
- * Check rcu_scheduler_active to prevent false positives during boot.
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot
+ * and while lockdep is disabled.
  */
 static inline int rcu_read_lock_held(void)
 {
@@ -132,13 +134,15 @@ extern int rcu_read_lock_bh_held(void);
 /**
  * rcu_read_lock_sched_held - might we be in RCU-sched read-side critical section?
  *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in an
- * RCU-sched read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
- * this assumes we are in an RCU-sched read-side critical section unless it
- * can prove otherwise.  Note that disabling of preemption (including
- * disabling irqs) counts as an RCU-sched read-side critical section.
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an
+ * RCU-sched read-side critical section.  In absence of
+ * CONFIG_DEBUG_LOCK_ALLOC, this assumes we are in an RCU-sched read-side
+ * critical section unless it can prove otherwise.  Note that disabling
+ * of preemption (including disabling irqs) counts as an RCU-sched
+ * read-side critical section.
  *
- * Check rcu_scheduler_active to prevent false positives during boot.
+ * Check debug_lockdep_rcu_enabled() to prevent false positives during boot
+ * and while lockdep is disabled.
  */
 #ifdef CONFIG_PREEMPT
 static inline int rcu_read_lock_sched_held(void)
@@ -180,7 +184,7 @@ static inline int rcu_read_lock_bh_held(void)
 #ifdef CONFIG_PREEMPT
 static inline int rcu_read_lock_sched_held(void)
 {
-       return !rcu_scheduler_active || preempt_count() != 0 || irqs_disabled();
+       return preempt_count() != 0 || irqs_disabled();
 }
 #else /* #ifdef CONFIG_PREEMPT */
 static inline int rcu_read_lock_sched_held(void)
@@ -193,28 +197,87 @@ static inline int rcu_read_lock_sched_held(void)
 
 #ifdef CONFIG_PROVE_RCU
 
+extern int rcu_my_thread_group_empty(void);
+
+#define __do_rcu_dereference_check(c)                                  \
+       do {                                                            \
+               static bool __warned;                                   \
+               if (debug_lockdep_rcu_enabled() && !__warned && !(c)) { \
+                       __warned = true;                                \
+                       lockdep_rcu_dereference(__FILE__, __LINE__);    \
+               }                                                       \
+       } while (0)
+
 /**
  * rcu_dereference_check - rcu_dereference with debug checking
+ * @p: The pointer to read, prior to dereferencing
+ * @c: The conditions under which the dereference will take place
+ *
+ * Do an rcu_dereference(), but check that the conditions under which the
+ * dereference will take place are correct.  Typically the conditions indicate
+ * the various locking conditions that should be held at that point.  The check
+ * should return true if the conditions are satisfied.
+ *
+ * For example:
+ *
+ *     bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ *                                           lockdep_is_held(&foo->lock));
  *
- * Do an rcu_dereference(), but check that the context is correct.
- * For example, rcu_dereference_check(gp, rcu_read_lock_held()) to
- * ensure that the rcu_dereference_check() executes within an RCU
- * read-side critical section.  It is also possible to check for
- * locks being held, for example, by using lockdep_is_held().
+ * could be used to indicate to lockdep that foo->bar may only be dereferenced
+ * if either the RCU read lock is held, or that the lock required to replace
+ * the bar struct at foo->bar is held.
+ *
+ * Note that the list of conditions may also include indications of when a lock
+ * need not be held, for example during initialisation or destruction of the
+ * target struct:
+ *
+ *     bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ *                                           lockdep_is_held(&foo->lock) ||
+ *                                           atomic_read(&foo->usage) == 0);
  */
 #define rcu_dereference_check(p, c) \
        ({ \
-               if (debug_lockdep_rcu_enabled() && !(c)) \
-                       lockdep_rcu_dereference(__FILE__, __LINE__); \
+               __do_rcu_dereference_check(c); \
                rcu_dereference_raw(p); \
        })
 
+/**
+ * rcu_dereference_protected - fetch RCU pointer when updates prevented
+ *
+ * Return the value of the specified RCU-protected pointer, but omit
+ * both the smp_read_barrier_depends() and the ACCESS_ONCE().  This
+ * is useful in cases where update-side locks prevent the value of the
+ * pointer from changing.  Please note that this primitive does -not-
+ * prevent the compiler from repeating this reference or combining it
+ * with other references, so it should not be used without protection
+ * of appropriate locks.
+ */
+#define rcu_dereference_protected(p, c) \
+       ({ \
+               __do_rcu_dereference_check(c); \
+               (p); \
+       })
+
 #else /* #ifdef CONFIG_PROVE_RCU */
 
 #define rcu_dereference_check(p, c)    rcu_dereference_raw(p)
+#define rcu_dereference_protected(p, c) (p)
 
 #endif /* #else #ifdef CONFIG_PROVE_RCU */
 
+/**
+ * rcu_access_pointer - fetch RCU pointer with no dereferencing
+ *
+ * Return the value of the specified RCU-protected pointer, but omit the
+ * smp_read_barrier_depends() and keep the ACCESS_ONCE().  This is useful
+ * when the value of this pointer is accessed, but the pointer is not
+ * dereferenced, for example, when testing an RCU-protected pointer against
+ * NULL.  This may also be used in cases where update-side locks prevent
+ * the value of the pointer from changing, but rcu_dereference_protected()
+ * is a lighter-weight primitive for this use case.
+ */
+#define rcu_access_pointer(p)  ACCESS_ONCE(p)
+
 /**
  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
  *
index a519587..e2e8931 100644 (file)
 
 void rcu_sched_qs(int cpu);
 void rcu_bh_qs(int cpu);
+static inline void rcu_note_context_switch(int cpu)
+{
+       rcu_sched_qs(cpu);
+}
 
 #define __rcu_read_lock()      preempt_disable()
 #define __rcu_read_unlock()    preempt_enable()
@@ -60,8 +64,6 @@ static inline long rcu_batches_completed_bh(void)
        return 0;
 }
 
-extern int rcu_expedited_torture_stats(char *page);
-
 static inline void rcu_force_quiescent_state(void)
 {
 }
@@ -74,7 +76,17 @@ static inline void rcu_sched_force_quiescent_state(void)
 {
 }
 
-#define synchronize_rcu synchronize_sched
+extern void synchronize_sched(void);
+
+static inline void synchronize_rcu(void)
+{
+       synchronize_sched();
+}
+
+static inline void synchronize_rcu_bh(void)
+{
+       synchronize_sched();
+}
 
 static inline void synchronize_rcu_expedited(void)
 {
@@ -114,4 +126,17 @@ static inline int rcu_preempt_depth(void)
        return 0;
 }
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+extern int rcu_scheduler_active __read_mostly;
+extern void rcu_scheduler_starting(void);
+
+#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
+static inline void rcu_scheduler_starting(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
 #endif /* __LINUX_RCUTINY_H */
index 42cc3a0..c0ed1c0 100644 (file)
@@ -34,8 +34,8 @@ struct notifier_block;
 
 extern void rcu_sched_qs(int cpu);
 extern void rcu_bh_qs(int cpu);
+extern void rcu_note_context_switch(int cpu);
 extern int rcu_needs_cpu(int cpu);
-extern int rcu_expedited_torture_stats(char *page);
 
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
@@ -86,6 +86,8 @@ static inline void __rcu_read_unlock_bh(void)
 
 extern void call_rcu_sched(struct rcu_head *head,
                           void (*func)(struct rcu_head *rcu));
+extern void synchronize_rcu_bh(void);
+extern void synchronize_sched(void);
 extern void synchronize_rcu_expedited(void);
 
 static inline void synchronize_rcu_bh_expedited(void)
@@ -120,4 +122,7 @@ static inline int rcu_blocking_is_gp(void)
        return num_online_cpus() == 1;
 }
 
+extern void rcu_scheduler_starting(void);
+extern int rcu_scheduler_active __read_mostly;
+
 #endif /* __LINUX_RCUTREE_H */
index 28c9fd0..ebd7472 100644 (file)
@@ -183,9 +183,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
 {
        /* Nothing except the stubbed out regulator API should be
         * looking at the value except to check if it is an error
-        * value so the actual return value doesn't matter.
+        * value. Drivers are free to handle NULL specifically by
+        * skipping all regulator API calls, but they don't have to.
+        * Drivers which don't, should make sure they properly handle
+        * corner cases of the API, such as regulator_get_voltage()
+        * returning 0.
         */
-       return (struct regulator *)id;
+       return NULL;
 }
 static inline void regulator_put(struct regulator *regulator)
 {
index 5fcc31e..25b4f68 100644 (file)
@@ -120,12 +120,16 @@ int ring_buffer_write(struct ring_buffer *buffer,
                      unsigned long length, void *data);
 
 struct ring_buffer_event *
-ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts);
+ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
+                unsigned long *lost_events);
 struct ring_buffer_event *
-ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts);
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
+                   unsigned long *lost_events);
 
 struct ring_buffer_iter *
-ring_buffer_read_start(struct ring_buffer *buffer, int cpu);
+ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu);
+void ring_buffer_read_prepare_sync(void);
+void ring_buffer_read_start(struct ring_buffer_iter *iter);
 void ring_buffer_read_finish(struct ring_buffer_iter *iter);
 
 struct ring_buffer_event *
index dad7f66..b55e988 100644 (file)
@@ -99,7 +99,6 @@ struct futex_pi_state;
 struct robust_list_head;
 struct bio_list;
 struct fs_struct;
-struct bts_context;
 struct perf_event_context;
 
 /*
@@ -275,11 +274,17 @@ extern cpumask_var_t nohz_cpu_mask;
 #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
 extern int select_nohz_load_balancer(int cpu);
 extern int get_nohz_load_balancer(void);
+extern int nohz_ratelimit(int cpu);
 #else
 static inline int select_nohz_load_balancer(int cpu)
 {
        return 0;
 }
+
+static inline int nohz_ratelimit(int cpu)
+{
+       return 0;
+}
 #endif
 
 /*
@@ -954,6 +959,7 @@ struct sched_domain {
        char *name;
 #endif
 
+       unsigned int span_weight;
        /*
         * Span of all CPUs in this domain.
         *
@@ -1026,12 +1032,17 @@ struct sched_domain;
 #define WF_SYNC                0x01            /* waker goes to sleep after wakup */
 #define WF_FORK                0x02            /* child wakeup after fork */
 
+#define ENQUEUE_WAKEUP         1
+#define ENQUEUE_WAKING         2
+#define ENQUEUE_HEAD           4
+
+#define DEQUEUE_SLEEP          1
+
 struct sched_class {
        const struct sched_class *next;
 
-       void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup,
-                             bool head);
-       void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
+       void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
+       void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
        void (*yield_task) (struct rq *rq);
 
        void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
@@ -1040,7 +1051,8 @@ struct sched_class {
        void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 
 #ifdef CONFIG_SMP
-       int  (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
+       int  (*select_task_rq)(struct rq *rq, struct task_struct *p,
+                              int sd_flag, int flags);
 
        void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
        void (*post_schedule) (struct rq *this_rq);
@@ -1077,36 +1089,8 @@ struct load_weight {
        unsigned long weight, inv_weight;
 };
 
-/*
- * CFS stats for a schedulable entity (task, task-group etc)
- *
- * Current field usage histogram:
- *
- *     4 se->block_start
- *     4 se->run_node
- *     4 se->sleep_start
- *     6 se->load.weight
- */
-struct sched_entity {
-       struct load_weight      load;           /* for load-balancing */
-       struct rb_node          run_node;
-       struct list_head        group_node;
-       unsigned int            on_rq;
-
-       u64                     exec_start;
-       u64                     sum_exec_runtime;
-       u64                     vruntime;
-       u64                     prev_sum_exec_runtime;
-
-       u64                     last_wakeup;
-       u64                     avg_overlap;
-
-       u64                     nr_migrations;
-
-       u64                     start_runtime;
-       u64                     avg_wakeup;
-
 #ifdef CONFIG_SCHEDSTATS
+struct sched_statistics {
        u64                     wait_start;
        u64                     wait_max;
        u64                     wait_count;
@@ -1138,6 +1122,24 @@ struct sched_entity {
        u64                     nr_wakeups_affine_attempts;
        u64                     nr_wakeups_passive;
        u64                     nr_wakeups_idle;
+};
+#endif
+
+struct sched_entity {
+       struct load_weight      load;           /* for load-balancing */
+       struct rb_node          run_node;
+       struct list_head        group_node;
+       unsigned int            on_rq;
+
+       u64                     exec_start;
+       u64                     sum_exec_runtime;
+       u64                     vruntime;
+       u64                     prev_sum_exec_runtime;
+
+       u64                     nr_migrations;
+
+#ifdef CONFIG_SCHEDSTATS
+       struct sched_statistics statistics;
 #endif
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
@@ -1272,12 +1274,6 @@ struct task_struct {
        struct list_head ptraced;
        struct list_head ptrace_entry;
 
-       /*
-        * This is the tracer handle for the ptrace BTS extension.
-        * This field actually belongs to the ptracer task.
-        */
-       struct bts_context *bts;
-
        /* PID/PID hash table linkage. */
        struct pid_link pids[PIDTYPE_MAX];
        struct list_head thread_group;
@@ -1497,7 +1493,6 @@ struct task_struct {
        /* bitmask of trace recursion */
        unsigned long trace_recursion;
 #endif /* CONFIG_TRACING */
-       unsigned long stack_start;
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR /* memcg uses this to do batch job */
        struct memcg_batch_info {
                int do_batch;   /* incremented when batch uncharge started */
@@ -1847,6 +1842,7 @@ extern void sched_clock_idle_sleep_event(void);
 extern void sched_clock_idle_wakeup_event(u64 delta_ns);
 
 #ifdef CONFIG_HOTPLUG_CPU
+extern void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p);
 extern void idle_task_exit(void);
 #else
 static inline void idle_task_exit(void) {}
@@ -2123,10 +2119,8 @@ extern void set_task_comm(struct task_struct *tsk, char *from);
 extern char *get_task_comm(char *to, struct task_struct *tsk);
 
 #ifdef CONFIG_SMP
-extern void wait_task_context_switch(struct task_struct *p);
 extern unsigned long wait_task_inactive(struct task_struct *, long match_state);
 #else
-static inline void wait_task_context_switch(struct task_struct *p) {}
 static inline unsigned long wait_task_inactive(struct task_struct *p,
                                               long match_state)
 {
index 3158dd9..0c88191 100644 (file)
@@ -267,49 +267,16 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @orig the original mount data copied from userspace.
  *     @copy copied data which will be passed to the security module.
  *     Returns 0 if the copy was successful.
- * @sb_check_sb:
- *     Check permission before the device with superblock @mnt->sb is mounted
- *     on the mount point named by @nd.
- *     @mnt contains the vfsmount for device being mounted.
- *     @path contains the path for the mount point.
- *     Return 0 if permission is granted.
  * @sb_umount:
  *     Check permission before the @mnt file system is unmounted.
  *     @mnt contains the mounted file system.
  *     @flags contains the unmount flags, e.g. MNT_FORCE.
  *     Return 0 if permission is granted.
- * @sb_umount_close:
- *     Close any files in the @mnt mounted filesystem that are held open by
- *     the security module.  This hook is called during an umount operation
- *     prior to checking whether the filesystem is still busy.
- *     @mnt contains the mounted filesystem.
- * @sb_umount_busy:
- *     Handle a failed umount of the @mnt mounted filesystem, e.g.  re-opening
- *     any files that were closed by umount_close.  This hook is called during
- *     an umount operation if the umount fails after a call to the
- *     umount_close hook.
- *     @mnt contains the mounted filesystem.
- * @sb_post_remount:
- *     Update the security module's state when a filesystem is remounted.
- *     This hook is only called if the remount was successful.
- *     @mnt contains the mounted file system.
- *     @flags contains the new filesystem flags.
- *     @data contains the filesystem-specific data.
- * @sb_post_addmount:
- *     Update the security module's state when a filesystem is mounted.
- *     This hook is called any time a mount is successfully grafetd to
- *     the tree.
- *     @mnt contains the mounted filesystem.
- *     @mountpoint contains the path for the mount point.
  * @sb_pivotroot:
  *     Check permission before pivoting the root filesystem.
  *     @old_path contains the path for the new location of the current root (put_old).
  *     @new_path contains the path for the new root (new_root).
  *     Return 0 if permission is granted.
- * @sb_post_pivotroot:
- *     Update module state after a successful pivot.
- *     @old_path contains the path for the old root.
- *     @new_path contains the path for the new root.
  * @sb_set_mnt_opts:
  *     Set the security relevant mount options used for a superblock
  *     @sb the superblock to set security mount options for
@@ -511,12 +478,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @mnt is the vfsmount where the dentry was looked up
  *     @dentry contains the dentry structure for the file.
  *     Return 0 if permission is granted.
- * @inode_delete:
- *     @inode contains the inode structure for deleted inode.
- *     This hook is called when a deleted inode is released (i.e. an inode
- *     with no hard links has its use count drop to zero).  A security module
- *     can use this hook to release any persistent label associated with the
- *     inode.
  * @inode_setxattr:
  *     Check permission before setting the extended attributes
  *     @value identified by @name for @dentry.
@@ -691,10 +652,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @old points to the original credentials.
  *     @gfp indicates the atomicity of any memory allocations.
  *     Prepare a new set of credentials by copying the data from the old set.
- * @cred_commit:
- *     @new points to the new credentials.
- *     @old points to the original credentials.
- *     Install a new set of credentials.
  * @cred_transfer:
  *     @new points to the new credentials.
  *     @old points to the original credentials.
@@ -717,18 +674,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     userspace to load a kernel module with the given name.
  *     @kmod_name name of the module requested by the kernel
  *     Return 0 if successful.
- * @task_setuid:
- *     Check permission before setting one or more of the user identity
- *     attributes of the current process.  The @flags parameter indicates
- *     which of the set*uid system calls invoked this hook and how to
- *     interpret the @id0, @id1, and @id2 parameters.  See the LSM_SETID
- *     definitions at the beginning of this file for the @flags values and
- *     their meanings.
- *     @id0 contains a uid.
- *     @id1 contains a uid.
- *     @id2 contains a uid.
- *     @flags contains one of the LSM_SETID_* values.
- *     Return 0 if permission is granted.
  * @task_fix_setuid:
  *     Update the module's state after setting one or more of the user
  *     identity attributes of the current process.  The @flags parameter
@@ -738,18 +683,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @old is the set of credentials that are being replaces
  *     @flags contains one of the LSM_SETID_* values.
  *     Return 0 on success.
- * @task_setgid:
- *     Check permission before setting one or more of the group identity
- *     attributes of the current process.  The @flags parameter indicates
- *     which of the set*gid system calls invoked this hook and how to
- *     interpret the @id0, @id1, and @id2 parameters.  See the LSM_SETID
- *     definitions at the beginning of this file for the @flags values and
- *     their meanings.
- *     @id0 contains a gid.
- *     @id1 contains a gid.
- *     @id2 contains a gid.
- *     @flags contains one of the LSM_SETID_* values.
- *     Return 0 if permission is granted.
  * @task_setpgid:
  *     Check permission before setting the process group identifier of the
  *     process @p to @pgid.
@@ -771,11 +704,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @p contains the task_struct for the process and place is into @secid.
  *     In case of failure, @secid will be set to zero.
  *
- * @task_setgroups:
- *     Check permission before setting the supplementary group set of the
- *     current process.
- *     @group_info contains the new group information.
- *     Return 0 if permission is granted.
  * @task_setnice:
  *     Check permission before setting the nice value of @p to @nice.
  *     @p contains the task_struct of process.
@@ -1139,13 +1067,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     Return the length of the string (including terminating NUL) or -ve if
  *      an error.
  *     May also return 0 (and a NULL buffer pointer) if there is no label.
- * @key_session_to_parent:
- *     Forcibly assign the session keyring from a process to its parent
- *     process.
- *     @cred: Pointer to process's credentials
- *     @parent_cred: Pointer to parent process's credentials
- *     @keyring: Proposed new session keyring
- *     Return 0 if permission is granted, -ve error otherwise.
  *
  * Security hooks affecting all System V IPC operations.
  *
@@ -1333,13 +1254,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @cap contains the capability <include/linux/capability.h>.
  *     @audit: Whether to write an audit message or not
  *     Return 0 if the capability is granted for @tsk.
- * @acct:
- *     Check permission before enabling or disabling process accounting.  If
- *     accounting is being enabled, then @file refers to the open file used to
- *     store accounting records.  If accounting is being disabled, then @file
- *     is NULL.
- *     @file contains the file structure for the accounting file (may be NULL).
- *     Return 0 if permission is granted.
  * @sysctl:
  *     Check permission before accessing the @table sysctl variable in the
  *     manner specified by @op.
@@ -1462,7 +1376,6 @@ struct security_operations {
                       const kernel_cap_t *permitted);
        int (*capable) (struct task_struct *tsk, const struct cred *cred,
                        int cap, int audit);
-       int (*acct) (struct file *file);
        int (*sysctl) (struct ctl_table *table, int op);
        int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
        int (*quota_on) (struct dentry *dentry);
@@ -1484,18 +1397,9 @@ struct security_operations {
        int (*sb_statfs) (struct dentry *dentry);
        int (*sb_mount) (char *dev_name, struct path *path,
                         char *type, unsigned long flags, void *data);
-       int (*sb_check_sb) (struct vfsmount *mnt, struct path *path);
        int (*sb_umount) (struct vfsmount *mnt, int flags);
-       void (*sb_umount_close) (struct vfsmount *mnt);
-       void (*sb_umount_busy) (struct vfsmount *mnt);
-       void (*sb_post_remount) (struct vfsmount *mnt,
-                                unsigned long flags, void *data);
-       void (*sb_post_addmount) (struct vfsmount *mnt,
-                                 struct path *mountpoint);
        int (*sb_pivotroot) (struct path *old_path,
                             struct path *new_path);
-       void (*sb_post_pivotroot) (struct path *old_path,
-                                  struct path *new_path);
        int (*sb_set_mnt_opts) (struct super_block *sb,
                                struct security_mnt_opts *opts);
        void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
@@ -1544,7 +1448,6 @@ struct security_operations {
        int (*inode_permission) (struct inode *inode, int mask);
        int (*inode_setattr)    (struct dentry *dentry, struct iattr *attr);
        int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
-       void (*inode_delete) (struct inode *inode);
        int (*inode_setxattr) (struct dentry *dentry, const char *name,
                               const void *value, size_t size, int flags);
        void (*inode_post_setxattr) (struct dentry *dentry, const char *name,
@@ -1585,20 +1488,16 @@ struct security_operations {
        void (*cred_free) (struct cred *cred);
        int (*cred_prepare)(struct cred *new, const struct cred *old,
                            gfp_t gfp);
-       void (*cred_commit)(struct cred *new, const struct cred *old);
        void (*cred_transfer)(struct cred *new, const struct cred *old);
        int (*kernel_act_as)(struct cred *new, u32 secid);
        int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
        int (*kernel_module_request)(char *kmod_name);
-       int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
        int (*task_fix_setuid) (struct cred *new, const struct cred *old,
                                int flags);
-       int (*task_setgid) (gid_t id0, gid_t id1, gid_t id2, int flags);
        int (*task_setpgid) (struct task_struct *p, pid_t pgid);
        int (*task_getpgid) (struct task_struct *p);
        int (*task_getsid) (struct task_struct *p);
        void (*task_getsecid) (struct task_struct *p, u32 *secid);
-       int (*task_setgroups) (struct group_info *group_info);
        int (*task_setnice) (struct task_struct *p, int nice);
        int (*task_setioprio) (struct task_struct *p, int ioprio);
        int (*task_getioprio) (struct task_struct *p);
@@ -1728,9 +1627,6 @@ struct security_operations {
                               const struct cred *cred,
                               key_perm_t perm);
        int (*key_getsecurity)(struct key *key, char **_buffer);
-       int (*key_session_to_parent)(const struct cred *cred,
-                                    const struct cred *parent_cred,
-                                    struct key *key);
 #endif /* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
@@ -1761,7 +1657,6 @@ int security_capset(struct cred *new, const struct cred *old,
 int security_capable(int cap);
 int security_real_capable(struct task_struct *tsk, int cap);
 int security_real_capable_noaudit(struct task_struct *tsk, int cap);
-int security_acct(struct file *file);
 int security_sysctl(struct ctl_table *table, int op);
 int security_quotactl(int cmds, int type, int id, struct super_block *sb);
 int security_quota_on(struct dentry *dentry);
@@ -1783,14 +1678,8 @@ int security_sb_show_options(struct seq_file *m, struct super_block *sb);
 int security_sb_statfs(struct dentry *dentry);
 int security_sb_mount(char *dev_name, struct path *path,
                      char *type, unsigned long flags, void *data);
-int security_sb_check_sb(struct vfsmount *mnt, struct path *path);
 int security_sb_umount(struct vfsmount *mnt, int flags);
-void security_sb_umount_close(struct vfsmount *mnt);
-void security_sb_umount_busy(struct vfsmount *mnt);
-void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data);
-void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint);
 int security_sb_pivotroot(struct path *old_path, struct path *new_path);
-void security_sb_post_pivotroot(struct path *old_path, struct path *new_path);
 int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
 void security_sb_clone_mnt_opts(const struct super_block *oldsb,
                                struct super_block *newsb);
@@ -1816,7 +1705,6 @@ int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
 int security_inode_permission(struct inode *inode, int mask);
 int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
 int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
-void security_inode_delete(struct inode *inode);
 int security_inode_setxattr(struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags);
 void security_inode_post_setxattr(struct dentry *dentry, const char *name,
@@ -1850,20 +1738,16 @@ int security_task_create(unsigned long clone_flags);
 int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
 void security_cred_free(struct cred *cred);
 int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
-void security_commit_creds(struct cred *new, const struct cred *old);
 void security_transfer_creds(struct cred *new, const struct cred *old);
 int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
 int security_kernel_module_request(char *kmod_name);
-int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags);
-int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags);
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
 int security_task_getpgid(struct task_struct *p);
 int security_task_getsid(struct task_struct *p);
 void security_task_getsecid(struct task_struct *p, u32 *secid);
-int security_task_setgroups(struct group_info *group_info);
 int security_task_setnice(struct task_struct *p, int nice);
 int security_task_setioprio(struct task_struct *p, int ioprio);
 int security_task_getioprio(struct task_struct *p);
@@ -1990,11 +1874,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap)
        return ret;
 }
 
-static inline int security_acct(struct file *file)
-{
-       return 0;
-}
-
 static inline int security_sysctl(struct ctl_table *table, int op)
 {
        return 0;
@@ -2099,41 +1978,17 @@ static inline int security_sb_mount(char *dev_name, struct path *path,
        return 0;
 }
 
-static inline int security_sb_check_sb(struct vfsmount *mnt,
-                                      struct path *path)
-{
-       return 0;
-}
-
 static inline int security_sb_umount(struct vfsmount *mnt, int flags)
 {
        return 0;
 }
 
-static inline void security_sb_umount_close(struct vfsmount *mnt)
-{ }
-
-static inline void security_sb_umount_busy(struct vfsmount *mnt)
-{ }
-
-static inline void security_sb_post_remount(struct vfsmount *mnt,
-                                            unsigned long flags, void *data)
-{ }
-
-static inline void security_sb_post_addmount(struct vfsmount *mnt,
-                                            struct path *mountpoint)
-{ }
-
 static inline int security_sb_pivotroot(struct path *old_path,
                                        struct path *new_path)
 {
        return 0;
 }
 
-static inline void security_sb_post_pivotroot(struct path *old_path,
-                                             struct path *new_path)
-{ }
-
 static inline int security_sb_set_mnt_opts(struct super_block *sb,
                                           struct security_mnt_opts *opts)
 {
@@ -2249,9 +2104,6 @@ static inline int security_inode_getattr(struct vfsmount *mnt,
        return 0;
 }
 
-static inline void security_inode_delete(struct inode *inode)
-{ }
-
 static inline int security_inode_setxattr(struct dentry *dentry,
                const char *name, const void *value, size_t size, int flags)
 {
@@ -2398,11 +2250,6 @@ static inline int security_prepare_creds(struct cred *new,
        return 0;
 }
 
-static inline void security_commit_creds(struct cred *new,
-                                        const struct cred *old)
-{
-}
-
 static inline void security_transfer_creds(struct cred *new,
                                           const struct cred *old)
 {
@@ -2424,12 +2271,6 @@ static inline int security_kernel_module_request(char *kmod_name)
        return 0;
 }
 
-static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
-                                      int flags)
-{
-       return 0;
-}
-
 static inline int security_task_fix_setuid(struct cred *new,
                                           const struct cred *old,
                                           int flags)
@@ -2437,12 +2278,6 @@ static inline int security_task_fix_setuid(struct cred *new,
        return cap_task_fix_setuid(new, old, flags);
 }
 
-static inline int security_task_setgid(gid_t id0, gid_t id1, gid_t id2,
-                                      int flags)
-{
-       return 0;
-}
-
 static inline int security_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return 0;
@@ -2463,11 +2298,6 @@ static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
        *secid = 0;
 }
 
-static inline int security_task_setgroups(struct group_info *group_info)
-{
-       return 0;
-}
-
 static inline int security_task_setnice(struct task_struct *p, int nice)
 {
        return cap_task_setnice(p, nice);
@@ -3064,9 +2894,6 @@ void security_key_free(struct key *key);
 int security_key_permission(key_ref_t key_ref,
                            const struct cred *cred, key_perm_t perm);
 int security_key_getsecurity(struct key *key, char **_buffer);
-int security_key_session_to_parent(const struct cred *cred,
-                                  const struct cred *parent_cred,
-                                  struct key *key);
 
 #else
 
@@ -3094,13 +2921,6 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer)
        return 0;
 }
 
-static inline int security_key_session_to_parent(const struct cred *cred,
-                                                const struct cred *parent_cred,
-                                                struct key *key)
-{
-       return 0;
-}
-
 #endif
 #endif /* CONFIG_KEYS */
 
index 193d4bf..f5364a1 100644 (file)
@@ -33,8 +33,8 @@ struct plat_sci_port {
        char            *clk;                   /* clock string */
        struct device   *dma_dev;
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
-       enum sh_dmae_slave_chan_id dma_slave_tx;
-       enum sh_dmae_slave_chan_id dma_slave_rx;
+       unsigned int dma_slave_tx;
+       unsigned int dma_slave_rx;
 #endif
 };
 
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
new file mode 100644 (file)
index 0000000..1636d1e
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef __SH_CLOCK_H
+#define __SH_CLOCK_H
+
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+struct clk;
+
+struct clk_ops {
+       void (*init)(struct clk *clk);
+       int (*enable)(struct clk *clk);
+       void (*disable)(struct clk *clk);
+       unsigned long (*recalc)(struct clk *clk);
+       int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
+       int (*set_parent)(struct clk *clk, struct clk *parent);
+       long (*round_rate)(struct clk *clk, unsigned long rate);
+};
+
+struct clk {
+       struct list_head        node;
+       const char              *name;
+       int                     id;
+
+       struct clk              *parent;
+       struct clk_ops          *ops;
+
+       struct list_head        children;
+       struct list_head        sibling;        /* node for children */
+
+       int                     usecount;
+
+       unsigned long           rate;
+       unsigned long           flags;
+
+       void __iomem            *enable_reg;
+       unsigned int            enable_bit;
+
+       unsigned long           arch_flags;
+       void                    *priv;
+       struct dentry           *dentry;
+       struct cpufreq_frequency_table *freq_table;
+};
+
+#define CLK_ENABLE_ON_INIT     (1 << 0)
+
+/* drivers/sh/clk.c */
+unsigned long followparent_recalc(struct clk *);
+void recalculate_root_clocks(void);
+void propagate_rate(struct clk *);
+int clk_reparent(struct clk *child, struct clk *parent);
+int clk_register(struct clk *);
+void clk_unregister(struct clk *);
+void clk_enable_init_clocks(void);
+
+/**
+ * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ * @algo_id: algorithm id to be passed down to ops->set_rate
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
+
+enum clk_sh_algo_id {
+       NO_CHANGE = 0,
+
+       IUS_N1_N1,
+       IUS_322,
+       IUS_522,
+       IUS_N11,
+
+       SB_N1,
+
+       SB3_N1,
+       SB3_32,
+       SB3_43,
+       SB3_54,
+
+       BP_N1,
+
+       IP_N1,
+};
+
+struct clk_div_mult_table {
+       unsigned int *divisors;
+       unsigned int nr_divisors;
+       unsigned int *multipliers;
+       unsigned int nr_multipliers;
+};
+
+struct cpufreq_frequency_table;
+void clk_rate_table_build(struct clk *clk,
+                         struct cpufreq_frequency_table *freq_table,
+                         int nr_freqs,
+                         struct clk_div_mult_table *src_table,
+                         unsigned long *bitmap);
+
+long clk_rate_table_round(struct clk *clk,
+                         struct cpufreq_frequency_table *freq_table,
+                         unsigned long rate);
+
+int clk_rate_table_find(struct clk *clk,
+                       struct cpufreq_frequency_table *freq_table,
+                       unsigned long rate);
+
+#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags)       \
+{                                                                      \
+       .parent         = _parent,                                      \
+       .enable_reg     = (void __iomem *)_enable_reg,                  \
+       .enable_bit     = _enable_bit,                                  \
+       .flags          = _flags,                                       \
+}
+
+int sh_clk_mstp32_register(struct clk *clks, int nr);
+
+#define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags)        \
+{                                                              \
+       .parent = _parent,                                      \
+       .enable_reg = (void __iomem *)_reg,                     \
+       .enable_bit = _shift,                                   \
+       .arch_flags = _div_bitmap,                              \
+       .flags = _flags,                                        \
+}
+
+struct clk_div4_table {
+       struct clk_div_mult_table *div_mult_table;
+       void (*kick)(struct clk *clk);
+};
+
+int sh_clk_div4_register(struct clk *clks, int nr,
+                        struct clk_div4_table *table);
+int sh_clk_div4_enable_register(struct clk *clks, int nr,
+                        struct clk_div4_table *table);
+int sh_clk_div4_reparent_register(struct clk *clks, int nr,
+                        struct clk_div4_table *table);
+
+#define SH_CLK_DIV6(_parent, _reg, _flags)     \
+{                                              \
+       .parent = _parent,                      \
+       .enable_reg = (void __iomem *)_reg,     \
+       .flags = _flags,                        \
+}
+
+int sh_clk_div6_register(struct clk *clks, int nr);
+
+#endif /* __SH_CLOCK_H */
diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
new file mode 100644 (file)
index 0000000..b08cd4e
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Header for the new SH dmaengine driver
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.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.
+ */
+#ifndef SH_DMA_H
+#define SH_DMA_H
+
+#include <linux/list.h>
+#include <linux/dmaengine.h>
+
+/* Used by slave DMA clients to request DMA to/from a specific peripheral */
+struct sh_dmae_slave {
+       unsigned int                    slave_id; /* Set by the platform */
+       struct device                   *dma_dev; /* Set by the platform */
+       const struct sh_dmae_slave_config       *config;  /* Set by the driver */
+};
+
+struct sh_dmae_regs {
+       u32 sar; /* SAR / source address */
+       u32 dar; /* DAR / destination address */
+       u32 tcr; /* TCR / transfer count */
+};
+
+struct sh_desc {
+       struct sh_dmae_regs hw;
+       struct list_head node;
+       struct dma_async_tx_descriptor async_tx;
+       enum dma_data_direction direction;
+       dma_cookie_t cookie;
+       size_t partial;
+       int chunks;
+       int mark;
+};
+
+struct sh_dmae_slave_config {
+       unsigned int                    slave_id;
+       dma_addr_t                      addr;
+       u32                             chcr;
+       char                            mid_rid;
+};
+
+struct sh_dmae_channel {
+       unsigned int    offset;
+       unsigned int    dmars;
+       unsigned int    dmars_bit;
+};
+
+struct sh_dmae_pdata {
+       const struct sh_dmae_slave_config *slave;
+       int slave_num;
+       const struct sh_dmae_channel *channel;
+       int channel_num;
+       unsigned int ts_low_shift;
+       unsigned int ts_low_mask;
+       unsigned int ts_high_shift;
+       unsigned int ts_high_mask;
+       const unsigned int *ts_shift;
+       int ts_shift_num;
+       u16 dmaor_init;
+};
+
+/* DMA register */
+#define SAR    0x00
+#define DAR    0x04
+#define TCR    0x08
+#define CHCR   0x0C
+#define DMAOR  0x40
+
+/* DMAOR definitions */
+#define DMAOR_AE       0x00000004
+#define DMAOR_NMIF     0x00000002
+#define DMAOR_DME      0x00000001
+
+/* Definitions for the SuperH DMAC */
+#define REQ_L  0x00000000
+#define REQ_E  0x00080000
+#define RACK_H 0x00000000
+#define RACK_L 0x00040000
+#define ACK_R  0x00000000
+#define ACK_W  0x00020000
+#define ACK_H  0x00000000
+#define ACK_L  0x00010000
+#define DM_INC 0x00004000
+#define DM_DEC 0x00008000
+#define DM_FIX 0x0000c000
+#define SM_INC 0x00001000
+#define SM_DEC 0x00002000
+#define SM_FIX 0x00003000
+#define RS_IN  0x00000200
+#define RS_OUT 0x00000300
+#define TS_BLK 0x00000040
+#define TM_BUR 0x00000020
+#define CHCR_DE        0x00000001
+#define CHCR_TE        0x00000002
+#define CHCR_IE        0x00000004
+
+#endif
index 51d288d..0d6cd38 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __SH_INTC_H
 #define __SH_INTC_H
 
+#include <linux/ioport.h>
+
 typedef unsigned char intc_enum;
 
 struct intc_vect {
@@ -21,6 +23,9 @@ struct intc_group {
 struct intc_mask_reg {
        unsigned long set_reg, clr_reg, reg_width;
        intc_enum enum_ids[32];
+#ifdef CONFIG_INTC_BALANCING
+       unsigned long dist_reg;
+#endif
 #ifdef CONFIG_SMP
        unsigned long smp;
 #endif
@@ -39,8 +44,14 @@ struct intc_sense_reg {
        intc_enum enum_ids[16];
 };
 
+#ifdef CONFIG_INTC_BALANCING
+#define INTC_SMP_BALANCING(reg)        .dist_reg = (reg)
+#else
+#define INTC_SMP_BALANCING(reg)
+#endif
+
 #ifdef CONFIG_SMP
-#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8)
+#define INTC_SMP(stride, nr)   .smp = (stride) | ((nr) << 8)
 #else
 #define INTC_SMP(stride, nr)
 #endif
@@ -71,6 +82,8 @@ struct intc_hw_desc {
 
 struct intc_desc {
        char *name;
+       struct resource *resource;
+       unsigned int num_resources;
        intc_enum force_enable;
        intc_enum force_disable;
        struct intc_hw_desc hw;
@@ -92,9 +105,18 @@ struct intc_desc symbol __initdata = {                                      \
                           prio_regs, sense_regs, ack_regs),            \
 }
 
-void __init register_intc_controller(struct intc_desc *desc);
+int __init register_intc_controller(struct intc_desc *desc);
 int intc_set_priority(unsigned int irq, unsigned int prio);
 
+#ifdef CONFIG_INTC_USERIMASK
+int register_intc_userimask(unsigned long addr);
+#else
+static inline int register_intc_userimask(unsigned long addr)
+{
+       return 0;
+}
+#endif
+
 int reserve_irq_vector(unsigned int irq);
 void reserve_irq_legacy(void);
 
index 8a060a7..bb947dd 100644 (file)
@@ -10,6 +10,7 @@
 #define _SMB_FS_SB
 
 #include <linux/types.h>
+#include <linux/backing-dev.h>
 #include <linux/smb.h>
 
 /*
@@ -74,6 +75,8 @@ struct smb_sb_info {
        struct smb_ops *ops;
 
        struct super_block *super_block;
+
+       struct backing_dev_info bdi;
 };
 
 static inline int
index 4d5ecb2..4d5d2f5 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef _LINUX_SRCU_H
 #define _LINUX_SRCU_H
 
+#include <linux/mutex.h>
+
 struct srcu_struct_array {
        int c[2];
 };
@@ -84,8 +86,8 @@ long srcu_batches_completed(struct srcu_struct *sp);
 /**
  * srcu_read_lock_held - might we be in SRCU read-side critical section?
  *
- * If CONFIG_PROVE_LOCKING is selected and enabled, returns nonzero iff in
- * an SRCU read-side critical section.  In absence of CONFIG_PROVE_LOCKING,
+ * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an SRCU
+ * read-side critical section.  In absence of CONFIG_DEBUG_LOCK_ALLOC,
  * this assumes we are in an SRCU read-side critical section unless it can
  * prove otherwise.
  */
index baba3a2..6b524a0 100644 (file)
 #ifndef _LINUX_STOP_MACHINE
 #define _LINUX_STOP_MACHINE
-/* "Bogolock": stop the entire machine, disable interrupts.  This is a
-   very heavy lock, which is equivalent to grabbing every spinlock
-   (and more).  So the "read" side to such a lock is anything which
-   disables preeempt. */
+
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
+#include <linux/list.h>
 #include <asm/system.h>
 
+/*
+ * stop_cpu[s]() is simplistic per-cpu maximum priority cpu
+ * monopolization mechanism.  The caller can specify a non-sleeping
+ * function to be executed on a single or multiple cpus preempting all
+ * other processes and monopolizing those cpus until it finishes.
+ *
+ * Resources for this mechanism are preallocated when a cpu is brought
+ * up and requests are guaranteed to be served as long as the target
+ * cpus are online.
+ */
+typedef int (*cpu_stop_fn_t)(void *arg);
+
+#ifdef CONFIG_SMP
+
+struct cpu_stop_work {
+       struct list_head        list;           /* cpu_stopper->works */
+       cpu_stop_fn_t           fn;
+       void                    *arg;
+       struct cpu_stop_done    *done;
+};
+
+int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg);
+void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg,
+                        struct cpu_stop_work *work_buf);
+int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg);
+int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg);
+
+#else  /* CONFIG_SMP */
+
+#include <linux/workqueue.h>
+
+struct cpu_stop_work {
+       struct work_struct      work;
+       cpu_stop_fn_t           fn;
+       void                    *arg;
+};
+
+static inline int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg)
+{
+       int ret = -ENOENT;
+       preempt_disable();
+       if (cpu == smp_processor_id())
+               ret = fn(arg);
+       preempt_enable();
+       return ret;
+}
+
+static void stop_one_cpu_nowait_workfn(struct work_struct *work)
+{
+       struct cpu_stop_work *stwork =
+               container_of(work, struct cpu_stop_work, work);
+       preempt_disable();
+       stwork->fn(stwork->arg);
+       preempt_enable();
+}
+
+static inline void stop_one_cpu_nowait(unsigned int cpu,
+                                      cpu_stop_fn_t fn, void *arg,
+                                      struct cpu_stop_work *work_buf)
+{
+       if (cpu == smp_processor_id()) {
+               INIT_WORK(&work_buf->work, stop_one_cpu_nowait_workfn);
+               work_buf->fn = fn;
+               work_buf->arg = arg;
+               schedule_work(&work_buf->work);
+       }
+}
+
+static inline int stop_cpus(const struct cpumask *cpumask,
+                           cpu_stop_fn_t fn, void *arg)
+{
+       if (cpumask_test_cpu(raw_smp_processor_id(), cpumask))
+               return stop_one_cpu(raw_smp_processor_id(), fn, arg);
+       return -ENOENT;
+}
+
+static inline int try_stop_cpus(const struct cpumask *cpumask,
+                               cpu_stop_fn_t fn, void *arg)
+{
+       return stop_cpus(cpumask, fn, arg);
+}
+
+#endif /* CONFIG_SMP */
+
+/*
+ * stop_machine "Bogolock": stop the entire machine, disable
+ * interrupts.  This is a very heavy lock, which is equivalent to
+ * grabbing every spinlock (and more).  So the "read" side to such a
+ * lock is anything which disables preeempt.
+ */
 #if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
 
 /**
@@ -36,24 +124,7 @@ int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus);
  */
 int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus);
 
-/**
- * stop_machine_create: create all stop_machine threads
- *
- * Description: This causes all stop_machine threads to be created before
- * stop_machine actually gets called. This can be used by subsystems that
- * need a non failing stop_machine infrastructure.
- */
-int stop_machine_create(void);
-
-/**
- * stop_machine_destroy: destroy all stop_machine threads
- *
- * Description: This causes all stop_machine threads which were created with
- * stop_machine_create to be destroyed again.
- */
-void stop_machine_destroy(void);
-
-#else
+#else   /* CONFIG_STOP_MACHINE && CONFIG_SMP */
 
 static inline int stop_machine(int (*fn)(void *), void *data,
                               const struct cpumask *cpus)
@@ -65,8 +136,5 @@ static inline int stop_machine(int (*fn)(void *), void *data,
        return ret;
 }
 
-static inline int stop_machine_create(void) { return 0; }
-static inline void stop_machine_destroy(void) { }
-
-#endif /* CONFIG_SMP */
-#endif /* _LINUX_STOP_MACHINE */
+#endif /* CONFIG_STOP_MACHINE && CONFIG_SMP */
+#endif /* _LINUX_STOP_MACHINE */
index 996df4d..87d7ec0 100644 (file)
@@ -54,6 +54,7 @@ struct rpc_cred {
 #define RPCAUTH_CRED_NEW       0
 #define RPCAUTH_CRED_UPTODATE  1
 #define RPCAUTH_CRED_HASHED    2
+#define RPCAUTH_CRED_NEGATIVE  3
 
 #define RPCAUTH_CRED_MAGIC     0x0f4aa4f0
 
index d48d4e6..671538d 100644 (file)
@@ -82,6 +82,7 @@ struct gss_cred {
        enum rpc_gss_svc        gc_service;
        struct gss_cl_ctx       *gc_ctx;
        struct gss_upcall_msg   *gc_upcall;
+       unsigned long           gc_upcall_timestamp;
        unsigned char           gc_machine_cred : 1;
 };
 
index 03f3333..5d8048b 100644 (file)
@@ -35,7 +35,8 @@ int gss_import_sec_context(
                const void*             input_token,
                size_t                  bufsize,
                struct gss_api_mech     *mech,
-               struct gss_ctx          **ctx_id);
+               struct gss_ctx          **ctx_id,
+               gfp_t                   gfp_mask);
 u32 gss_get_mic(
                struct gss_ctx          *ctx_id,
                struct xdr_buf          *message,
@@ -80,6 +81,8 @@ struct gss_api_mech {
        /* pseudoflavors supported by this mechanism: */
        int                     gm_pf_num;
        struct pf_desc *        gm_pfs;
+       /* Should the following be a callback operation instead? */
+       const char              *gm_upcall_enctypes;
 };
 
 /* and must provide the following operations: */
@@ -87,7 +90,8 @@ struct gss_api_ops {
        int (*gss_import_sec_context)(
                        const void              *input_token,
                        size_t                  bufsize,
-                       struct gss_ctx          *ctx_id);
+                       struct gss_ctx          *ctx_id,
+                       gfp_t                   gfp_mask);
        u32 (*gss_get_mic)(
                        struct gss_ctx          *ctx_id,
                        struct xdr_buf          *message,
index e7bbdba..5af2931 100644 (file)
@@ -4,7 +4,7 @@
  *  Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
  *  lib/gssapi/krb5/gssapiP_krb5.h, and others
  *
- *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  Copyright (c) 2000-2008 The Regents of the University of Michigan.
  *  All rights reserved.
  *
  *  Andy Adamson   <andros@umich.edu>
  *
  */
 
+#include <linux/crypto.h>
 #include <linux/sunrpc/auth_gss.h>
 #include <linux/sunrpc/gss_err.h>
 #include <linux/sunrpc/gss_asn1.h>
 
+/* Length of constant used in key derivation */
+#define GSS_KRB5_K5CLENGTH (5)
+
+/* Maximum key length (in bytes) for the supported crypto algorithms*/
+#define GSS_KRB5_MAX_KEYLEN (32)
+
+/* Maximum checksum function output for the supported crypto algorithms */
+#define GSS_KRB5_MAX_CKSUM_LEN  (20)
+
+/* Maximum blocksize for the supported crypto algorithms */
+#define GSS_KRB5_MAX_BLOCKSIZE  (16)
+
+struct krb5_ctx;
+
+struct gss_krb5_enctype {
+       const u32               etype;          /* encryption (key) type */
+       const u32               ctype;          /* checksum type */
+       const char              *name;          /* "friendly" name */
+       const char              *encrypt_name;  /* crypto encrypt name */
+       const char              *cksum_name;    /* crypto checksum name */
+       const u16               signalg;        /* signing algorithm */
+       const u16               sealalg;        /* sealing algorithm */
+       const u32               blocksize;      /* encryption blocksize */
+       const u32               conflen;        /* confounder length
+                                                  (normally the same as
+                                                  the blocksize) */
+       const u32               cksumlength;    /* checksum length */
+       const u32               keyed_cksum;    /* is it a keyed cksum? */
+       const u32               keybytes;       /* raw key len, in bytes */
+       const u32               keylength;      /* final key len, in bytes */
+       u32 (*encrypt) (struct crypto_blkcipher *tfm,
+                       void *iv, void *in, void *out,
+                       int length);            /* encryption function */
+       u32 (*decrypt) (struct crypto_blkcipher *tfm,
+                       void *iv, void *in, void *out,
+                       int length);            /* decryption function */
+       u32 (*mk_key) (const struct gss_krb5_enctype *gk5e,
+                      struct xdr_netobj *in,
+                      struct xdr_netobj *out); /* complete key generation */
+       u32 (*encrypt_v2) (struct krb5_ctx *kctx, u32 offset,
+                          struct xdr_buf *buf, int ec,
+                          struct page **pages); /* v2 encryption function */
+       u32 (*decrypt_v2) (struct krb5_ctx *kctx, u32 offset,
+                          struct xdr_buf *buf, u32 *headskip,
+                          u32 *tailskip);      /* v2 decryption function */
+};
+
+/* krb5_ctx flags definitions */
+#define KRB5_CTX_FLAG_INITIATOR         0x00000001
+#define KRB5_CTX_FLAG_CFX               0x00000002
+#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY   0x00000004
+
 struct krb5_ctx {
        int                     initiate; /* 1 = initiating, 0 = accepting */
+       u32                     enctype;
+       u32                     flags;
+       const struct gss_krb5_enctype *gk5e; /* enctype-specific info */
        struct crypto_blkcipher *enc;
        struct crypto_blkcipher *seq;
+       struct crypto_blkcipher *acceptor_enc;
+       struct crypto_blkcipher *initiator_enc;
+       struct crypto_blkcipher *acceptor_enc_aux;
+       struct crypto_blkcipher *initiator_enc_aux;
+       u8                      Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */
+       u8                      cksum[GSS_KRB5_MAX_KEYLEN];
        s32                     endtime;
        u32                     seq_send;
+       u64                     seq_send64;
        struct xdr_netobj       mech_used;
+       u8                      initiator_sign[GSS_KRB5_MAX_KEYLEN];
+       u8                      acceptor_sign[GSS_KRB5_MAX_KEYLEN];
+       u8                      initiator_seal[GSS_KRB5_MAX_KEYLEN];
+       u8                      acceptor_seal[GSS_KRB5_MAX_KEYLEN];
+       u8                      initiator_integ[GSS_KRB5_MAX_KEYLEN];
+       u8                      acceptor_integ[GSS_KRB5_MAX_KEYLEN];
 };
 
 extern spinlock_t krb5_seq_lock;
@@ -57,6 +126,18 @@ extern spinlock_t krb5_seq_lock;
 #define KG_TOK_MIC_MSG    0x0101
 #define KG_TOK_WRAP_MSG   0x0201
 
+#define KG2_TOK_INITIAL     0x0101
+#define KG2_TOK_RESPONSE    0x0202
+#define KG2_TOK_MIC         0x0404
+#define KG2_TOK_WRAP        0x0504
+
+#define KG2_TOKEN_FLAG_SENTBYACCEPTOR   0x01
+#define KG2_TOKEN_FLAG_SEALED           0x02
+#define KG2_TOKEN_FLAG_ACCEPTORSUBKEY   0x04
+
+#define KG2_RESP_FLAG_ERROR             0x0001
+#define KG2_RESP_FLAG_DELEG_OK          0x0002
+
 enum sgn_alg {
        SGN_ALG_DES_MAC_MD5 = 0x0000,
        SGN_ALG_MD2_5 = 0x0001,
@@ -81,6 +162,9 @@ enum seal_alg {
 #define CKSUMTYPE_RSA_MD5_DES          0x0008
 #define CKSUMTYPE_NIST_SHA             0x0009
 #define CKSUMTYPE_HMAC_SHA1_DES3       0x000c
+#define CKSUMTYPE_HMAC_SHA1_96_AES128   0x000f
+#define CKSUMTYPE_HMAC_SHA1_96_AES256   0x0010
+#define CKSUMTYPE_HMAC_MD5_ARCFOUR      -138 /* Microsoft md5 hmac cksumtype */
 
 /* from gssapi_err_krb5.h */
 #define KG_CCACHE_NOMATCH                        (39756032L)
@@ -111,11 +195,56 @@ enum seal_alg {
 #define ENCTYPE_DES3_CBC_RAW    0x0006 /* DES-3 cbc mode raw */
 #define ENCTYPE_DES_HMAC_SHA1   0x0008
 #define ENCTYPE_DES3_CBC_SHA1   0x0010
+#define ENCTYPE_AES128_CTS_HMAC_SHA1_96 0x0011
+#define ENCTYPE_AES256_CTS_HMAC_SHA1_96 0x0012
+#define ENCTYPE_ARCFOUR_HMAC            0x0017
+#define ENCTYPE_ARCFOUR_HMAC_EXP        0x0018
 #define ENCTYPE_UNKNOWN         0x01ff
 
-s32
-make_checksum(char *, char *header, int hdrlen, struct xdr_buf *body,
-                  int body_offset, struct xdr_netobj *cksum);
+/*
+ * Constants used for key derivation
+ */
+/* for 3DES */
+#define KG_USAGE_SEAL (22)
+#define KG_USAGE_SIGN (23)
+#define KG_USAGE_SEQ  (24)
+
+/* from rfc3961 */
+#define KEY_USAGE_SEED_CHECKSUM         (0x99)
+#define KEY_USAGE_SEED_ENCRYPTION       (0xAA)
+#define KEY_USAGE_SEED_INTEGRITY        (0x55)
+
+/* from rfc4121 */
+#define KG_USAGE_ACCEPTOR_SEAL  (22)
+#define KG_USAGE_ACCEPTOR_SIGN  (23)
+#define KG_USAGE_INITIATOR_SEAL (24)
+#define KG_USAGE_INITIATOR_SIGN (25)
+
+/*
+ * This compile-time check verifies that we will not exceed the
+ * slack space allotted by the client and server auth_gss code
+ * before they call gss_wrap().
+ */
+#define GSS_KRB5_MAX_SLACK_NEEDED \
+       (GSS_KRB5_TOK_HDR_LEN     /* gss token header */         \
+       + GSS_KRB5_MAX_CKSUM_LEN  /* gss token checksum */       \
+       + GSS_KRB5_MAX_BLOCKSIZE  /* confounder */               \
+       + GSS_KRB5_MAX_BLOCKSIZE  /* possible padding */         \
+       + GSS_KRB5_TOK_HDR_LEN    /* encrypted hdr in v2 token */\
+       + GSS_KRB5_MAX_CKSUM_LEN  /* encryption hmac */          \
+       + 4 + 4                   /* RPC verifier */             \
+       + GSS_KRB5_TOK_HDR_LEN                                   \
+       + GSS_KRB5_MAX_CKSUM_LEN)
+
+u32
+make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
+               struct xdr_buf *body, int body_offset, u8 *cksumkey,
+               unsigned int usage, struct xdr_netobj *cksumout);
+
+u32
+make_checksum_v2(struct krb5_ctx *, char *header, int hdrlen,
+                struct xdr_buf *body, int body_offset, u8 *key,
+                unsigned int usage, struct xdr_netobj *cksum);
 
 u32 gss_get_mic_kerberos(struct gss_ctx *, struct xdr_buf *,
                struct xdr_netobj *);
@@ -149,11 +278,54 @@ gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *inbuf,
                    int offset);
 
 s32
-krb5_make_seq_num(struct crypto_blkcipher *key,
+krb5_make_seq_num(struct krb5_ctx *kctx,
+               struct crypto_blkcipher *key,
                int direction,
                u32 seqnum, unsigned char *cksum, unsigned char *buf);
 
 s32
-krb5_get_seq_num(struct crypto_blkcipher *key,
+krb5_get_seq_num(struct krb5_ctx *kctx,
               unsigned char *cksum,
               unsigned char *buf, int *direction, u32 *seqnum);
+
+int
+xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen);
+
+u32
+krb5_derive_key(const struct gss_krb5_enctype *gk5e,
+               const struct xdr_netobj *inkey,
+               struct xdr_netobj *outkey,
+               const struct xdr_netobj *in_constant,
+               gfp_t gfp_mask);
+
+u32
+gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e,
+                      struct xdr_netobj *randombits,
+                      struct xdr_netobj *key);
+
+u32
+gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
+                     struct xdr_netobj *randombits,
+                     struct xdr_netobj *key);
+
+u32
+gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
+                    struct xdr_buf *buf, int ec,
+                    struct page **pages);
+
+u32
+gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset,
+                    struct xdr_buf *buf, u32 *plainoffset,
+                    u32 *plainlen);
+
+int
+krb5_rc4_setup_seq_key(struct krb5_ctx *kctx,
+                      struct crypto_blkcipher *cipher,
+                      unsigned char *cksum);
+
+int
+krb5_rc4_setup_enc_key(struct krb5_ctx *kctx,
+                      struct crypto_blkcipher *cipher,
+                      s32 seqnum);
+void
+gss_krb5_make_confounder(char *p, u32 conflen);
index 77f78e5..b6edbc0 100644 (file)
@@ -26,6 +26,7 @@
 #define _LINUX_SUNRPC_METRICS_H
 
 #include <linux/seq_file.h>
+#include <linux/ktime.h>
 
 #define RPC_IOSTATS_VERS       "1.0"
 
@@ -58,9 +59,9 @@ struct rpc_iostats {
         * and the total time the request spent from init to release
         * are measured.
         */
-       unsigned long long      om_queue,       /* jiffies queued for xmit */
-                               om_rtt,         /* jiffies for RPC RTT */
-                               om_execute;     /* jiffies for RPC execution */
+       ktime_t                 om_queue,       /* queued for xmit */
+                               om_rtt,         /* RPC RTT */
+                               om_execute;     /* RPC execution */
 } ____cacheline_aligned;
 
 struct rpc_task;
index 7bc7fd5..7be4f3a 100644 (file)
@@ -10,6 +10,7 @@
 #define _LINUX_SUNRPC_SCHED_H_
 
 #include <linux/timer.h>
+#include <linux/ktime.h>
 #include <linux/sunrpc/types.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
@@ -40,21 +41,15 @@ struct rpc_wait {
  * This is the RPC task struct
  */
 struct rpc_task {
-#ifdef RPC_DEBUG
-       unsigned long           tk_magic;       /* 0xf00baa */
-#endif
        atomic_t                tk_count;       /* Reference count */
        struct list_head        tk_task;        /* global list of tasks */
        struct rpc_clnt *       tk_client;      /* RPC client */
        struct rpc_rqst *       tk_rqstp;       /* RPC request */
-       int                     tk_status;      /* result of last operation */
 
        /*
         * RPC call state
         */
        struct rpc_message      tk_msg;         /* RPC call info */
-       __u8                    tk_garb_retry;
-       __u8                    tk_cred_retry;
 
        /*
         * callback     to be executed after waking up
@@ -67,7 +62,6 @@ struct rpc_task {
        void *                  tk_calldata;
 
        unsigned long           tk_timeout;     /* timeout for rpc_sleep() */
-       unsigned short          tk_flags;       /* misc flags */
        unsigned long           tk_runstate;    /* Task run status */
        struct workqueue_struct *tk_workqueue;  /* Normally rpciod, but could
                                                 * be any workqueue
@@ -78,17 +72,19 @@ struct rpc_task {
                struct rpc_wait         tk_wait;        /* RPC wait */
        } u;
 
-       unsigned short          tk_timeouts;    /* maj timeouts */
-       size_t                  tk_bytes_sent;  /* total bytes sent */
-       unsigned long           tk_start;       /* RPC task init timestamp */
-       long                    tk_rtt;         /* round-trip time (jiffies) */
+       ktime_t                 tk_start;       /* RPC task init timestamp */
 
        pid_t                   tk_owner;       /* Process id for batching tasks */
-       unsigned char           tk_priority : 2;/* Task priority */
+       int                     tk_status;      /* result of last operation */
+       unsigned short          tk_flags;       /* misc flags */
+       unsigned short          tk_timeouts;    /* maj timeouts */
 
 #ifdef RPC_DEBUG
        unsigned short          tk_pid;         /* debugging aid */
 #endif
+       unsigned char           tk_priority : 2,/* Task priority */
+                               tk_garb_retry : 2,
+                               tk_cred_retry : 2;
 };
 #define tk_xprt                        tk_client->cl_xprt
 
index f5cc089..35cf2e8 100644 (file)
@@ -1,7 +1,10 @@
 /*
- * include/linux/sunrpc/xdr.h
+ * XDR standard data types and function declarations
  *
  * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
+ *
+ * Based on:
+ *   RFC 4506 "XDR: External Data Representation Standard", May 2006
  */
 
 #ifndef _SUNRPC_XDR_H_
@@ -62,7 +65,6 @@ struct xdr_buf {
 
        unsigned int    buflen,         /* Total length of storage buffer */
                        len;            /* Length of XDR encoded message */
-
 };
 
 /*
@@ -178,7 +180,7 @@ struct xdr_array2_desc {
 };
 
 extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
-                             struct xdr_array2_desc *desc);
+                            struct xdr_array2_desc *desc);
 extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
                             struct xdr_array2_desc *desc);
 
index 6f9457a..b514703 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/kref.h>
+#include <linux/ktime.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/msg_prot.h>
@@ -65,8 +66,6 @@ struct rpc_rqst {
        struct rpc_task *       rq_task;        /* RPC task data */
        __be32                  rq_xid;         /* request XID */
        int                     rq_cong;        /* has incremented xprt->cong */
-       int                     rq_reply_bytes_recvd;   /* number of reply */
-                                                       /* bytes received */
        u32                     rq_seqno;       /* gss seq no. used on req. */
        int                     rq_enc_pages_num;
        struct page             **rq_enc_pages; /* scratch pages for use by
@@ -77,12 +76,16 @@ struct rpc_rqst {
        __u32 *                 rq_buffer;      /* XDR encode buffer */
        size_t                  rq_callsize,
                                rq_rcvsize;
+       size_t                  rq_xmit_bytes_sent;     /* total bytes sent */
+       size_t                  rq_reply_bytes_recvd;   /* total reply bytes */
+                                                       /* received */
 
        struct xdr_buf          rq_private_buf;         /* The receive buffer
                                                         * used in the softirq.
                                                         */
        unsigned long           rq_majortimeo;  /* major timeout alarm */
        unsigned long           rq_timeout;     /* Current timeout value */
+       ktime_t                 rq_rtt;         /* round-trip time */
        unsigned int            rq_retries;     /* # of retries */
        unsigned int            rq_connect_cookie;
                                                /* A cookie used to track the
@@ -94,7 +97,7 @@ struct rpc_rqst {
         */
        u32                     rq_bytes_sent;  /* Bytes we have sent */
 
-       unsigned long           rq_xtime;       /* when transmitted */
+       ktime_t                 rq_xtime;       /* transmit time stamp */
        int                     rq_ntrans;
 
 #if defined(CONFIG_NFS_V4_1)
@@ -174,8 +177,7 @@ struct rpc_xprt {
        /*
         * Connection of transports
         */
-       unsigned long           connect_timeout,
-                               bind_timeout,
+       unsigned long           bind_timeout,
                                reestablish_timeout;
        unsigned int            connect_cookie; /* A cookie that gets bumped
                                                   every time the transport
@@ -294,7 +296,6 @@ void                        xprt_set_retrans_timeout_rtt(struct rpc_task *task);
 void                   xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
 void                   xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action);
 void                   xprt_write_space(struct rpc_xprt *xprt);
-void                   xprt_update_rtt(struct rpc_task *task);
 void                   xprt_adjust_cwnd(struct rpc_task *task, int result);
 struct rpc_rqst *      xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid);
 void                   xprt_complete_rqst(struct rpc_task *task, int copied);
index d2ae79e..b232ccc 100644 (file)
@@ -42,6 +42,7 @@ enum tick_nohz_mode {
  * @idle_waketime:     Time when the idle was interrupted
  * @idle_exittime:     Time when the idle state was left
  * @idle_sleeptime:    Sum of the time slept in idle with sched tick stopped
+ * @iowait_sleeptime:  Sum of the time slept in idle with sched tick stopped, with IO outstanding
  * @sleep_length:      Duration of the current idle sleep
  * @do_timer_lst:      CPU was the last one doing do_timer before going idle
  */
@@ -60,7 +61,7 @@ struct tick_sched {
        ktime_t                         idle_waketime;
        ktime_t                         idle_exittime;
        ktime_t                         idle_sleeptime;
-       ktime_t                         idle_lastupdate;
+       ktime_t                         iowait_sleeptime;
        ktime_t                         sleep_length;
        unsigned long                   last_jiffies;
        unsigned long                   next_jiffies;
@@ -124,6 +125,7 @@ extern void tick_nohz_stop_sched_tick(int inidle);
 extern void tick_nohz_restart_sched_tick(void);
 extern ktime_t tick_nohz_get_sleep_length(void);
 extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
+extern u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time);
 # else
 static inline void tick_nohz_stop_sched_tick(int inidle) { }
 static inline void tick_nohz_restart_sched_tick(void) { }
@@ -134,6 +136,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void)
        return len;
 }
 static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
+static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
 # endif /* !NO_HZ */
 
 #endif
index 6e026e4..ea3559f 100644 (file)
@@ -150,7 +150,6 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 extern int timekeeping_valid_for_hres(void);
 extern u64 timekeeping_max_deferment(void);
 extern void update_wall_time(void);
-extern void update_xtime_cache(u64 nsec);
 extern void timekeeping_leap_insert(int leapsecond);
 
 struct tms;
index a2d1eb6..ea965b8 100644 (file)
 struct tvec_base;
 
 struct timer_list {
+       /*
+        * All fields that change during normal runtime grouped to the
+        * same cacheline
+        */
        struct list_head entry;
        unsigned long expires;
+       struct tvec_base *base;
 
        void (*function)(unsigned long);
        unsigned long data;
 
-       struct tvec_base *base;
+       int slack;
+
 #ifdef CONFIG_TIMER_STATS
        void *start_site;
        char start_comm[16];
@@ -165,6 +171,8 @@ extern int mod_timer(struct timer_list *timer, unsigned long expires);
 extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
 extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
 
+extern void set_timer_slack(struct timer_list *time, int slack_hz);
+
 #define TIMER_NOT_PINNED       0
 #define TIMER_PINNED           1
 /*
index 7a082b3..32d852f 100644 (file)
@@ -232,13 +232,11 @@ struct timex {
  */
 extern unsigned long tick_usec;                /* USER_HZ period (usec) */
 extern unsigned long tick_nsec;                /* ACTHZ          period (nsec) */
-extern int tickadj;                    /* amount of adjustment per tick */
 
 /*
  * phase-lock loop variables
  */
 extern int time_status;                /* clock synchronization status bits */
-extern long time_adjust;       /* The amount of adjtime left */
 
 extern void ntp_init(void);
 extern void ntp_clear(void);
@@ -271,9 +269,6 @@ extern void second_overflow(void);
 extern void update_ntp_one_tick(void);
 extern int do_adjtimex(struct timex *);
 
-/* Don't use! Compatibility define for existing users. */
-#define tickadj        (500/HZ ? : 1)
-
 int read_current_timer(unsigned long *timer_val);
 
 /* The clock frequency of the i8253/i8254 PIT */
index 78b4bd3..1d85f9a 100644 (file)
@@ -33,6 +33,65 @@ struct tracepoint {
                                         * Keep in sync with vmlinux.lds.h.
                                         */
 
+/*
+ * Connect a probe to a tracepoint.
+ * Internal API, should not be used directly.
+ */
+extern int tracepoint_probe_register(const char *name, void *probe);
+
+/*
+ * Disconnect a probe from a tracepoint.
+ * Internal API, should not be used directly.
+ */
+extern int tracepoint_probe_unregister(const char *name, void *probe);
+
+extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
+extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
+extern void tracepoint_probe_update_all(void);
+
+struct tracepoint_iter {
+       struct module *module;
+       struct tracepoint *tracepoint;
+};
+
+extern void tracepoint_iter_start(struct tracepoint_iter *iter);
+extern void tracepoint_iter_next(struct tracepoint_iter *iter);
+extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
+extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
+extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
+       struct tracepoint *begin, struct tracepoint *end);
+
+/*
+ * tracepoint_synchronize_unregister must be called between the last tracepoint
+ * probe unregistration and the end of module exit to make sure there is no
+ * caller executing a probe when it is freed.
+ */
+static inline void tracepoint_synchronize_unregister(void)
+{
+       synchronize_sched();
+}
+
+#define PARAMS(args...) args
+
+#ifdef CONFIG_TRACEPOINTS
+extern void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end);
+#else
+static inline void tracepoint_update_probe_range(struct tracepoint *begin,
+       struct tracepoint *end)
+{ }
+#endif /* CONFIG_TRACEPOINTS */
+
+#endif /* _LINUX_TRACEPOINT_H */
+
+/*
+ * Note: we keep the TRACE_EVENT and DECLARE_TRACE outside the include
+ *  file ifdef protection.
+ *  This is due to the way trace events work. If a file includes two
+ *  trace event headers under one "CREATE_TRACE_POINTS" the first include
+ *  will override the TRACE_EVENT and break the second include.
+ */
+
 #ifndef DECLARE_TRACE
 
 #define TP_PROTO(args...)      args
@@ -96,9 +155,6 @@ struct tracepoint {
 #define EXPORT_TRACEPOINT_SYMBOL(name)                                 \
        EXPORT_SYMBOL(__tracepoint_##name)
 
-extern void tracepoint_update_probe_range(struct tracepoint *begin,
-       struct tracepoint *end);
-
 #else /* !CONFIG_TRACEPOINTS */
 #define DECLARE_TRACE(name, proto, args)                               \
        static inline void _do_trace_##name(struct tracepoint *tp, proto) \
@@ -119,61 +175,9 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
 #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
 #define EXPORT_TRACEPOINT_SYMBOL(name)
 
-static inline void tracepoint_update_probe_range(struct tracepoint *begin,
-       struct tracepoint *end)
-{ }
 #endif /* CONFIG_TRACEPOINTS */
 #endif /* DECLARE_TRACE */
 
-/*
- * Connect a probe to a tracepoint.
- * Internal API, should not be used directly.
- */
-extern int tracepoint_probe_register(const char *name, void *probe);
-
-/*
- * Disconnect a probe from a tracepoint.
- * Internal API, should not be used directly.
- */
-extern int tracepoint_probe_unregister(const char *name, void *probe);
-
-extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
-extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
-extern void tracepoint_probe_update_all(void);
-
-struct tracepoint_iter {
-       struct module *module;
-       struct tracepoint *tracepoint;
-};
-
-extern void tracepoint_iter_start(struct tracepoint_iter *iter);
-extern void tracepoint_iter_next(struct tracepoint_iter *iter);
-extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
-extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
-extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
-       struct tracepoint *begin, struct tracepoint *end);
-
-/*
- * tracepoint_synchronize_unregister must be called between the last tracepoint
- * probe unregistration and the end of module exit to make sure there is no
- * caller executing a probe when it is freed.
- */
-static inline void tracepoint_synchronize_unregister(void)
-{
-       synchronize_sched();
-}
-
-#define PARAMS(args...) args
-
-#endif /* _LINUX_TRACEPOINT_H */
-
-/*
- * Note: we keep the TRACE_EVENT outside the include file ifdef protection.
- *  This is due to the way trace events work. If a file includes two
- *  trace event headers under one "CREATE_TRACE_POINTS" the first include
- *  will override the TRACE_EVENT and break the second include.
- */
-
 #ifndef TRACE_EVENT
 /*
  * For use with the TRACE_EVENT macro:
index c42724f..23d237a 100644 (file)
@@ -188,12 +188,12 @@ typedef u32 phys_addr_t;
 typedef phys_addr_t resource_size_t;
 
 typedef struct {
-       volatile int counter;
+       int counter;
 } atomic_t;
 
 #ifdef CONFIG_64BIT
 typedef struct {
-       volatile long counter;
+       long counter;
 } atomic64_t;
 #endif
 
index ce1323c..739f1fd 100644 (file)
@@ -1085,7 +1085,7 @@ typedef void (*usb_complete_t)(struct urb *);
  * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
  * which tell the host controller driver that no such mapping is needed since
  * the device driver is DMA-aware.  For example, a device driver might
- * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
+ * allocate a DMA buffer with usb_alloc_coherent() or call usb_buffer_map().
  * When these transfer flags are provided, host controller drivers will
  * attempt to use the dma addresses found in the transfer_dma and/or
  * setup_dma fields rather than determining a dma address themselves.
@@ -1366,11 +1366,23 @@ static inline int usb_urb_dir_out(struct urb *urb)
        return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT;
 }
 
-void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+void *usb_alloc_coherent(struct usb_device *dev, size_t size,
        gfp_t mem_flags, dma_addr_t *dma);
-void usb_buffer_free(struct usb_device *dev, size_t size,
+void usb_free_coherent(struct usb_device *dev, size_t size,
        void *addr, dma_addr_t dma);
 
+/* Compatible macros while we switch over */
+static inline void *usb_buffer_alloc(struct usb_device *dev, size_t size,
+                                    gfp_t mem_flags, dma_addr_t *dma)
+{
+       return usb_alloc_coherent(dev, size, mem_flags, dma);
+}
+static inline void usb_buffer_free(struct usb_device *dev, size_t size,
+                                  void *addr, dma_addr_t dma)
+{
+       return usb_free_coherent(dev, size, addr, dma);
+}
+
 #if 0
 struct urb *usb_buffer_map(struct urb *urb);
 void usb_buffer_dmasync(struct urb *urb);
index a48e16b..76d96d0 100644 (file)
@@ -127,12 +127,26 @@ static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
 /*
  * Used for wake-one threads:
  */
+static inline void __add_wait_queue_exclusive(wait_queue_head_t *q,
+                                             wait_queue_t *wait)
+{
+       wait->flags |= WQ_FLAG_EXCLUSIVE;
+       __add_wait_queue(q, wait);
+}
+
 static inline void __add_wait_queue_tail(wait_queue_head_t *head,
-                                               wait_queue_t *new)
+                                        wait_queue_t *new)
 {
        list_add_tail(&new->task_list, &head->task_list);
 }
 
+static inline void __add_wait_queue_tail_exclusive(wait_queue_head_t *q,
+                                             wait_queue_t *wait)
+{
+       wait->flags |= WQ_FLAG_EXCLUSIVE;
+       __add_wait_queue_tail(q, wait);
+}
+
 static inline void __remove_wait_queue(wait_queue_head_t *head,
                                                        wait_queue_t *old)
 {
@@ -403,25 +417,6 @@ do {                                                                       \
        __ret;                                                          \
 })
 
-/*
- * Must be called with the spinlock in the wait_queue_head_t held.
- */
-static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q,
-                                                  wait_queue_t * wait)
-{
-       wait->flags |= WQ_FLAG_EXCLUSIVE;
-       __add_wait_queue_tail(q,  wait);
-}
-
-/*
- * Must be called with the spinlock in the wait_queue_head_t held.
- */
-static inline void remove_wait_queue_locked(wait_queue_head_t *q,
-                                           wait_queue_t * wait)
-{
-       __remove_wait_queue(q,  wait);
-}
-
 /*
  * These are the old interfaces to sleep waiting for an event.
  * They are racy.  DO NOT use them, use the wait_event* interfaces above.
index 913bfc2..7bf9db5 100644 (file)
@@ -38,8 +38,6 @@
 typedef __u32 zorro_id;
 
 
-#define ZORRO_WILDCARD         (0xffffffff)    /* not official */
-
 /* Include the ID list */
 #include <linux/zorro_ids.h>
 
@@ -116,6 +114,7 @@ struct ConfigDev {
 
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/mod_devicetable.h>
 
 #include <asm/zorro.h>
 
@@ -142,28 +141,9 @@ struct zorro_dev {
      *  Zorro bus
      */
 
-struct zorro_bus {
-    struct list_head devices;          /* list of devices on this bus */
-    unsigned int num_resources;                /* number of resources */
-    struct resource resources[4];      /* address space routed to this bus */
-    struct device dev;
-    char name[10];
-};
-
-extern struct zorro_bus zorro_bus;     /* single Zorro bus */
 extern struct bus_type zorro_bus_type;
 
 
-    /*
-     *  Zorro device IDs
-     */
-
-struct zorro_device_id {
-       zorro_id id;                    /* Device ID or ZORRO_WILDCARD */
-       unsigned long driver_data;      /* Data private to the driver */
-};
-
-
     /*
      *  Zorro device drivers
      */
index b9da1f5..4aeff96 100644 (file)
@@ -188,7 +188,6 @@ void saa7146_buffer_timeout(unsigned long data);
 void saa7146_dma_free(struct saa7146_dev* dev,struct videobuf_queue *q,
                                                struct saa7146_buf *buf);
 
-int saa7146_vv_devinit(struct saa7146_dev *dev);
 int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv);
 int saa7146_vv_release(struct saa7146_dev* dev);
 
index 8be5135..2c55a7e 100644 (file)
@@ -107,6 +107,7 @@ typedef enum {
        SCTP_CMD_T1_RETRAN,      /* Mark for retransmission after T1 timeout  */
        SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
        SCTP_CMD_SEND_MSG,       /* Send the whole use message */
+       SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index 78740ec..fa6cde5 100644 (file)
@@ -128,6 +128,7 @@ extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
 int sctp_inet_listen(struct socket *sock, int backlog);
 void sctp_write_space(struct sock *sk);
+void sctp_data_ready(struct sock *sk, int len);
 unsigned int sctp_poll(struct file *file, struct socket *sock,
                poll_table *wait);
 void sctp_sock_rfree(struct sk_buff *skb);
index 851c813..61d73e3 100644 (file)
@@ -279,6 +279,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
 /* 2nd level prototypes */
 void sctp_generate_t3_rtx_event(unsigned long peer);
 void sctp_generate_heartbeat_event(unsigned long peer);
+void sctp_generate_proto_unreach_event(unsigned long peer);
 
 void sctp_ootb_pkt_free(struct sctp_packet *);
 
index ff30177..219043a 100644 (file)
@@ -778,6 +778,7 @@ int sctp_user_addto_chunk(struct sctp_chunk *chunk, int off, int len,
                          struct iovec *data);
 void sctp_chunk_free(struct sctp_chunk *);
 void  *sctp_addto_chunk(struct sctp_chunk *, int len, const void *data);
+void  *sctp_addto_chunk_fixed(struct sctp_chunk *, int len, const void *data);
 struct sctp_chunk *sctp_chunkify(struct sk_buff *,
                                 const struct sctp_association *,
                                 struct sock *);
@@ -1009,6 +1010,9 @@ struct sctp_transport {
        /* Heartbeat timer is per destination. */
        struct timer_list hb_timer;
 
+       /* Timer to handle ICMP proto unreachable envets */
+       struct timer_list proto_unreach_timer;
+
        /* Since we're using per-destination retransmission timers
         * (see above), we're also using per-destination "transmitted"
         * queues.  This probably ought to be a private struct
index b4603cd..1ad6435 100644 (file)
@@ -74,7 +74,7 @@
                                        printk(KERN_DEBUG msg); } while (0)
 #else
 /* Validate arguments and do nothing */
-static void inline int __attribute__ ((format (printf, 2, 3)))
+static inline void __attribute__ ((format (printf, 2, 3)))
 SOCK_DEBUG(struct sock *sk, const char *msg, ...)
 {
 }
index 75be5a2..aa04b9a 100644 (file)
@@ -1197,30 +1197,15 @@ extern int                      tcp_v4_md5_do_del(struct sock *sk,
 extern struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *);
 extern void                    tcp_free_md5sig_pool(void);
 
-extern struct tcp_md5sig_pool  *__tcp_get_md5sig_pool(int cpu);
-extern void                    __tcp_put_md5sig_pool(void);
+extern struct tcp_md5sig_pool  *tcp_get_md5sig_pool(void);
+extern void                    tcp_put_md5sig_pool(void);
+
 extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, struct tcphdr *);
 extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, struct sk_buff *,
                                 unsigned header_len);
 extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp,
                            struct tcp_md5sig_key *key);
 
-static inline
-struct tcp_md5sig_pool         *tcp_get_md5sig_pool(void)
-{
-       int cpu = get_cpu();
-       struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
-       if (!ret)
-               put_cpu();
-       return ret;
-}
-
-static inline void             tcp_put_md5sig_pool(void)
-{
-       __tcp_put_md5sig_pool();
-       put_cpu();
-}
-
 /* write queue abstraction */
 static inline void tcp_write_queue_purge(struct sock *sk)
 {
index 15ef962..468551e 100644 (file)
@@ -183,6 +183,10 @@ extern int  sysctl_x25_clear_request_timeout;
 extern int  sysctl_x25_ack_holdback_timeout;
 extern int  sysctl_x25_forward;
 
+extern int x25_parse_address_block(struct sk_buff *skb,
+               struct x25_address *called_addr,
+               struct x25_address *calling_addr);
+
 extern int  x25_addr_ntoa(unsigned char *, struct x25_address *,
                          struct x25_address *);
 extern int  x25_addr_aton(unsigned char *, struct x25_address *,
index d57847f..aab3c13 100644 (file)
@@ -26,6 +26,7 @@
 #ifdef __KERNEL__
 #include <linux/device.h>
 #include <pcmcia/ss.h>
+#include <asm/atomic.h>
 
 /*
  * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
@@ -94,10 +95,8 @@ struct pcmcia_device {
        config_req_t            conf;
        window_handle_t         win;
 
-       /* Is the device suspended, or in the process of
-        * being removed? */
+       /* Is the device suspended? */
        u16                     suspended:1;
-       u16                     _removed:1;
 
        /* Flags whether io, irq, win configurations were
         * requested, and whether the configuration is "locked" */
@@ -115,7 +114,7 @@ struct pcmcia_device {
        u16                     has_card_id:1;
        u16                     has_func_id:1;
 
-       u16                     reserved:3;
+       u16                     reserved:4;
 
        u8                      func_id;
        u16                     manf_id;
index 2e488b6..344705c 100644 (file)
@@ -224,18 +224,16 @@ struct pcmcia_socket {
 
        /* 16-bit state: */
        struct {
-               /* PCMCIA card is present in socket */
-               u8                      present:1;
                /* "master" ioctl is used */
                u8                      busy:1;
-               /* pcmcia module is being unloaded */
-               u8                      dead:1;
                /* the PCMCIA card consists of two pseudo devices */
                u8                      has_pfc:1;
 
-               u8                      reserved:4;
+               u8                      reserved:6;
        } pcmcia_state;
 
+       /* non-zero if PCMCIA card is present */
+       atomic_t                        present;
 
 #ifdef CONFIG_PCMCIA_IOCTL
        struct user_info_t              *user;
index 5acfb1e..1dfab54 100644 (file)
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
+/* Make all open coded DECLARE_TRACE nops */
+#undef DECLARE_TRACE
+#define DECLARE_TRACE(name, proto, args)
+
 #ifdef CONFIG_EVENT_TRACING
 #include <trace/ftrace.h>
 #endif
@@ -75,6 +79,7 @@
 #undef DEFINE_EVENT
 #undef DEFINE_EVENT_PRINT
 #undef TRACE_HEADER_MULTI_READ
+#undef DECLARE_TRACE
 
 /* Only undef what we defined in this file */
 #ifdef UNDEF_TRACE_INCLUDE_FILE
index 5c1dcfc..2821b86 100644 (file)
@@ -35,15 +35,15 @@ TRACE_EVENT(lock_acquire,
                  __get_str(name))
 );
 
-TRACE_EVENT(lock_release,
+DECLARE_EVENT_CLASS(lock,
 
-       TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
+       TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-       TP_ARGS(lock, nested, ip),
+       TP_ARGS(lock, ip),
 
        TP_STRUCT__entry(
-               __string(name, lock->name)
-               __field(void *, lockdep_addr)
+               __string(       name,   lock->name      )
+               __field(        void *, lockdep_addr    )
        ),
 
        TP_fast_assign(
@@ -51,51 +51,30 @@ TRACE_EVENT(lock_release,
                __entry->lockdep_addr = lock;
        ),
 
-       TP_printk("%p %s",
-                 __entry->lockdep_addr, __get_str(name))
+       TP_printk("%p %s",  __entry->lockdep_addr, __get_str(name))
 );
 
-#ifdef CONFIG_LOCK_STAT
-
-TRACE_EVENT(lock_contended,
+DEFINE_EVENT(lock, lock_release,
 
        TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-       TP_ARGS(lock, ip),
+       TP_ARGS(lock, ip)
+);
 
-       TP_STRUCT__entry(
-               __string(name, lock->name)
-               __field(void *, lockdep_addr)
-       ),
+#ifdef CONFIG_LOCK_STAT
 
-       TP_fast_assign(
-               __assign_str(name, lock->name);
-               __entry->lockdep_addr = lock;
-       ),
+DEFINE_EVENT(lock, lock_contended,
 
-       TP_printk("%p %s",
-                 __entry->lockdep_addr, __get_str(name))
-);
+       TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-TRACE_EVENT(lock_acquired,
-       TP_PROTO(struct lockdep_map *lock, unsigned long ip, s64 waittime),
+       TP_ARGS(lock, ip)
+);
 
-       TP_ARGS(lock, ip, waittime),
+DEFINE_EVENT(lock, lock_acquired,
 
-       TP_STRUCT__entry(
-               __string(name, lock->name)
-               __field(s64, wait_nsec)
-               __field(void *, lockdep_addr)
-       ),
+       TP_PROTO(struct lockdep_map *lock, unsigned long ip),
 
-       TP_fast_assign(
-               __assign_str(name, lock->name);
-               __entry->wait_nsec = waittime;
-               __entry->lockdep_addr = lock;
-       ),
-       TP_printk("%p %s (%llu ns)", __entry->lockdep_addr,
-                 __get_str(name),
-                 __entry->wait_nsec)
+       TP_ARGS(lock, ip)
 );
 
 #endif
index 4b0f48b..c7bb2f0 100644 (file)
@@ -51,11 +51,14 @@ TRACE_EVENT(module_free,
        TP_printk("%s", __get_str(name))
 );
 
+#ifdef CONFIG_MODULE_UNLOAD
+/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */
+
 DECLARE_EVENT_CLASS(module_refcnt,
 
-       TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
+       TP_PROTO(struct module *mod, unsigned long ip),
 
-       TP_ARGS(mod, ip, refcnt),
+       TP_ARGS(mod, ip),
 
        TP_STRUCT__entry(
                __field(        unsigned long,  ip              )
@@ -65,7 +68,7 @@ DECLARE_EVENT_CLASS(module_refcnt,
 
        TP_fast_assign(
                __entry->ip     = ip;
-               __entry->refcnt = refcnt;
+               __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs);
                __assign_str(name, mod->name);
        ),
 
@@ -75,17 +78,18 @@ DECLARE_EVENT_CLASS(module_refcnt,
 
 DEFINE_EVENT(module_refcnt, module_get,
 
-       TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
+       TP_PROTO(struct module *mod, unsigned long ip),
 
-       TP_ARGS(mod, ip, refcnt)
+       TP_ARGS(mod, ip)
 );
 
 DEFINE_EVENT(module_refcnt, module_put,
 
-       TP_PROTO(struct module *mod, unsigned long ip, int refcnt),
+       TP_PROTO(struct module *mod, unsigned long ip),
 
-       TP_ARGS(mod, ip, refcnt)
+       TP_ARGS(mod, ip)
 );
+#endif /* CONFIG_MODULE_UNLOAD */
 
 TRACE_EVENT(module_request,
 
index a8989c4..188deca 100644 (file)
@@ -1,4 +1,7 @@
-#ifndef _TRACE_NAPI_H_
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM napi
+
+#if !defined(_TRACE_NAPI_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_NAPI_H_
 
 #include <linux/netdevice.h>
@@ -8,4 +11,7 @@ DECLARE_TRACE(napi_poll,
        TP_PROTO(struct napi_struct *napi),
        TP_ARGS(napi));
 
-#endif
+#endif /* _TRACE_NAPI_H_ */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index cfceb0b..4f733ec 100644 (file)
@@ -51,15 +51,12 @@ TRACE_EVENT(sched_kthread_stop_ret,
 
 /*
  * Tracepoint for waiting on task to unschedule:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 TRACE_EVENT(sched_wait_task,
 
-       TP_PROTO(struct rq *rq, struct task_struct *p),
+       TP_PROTO(struct task_struct *p),
 
-       TP_ARGS(rq, p),
+       TP_ARGS(p),
 
        TP_STRUCT__entry(
                __array(        char,   comm,   TASK_COMM_LEN   )
@@ -79,15 +76,12 @@ TRACE_EVENT(sched_wait_task,
 
 /*
  * Tracepoint for waking up a task:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 DECLARE_EVENT_CLASS(sched_wakeup_template,
 
-       TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+       TP_PROTO(struct task_struct *p, int success),
 
-       TP_ARGS(rq, p, success),
+       TP_ARGS(p, success),
 
        TP_STRUCT__entry(
                __array(        char,   comm,   TASK_COMM_LEN   )
@@ -111,31 +105,25 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
 );
 
 DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
-            TP_PROTO(struct rq *rq, struct task_struct *p, int success),
-            TP_ARGS(rq, p, success));
+            TP_PROTO(struct task_struct *p, int success),
+            TP_ARGS(p, success));
 
 /*
  * Tracepoint for waking up a new task:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
-            TP_PROTO(struct rq *rq, struct task_struct *p, int success),
-            TP_ARGS(rq, p, success));
+            TP_PROTO(struct task_struct *p, int success),
+            TP_ARGS(p, success));
 
 /*
  * Tracepoint for task switches, performed by the scheduler:
- *
- * (NOTE: the 'rq' argument is not used by generic trace events,
- *        but used by the latency tracer plugin. )
  */
 TRACE_EVENT(sched_switch,
 
-       TP_PROTO(struct rq *rq, struct task_struct *prev,
+       TP_PROTO(struct task_struct *prev,
                 struct task_struct *next),
 
-       TP_ARGS(rq, prev, next),
+       TP_ARGS(prev, next),
 
        TP_STRUCT__entry(
                __array(        char,   prev_comm,      TASK_COMM_LEN   )
index a510b75..814566c 100644 (file)
@@ -100,18 +100,7 @@ TRACE_EVENT(signal_deliver,
                  __entry->sa_handler, __entry->sa_flags)
 );
 
-/**
- * signal_overflow_fail - called when signal queue is overflow
- * @sig: signal number
- * @group: signal to process group or not (bool)
- * @info: pointer to struct siginfo
- *
- * Kernel fails to generate 'sig' signal with 'info' siginfo, because
- * siginfo queue is overflow, and the signal is dropped.
- * 'group' is not 0 if the signal will be sent to a process group.
- * 'sig' is always one of RT signals.
- */
-TRACE_EVENT(signal_overflow_fail,
+DECLARE_EVENT_CLASS(signal_queue_overflow,
 
        TP_PROTO(int sig, int group, struct siginfo *info),
 
@@ -134,6 +123,24 @@ TRACE_EVENT(signal_overflow_fail,
                  __entry->sig, __entry->group, __entry->errno, __entry->code)
 );
 
+/**
+ * signal_overflow_fail - called when signal queue is overflow
+ * @sig: signal number
+ * @group: signal to process group or not (bool)
+ * @info: pointer to struct siginfo
+ *
+ * Kernel fails to generate 'sig' signal with 'info' siginfo, because
+ * siginfo queue is overflow, and the signal is dropped.
+ * 'group' is not 0 if the signal will be sent to a process group.
+ * 'sig' is always one of RT signals.
+ */
+DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail,
+
+       TP_PROTO(int sig, int group, struct siginfo *info),
+
+       TP_ARGS(sig, group, info)
+);
+
 /**
  * signal_lose_info - called when siginfo is lost
  * @sig: signal number
@@ -145,28 +152,13 @@ TRACE_EVENT(signal_overflow_fail,
  * 'group' is not 0 if the signal will be sent to a process group.
  * 'sig' is always one of non-RT signals.
  */
-TRACE_EVENT(signal_lose_info,
+DEFINE_EVENT(signal_queue_overflow, signal_lose_info,
 
        TP_PROTO(int sig, int group, struct siginfo *info),
 
-       TP_ARGS(sig, group, info),
-
-       TP_STRUCT__entry(
-               __field(        int,    sig     )
-               __field(        int,    group   )
-               __field(        int,    errno   )
-               __field(        int,    code    )
-       ),
-
-       TP_fast_assign(
-               __entry->sig    = sig;
-               __entry->group  = group;
-               TP_STORE_SIGINFO(__entry, info);
-       ),
-
-       TP_printk("sig=%d group=%d errno=%d code=%d",
-                 __entry->sig, __entry->group, __entry->errno, __entry->code)
+       TP_ARGS(sig, group, info)
 );
+
 #endif /* _TRACE_SIGNAL_H */
 
 /* This part must be outside protection */
index ea6f9d4..16253db 100644 (file)
  *
  *     field = (typeof(field))entry;
  *
- *     p = get_cpu_var(ftrace_event_seq);
+ *     p = &get_cpu_var(ftrace_event_seq);
  *     trace_seq_init(p);
- *     ret = trace_seq_printf(s, <TP_printk> "\n");
+ *     ret = trace_seq_printf(s, "%s: ", <call>);
+ *     if (ret)
+ *             ret = trace_seq_printf(s, <TP_printk> "\n");
  *     put_cpu();
  *     if (!ret)
  *             return TRACE_TYPE_PARTIAL_LINE;
@@ -450,38 +452,38 @@ perf_trace_disable_##name(struct ftrace_event_call *unused)               \
  *
  * static void ftrace_raw_event_<call>(proto)
  * {
+ *     struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
  *     struct ring_buffer_event *event;
  *     struct ftrace_raw_<call> *entry; <-- defined in stage 1
  *     struct ring_buffer *buffer;
  *     unsigned long irq_flags;
+ *     int __data_size;
  *     int pc;
  *
  *     local_save_flags(irq_flags);
  *     pc = preempt_count();
  *
+ *     __data_size = ftrace_get_offsets_<call>(&__data_offsets, args);
+ *
  *     event = trace_current_buffer_lock_reserve(&buffer,
  *                               event_<call>.id,
- *                               sizeof(struct ftrace_raw_<call>),
+ *                               sizeof(*entry) + __data_size,
  *                               irq_flags, pc);
  *     if (!event)
  *             return;
  *     entry   = ring_buffer_event_data(event);
  *
- *     <assign>;  <-- Here we assign the entries by the __field and
- *                     __array macros.
+ *     { <assign>; }  <-- Here we assign the entries by the __field and
+ *                        __array macros.
  *
- *     trace_current_buffer_unlock_commit(buffer, event, irq_flags, pc);
+ *     if (!filter_current_check_discard(buffer, event_call, entry, event))
+ *             trace_current_buffer_unlock_commit(buffer,
+ *                                                event, irq_flags, pc);
  * }
  *
  * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused)
  * {
- *     int ret;
- *
- *     ret = register_trace_<call>(ftrace_raw_event_<call>);
- *     if (!ret)
- *             pr_info("event trace: Could not activate trace point "
- *                     "probe to <call>");
- *     return ret;
+ *     return register_trace_<call>(ftrace_raw_event_<call>);
  * }
  *
  * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused)
@@ -493,6 +495,8 @@ perf_trace_disable_##name(struct ftrace_event_call *unused)         \
  *     .trace                  = ftrace_raw_output_<call>, <-- stage 2
  * };
  *
+ * static const char print_fmt_<call>[] = <TP_printk>;
+ *
  * static struct ftrace_event_call __used
  * __attribute__((__aligned__(4)))
  * __attribute__((section("_ftrace_events"))) event_<call> = {
@@ -501,6 +505,8 @@ perf_trace_disable_##name(struct ftrace_event_call *unused)         \
  *     .raw_init               = trace_event_raw_init,
  *     .regfunc                = ftrace_reg_event_<call>,
  *     .unregfunc              = ftrace_unreg_event_<call>,
+ *     .print_fmt              = print_fmt_<call>,
+ *     .define_fields          = ftrace_define_fields_<call>,
  * }
  *
  */
@@ -569,7 +575,6 @@ ftrace_raw_event_id_##call(struct ftrace_event_call *event_call,    \
                return;                                                 \
        entry   = ring_buffer_event_data(event);                        \
                                                                        \
-                                                                       \
        tstruct                                                         \
                                                                        \
        { assign; }                                                     \
@@ -758,13 +763,12 @@ __attribute__((section("_ftrace_events"))) event_##call = {               \
 #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
 static notrace void                                                    \
 perf_trace_templ_##call(struct ftrace_event_call *event_call,          \
-                           proto)                                      \
+                       struct pt_regs *__regs, proto)                  \
 {                                                                      \
        struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
        struct ftrace_raw_##call *entry;                                \
        u64 __addr = 0, __count = 1;                                    \
        unsigned long irq_flags;                                        \
-       struct pt_regs *__regs;                                         \
        int __entry_size;                                               \
        int __data_size;                                                \
        int rctx;                                                       \
@@ -785,20 +789,22 @@ perf_trace_templ_##call(struct ftrace_event_call *event_call,             \
                                                                        \
        { assign; }                                                     \
                                                                        \
-       __regs = &__get_cpu_var(perf_trace_regs);                       \
-       perf_fetch_caller_regs(__regs, 2);                              \
-                                                                       \
        perf_trace_buf_submit(entry, __entry_size, rctx, __addr,        \
                               __count, irq_flags, __regs);             \
 }
 
 #undef DEFINE_EVENT
-#define DEFINE_EVENT(template, call, proto, args)              \
-static notrace void perf_trace_##call(proto)                   \
-{                                                              \
-       struct ftrace_event_call *event_call = &event_##call;   \
-                                                               \
-       perf_trace_templ_##template(event_call, args);          \
+#define DEFINE_EVENT(template, call, proto, args)                      \
+static notrace void perf_trace_##call(proto)                           \
+{                                                                      \
+       struct ftrace_event_call *event_call = &event_##call;           \
+       struct pt_regs *__regs = &get_cpu_var(perf_trace_regs);         \
+                                                                       \
+       perf_fetch_caller_regs(__regs, 1);                              \
+                                                                       \
+       perf_trace_templ_##template(event_call, __regs, args);          \
+                                                                       \
+       put_cpu_var(perf_trace_regs);                                   \
 }
 
 #undef DEFINE_EVENT_PRINT
index eb77e8c..5fe94b8 100644 (file)
@@ -604,8 +604,7 @@ config RT_GROUP_SCHED
        default n
        help
          This feature lets you explicitly allocate real CPU bandwidth
-         to users or control groups (depending on the "Basis for grouping tasks"
-         setting below. If enabled, it will also make it impossible to
+         to task groups. If enabled, it will also make it impossible to
          schedule realtime tasks for non-root users until you allocate
          realtime bandwidth for them.
          See Documentation/scheduler/sched-rt-group.txt for more information.
index 37d3859..4b9c202 100644 (file)
@@ -457,7 +457,8 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len)
                                         compress_name);
                                message = msg_buf;
                        }
-               }
+               } else
+                       error("junk in compressed archive");
                if (state != Reset)
                        error("junk in compressed archive");
                this_header = saved_offset + my_inptr;
index 722b013..5108232 100644 (file)
@@ -158,7 +158,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
                            u->mq_bytes + mq_bytes >
                            task_rlimit(p, RLIMIT_MSGQUEUE)) {
                                spin_unlock(&mq_lock);
-                               kfree(info->messages);
+                               /* mqueue_delete_inode() releases info->messages */
                                goto out_inode;
                        }
                        u->mq_bytes += mq_bytes;
@@ -429,7 +429,7 @@ static void wq_add(struct mqueue_inode_info *info, int sr,
  * sr: SEND or RECV
  */
 static int wq_sleep(struct mqueue_inode_info *info, int sr,
-                       long timeout, struct ext_wait_queue *ewp)
+                   ktime_t *timeout, struct ext_wait_queue *ewp)
 {
        int retval;
        signed long time;
@@ -440,7 +440,8 @@ static int wq_sleep(struct mqueue_inode_info *info, int sr,
                set_current_state(TASK_INTERRUPTIBLE);
 
                spin_unlock(&info->lock);
-               time = schedule_timeout(timeout);
+               time = schedule_hrtimeout_range_clock(timeout,
+                   HRTIMER_MODE_ABS, 0, CLOCK_REALTIME);
 
                while (ewp->state == STATE_PENDING)
                        cpu_relax();
@@ -552,31 +553,16 @@ static void __do_notify(struct mqueue_inode_info *info)
        wake_up(&info->wait_q);
 }
 
-static long prepare_timeout(struct timespec *p)
+static int prepare_timeout(const struct timespec __user *u_abs_timeout,
+                          ktime_t *expires, struct timespec *ts)
 {
-       struct timespec nowts;
-       long timeout;
-
-       if (p) {
-               if (unlikely(p->tv_nsec < 0 || p->tv_sec < 0
-                       || p->tv_nsec >= NSEC_PER_SEC))
-                       return -EINVAL;
-               nowts = CURRENT_TIME;
-               /* first subtract as jiffies can't be too big */
-               p->tv_sec -= nowts.tv_sec;
-               if (p->tv_nsec < nowts.tv_nsec) {
-                       p->tv_nsec += NSEC_PER_SEC;
-                       p->tv_sec--;
-               }
-               p->tv_nsec -= nowts.tv_nsec;
-               if (p->tv_sec < 0)
-                       return 0;
-
-               timeout = timespec_to_jiffies(p) + 1;
-       } else
-               return MAX_SCHEDULE_TIMEOUT;
+       if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec)))
+               return -EFAULT;
+       if (!timespec_valid(ts))
+               return -EINVAL;
 
-       return timeout;
+       *expires = timespec_to_ktime(*ts);
+       return 0;
 }
 
 static void remove_notification(struct mqueue_inode_info *info)
@@ -862,22 +848,21 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
        struct ext_wait_queue *receiver;
        struct msg_msg *msg_ptr;
        struct mqueue_inode_info *info;
-       struct timespec ts, *p = NULL;
-       long timeout;
+       ktime_t expires, *timeout = NULL;
+       struct timespec ts;
        int ret;
 
        if (u_abs_timeout) {
-               if (copy_from_user(&ts, u_abs_timeout, 
-                                       sizeof(struct timespec)))
-                       return -EFAULT;
-               p = &ts;
+               int res = prepare_timeout(u_abs_timeout, &expires, &ts);
+               if (res)
+                       return res;
+               timeout = &expires;
        }
 
        if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
                return -EINVAL;
 
-       audit_mq_sendrecv(mqdes, msg_len, msg_prio, p);
-       timeout = prepare_timeout(p);
+       audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL);
 
        filp = fget(mqdes);
        if (unlikely(!filp)) {
@@ -919,9 +904,6 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
                if (filp->f_flags & O_NONBLOCK) {
                        spin_unlock(&info->lock);
                        ret = -EAGAIN;
-               } else if (unlikely(timeout < 0)) {
-                       spin_unlock(&info->lock);
-                       ret = timeout;
                } else {
                        wait.task = current;
                        wait.msg = (void *) msg_ptr;
@@ -954,24 +936,23 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
                size_t, msg_len, unsigned int __user *, u_msg_prio,
                const struct timespec __user *, u_abs_timeout)
 {
-       long timeout;
        ssize_t ret;
        struct msg_msg *msg_ptr;
        struct file *filp;
        struct inode *inode;
        struct mqueue_inode_info *info;
        struct ext_wait_queue wait;
-       struct timespec ts, *p = NULL;
+       ktime_t expires, *timeout = NULL;
+       struct timespec ts;
 
        if (u_abs_timeout) {
-               if (copy_from_user(&ts, u_abs_timeout, 
-                                       sizeof(struct timespec)))
-                       return -EFAULT;
-               p = &ts;
+               int res = prepare_timeout(u_abs_timeout, &expires, &ts);
+               if (res)
+                       return res;
+               timeout = &expires;
        }
 
-       audit_mq_sendrecv(mqdes, msg_len, 0, p);
-       timeout = prepare_timeout(p);
+       audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL);
 
        filp = fget(mqdes);
        if (unlikely(!filp)) {
@@ -1003,11 +984,6 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
                if (filp->f_flags & O_NONBLOCK) {
                        spin_unlock(&info->lock);
                        ret = -EAGAIN;
-                       msg_ptr = NULL;
-               } else if (unlikely(timeout < 0)) {
-                       spin_unlock(&info->lock);
-                       ret = timeout;
-                       msg_ptr = NULL;
                } else {
                        wait.task = current;
                        wait.state = STATE_NONE;
index a987aa1..149e18e 100644 (file)
@@ -68,7 +68,7 @@ obj-$(CONFIG_USER_NS) += user_namespace.o
 obj-$(CONFIG_PID_NS) += pid_namespace.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o
-obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+obj-$(CONFIG_SMP) += stop_machine.o
 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o audit_watch.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
index 24f8c81..385b884 100644 (file)
@@ -216,7 +216,6 @@ static int acct_on(char *name)
 {
        struct file *file;
        struct vfsmount *mnt;
-       int error;
        struct pid_namespace *ns;
        struct bsd_acct_struct *acct = NULL;
 
@@ -244,13 +243,6 @@ static int acct_on(char *name)
                }
        }
 
-       error = security_acct(file);
-       if (error) {
-               kfree(acct);
-               filp_close(file, NULL);
-               return error;
-       }
-
        spin_lock(&acct_lock);
        if (ns->bacct == NULL) {
                ns->bacct = acct;
@@ -281,7 +273,7 @@ static int acct_on(char *name)
  */
 SYSCALL_DEFINE1(acct, const char __user *, name)
 {
-       int error;
+       int error = 0;
 
        if (!capable(CAP_SYS_PACCT))
                return -EPERM;
@@ -299,13 +291,11 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
                if (acct == NULL)
                        return 0;
 
-               error = security_acct(NULL);
-               if (!error) {
-                       spin_lock(&acct_lock);
-                       acct_file_reopen(acct, NULL, NULL);
-                       spin_unlock(&acct_lock);
-               }
+               spin_lock(&acct_lock);
+               acct_file_reopen(acct, NULL, NULL);
+               spin_unlock(&acct_lock);
        }
+
        return error;
 }
 
@@ -353,17 +343,18 @@ restart:
 
 void acct_exit_ns(struct pid_namespace *ns)
 {
-       struct bsd_acct_struct *acct;
+       struct bsd_acct_struct *acct = ns->bacct;
 
-       spin_lock(&acct_lock);
-       acct = ns->bacct;
-       if (acct != NULL) {
-               if (acct->file != NULL)
-                       acct_file_reopen(acct, NULL, NULL);
+       if (acct == NULL)
+               return;
 
-               kfree(acct);
-       }
+       del_timer_sync(&acct->timer);
+       spin_lock(&acct_lock);
+       if (acct->file != NULL)
+               acct_file_reopen(acct, NULL, NULL);
        spin_unlock(&acct_lock);
+
+       kfree(acct);
 }
 
 /*
index 9e4697e..2f05303 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/syscalls.h>
 #include <linux/pid_namespace.h>
 #include <asm/uaccess.h>
-#include "cred-internals.h"
 
 /*
  * Leveraged for setting/resetting capabilities
index e2769e1..e9ec642 100644 (file)
@@ -1646,7 +1646,9 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
 int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
 {
        char *start;
-       struct dentry *dentry = rcu_dereference(cgrp->dentry);
+       struct dentry *dentry = rcu_dereference_check(cgrp->dentry,
+                                                     rcu_read_lock_held() ||
+                                                     cgroup_lock_is_held());
 
        if (!dentry || cgrp == dummytop) {
                /*
@@ -1662,13 +1664,17 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
        *--start = '\0';
        for (;;) {
                int len = dentry->d_name.len;
+
                if ((start -= len) < buf)
                        return -ENAMETOOLONG;
-               memcpy(start, cgrp->dentry->d_name.name, len);
+               memcpy(start, dentry->d_name.name, len);
                cgrp = cgrp->parent;
                if (!cgrp)
                        break;
-               dentry = rcu_dereference(cgrp->dentry);
+
+               dentry = rcu_dereference_check(cgrp->dentry,
+                                              rcu_read_lock_held() ||
+                                              cgroup_lock_is_held());
                if (!cgrp->parent)
                        continue;
                if (--start < buf)
@@ -3010,7 +3016,7 @@ static int cgroup_event_wake(wait_queue_t *wait, unsigned mode,
        unsigned long flags = (unsigned long)key;
 
        if (flags & POLLHUP) {
-               remove_wait_queue_locked(event->wqh, &event->wait);
+               __remove_wait_queue(event->wqh, &event->wait);
                spin_lock(&cgrp->event_list_lock);
                list_del(&event->list);
                spin_unlock(&cgrp->event_list_lock);
@@ -4429,7 +4435,15 @@ __setup("cgroup_disable=", cgroup_disable);
  */
 unsigned short css_id(struct cgroup_subsys_state *css)
 {
-       struct css_id *cssid = rcu_dereference(css->id);
+       struct css_id *cssid;
+
+       /*
+        * This css_id() can return correct value when somone has refcnt
+        * on this or this is under rcu_read_lock(). Once css->id is allocated,
+        * it's unchanged until freed.
+        */
+       cssid = rcu_dereference_check(css->id,
+                       rcu_read_lock_held() || atomic_read(&css->refcnt));
 
        if (cssid)
                return cssid->id;
@@ -4439,7 +4453,10 @@ EXPORT_SYMBOL_GPL(css_id);
 
 unsigned short css_depth(struct cgroup_subsys_state *css)
 {
-       struct css_id *cssid = rcu_dereference(css->id);
+       struct css_id *cssid;
+
+       cssid = rcu_dereference_check(css->id,
+                       rcu_read_lock_held() || atomic_read(&css->refcnt));
 
        if (cssid)
                return cssid->depth;
@@ -4447,15 +4464,36 @@ unsigned short css_depth(struct cgroup_subsys_state *css)
 }
 EXPORT_SYMBOL_GPL(css_depth);
 
+/**
+ *  css_is_ancestor - test "root" css is an ancestor of "child"
+ * @child: the css to be tested.
+ * @root: the css supporsed to be an ancestor of the child.
+ *
+ * Returns true if "root" is an ancestor of "child" in its hierarchy. Because
+ * this function reads css->id, this use rcu_dereference() and rcu_read_lock().
+ * But, considering usual usage, the csses should be valid objects after test.
+ * Assuming that the caller will do some action to the child if this returns
+ * returns true, the caller must take "child";s reference count.
+ * If "child" is valid object and this returns true, "root" is valid, too.
+ */
+
 bool css_is_ancestor(struct cgroup_subsys_state *child,
                    const struct cgroup_subsys_state *root)
 {
-       struct css_id *child_id = rcu_dereference(child->id);
-       struct css_id *root_id = rcu_dereference(root->id);
+       struct css_id *child_id;
+       struct css_id *root_id;
+       bool ret = true;
 
-       if (!child_id || !root_id || (child_id->depth < root_id->depth))
-               return false;
-       return child_id->stack[root_id->depth] == root_id->id;
+       rcu_read_lock();
+       child_id  = rcu_dereference(child->id);
+       root_id = rcu_dereference(root->id);
+       if (!child_id
+           || !root_id
+           || (child_id->depth < root_id->depth)
+           || (child_id->stack[root_id->depth] != root_id->id))
+               ret = false;
+       rcu_read_unlock();
+       return ret;
 }
 
 static void __free_css_id_cb(struct rcu_head *head)
@@ -4555,13 +4593,13 @@ static int alloc_css_id(struct cgroup_subsys *ss, struct cgroup *parent,
 {
        int subsys_id, i, depth = 0;
        struct cgroup_subsys_state *parent_css, *child_css;
-       struct css_id *child_id, *parent_id = NULL;
+       struct css_id *child_id, *parent_id;
 
        subsys_id = ss->subsys_id;
        parent_css = parent->subsys[subsys_id];
        child_css = child->subsys[subsys_id];
-       depth = css_depth(parent_css) + 1;
        parent_id = parent_css->id;
+       depth = parent_id->depth;
 
        child_id = get_new_cssid(ss, depth);
        if (IS_ERR(child_id))
index da5e139..e5c0244 100644 (file)
@@ -205,9 +205,12 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
         * No lock is needed, since the task isn't on tasklist yet,
         * so it can't be moved to another cgroup, which means the
         * freezer won't be removed and will be valid during this
-        * function call.
+        * function call.  Nevertheless, apply RCU read-side critical
+        * section to suppress RCU lockdep false positives.
         */
+       rcu_read_lock();
        freezer = task_freezer(task);
+       rcu_read_unlock();
 
        /*
         * The root cgroup is non-freezable, so we can skip the
index 7f40e92..5adab05 100644 (file)
@@ -495,29 +495,26 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len,
 {
        int ret;
        cpumask_var_t mask;
-       unsigned long *k;
-       unsigned int min_length = cpumask_size();
-
-       if (nr_cpu_ids <= BITS_PER_COMPAT_LONG)
-               min_length = sizeof(compat_ulong_t);
 
-       if (len < min_length)
+       if ((len * BITS_PER_BYTE) < nr_cpu_ids)
+               return -EINVAL;
+       if (len & (sizeof(compat_ulong_t)-1))
                return -EINVAL;
 
        if (!alloc_cpumask_var(&mask, GFP_KERNEL))
                return -ENOMEM;
 
        ret = sched_getaffinity(pid, mask);
-       if (ret < 0)
-               goto out;
+       if (ret == 0) {
+               size_t retlen = min_t(size_t, len, cpumask_size());
 
-       k = cpumask_bits(mask);
-       ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8);
-       if (ret == 0)
-               ret = min_length;
-
-out:
+               if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
+                       ret = -EFAULT;
+               else
+                       ret = retlen;
+       }
        free_cpumask_var(mask);
+
        return ret;
 }
 
index 25bba73..5457775 100644 (file)
@@ -164,6 +164,7 @@ static inline void check_for_tasks(int cpu)
 }
 
 struct take_cpu_down_param {
+       struct task_struct *caller;
        unsigned long mod;
        void *hcpu;
 };
@@ -172,6 +173,7 @@ struct take_cpu_down_param {
 static int __ref take_cpu_down(void *_param)
 {
        struct take_cpu_down_param *param = _param;
+       unsigned int cpu = (unsigned long)param->hcpu;
        int err;
 
        /* Ensure this CPU doesn't handle any more interrupts. */
@@ -182,6 +184,8 @@ static int __ref take_cpu_down(void *_param)
        raw_notifier_call_chain(&cpu_chain, CPU_DYING | param->mod,
                                param->hcpu);
 
+       if (task_cpu(param->caller) == cpu)
+               move_task_off_dead_cpu(cpu, param->caller);
        /* Force idle task to run as soon as we yield: it should
           immediately notice cpu is offline and die quickly. */
        sched_idle_next();
@@ -192,10 +196,10 @@ static int __ref take_cpu_down(void *_param)
 static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 {
        int err, nr_calls = 0;
-       cpumask_var_t old_allowed;
        void *hcpu = (void *)(long)cpu;
        unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;
        struct take_cpu_down_param tcd_param = {
+               .caller = current,
                .mod = mod,
                .hcpu = hcpu,
        };
@@ -206,9 +210,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
        if (!cpu_online(cpu))
                return -EINVAL;
 
-       if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL))
-               return -ENOMEM;
-
        cpu_hotplug_begin();
        set_cpu_active(cpu, false);
        err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
@@ -225,10 +226,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                goto out_release;
        }
 
-       /* Ensure that we are not runnable on dying cpu */
-       cpumask_copy(old_allowed, &current->cpus_allowed);
-       set_cpus_allowed_ptr(current, cpu_active_mask);
-
        err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
        if (err) {
                set_cpu_active(cpu, true);
@@ -237,7 +234,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                                            hcpu) == NOTIFY_BAD)
                        BUG();
 
-               goto out_allowed;
+               goto out_release;
        }
        BUG_ON(cpu_online(cpu));
 
@@ -255,8 +252,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 
        check_for_tasks(cpu);
 
-out_allowed:
-       set_cpus_allowed_ptr(current, old_allowed);
 out_release:
        cpu_hotplug_done();
        if (!err) {
@@ -264,7 +259,6 @@ out_release:
                                            hcpu) == NOTIFY_BAD)
                        BUG();
        }
-       free_cpumask_var(old_allowed);
        return err;
 }
 
@@ -272,9 +266,6 @@ int __ref cpu_down(unsigned int cpu)
 {
        int err;
 
-       err = stop_machine_create();
-       if (err)
-               return err;
        cpu_maps_update_begin();
 
        if (cpu_hotplug_disabled) {
@@ -286,7 +277,6 @@ int __ref cpu_down(unsigned int cpu)
 
 out:
        cpu_maps_update_done();
-       stop_machine_destroy();
        return err;
 }
 EXPORT_SYMBOL(cpu_down);
@@ -367,9 +357,6 @@ int disable_nonboot_cpus(void)
 {
        int cpu, first_cpu, error;
 
-       error = stop_machine_create();
-       if (error)
-               return error;
        cpu_maps_update_begin();
        first_cpu = cpumask_first(cpu_online_mask);
        /*
@@ -400,7 +387,6 @@ int disable_nonboot_cpus(void)
                printk(KERN_ERR "Non-boot CPUs are not disabled\n");
        }
        cpu_maps_update_done();
-       stop_machine_destroy();
        return error;
 }
 
index d109467..9a50c5f 100644 (file)
@@ -2182,19 +2182,52 @@ void __init cpuset_init_smp(void)
 void cpuset_cpus_allowed(struct task_struct *tsk, struct cpumask *pmask)
 {
        mutex_lock(&callback_mutex);
-       cpuset_cpus_allowed_locked(tsk, pmask);
+       task_lock(tsk);
+       guarantee_online_cpus(task_cs(tsk), pmask);
+       task_unlock(tsk);
        mutex_unlock(&callback_mutex);
 }
 
-/**
- * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset.
- * Must be called with callback_mutex held.
- **/
-void cpuset_cpus_allowed_locked(struct task_struct *tsk, struct cpumask *pmask)
+int cpuset_cpus_allowed_fallback(struct task_struct *tsk)
 {
-       task_lock(tsk);
-       guarantee_online_cpus(task_cs(tsk), pmask);
-       task_unlock(tsk);
+       const struct cpuset *cs;
+       int cpu;
+
+       rcu_read_lock();
+       cs = task_cs(tsk);
+       if (cs)
+               cpumask_copy(&tsk->cpus_allowed, cs->cpus_allowed);
+       rcu_read_unlock();
+
+       /*
+        * We own tsk->cpus_allowed, nobody can change it under us.
+        *
+        * But we used cs && cs->cpus_allowed lockless and thus can
+        * race with cgroup_attach_task() or update_cpumask() and get
+        * the wrong tsk->cpus_allowed. However, both cases imply the
+        * subsequent cpuset_change_cpumask()->set_cpus_allowed_ptr()
+        * which takes task_rq_lock().
+        *
+        * If we are called after it dropped the lock we must see all
+        * changes in tsk_cs()->cpus_allowed. Otherwise we can temporary
+        * set any mask even if it is not right from task_cs() pov,
+        * the pending set_cpus_allowed_ptr() will fix things.
+        */
+
+       cpu = cpumask_any_and(&tsk->cpus_allowed, cpu_active_mask);
+       if (cpu >= nr_cpu_ids) {
+               /*
+                * Either tsk->cpus_allowed is wrong (see above) or it
+                * is actually empty. The latter case is only possible
+                * if we are racing with remove_tasks_in_empty_cpuset().
+                * Like above we can temporary set any mask and rely on
+                * set_cpus_allowed_ptr() as synchronization point.
+                */
+               cpumask_copy(&tsk->cpus_allowed, cpu_possible_mask);
+               cpu = cpumask_any(cpu_active_mask);
+       }
+
+       return cpu;
 }
 
 void cpuset_init_current_mems_allowed(void)
@@ -2382,22 +2415,6 @@ int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask)
        return 0;
 }
 
-/**
- * cpuset_lock - lock out any changes to cpuset structures
- *
- * The out of memory (oom) code needs to mutex_lock cpusets
- * from being changed while it scans the tasklist looking for a
- * task in an overlapping cpuset.  Expose callback_mutex via this
- * cpuset_lock() routine, so the oom code can lock it, before
- * locking the task list.  The tasklist_lock is a spinlock, so
- * must be taken inside callback_mutex.
- */
-
-void cpuset_lock(void)
-{
-       mutex_lock(&callback_mutex);
-}
-
 /**
  * cpuset_unlock - release lock on cpuset changes
  *
diff --git a/kernel/cred-internals.h b/kernel/cred-internals.h
deleted file mode 100644 (file)
index 2dc4fc2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Internal credentials stuff
- *
- * Copyright (C) 2008 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.
- */
-
-/*
- * user.c
- */
-static inline void sched_switch_user(struct task_struct *p)
-{
-#ifdef CONFIG_USER_SCHED
-       sched_move_task(p);
-#endif /* CONFIG_USER_SCHED */
-}
-
index e1dbe9e..2c24870 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/init_task.h>
 #include <linux/security.h>
 #include <linux/cn_proc.h>
-#include "cred-internals.h"
 
 #if 0
 #define kdebug(FMT, ...) \
@@ -398,6 +397,8 @@ struct cred *prepare_usermodehelper_creds(void)
 
 error:
        put_cred(new);
+       return NULL;
+
 free_tgcred:
 #ifdef CONFIG_KEYS
        kfree(tgcred);
@@ -521,8 +522,6 @@ int commit_creds(struct cred *new)
 #endif
        BUG_ON(atomic_read(&new->usage) < 1);
 
-       security_commit_creds(new, old);
-
        get_cred(new); /* we will require a ref for the subj creds too */
 
        /* dumpability changes */
@@ -558,8 +557,6 @@ int commit_creds(struct cred *new)
                atomic_dec(&old->user->processes);
        alter_cred_subscribers(old, -2);
 
-       sched_switch_user(task);
-
        /* send notifications */
        if (new->uid   != old->uid  ||
            new->euid  != old->euid ||
@@ -791,8 +788,6 @@ bool creds_are_invalid(const struct cred *cred)
 {
        if (cred->magic != CRED_MAGIC)
                return true;
-       if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
-               return true;
 #ifdef CONFIG_SECURITY_SELINUX
        if (selinux_is_enabled()) {
                if ((unsigned long) cred->security < PAGE_SIZE)
index 7f2683a..eabca5a 100644 (file)
@@ -55,7 +55,6 @@
 #include <asm/unistd.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
-#include "cred-internals.h"
 
 static void exit_mm(struct task_struct * tsk);
 
index 44b0791..4d57d9e 100644 (file)
@@ -1112,10 +1112,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        p->memcg_batch.memcg = NULL;
 #endif
 
-       p->bts = NULL;
-
-       p->stack_start = stack_start;
-
        /* Perform scheduler related setup. Assign this task to a CPU. */
        sched_fork(p, clone_flags);
 
index 2b45b2e..53b1916 100644 (file)
@@ -164,12 +164,6 @@ int groups_search(const struct group_info *group_info, gid_t grp)
  */
 int set_groups(struct cred *new, struct group_info *group_info)
 {
-       int retval;
-
-       retval = security_task_setgroups(group_info);
-       if (retval)
-               return retval;
-
        put_group_info(new->group_info);
        groups_sort(group_info);
        get_group_info(group_info);
index 0086628..b9b134b 100644 (file)
@@ -1749,35 +1749,15 @@ void __init hrtimers_init(void)
 }
 
 /**
- * schedule_hrtimeout_range - sleep until timeout
+ * schedule_hrtimeout_range_clock - sleep until timeout
  * @expires:   timeout value (ktime_t)
  * @delta:     slack in expires timeout (ktime_t)
  * @mode:      timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
- *
- * Make the current task sleep until the given expiry time has
- * elapsed. The routine will return immediately unless
- * the current task state has been set (see set_current_state()).
- *
- * The @delta argument gives the kernel the freedom to schedule the
- * actual wakeup to a time that is both power and performance friendly.
- * The kernel give the normal best effort behavior for "@expires+@delta",
- * but may decide to fire the timer earlier, but no earlier than @expires.
- *
- * You can set the task state as follows -
- *
- * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
- * pass before the routine returns.
- *
- * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
- * delivered to the current task.
- *
- * The current task state is guaranteed to be TASK_RUNNING when this
- * routine returns.
- *
- * Returns 0 when the timer has expired otherwise -EINTR
+ * @clock:     timer clock, CLOCK_MONOTONIC or CLOCK_REALTIME
  */
-int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
-                              const enum hrtimer_mode mode)
+int __sched
+schedule_hrtimeout_range_clock(ktime_t *expires, unsigned long delta,
+                              const enum hrtimer_mode mode, int clock)
 {
        struct hrtimer_sleeper t;
 
@@ -1799,7 +1779,7 @@ int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
                return -EINTR;
        }
 
-       hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
+       hrtimer_init_on_stack(&t.timer, clock, mode);
        hrtimer_set_expires_range_ns(&t.timer, *expires, delta);
 
        hrtimer_init_sleeper(&t, current);
@@ -1818,6 +1798,41 @@ int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
 
        return !t.task ? 0 : -EINTR;
 }
+
+/**
+ * schedule_hrtimeout_range - sleep until timeout
+ * @expires:   timeout value (ktime_t)
+ * @delta:     slack in expires timeout (ktime_t)
+ * @mode:      timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
+ *
+ * Make the current task sleep until the given expiry time has
+ * elapsed. The routine will return immediately unless
+ * the current task state has been set (see set_current_state()).
+ *
+ * The @delta argument gives the kernel the freedom to schedule the
+ * actual wakeup to a time that is both power and performance friendly.
+ * The kernel give the normal best effort behavior for "@expires+@delta",
+ * but may decide to fire the timer earlier, but no earlier than @expires.
+ *
+ * You can set the task state as follows -
+ *
+ * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
+ * pass before the routine returns.
+ *
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
+ * delivered to the current task.
+ *
+ * The current task state is guaranteed to be TASK_RUNNING when this
+ * routine returns.
+ *
+ * Returns 0 when the timer has expired otherwise -EINTR
+ */
+int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
+                                    const enum hrtimer_mode mode)
+{
+       return schedule_hrtimeout_range_clock(expires, delta, mode,
+                                             CLOCK_MONOTONIC);
+}
 EXPORT_SYMBOL_GPL(schedule_hrtimeout_range);
 
 /**
index 03808ed..7a56b22 100644 (file)
 #include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
 
 #include <linux/hw_breakpoint.h>
 
+
 /*
  * Constraints data
  */
 
 /* Number of pinned cpu breakpoints in a cpu */
-static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned);
+static DEFINE_PER_CPU(unsigned int, nr_cpu_bp_pinned[TYPE_MAX]);
 
 /* Number of pinned task breakpoints in a cpu */
-static DEFINE_PER_CPU(unsigned int, nr_task_bp_pinned[HBP_NUM]);
+static DEFINE_PER_CPU(unsigned int *, nr_task_bp_pinned[TYPE_MAX]);
 
 /* Number of non-pinned cpu/task breakpoints in a cpu */
-static DEFINE_PER_CPU(unsigned int, nr_bp_flexible);
+static DEFINE_PER_CPU(unsigned int, nr_bp_flexible[TYPE_MAX]);
+
+static int nr_slots[TYPE_MAX];
+
+static int constraints_initialized;
 
 /* Gather the number of total pinned and un-pinned bp in a cpuset */
 struct bp_busy_slots {
@@ -67,16 +73,29 @@ struct bp_busy_slots {
 /* Serialize accesses to the above constraints */
 static DEFINE_MUTEX(nr_bp_mutex);
 
+__weak int hw_breakpoint_weight(struct perf_event *bp)
+{
+       return 1;
+}
+
+static inline enum bp_type_idx find_slot_idx(struct perf_event *bp)
+{
+       if (bp->attr.bp_type & HW_BREAKPOINT_RW)
+               return TYPE_DATA;
+
+       return TYPE_INST;
+}
+
 /*
  * Report the maximum number of pinned breakpoints a task
  * have in this cpu
  */
-static unsigned int max_task_bp_pinned(int cpu)
+static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type)
 {
        int i;
-       unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned, cpu);
+       unsigned int *tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
 
-       for (i = HBP_NUM -1; i >= 0; i--) {
+       for (i = nr_slots[type] - 1; i >= 0; i--) {
                if (tsk_pinned[i] > 0)
                        return i + 1;
        }
@@ -84,7 +103,7 @@ static unsigned int max_task_bp_pinned(int cpu)
        return 0;
 }
 
-static int task_bp_pinned(struct task_struct *tsk)
+static int task_bp_pinned(struct task_struct *tsk, enum bp_type_idx type)
 {
        struct perf_event_context *ctx = tsk->perf_event_ctxp;
        struct list_head *list;
@@ -105,7 +124,8 @@ static int task_bp_pinned(struct task_struct *tsk)
         */
        list_for_each_entry(bp, list, event_entry) {
                if (bp->attr.type == PERF_TYPE_BREAKPOINT)
-                       count++;
+                       if (find_slot_idx(bp) == type)
+                               count += hw_breakpoint_weight(bp);
        }
 
        raw_spin_unlock_irqrestore(&ctx->lock, flags);
@@ -118,18 +138,19 @@ static int task_bp_pinned(struct task_struct *tsk)
  * a given cpu (cpu > -1) or in all of them (cpu = -1).
  */
 static void
-fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp)
+fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp,
+                   enum bp_type_idx type)
 {
        int cpu = bp->cpu;
        struct task_struct *tsk = bp->ctx->task;
 
        if (cpu >= 0) {
-               slots->pinned = per_cpu(nr_cpu_bp_pinned, cpu);
+               slots->pinned = per_cpu(nr_cpu_bp_pinned[type], cpu);
                if (!tsk)
-                       slots->pinned += max_task_bp_pinned(cpu);
+                       slots->pinned += max_task_bp_pinned(cpu, type);
                else
-                       slots->pinned += task_bp_pinned(tsk);
-               slots->flexible = per_cpu(nr_bp_flexible, cpu);
+                       slots->pinned += task_bp_pinned(tsk, type);
+               slots->flexible = per_cpu(nr_bp_flexible[type], cpu);
 
                return;
        }
@@ -137,48 +158,66 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp)
        for_each_online_cpu(cpu) {
                unsigned int nr;
 
-               nr = per_cpu(nr_cpu_bp_pinned, cpu);
+               nr = per_cpu(nr_cpu_bp_pinned[type], cpu);
                if (!tsk)
-                       nr += max_task_bp_pinned(cpu);
+                       nr += max_task_bp_pinned(cpu, type);
                else
-                       nr += task_bp_pinned(tsk);
+                       nr += task_bp_pinned(tsk, type);
 
                if (nr > slots->pinned)
                        slots->pinned = nr;
 
-               nr = per_cpu(nr_bp_flexible, cpu);
+               nr = per_cpu(nr_bp_flexible[type], cpu);
 
                if (nr > slots->flexible)
                        slots->flexible = nr;
        }
 }
 
+/*
+ * For now, continue to consider flexible as pinned, until we can
+ * ensure no flexible event can ever be scheduled before a pinned event
+ * in a same cpu.
+ */
+static void
+fetch_this_slot(struct bp_busy_slots *slots, int weight)
+{
+       slots->pinned += weight;
+}
+
 /*
  * Add a pinned breakpoint for the given task in our constraint table
  */
-static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable)
+static void toggle_bp_task_slot(struct task_struct *tsk, int cpu, bool enable,
+                               enum bp_type_idx type, int weight)
 {
        unsigned int *tsk_pinned;
-       int count = 0;
+       int old_count = 0;
+       int old_idx = 0;
+       int idx = 0;
 
-       count = task_bp_pinned(tsk);
+       old_count = task_bp_pinned(tsk, type);
+       old_idx = old_count - 1;
+       idx = old_idx + weight;
 
-       tsk_pinned = per_cpu(nr_task_bp_pinned, cpu);
+       tsk_pinned = per_cpu(nr_task_bp_pinned[type], cpu);
        if (enable) {
-               tsk_pinned[count]++;
-               if (count > 0)
-                       tsk_pinned[count-1]--;
+               tsk_pinned[idx]++;
+               if (old_count > 0)
+                       tsk_pinned[old_idx]--;
        } else {
-               tsk_pinned[count]--;
-               if (count > 0)
-                       tsk_pinned[count-1]++;
+               tsk_pinned[idx]--;
+               if (old_count > 0)
+                       tsk_pinned[old_idx]++;
        }
 }
 
 /*
  * Add/remove the given breakpoint in our constraint table
  */
-static void toggle_bp_slot(struct perf_event *bp, bool enable)
+static void
+toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
+              int weight)
 {
        int cpu = bp->cpu;
        struct task_struct *tsk = bp->ctx->task;
@@ -186,20 +225,20 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
        /* Pinned counter task profiling */
        if (tsk) {
                if (cpu >= 0) {
-                       toggle_bp_task_slot(tsk, cpu, enable);
+                       toggle_bp_task_slot(tsk, cpu, enable, type, weight);
                        return;
                }
 
                for_each_online_cpu(cpu)
-                       toggle_bp_task_slot(tsk, cpu, enable);
+                       toggle_bp_task_slot(tsk, cpu, enable, type, weight);
                return;
        }
 
        /* Pinned counter cpu profiling */
        if (enable)
-               per_cpu(nr_cpu_bp_pinned, bp->cpu)++;
+               per_cpu(nr_cpu_bp_pinned[type], bp->cpu) += weight;
        else
-               per_cpu(nr_cpu_bp_pinned, bp->cpu)--;
+               per_cpu(nr_cpu_bp_pinned[type], bp->cpu) -= weight;
 }
 
 /*
@@ -246,14 +285,29 @@ static void toggle_bp_slot(struct perf_event *bp, bool enable)
 static int __reserve_bp_slot(struct perf_event *bp)
 {
        struct bp_busy_slots slots = {0};
+       enum bp_type_idx type;
+       int weight;
 
-       fetch_bp_busy_slots(&slots, bp);
+       /* We couldn't initialize breakpoint constraints on boot */
+       if (!constraints_initialized)
+               return -ENOMEM;
+
+       /* Basic checks */
+       if (bp->attr.bp_type == HW_BREAKPOINT_EMPTY ||
+           bp->attr.bp_type == HW_BREAKPOINT_INVALID)
+               return -EINVAL;
+
+       type = find_slot_idx(bp);
+       weight = hw_breakpoint_weight(bp);
+
+       fetch_bp_busy_slots(&slots, bp, type);
+       fetch_this_slot(&slots, weight);
 
        /* Flexible counters need to keep at least one slot */
-       if (slots.pinned + (!!slots.flexible) == HBP_NUM)
+       if (slots.pinned + (!!slots.flexible) > nr_slots[type])
                return -ENOSPC;
 
-       toggle_bp_slot(bp, true);
+       toggle_bp_slot(bp, true, type, weight);
 
        return 0;
 }
@@ -273,7 +327,12 @@ int reserve_bp_slot(struct perf_event *bp)
 
 static void __release_bp_slot(struct perf_event *bp)
 {
-       toggle_bp_slot(bp, false);
+       enum bp_type_idx type;
+       int weight;
+
+       type = find_slot_idx(bp);
+       weight = hw_breakpoint_weight(bp);
+       toggle_bp_slot(bp, false, type, weight);
 }
 
 void release_bp_slot(struct perf_event *bp)
@@ -308,6 +367,28 @@ int dbg_release_bp_slot(struct perf_event *bp)
        return 0;
 }
 
+static int validate_hw_breakpoint(struct perf_event *bp)
+{
+       int ret;
+
+       ret = arch_validate_hwbkpt_settings(bp);
+       if (ret)
+               return ret;
+
+       if (arch_check_bp_in_kernelspace(bp)) {
+               if (bp->attr.exclude_kernel)
+                       return -EINVAL;
+               /*
+                * Don't let unprivileged users set a breakpoint in the trap
+                * path to avoid trap recursion attacks.
+                */
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+       }
+
+       return 0;
+}
+
 int register_perf_hw_breakpoint(struct perf_event *bp)
 {
        int ret;
@@ -316,17 +397,7 @@ int register_perf_hw_breakpoint(struct perf_event *bp)
        if (ret)
                return ret;
 
-       /*
-        * Ptrace breakpoints can be temporary perf events only
-        * meant to reserve a slot. In this case, it is created disabled and
-        * we don't want to check the params right now (as we put a null addr)
-        * But perf tools create events as disabled and we want to check
-        * the params for them.
-        * This is a quick hack that will be removed soon, once we remove
-        * the tmp breakpoints from ptrace
-        */
-       if (!bp->attr.disabled || !bp->overflow_handler)
-               ret = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
+       ret = validate_hw_breakpoint(bp);
 
        /* if arch_validate_hwbkpt_settings() fails then release bp slot */
        if (ret)
@@ -373,7 +444,7 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
        if (attr->disabled)
                goto end;
 
-       err = arch_validate_hwbkpt_settings(bp, bp->ctx->task);
+       err = validate_hw_breakpoint(bp);
        if (!err)
                perf_event_enable(bp);
 
@@ -480,7 +551,36 @@ static struct notifier_block hw_breakpoint_exceptions_nb = {
 
 static int __init init_hw_breakpoint(void)
 {
+       unsigned int **task_bp_pinned;
+       int cpu, err_cpu;
+       int i;
+
+       for (i = 0; i < TYPE_MAX; i++)
+               nr_slots[i] = hw_breakpoint_slots(i);
+
+       for_each_possible_cpu(cpu) {
+               for (i = 0; i < TYPE_MAX; i++) {
+                       task_bp_pinned = &per_cpu(nr_task_bp_pinned[i], cpu);
+                       *task_bp_pinned = kzalloc(sizeof(int) * nr_slots[i],
+                                                 GFP_KERNEL);
+                       if (!*task_bp_pinned)
+                               goto err_alloc;
+               }
+       }
+
+       constraints_initialized = 1;
+
        return register_die_notifier(&hw_breakpoint_exceptions_nb);
+
+ err_alloc:
+       for_each_possible_cpu(err_cpu) {
+               if (err_cpu == cpu)
+                       break;
+               for (i = 0; i < TYPE_MAX; i++)
+                       kfree(per_cpu(nr_task_bp_pinned[i], cpu));
+       }
+
+       return -ENOMEM;
 }
 core_initcall(init_hw_breakpoint);
 
index 76d5a67..27e5c69 100644 (file)
@@ -370,9 +370,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
 
-       if (!(action->flags & IRQF_DISABLED))
-               local_irq_enable_in_hardirq();
-
        do {
                trace_irq_handler_entry(irq, action);
                ret = action->handler(irq, action->dev_id);
index 704e488..3164ba7 100644 (file)
@@ -138,6 +138,22 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
        return 0;
 }
 
+int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       unsigned long flags;
+
+       if (!desc)
+               return -EINVAL;
+
+       raw_spin_lock_irqsave(&desc->lock, flags);
+       desc->affinity_hint = m;
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
+
 #ifndef CONFIG_AUTO_IRQ_AFFINITY
 /*
  * Generic version of the affinity autoselector.
@@ -757,16 +773,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
                if (new->flags & IRQF_ONESHOT)
                        desc->status |= IRQ_ONESHOT;
 
-               /*
-                * Force MSI interrupts to run with interrupts
-                * disabled. The multi vector cards can cause stack
-                * overflows due to nested interrupts when enough of
-                * them are directed to a core and fire at the same
-                * time.
-                */
-               if (desc->msi_desc)
-                       new->flags |= IRQF_DISABLED;
-
                if (!(desc->status & IRQ_NOAUTOEN)) {
                        desc->depth = 0;
                        desc->status &= ~IRQ_DISABLED;
@@ -916,6 +922,12 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                        desc->chip->disable(irq);
        }
 
+#ifdef CONFIG_SMP
+       /* make sure affinity_hint is cleaned up */
+       if (WARN_ON_ONCE(desc->affinity_hint))
+               desc->affinity_hint = NULL;
+#endif
+
        raw_spin_unlock_irqrestore(&desc->lock, flags);
 
        unregister_handler_proc(irq, action);
@@ -1027,7 +1039,6 @@ EXPORT_SYMBOL(free_irq);
  *     Flags:
  *
  *     IRQF_SHARED             Interrupt is shared
- *     IRQF_DISABLED   Disable local interrupts while processing
  *     IRQF_SAMPLE_RANDOM      The interrupt can be used for entropy
  *     IRQF_TRIGGER_*          Specify active edge(s) or level
  *
@@ -1040,25 +1051,6 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
        struct irq_desc *desc;
        int retval;
 
-       /*
-        * handle_IRQ_event() always ignores IRQF_DISABLED except for
-        * the _first_ irqaction (sigh).  That can cause oopsing, but
-        * the behavior is classified as "will not fix" so we need to
-        * start nudging drivers away from using that idiom.
-        */
-       if ((irqflags & (IRQF_SHARED|IRQF_DISABLED)) ==
-                                       (IRQF_SHARED|IRQF_DISABLED)) {
-               pr_warning(
-                 "IRQ %d/%s: IRQF_DISABLED is not guaranteed on shared IRQs\n",
-                       irq, devname);
-       }
-
-#ifdef CONFIG_LOCKDEP
-       /*
-        * Lockdep wants atomic interrupt handlers:
-        */
-       irqflags |= IRQF_DISABLED;
-#endif
        /*
         * Sanity-check: shared interrupts must pass in a real dev-ID,
         * otherwise we'll have trouble later trying to figure out
@@ -1120,3 +1112,40 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
        return retval;
 }
 EXPORT_SYMBOL(request_threaded_irq);
+
+/**
+ *     request_any_context_irq - allocate an interrupt line
+ *     @irq: Interrupt line to allocate
+ *     @handler: Function to be called when the IRQ occurs.
+ *               Threaded handler for threaded interrupts.
+ *     @flags: Interrupt type flags
+ *     @name: An ascii name for the claiming device
+ *     @dev_id: A cookie passed back to the handler function
+ *
+ *     This call allocates interrupt resources and enables the
+ *     interrupt line and IRQ handling. It selects either a
+ *     hardirq or threaded handling method depending on the
+ *     context.
+ *
+ *     On failure, it returns a negative value. On success,
+ *     it returns either IRQC_IS_HARDIRQ or IRQC_IS_NESTED.
+ */
+int request_any_context_irq(unsigned int irq, irq_handler_t handler,
+                           unsigned long flags, const char *name, void *dev_id)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       int ret;
+
+       if (!desc)
+               return -EINVAL;
+
+       if (desc->status & IRQ_NESTED_THREAD) {
+               ret = request_threaded_irq(irq, NULL, handler,
+                                          flags, name, dev_id);
+               return !ret ? IRQC_IS_NESTED : ret;
+       }
+
+       ret = request_irq(irq, handler, flags, name, dev_id);
+       return !ret ? IRQC_IS_HARDIRQ : ret;
+}
+EXPORT_SYMBOL_GPL(request_any_context_irq);
index 7a6eb04..09a2ee5 100644 (file)
@@ -32,6 +32,27 @@ static int irq_affinity_proc_show(struct seq_file *m, void *v)
        return 0;
 }
 
+static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
+{
+       struct irq_desc *desc = irq_to_desc((long)m->private);
+       unsigned long flags;
+       cpumask_var_t mask;
+
+       if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
+               return -ENOMEM;
+
+       raw_spin_lock_irqsave(&desc->lock, flags);
+       if (desc->affinity_hint)
+               cpumask_copy(mask, desc->affinity_hint);
+       raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+       seq_cpumask(m, mask);
+       seq_putc(m, '\n');
+       free_cpumask_var(mask);
+
+       return 0;
+}
+
 #ifndef is_affinity_mask_valid
 #define is_affinity_mask_valid(val) 1
 #endif
@@ -84,6 +105,11 @@ static int irq_affinity_proc_open(struct inode *inode, struct file *file)
        return single_open(file, irq_affinity_proc_show, PDE(inode)->data);
 }
 
+static int irq_affinity_hint_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, irq_affinity_hint_proc_show, PDE(inode)->data);
+}
+
 static const struct file_operations irq_affinity_proc_fops = {
        .open           = irq_affinity_proc_open,
        .read           = seq_read,
@@ -92,6 +118,13 @@ static const struct file_operations irq_affinity_proc_fops = {
        .write          = irq_affinity_proc_write,
 };
 
+static const struct file_operations irq_affinity_hint_proc_fops = {
+       .open           = irq_affinity_hint_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static int default_affinity_show(struct seq_file *m, void *v)
 {
        seq_cpumask(m, irq_default_affinity);
@@ -147,6 +180,26 @@ static const struct file_operations default_affinity_proc_fops = {
        .release        = single_release,
        .write          = default_affinity_write,
 };
+
+static int irq_node_proc_show(struct seq_file *m, void *v)
+{
+       struct irq_desc *desc = irq_to_desc((long) m->private);
+
+       seq_printf(m, "%d\n", desc->node);
+       return 0;
+}
+
+static int irq_node_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, irq_node_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations irq_node_proc_fops = {
+       .open           = irq_node_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif
 
 static int irq_spurious_proc_show(struct seq_file *m, void *v)
@@ -231,6 +284,13 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
        /* create /proc/irq/<irq>/smp_affinity */
        proc_create_data("smp_affinity", 0600, desc->dir,
                         &irq_affinity_proc_fops, (void *)(long)irq);
+
+       /* create /proc/irq/<irq>/affinity_hint */
+       proc_create_data("affinity_hint", 0400, desc->dir,
+                        &irq_affinity_hint_proc_fops, (void *)(long)irq);
+
+       proc_create_data("node", 0444, desc->dir,
+                        &irq_node_proc_fops, (void *)(long)irq);
 #endif
 
        proc_create_data("spurious", 0444, desc->dir,
index 87ebe8a..474a847 100644 (file)
@@ -1134,11 +1134,9 @@ int crash_shrink_memory(unsigned long new_size)
 
        free_reserved_phys_range(end, crashk_res.end);
 
-       if (start == end) {
-               crashk_res.end = end;
+       if (start == end)
                release_resource(&crashk_res);
-       } else
-               crashk_res.end = end - 1;
+       crashk_res.end = end - 1;
 
 unlock:
        mutex_unlock(&kexec_mutex);
index 0ed46f3..282035f 100644 (file)
@@ -1588,6 +1588,72 @@ static void __kprobes kill_kprobe(struct kprobe *p)
        arch_remove_kprobe(p);
 }
 
+/* Disable one kprobe */
+int __kprobes disable_kprobe(struct kprobe *kp)
+{
+       int ret = 0;
+       struct kprobe *p;
+
+       mutex_lock(&kprobe_mutex);
+
+       /* Check whether specified probe is valid. */
+       p = __get_valid_kprobe(kp);
+       if (unlikely(p == NULL)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* If the probe is already disabled (or gone), just return */
+       if (kprobe_disabled(kp))
+               goto out;
+
+       kp->flags |= KPROBE_FLAG_DISABLED;
+       if (p != kp)
+               /* When kp != p, p is always enabled. */
+               try_to_disable_aggr_kprobe(p);
+
+       if (!kprobes_all_disarmed && kprobe_disabled(p))
+               disarm_kprobe(p);
+out:
+       mutex_unlock(&kprobe_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(disable_kprobe);
+
+/* Enable one kprobe */
+int __kprobes enable_kprobe(struct kprobe *kp)
+{
+       int ret = 0;
+       struct kprobe *p;
+
+       mutex_lock(&kprobe_mutex);
+
+       /* Check whether specified probe is valid. */
+       p = __get_valid_kprobe(kp);
+       if (unlikely(p == NULL)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (kprobe_gone(kp)) {
+               /* This kprobe has gone, we couldn't enable it. */
+               ret = -EINVAL;
+               goto out;
+       }
+
+       if (p != kp)
+               kp->flags &= ~KPROBE_FLAG_DISABLED;
+
+       if (!kprobes_all_disarmed && kprobe_disabled(p)) {
+               p->flags &= ~KPROBE_FLAG_DISABLED;
+               arm_kprobe(p);
+       }
+out:
+       mutex_unlock(&kprobe_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(enable_kprobe);
+
 void __kprobes dump_kprobe(struct kprobe *kp)
 {
        printk(KERN_WARNING "Dumping kprobe:\n");
@@ -1805,72 +1871,6 @@ static const struct file_operations debugfs_kprobes_operations = {
        .release        = seq_release,
 };
 
-/* Disable one kprobe */
-int __kprobes disable_kprobe(struct kprobe *kp)
-{
-       int ret = 0;
-       struct kprobe *p;
-
-       mutex_lock(&kprobe_mutex);
-
-       /* Check whether specified probe is valid. */
-       p = __get_valid_kprobe(kp);
-       if (unlikely(p == NULL)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       /* If the probe is already disabled (or gone), just return */
-       if (kprobe_disabled(kp))
-               goto out;
-
-       kp->flags |= KPROBE_FLAG_DISABLED;
-       if (p != kp)
-               /* When kp != p, p is always enabled. */
-               try_to_disable_aggr_kprobe(p);
-
-       if (!kprobes_all_disarmed && kprobe_disabled(p))
-               disarm_kprobe(p);
-out:
-       mutex_unlock(&kprobe_mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(disable_kprobe);
-
-/* Enable one kprobe */
-int __kprobes enable_kprobe(struct kprobe *kp)
-{
-       int ret = 0;
-       struct kprobe *p;
-
-       mutex_lock(&kprobe_mutex);
-
-       /* Check whether specified probe is valid. */
-       p = __get_valid_kprobe(kp);
-       if (unlikely(p == NULL)) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (kprobe_gone(kp)) {
-               /* This kprobe has gone, we couldn't enable it. */
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (p != kp)
-               kp->flags &= ~KPROBE_FLAG_DISABLED;
-
-       if (!kprobes_all_disarmed && kprobe_disabled(p)) {
-               p->flags &= ~KPROBE_FLAG_DISABLED;
-               arm_kprobe(p);
-       }
-out:
-       mutex_unlock(&kprobe_mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(enable_kprobe);
-
 static void __kprobes arm_all_kprobes(void)
 {
        struct hlist_head *head;
index 2594e1c..ec21304 100644 (file)
@@ -431,20 +431,7 @@ static struct stack_trace lockdep_init_trace = {
 /*
  * Various lockdep statistics:
  */
-atomic_t chain_lookup_hits;
-atomic_t chain_lookup_misses;
-atomic_t hardirqs_on_events;
-atomic_t hardirqs_off_events;
-atomic_t redundant_hardirqs_on;
-atomic_t redundant_hardirqs_off;
-atomic_t softirqs_on_events;
-atomic_t softirqs_off_events;
-atomic_t redundant_softirqs_on;
-atomic_t redundant_softirqs_off;
-atomic_t nr_unused_locks;
-atomic_t nr_cyclic_checks;
-atomic_t nr_find_usage_forwards_checks;
-atomic_t nr_find_usage_backwards_checks;
+DEFINE_PER_CPU(struct lockdep_stats, lockdep_stats);
 #endif
 
 /*
@@ -748,7 +735,7 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
                return NULL;
        }
        class = lock_classes + nr_lock_classes++;
-       debug_atomic_inc(&nr_unused_locks);
+       debug_atomic_inc(nr_unused_locks);
        class->key = key;
        class->name = lock->name;
        class->subclass = subclass;
@@ -818,7 +805,8 @@ static struct lock_list *alloc_list_entry(void)
  * Add a new dependency to the head of the list:
  */
 static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
-                           struct list_head *head, unsigned long ip, int distance)
+                           struct list_head *head, unsigned long ip,
+                           int distance, struct stack_trace *trace)
 {
        struct lock_list *entry;
        /*
@@ -829,11 +817,9 @@ static int add_lock_to_list(struct lock_class *class, struct lock_class *this,
        if (!entry)
                return 0;
 
-       if (!save_trace(&entry->trace))
-               return 0;
-
        entry->class = this;
        entry->distance = distance;
+       entry->trace = *trace;
        /*
         * Since we never remove from the dependency list, the list can
         * be walked lockless by other CPUs, it's only allocation
@@ -1205,7 +1191,7 @@ check_noncircular(struct lock_list *root, struct lock_class *target,
 {
        int result;
 
-       debug_atomic_inc(&nr_cyclic_checks);
+       debug_atomic_inc(nr_cyclic_checks);
 
        result = __bfs_forwards(root, target, class_equal, target_entry);
 
@@ -1242,7 +1228,7 @@ find_usage_forwards(struct lock_list *root, enum lock_usage_bit bit,
 {
        int result;
 
-       debug_atomic_inc(&nr_find_usage_forwards_checks);
+       debug_atomic_inc(nr_find_usage_forwards_checks);
 
        result = __bfs_forwards(root, (void *)bit, usage_match, target_entry);
 
@@ -1265,7 +1251,7 @@ find_usage_backwards(struct lock_list *root, enum lock_usage_bit bit,
 {
        int result;
 
-       debug_atomic_inc(&nr_find_usage_backwards_checks);
+       debug_atomic_inc(nr_find_usage_backwards_checks);
 
        result = __bfs_backwards(root, (void *)bit, usage_match, target_entry);
 
@@ -1635,12 +1621,20 @@ check_deadlock(struct task_struct *curr, struct held_lock *next,
  */
 static int
 check_prev_add(struct task_struct *curr, struct held_lock *prev,
-              struct held_lock *next, int distance)
+              struct held_lock *next, int distance, int trylock_loop)
 {
        struct lock_list *entry;
        int ret;
        struct lock_list this;
        struct lock_list *uninitialized_var(target_entry);
+       /*
+        * Static variable, serialized by the graph_lock().
+        *
+        * We use this static variable to save the stack trace in case
+        * we call into this function multiple times due to encountering
+        * trylocks in the held lock stack.
+        */
+       static struct stack_trace trace;
 
        /*
         * Prove that the new <prev> -> <next> dependency would not
@@ -1688,20 +1682,23 @@ check_prev_add(struct task_struct *curr, struct held_lock *prev,
                }
        }
 
+       if (!trylock_loop && !save_trace(&trace))
+               return 0;
+
        /*
         * Ok, all validations passed, add the new lock
         * to the previous lock's dependency list:
         */
        ret = add_lock_to_list(hlock_class(prev), hlock_class(next),
                               &hlock_class(prev)->locks_after,
-                              next->acquire_ip, distance);
+                              next->acquire_ip, distance, &trace);
 
        if (!ret)
                return 0;
 
        ret = add_lock_to_list(hlock_class(next), hlock_class(prev),
                               &hlock_class(next)->locks_before,
-                              next->acquire_ip, distance);
+                              next->acquire_ip, distance, &trace);
        if (!ret)
                return 0;
 
@@ -1731,6 +1728,7 @@ static int
 check_prevs_add(struct task_struct *curr, struct held_lock *next)
 {
        int depth = curr->lockdep_depth;
+       int trylock_loop = 0;
        struct held_lock *hlock;
 
        /*
@@ -1756,7 +1754,8 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
                 * added:
                 */
                if (hlock->read != 2) {
-                       if (!check_prev_add(curr, hlock, next, distance))
+                       if (!check_prev_add(curr, hlock, next,
+                                               distance, trylock_loop))
                                return 0;
                        /*
                         * Stop after the first non-trylock entry,
@@ -1779,6 +1778,7 @@ check_prevs_add(struct task_struct *curr, struct held_lock *next)
                if (curr->held_locks[depth].irq_context !=
                                curr->held_locks[depth-1].irq_context)
                        break;
+               trylock_loop = 1;
        }
        return 1;
 out_bug:
@@ -1825,7 +1825,7 @@ static inline int lookup_chain_cache(struct task_struct *curr,
        list_for_each_entry(chain, hash_head, entry) {
                if (chain->chain_key == chain_key) {
 cache_hit:
-                       debug_atomic_inc(&chain_lookup_hits);
+                       debug_atomic_inc(chain_lookup_hits);
                        if (very_verbose(class))
                                printk("\nhash chain already cached, key: "
                                        "%016Lx tail class: [%p] %s\n",
@@ -1890,7 +1890,7 @@ cache_hit:
                chain_hlocks[chain->base + j] = class - lock_classes;
        }
        list_add_tail_rcu(&chain->entry, hash_head);
-       debug_atomic_inc(&chain_lookup_misses);
+       debug_atomic_inc(chain_lookup_misses);
        inc_chains();
 
        return 1;
@@ -2311,7 +2311,12 @@ void trace_hardirqs_on_caller(unsigned long ip)
                return;
 
        if (unlikely(curr->hardirqs_enabled)) {
-               debug_atomic_inc(&redundant_hardirqs_on);
+               /*
+                * Neither irq nor preemption are disabled here
+                * so this is racy by nature but loosing one hit
+                * in a stat is not a big deal.
+                */
+               __debug_atomic_inc(redundant_hardirqs_on);
                return;
        }
        /* we'll do an OFF -> ON transition: */
@@ -2338,7 +2343,7 @@ void trace_hardirqs_on_caller(unsigned long ip)
 
        curr->hardirq_enable_ip = ip;
        curr->hardirq_enable_event = ++curr->irq_events;
-       debug_atomic_inc(&hardirqs_on_events);
+       debug_atomic_inc(hardirqs_on_events);
 }
 EXPORT_SYMBOL(trace_hardirqs_on_caller);
 
@@ -2370,9 +2375,9 @@ void trace_hardirqs_off_caller(unsigned long ip)
                curr->hardirqs_enabled = 0;
                curr->hardirq_disable_ip = ip;
                curr->hardirq_disable_event = ++curr->irq_events;
-               debug_atomic_inc(&hardirqs_off_events);
+               debug_atomic_inc(hardirqs_off_events);
        } else
-               debug_atomic_inc(&redundant_hardirqs_off);
+               debug_atomic_inc(redundant_hardirqs_off);
 }
 EXPORT_SYMBOL(trace_hardirqs_off_caller);
 
@@ -2396,7 +2401,7 @@ void trace_softirqs_on(unsigned long ip)
                return;
 
        if (curr->softirqs_enabled) {
-               debug_atomic_inc(&redundant_softirqs_on);
+               debug_atomic_inc(redundant_softirqs_on);
                return;
        }
 
@@ -2406,7 +2411,7 @@ void trace_softirqs_on(unsigned long ip)
        curr->softirqs_enabled = 1;
        curr->softirq_enable_ip = ip;
        curr->softirq_enable_event = ++curr->irq_events;
-       debug_atomic_inc(&softirqs_on_events);
+       debug_atomic_inc(softirqs_on_events);
        /*
         * We are going to turn softirqs on, so set the
         * usage bit for all held locks, if hardirqs are
@@ -2436,10 +2441,10 @@ void trace_softirqs_off(unsigned long ip)
                curr->softirqs_enabled = 0;
                curr->softirq_disable_ip = ip;
                curr->softirq_disable_event = ++curr->irq_events;
-               debug_atomic_inc(&softirqs_off_events);
+               debug_atomic_inc(softirqs_off_events);
                DEBUG_LOCKS_WARN_ON(!softirq_count());
        } else
-               debug_atomic_inc(&redundant_softirqs_off);
+               debug_atomic_inc(redundant_softirqs_off);
 }
 
 static void __lockdep_trace_alloc(gfp_t gfp_mask, unsigned long flags)
@@ -2644,7 +2649,7 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this,
                        return 0;
                break;
        case LOCK_USED:
-               debug_atomic_dec(&nr_unused_locks);
+               debug_atomic_dec(nr_unused_locks);
                break;
        default:
                if (!debug_locks_off_graph_unlock())
@@ -2750,7 +2755,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
                if (!class)
                        return 0;
        }
-       debug_atomic_inc((atomic_t *)&class->ops);
+       atomic_inc((atomic_t *)&class->ops);
        if (very_verbose(class)) {
                printk("\nacquire class [%p] %s", class->key, class->name);
                if (class->name_version > 1)
@@ -3227,7 +3232,7 @@ void lock_release(struct lockdep_map *lock, int nested,
        raw_local_irq_save(flags);
        check_flags(flags);
        current->lockdep_recursion = 1;
-       trace_lock_release(lock, nested, ip);
+       trace_lock_release(lock, ip);
        __lock_release(lock, nested, ip);
        current->lockdep_recursion = 0;
        raw_local_irq_restore(flags);
@@ -3380,7 +3385,7 @@ found_it:
                hlock->holdtime_stamp = now;
        }
 
-       trace_lock_acquired(lock, ip, waittime);
+       trace_lock_acquired(lock, ip);
 
        stats = get_lock_stats(hlock_class(hlock));
        if (waittime) {
@@ -3801,8 +3806,11 @@ void lockdep_rcu_dereference(const char *file, const int line)
 {
        struct task_struct *curr = current;
 
+#ifndef CONFIG_PROVE_RCU_REPEATEDLY
        if (!debug_locks_off())
                return;
+#endif /* #ifdef CONFIG_PROVE_RCU_REPEATEDLY */
+       /* Note: the following can be executed concurrently, so be careful. */
        printk("\n===================================================\n");
        printk(  "[ INFO: suspicious rcu_dereference_check() usage. ]\n");
        printk(  "---------------------------------------------------\n");
index a2ee95a..4f560cf 100644 (file)
@@ -110,30 +110,60 @@ lockdep_count_backward_deps(struct lock_class *class)
 #endif
 
 #ifdef CONFIG_DEBUG_LOCKDEP
+
+#include <asm/local.h>
 /*
- * Various lockdep statistics:
+ * Various lockdep statistics.
+ * We want them per cpu as they are often accessed in fast path
+ * and we want to avoid too much cache bouncing.
  */
-extern atomic_t chain_lookup_hits;
-extern atomic_t chain_lookup_misses;
-extern atomic_t hardirqs_on_events;
-extern atomic_t hardirqs_off_events;
-extern atomic_t redundant_hardirqs_on;
-extern atomic_t redundant_hardirqs_off;
-extern atomic_t softirqs_on_events;
-extern atomic_t softirqs_off_events;
-extern atomic_t redundant_softirqs_on;
-extern atomic_t redundant_softirqs_off;
-extern atomic_t nr_unused_locks;
-extern atomic_t nr_cyclic_checks;
-extern atomic_t nr_cyclic_check_recursions;
-extern atomic_t nr_find_usage_forwards_checks;
-extern atomic_t nr_find_usage_forwards_recursions;
-extern atomic_t nr_find_usage_backwards_checks;
-extern atomic_t nr_find_usage_backwards_recursions;
-# define debug_atomic_inc(ptr)         atomic_inc(ptr)
-# define debug_atomic_dec(ptr)         atomic_dec(ptr)
-# define debug_atomic_read(ptr)                atomic_read(ptr)
+struct lockdep_stats {
+       int     chain_lookup_hits;
+       int     chain_lookup_misses;
+       int     hardirqs_on_events;
+       int     hardirqs_off_events;
+       int     redundant_hardirqs_on;
+       int     redundant_hardirqs_off;
+       int     softirqs_on_events;
+       int     softirqs_off_events;
+       int     redundant_softirqs_on;
+       int     redundant_softirqs_off;
+       int     nr_unused_locks;
+       int     nr_cyclic_checks;
+       int     nr_cyclic_check_recursions;
+       int     nr_find_usage_forwards_checks;
+       int     nr_find_usage_forwards_recursions;
+       int     nr_find_usage_backwards_checks;
+       int     nr_find_usage_backwards_recursions;
+};
+
+DECLARE_PER_CPU(struct lockdep_stats, lockdep_stats);
+
+#define __debug_atomic_inc(ptr)                                        \
+       this_cpu_inc(lockdep_stats.ptr);
+
+#define debug_atomic_inc(ptr)                  {               \
+       WARN_ON_ONCE(!irqs_disabled());                         \
+       __this_cpu_inc(lockdep_stats.ptr);                      \
+}
+
+#define debug_atomic_dec(ptr)                  {               \
+       WARN_ON_ONCE(!irqs_disabled());                         \
+       __this_cpu_dec(lockdep_stats.ptr);                      \
+}
+
+#define debug_atomic_read(ptr)         ({                              \
+       struct lockdep_stats *__cpu_lockdep_stats;                      \
+       unsigned long long __total = 0;                                 \
+       int __cpu;                                                      \
+       for_each_possible_cpu(__cpu) {                                  \
+               __cpu_lockdep_stats = &per_cpu(lockdep_stats, __cpu);   \
+               __total += __cpu_lockdep_stats->ptr;                    \
+       }                                                               \
+       __total;                                                        \
+})
 #else
+# define __debug_atomic_inc(ptr)       do { } while (0)
 # define debug_atomic_inc(ptr)         do { } while (0)
 # define debug_atomic_dec(ptr)         do { } while (0)
 # define debug_atomic_read(ptr)                0
index d4aba4f..59b76c8 100644 (file)
@@ -184,34 +184,34 @@ static const struct file_operations proc_lockdep_chains_operations = {
 static void lockdep_stats_debug_show(struct seq_file *m)
 {
 #ifdef CONFIG_DEBUG_LOCKDEP
-       unsigned int hi1 = debug_atomic_read(&hardirqs_on_events),
-                    hi2 = debug_atomic_read(&hardirqs_off_events),
-                    hr1 = debug_atomic_read(&redundant_hardirqs_on),
-                    hr2 = debug_atomic_read(&redundant_hardirqs_off),
-                    si1 = debug_atomic_read(&softirqs_on_events),
-                    si2 = debug_atomic_read(&softirqs_off_events),
-                    sr1 = debug_atomic_read(&redundant_softirqs_on),
-                    sr2 = debug_atomic_read(&redundant_softirqs_off);
-
-       seq_printf(m, " chain lookup misses:           %11u\n",
-               debug_atomic_read(&chain_lookup_misses));
-       seq_printf(m, " chain lookup hits:             %11u\n",
-               debug_atomic_read(&chain_lookup_hits));
-       seq_printf(m, " cyclic checks:                 %11u\n",
-               debug_atomic_read(&nr_cyclic_checks));
-       seq_printf(m, " find-mask forwards checks:     %11u\n",
-               debug_atomic_read(&nr_find_usage_forwards_checks));
-       seq_printf(m, " find-mask backwards checks:    %11u\n",
-               debug_atomic_read(&nr_find_usage_backwards_checks));
-
-       seq_printf(m, " hardirq on events:             %11u\n", hi1);
-       seq_printf(m, " hardirq off events:            %11u\n", hi2);
-       seq_printf(m, " redundant hardirq ons:         %11u\n", hr1);
-       seq_printf(m, " redundant hardirq offs:        %11u\n", hr2);
-       seq_printf(m, " softirq on events:             %11u\n", si1);
-       seq_printf(m, " softirq off events:            %11u\n", si2);
-       seq_printf(m, " redundant softirq ons:         %11u\n", sr1);
-       seq_printf(m, " redundant softirq offs:        %11u\n", sr2);
+       unsigned long long hi1 = debug_atomic_read(hardirqs_on_events),
+                          hi2 = debug_atomic_read(hardirqs_off_events),
+                          hr1 = debug_atomic_read(redundant_hardirqs_on),
+                          hr2 = debug_atomic_read(redundant_hardirqs_off),
+                          si1 = debug_atomic_read(softirqs_on_events),
+                          si2 = debug_atomic_read(softirqs_off_events),
+                          sr1 = debug_atomic_read(redundant_softirqs_on),
+                          sr2 = debug_atomic_read(redundant_softirqs_off);
+
+       seq_printf(m, " chain lookup misses:           %11llu\n",
+               debug_atomic_read(chain_lookup_misses));
+       seq_printf(m, " chain lookup hits:             %11llu\n",
+               debug_atomic_read(chain_lookup_hits));
+       seq_printf(m, " cyclic checks:                 %11llu\n",
+               debug_atomic_read(nr_cyclic_checks));
+       seq_printf(m, " find-mask forwards checks:     %11llu\n",
+               debug_atomic_read(nr_find_usage_forwards_checks));
+       seq_printf(m, " find-mask backwards checks:    %11llu\n",
+               debug_atomic_read(nr_find_usage_backwards_checks));
+
+       seq_printf(m, " hardirq on events:             %11llu\n", hi1);
+       seq_printf(m, " hardirq off events:            %11llu\n", hi2);
+       seq_printf(m, " redundant hardirq ons:         %11llu\n", hr1);
+       seq_printf(m, " redundant hardirq offs:        %11llu\n", hr2);
+       seq_printf(m, " softirq on events:             %11llu\n", si1);
+       seq_printf(m, " softirq off events:            %11llu\n", si2);
+       seq_printf(m, " redundant softirq ons:         %11llu\n", sr1);
+       seq_printf(m, " redundant softirq offs:        %11llu\n", sr2);
 #endif
 }
 
@@ -263,7 +263,7 @@ static int lockdep_stats_show(struct seq_file *m, void *v)
 #endif
        }
 #ifdef CONFIG_DEBUG_LOCKDEP
-       DEBUG_LOCKS_WARN_ON(debug_atomic_read(&nr_unused_locks) != nr_unused);
+       DEBUG_LOCKS_WARN_ON(debug_atomic_read(nr_unused_locks) != nr_unused);
 #endif
        seq_printf(m, " lock-classes:                  %11lu [max: %lu]\n",
                        nr_lock_classes, MAX_LOCKDEP_KEYS);
index 1016b75..e256458 100644 (file)
@@ -59,8 +59,6 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
 
-EXPORT_TRACEPOINT_SYMBOL(module_get);
-
 #if 0
 #define DEBUGP printk
 #else
@@ -515,6 +513,9 @@ MODINFO_ATTR(srcversion);
 static char last_unloaded_module[MODULE_NAME_LEN+1];
 
 #ifdef CONFIG_MODULE_UNLOAD
+
+EXPORT_TRACEPOINT_SYMBOL(module_get);
+
 /* Init the unload section of the module. */
 static void module_unload_init(struct module *mod)
 {
@@ -723,16 +724,8 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
                return -EFAULT;
        name[MODULE_NAME_LEN-1] = '\0';
 
-       /* Create stop_machine threads since free_module relies on
-        * a non-failing stop_machine call. */
-       ret = stop_machine_create();
-       if (ret)
-               return ret;
-
-       if (mutex_lock_interruptible(&module_mutex) != 0) {
-               ret = -EINTR;
-               goto out_stop;
-       }
+       if (mutex_lock_interruptible(&module_mutex) != 0)
+               return -EINTR;
 
        mod = find_module(name);
        if (!mod) {
@@ -792,8 +785,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
 
  out:
        mutex_unlock(&module_mutex);
-out_stop:
-       stop_machine_destroy();
        return ret;
 }
 
@@ -867,8 +858,7 @@ void module_put(struct module *module)
                smp_wmb(); /* see comment in module_refcount */
                __this_cpu_inc(module->refptr->decs);
 
-               trace_module_put(module, _RET_IP_,
-                                __this_cpu_read(module->refptr->decs));
+               trace_module_put(module, _RET_IP_);
                /* Maybe they're waiting for us to drop reference? */
                if (unlikely(!module_is_live(module)))
                        wake_up_process(module->waiter);
index 2f3fbf8..a4fa381 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/file.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
+#include <linux/hash.h>
 #include <linux/sysfs.h>
 #include <linux/dcache.h>
 #include <linux/percpu.h>
@@ -82,14 +83,6 @@ extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event)
 void __weak hw_perf_disable(void)              { barrier(); }
 void __weak hw_perf_enable(void)               { barrier(); }
 
-int __weak
-hw_perf_group_sched_in(struct perf_event *group_leader,
-              struct perf_cpu_context *cpuctx,
-              struct perf_event_context *ctx)
-{
-       return 0;
-}
-
 void __weak perf_event_print_debug(void)       { }
 
 static DEFINE_PER_CPU(int, perf_disable_count);
@@ -262,6 +255,18 @@ static void update_event_times(struct perf_event *event)
        event->total_time_running = run_end - event->tstamp_running;
 }
 
+/*
+ * Update total_time_enabled and total_time_running for all events in a group.
+ */
+static void update_group_times(struct perf_event *leader)
+{
+       struct perf_event *event;
+
+       update_event_times(leader);
+       list_for_each_entry(event, &leader->sibling_list, group_entry)
+               update_event_times(event);
+}
+
 static struct list_head *
 ctx_group_list(struct perf_event *event, struct perf_event_context *ctx)
 {
@@ -315,8 +320,6 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
 static void
 list_del_event(struct perf_event *event, struct perf_event_context *ctx)
 {
-       struct perf_event *sibling, *tmp;
-
        if (list_empty(&event->group_entry))
                return;
        ctx->nr_events--;
@@ -329,7 +332,7 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
        if (event->group_leader != event)
                event->group_leader->nr_siblings--;
 
-       update_event_times(event);
+       update_group_times(event);
 
        /*
         * If event was in error state, then keep it
@@ -340,6 +343,12 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
         */
        if (event->state > PERF_EVENT_STATE_OFF)
                event->state = PERF_EVENT_STATE_OFF;
+}
+
+static void
+perf_destroy_group(struct perf_event *event, struct perf_event_context *ctx)
+{
+       struct perf_event *sibling, *tmp;
 
        /*
         * If this was a group event with sibling events then
@@ -504,18 +513,6 @@ retry:
        raw_spin_unlock_irq(&ctx->lock);
 }
 
-/*
- * Update total_time_enabled and total_time_running for all events in a group.
- */
-static void update_group_times(struct perf_event *leader)
-{
-       struct perf_event *event;
-
-       update_event_times(leader);
-       list_for_each_entry(event, &leader->sibling_list, group_entry)
-               update_event_times(event);
-}
-
 /*
  * Cross CPU call to disable a performance event
  */
@@ -640,15 +637,20 @@ group_sched_in(struct perf_event *group_event,
               struct perf_cpu_context *cpuctx,
               struct perf_event_context *ctx)
 {
-       struct perf_event *event, *partial_group;
+       struct perf_event *event, *partial_group = NULL;
+       const struct pmu *pmu = group_event->pmu;
+       bool txn = false;
        int ret;
 
        if (group_event->state == PERF_EVENT_STATE_OFF)
                return 0;
 
-       ret = hw_perf_group_sched_in(group_event, cpuctx, ctx);
-       if (ret)
-               return ret < 0 ? ret : 0;
+       /* Check if group transaction availabe */
+       if (pmu->start_txn)
+               txn = true;
+
+       if (txn)
+               pmu->start_txn(pmu);
 
        if (event_sched_in(group_event, cpuctx, ctx))
                return -EAGAIN;
@@ -663,9 +665,19 @@ group_sched_in(struct perf_event *group_event,
                }
        }
 
-       return 0;
+       if (!txn)
+               return 0;
+
+       ret = pmu->commit_txn(pmu);
+       if (!ret) {
+               pmu->cancel_txn(pmu);
+               return 0;
+       }
 
 group_error:
+       if (txn)
+               pmu->cancel_txn(pmu);
+
        /*
         * Groups can be scheduled in as one unit only, so undo any
         * partial group before returning:
@@ -1367,6 +1379,8 @@ void perf_event_task_sched_in(struct task_struct *task)
        if (cpuctx->task_ctx == ctx)
                return;
 
+       perf_disable();
+
        /*
         * We want to keep the following priority order:
         * cpu pinned (that don't need to move), task pinned,
@@ -1379,6 +1393,8 @@ void perf_event_task_sched_in(struct task_struct *task)
        ctx_sched_in(ctx, cpuctx, EVENT_FLEXIBLE);
 
        cpuctx->task_ctx = ctx;
+
+       perf_enable();
 }
 
 #define MAX_INTERRUPTS (~0ULL)
@@ -1856,9 +1872,30 @@ int perf_event_release_kernel(struct perf_event *event)
 {
        struct perf_event_context *ctx = event->ctx;
 
+       /*
+        * Remove from the PMU, can't get re-enabled since we got
+        * here because the last ref went.
+        */
+       perf_event_disable(event);
+
        WARN_ON_ONCE(ctx->parent_ctx);
-       mutex_lock(&ctx->mutex);
-       perf_event_remove_from_context(event);
+       /*
+        * There are two ways this annotation is useful:
+        *
+        *  1) there is a lock recursion from perf_event_exit_task
+        *     see the comment there.
+        *
+        *  2) there is a lock-inversion with mmap_sem through
+        *     perf_event_read_group(), which takes faults while
+        *     holding ctx->mutex, however this is called after
+        *     the last filedesc died, so there is no possibility
+        *     to trigger the AB-BA case.
+        */
+       mutex_lock_nested(&ctx->mutex, SINGLE_DEPTH_NESTING);
+       raw_spin_lock_irq(&ctx->lock);
+       list_del_event(event, ctx);
+       perf_destroy_group(event, ctx);
+       raw_spin_unlock_irq(&ctx->lock);
        mutex_unlock(&ctx->mutex);
 
        mutex_lock(&event->owner->perf_event_mutex);
@@ -2642,6 +2679,7 @@ static int perf_fasync(int fd, struct file *filp, int on)
 }
 
 static const struct file_operations perf_fops = {
+       .llseek                 = no_llseek,
        .release                = perf_release,
        .read                   = perf_read,
        .poll                   = perf_poll,
@@ -2791,6 +2829,27 @@ void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int ski
 }
 
 
+/*
+ * We assume there is only KVM supporting the callbacks.
+ * Later on, we might change it to a list if there is
+ * another virtualization implementation supporting the callbacks.
+ */
+struct perf_guest_info_callbacks *perf_guest_cbs;
+
+int perf_register_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+{
+       perf_guest_cbs = cbs;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(perf_register_guest_info_callbacks);
+
+int perf_unregister_guest_info_callbacks(struct perf_guest_info_callbacks *cbs)
+{
+       perf_guest_cbs = NULL;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks);
+
 /*
  * Output
  */
@@ -3743,7 +3802,7 @@ void __perf_event_mmap(struct vm_area_struct *vma)
                .event_id  = {
                        .header = {
                                .type = PERF_RECORD_MMAP,
-                               .misc = 0,
+                               .misc = PERF_RECORD_MISC_USER,
                                /* .size */
                        },
                        /* .pid */
@@ -3961,36 +4020,6 @@ static void perf_swevent_add(struct perf_event *event, u64 nr,
        perf_swevent_overflow(event, 0, nmi, data, regs);
 }
 
-static int perf_swevent_is_counting(struct perf_event *event)
-{
-       /*
-        * The event is active, we're good!
-        */
-       if (event->state == PERF_EVENT_STATE_ACTIVE)
-               return 1;
-
-       /*
-        * The event is off/error, not counting.
-        */
-       if (event->state != PERF_EVENT_STATE_INACTIVE)
-               return 0;
-
-       /*
-        * The event is inactive, if the context is active
-        * we're part of a group that didn't make it on the 'pmu',
-        * not counting.
-        */
-       if (event->ctx->is_active)
-               return 0;
-
-       /*
-        * We're inactive and the context is too, this means the
-        * task is scheduled out, we're counting events that happen
-        * to us, like migration events.
-        */
-       return 1;
-}
-
 static int perf_tp_event_match(struct perf_event *event,
                                struct perf_sample_data *data);
 
@@ -4014,12 +4043,6 @@ static int perf_swevent_match(struct perf_event *event,
                                struct perf_sample_data *data,
                                struct pt_regs *regs)
 {
-       if (event->cpu != -1 && event->cpu != smp_processor_id())
-               return 0;
-
-       if (!perf_swevent_is_counting(event))
-               return 0;
-
        if (event->attr.type != type)
                return 0;
 
@@ -4036,18 +4059,53 @@ static int perf_swevent_match(struct perf_event *event,
        return 1;
 }
 
-static void perf_swevent_ctx_event(struct perf_event_context *ctx,
-                                    enum perf_type_id type,
-                                    u32 event_id, u64 nr, int nmi,
-                                    struct perf_sample_data *data,
-                                    struct pt_regs *regs)
+static inline u64 swevent_hash(u64 type, u32 event_id)
+{
+       u64 val = event_id | (type << 32);
+
+       return hash_64(val, SWEVENT_HLIST_BITS);
+}
+
+static struct hlist_head *
+find_swevent_head(struct perf_cpu_context *ctx, u64 type, u32 event_id)
+{
+       u64 hash;
+       struct swevent_hlist *hlist;
+
+       hash = swevent_hash(type, event_id);
+
+       hlist = rcu_dereference(ctx->swevent_hlist);
+       if (!hlist)
+               return NULL;
+
+       return &hlist->heads[hash];
+}
+
+static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
+                                   u64 nr, int nmi,
+                                   struct perf_sample_data *data,
+                                   struct pt_regs *regs)
 {
+       struct perf_cpu_context *cpuctx;
        struct perf_event *event;
+       struct hlist_node *node;
+       struct hlist_head *head;
 
-       list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+       cpuctx = &__get_cpu_var(perf_cpu_context);
+
+       rcu_read_lock();
+
+       head = find_swevent_head(cpuctx, type, event_id);
+
+       if (!head)
+               goto end;
+
+       hlist_for_each_entry_rcu(event, node, head, hlist_entry) {
                if (perf_swevent_match(event, type, event_id, data, regs))
                        perf_swevent_add(event, nr, nmi, data, regs);
        }
+end:
+       rcu_read_unlock();
 }
 
 int perf_swevent_get_recursion_context(void)
@@ -4085,27 +4143,6 @@ void perf_swevent_put_recursion_context(int rctx)
 }
 EXPORT_SYMBOL_GPL(perf_swevent_put_recursion_context);
 
-static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
-                                   u64 nr, int nmi,
-                                   struct perf_sample_data *data,
-                                   struct pt_regs *regs)
-{
-       struct perf_cpu_context *cpuctx;
-       struct perf_event_context *ctx;
-
-       cpuctx = &__get_cpu_var(perf_cpu_context);
-       rcu_read_lock();
-       perf_swevent_ctx_event(&cpuctx->ctx, type, event_id,
-                                nr, nmi, data, regs);
-       /*
-        * doesn't really matter which of the child contexts the
-        * events ends up in.
-        */
-       ctx = rcu_dereference(current->perf_event_ctxp);
-       if (ctx)
-               perf_swevent_ctx_event(ctx, type, event_id, nr, nmi, data, regs);
-       rcu_read_unlock();
-}
 
 void __perf_sw_event(u32 event_id, u64 nr, int nmi,
                            struct pt_regs *regs, u64 addr)
@@ -4131,16 +4168,28 @@ static void perf_swevent_read(struct perf_event *event)
 static int perf_swevent_enable(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
+       struct perf_cpu_context *cpuctx;
+       struct hlist_head *head;
+
+       cpuctx = &__get_cpu_var(perf_cpu_context);
 
        if (hwc->sample_period) {
                hwc->last_period = hwc->sample_period;
                perf_swevent_set_period(event);
        }
+
+       head = find_swevent_head(cpuctx, event->attr.type, event->attr.config);
+       if (WARN_ON_ONCE(!head))
+               return -EINVAL;
+
+       hlist_add_head_rcu(&event->hlist_entry, head);
+
        return 0;
 }
 
 static void perf_swevent_disable(struct perf_event *event)
 {
+       hlist_del_rcu(&event->hlist_entry);
 }
 
 static const struct pmu perf_ops_generic = {
@@ -4168,15 +4217,8 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
        perf_sample_data_init(&data, 0);
        data.period = event->hw.last_period;
        regs = get_irq_regs();
-       /*
-        * In case we exclude kernel IPs or are somehow not in interrupt
-        * context, provide the next best thing, the user IP.
-        */
-       if ((event->attr.exclude_kernel || !regs) &&
-                       !event->attr.exclude_user)
-               regs = task_pt_regs(current);
 
-       if (regs) {
+       if (regs && !perf_exclude_event(event, regs)) {
                if (!(event->attr.exclude_idle && current->pid == 0))
                        if (perf_event_overflow(event, 0, &data, regs))
                                ret = HRTIMER_NORESTART;
@@ -4324,6 +4366,105 @@ static const struct pmu perf_ops_task_clock = {
        .read           = task_clock_perf_event_read,
 };
 
+static void swevent_hlist_release_rcu(struct rcu_head *rcu_head)
+{
+       struct swevent_hlist *hlist;
+
+       hlist = container_of(rcu_head, struct swevent_hlist, rcu_head);
+       kfree(hlist);
+}
+
+static void swevent_hlist_release(struct perf_cpu_context *cpuctx)
+{
+       struct swevent_hlist *hlist;
+
+       if (!cpuctx->swevent_hlist)
+               return;
+
+       hlist = cpuctx->swevent_hlist;
+       rcu_assign_pointer(cpuctx->swevent_hlist, NULL);
+       call_rcu(&hlist->rcu_head, swevent_hlist_release_rcu);
+}
+
+static void swevent_hlist_put_cpu(struct perf_event *event, int cpu)
+{
+       struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+
+       mutex_lock(&cpuctx->hlist_mutex);
+
+       if (!--cpuctx->hlist_refcount)
+               swevent_hlist_release(cpuctx);
+
+       mutex_unlock(&cpuctx->hlist_mutex);
+}
+
+static void swevent_hlist_put(struct perf_event *event)
+{
+       int cpu;
+
+       if (event->cpu != -1) {
+               swevent_hlist_put_cpu(event, event->cpu);
+               return;
+       }
+
+       for_each_possible_cpu(cpu)
+               swevent_hlist_put_cpu(event, cpu);
+}
+
+static int swevent_hlist_get_cpu(struct perf_event *event, int cpu)
+{
+       struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+       int err = 0;
+
+       mutex_lock(&cpuctx->hlist_mutex);
+
+       if (!cpuctx->swevent_hlist && cpu_online(cpu)) {
+               struct swevent_hlist *hlist;
+
+               hlist = kzalloc(sizeof(*hlist), GFP_KERNEL);
+               if (!hlist) {
+                       err = -ENOMEM;
+                       goto exit;
+               }
+               rcu_assign_pointer(cpuctx->swevent_hlist, hlist);
+       }
+       cpuctx->hlist_refcount++;
+ exit:
+       mutex_unlock(&cpuctx->hlist_mutex);
+
+       return err;
+}
+
+static int swevent_hlist_get(struct perf_event *event)
+{
+       int err;
+       int cpu, failed_cpu;
+
+       if (event->cpu != -1)
+               return swevent_hlist_get_cpu(event, event->cpu);
+
+       get_online_cpus();
+       for_each_possible_cpu(cpu) {
+               err = swevent_hlist_get_cpu(event, cpu);
+               if (err) {
+                       failed_cpu = cpu;
+                       goto fail;
+               }
+       }
+       put_online_cpus();
+
+       return 0;
+ fail:
+       for_each_possible_cpu(cpu) {
+               if (cpu == failed_cpu)
+                       break;
+               swevent_hlist_put_cpu(event, cpu);
+       }
+
+       put_online_cpus();
+       return err;
+}
+
 #ifdef CONFIG_EVENT_TRACING
 
 void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
@@ -4357,10 +4498,13 @@ static int perf_tp_event_match(struct perf_event *event,
 static void tp_perf_event_destroy(struct perf_event *event)
 {
        perf_trace_disable(event->attr.config);
+       swevent_hlist_put(event);
 }
 
 static const struct pmu *tp_perf_event_init(struct perf_event *event)
 {
+       int err;
+
        /*
         * Raw tracepoint data is a severe data leak, only allow root to
         * have these.
@@ -4374,6 +4518,11 @@ static const struct pmu *tp_perf_event_init(struct perf_event *event)
                return NULL;
 
        event->destroy = tp_perf_event_destroy;
+       err = swevent_hlist_get(event);
+       if (err) {
+               perf_trace_disable(event->attr.config);
+               return ERR_PTR(err);
+       }
 
        return &perf_ops_generic;
 }
@@ -4474,6 +4623,7 @@ static void sw_perf_event_destroy(struct perf_event *event)
        WARN_ON(event->parent);
 
        atomic_dec(&perf_swevent_enabled[event_id]);
+       swevent_hlist_put(event);
 }
 
 static const struct pmu *sw_perf_event_init(struct perf_event *event)
@@ -4512,6 +4662,12 @@ static const struct pmu *sw_perf_event_init(struct perf_event *event)
        case PERF_COUNT_SW_ALIGNMENT_FAULTS:
        case PERF_COUNT_SW_EMULATION_FAULTS:
                if (!event->parent) {
+                       int err;
+
+                       err = swevent_hlist_get(event);
+                       if (err)
+                               return ERR_PTR(err);
+
                        atomic_inc(&perf_swevent_enabled[event_id]);
                        event->destroy = sw_perf_event_destroy;
                }
@@ -4897,7 +5053,7 @@ err_fput_free_put_context:
 
 err_free_put_context:
        if (err < 0)
-               kfree(event);
+               free_event(event);
 
 err_put_context:
        if (err < 0)
@@ -5176,7 +5332,7 @@ void perf_event_exit_task(struct task_struct *child)
         *
         * But since its the parent context it won't be the same instance.
         */
-       mutex_lock_nested(&child_ctx->mutex, SINGLE_DEPTH_NESTING);
+       mutex_lock(&child_ctx->mutex);
 
 again:
        list_for_each_entry_safe(child_event, tmp, &child_ctx->pinned_groups,
@@ -5384,6 +5540,7 @@ static void __init perf_event_init_all_cpus(void)
 
        for_each_possible_cpu(cpu) {
                cpuctx = &per_cpu(perf_cpu_context, cpu);
+               mutex_init(&cpuctx->hlist_mutex);
                __perf_event_init_context(&cpuctx->ctx, NULL);
        }
 }
@@ -5397,6 +5554,16 @@ static void __cpuinit perf_event_init_cpu(int cpu)
        spin_lock(&perf_resource_lock);
        cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
        spin_unlock(&perf_resource_lock);
+
+       mutex_lock(&cpuctx->hlist_mutex);
+       if (cpuctx->hlist_refcount > 0) {
+               struct swevent_hlist *hlist;
+
+               hlist = kzalloc(sizeof(*hlist), GFP_KERNEL);
+               WARN_ON_ONCE(!hlist);
+               rcu_assign_pointer(cpuctx->swevent_hlist, hlist);
+       }
+       mutex_unlock(&cpuctx->hlist_mutex);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -5416,6 +5583,10 @@ static void perf_event_exit_cpu(int cpu)
        struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
        struct perf_event_context *ctx = &cpuctx->ctx;
 
+       mutex_lock(&cpuctx->hlist_mutex);
+       swevent_hlist_release(cpuctx);
+       mutex_unlock(&cpuctx->hlist_mutex);
+
        mutex_lock(&ctx->mutex);
        smp_call_function_single(cpu, __perf_event_exit_cpu, NULL, 1);
        mutex_unlock(&ctx->mutex);
index bc7704b..00bb252 100644 (file)
 #include <trace/events/timer.h>
 
 /*
- * Called after updating RLIMIT_CPU to set timer expiration if necessary.
+ * Called after updating RLIMIT_CPU to run cpu timer and update
+ * tsk->signal->cputime_expires expiration cache if necessary. Needs
+ * siglock protection since other code may update expiration cache as
+ * well.
  */
 void update_rlimit_cpu(unsigned long rlim_new)
 {
        cputime_t cputime = secs_to_cputime(rlim_new);
-       struct signal_struct *const sig = current->signal;
 
-       if (cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) ||
-           cputime_gt(sig->it[CPUCLOCK_PROF].expires, cputime)) {
-               spin_lock_irq(&current->sighand->siglock);
-               set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
-               spin_unlock_irq(&current->sighand->siglock);
-       }
+       spin_lock_irq(&current->sighand->siglock);
+       set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
+       spin_unlock_irq(&current->sighand->siglock);
 }
 
 static int check_clock(const clockid_t which_clock)
@@ -548,111 +547,62 @@ static inline int expires_gt(cputime_t expires, cputime_t new_exp)
               cputime_gt(expires, new_exp);
 }
 
-static inline int expires_le(cputime_t expires, cputime_t new_exp)
-{
-       return !cputime_eq(expires, cputime_zero) &&
-              cputime_le(expires, new_exp);
-}
 /*
  * Insert the timer on the appropriate list before any timers that
  * expire later.  This must be called with the tasklist_lock held
- * for reading, and interrupts disabled.
+ * for reading, interrupts disabled and p->sighand->siglock taken.
  */
-static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
+static void arm_timer(struct k_itimer *timer)
 {
        struct task_struct *p = timer->it.cpu.task;
        struct list_head *head, *listpos;
+       struct task_cputime *cputime_expires;
        struct cpu_timer_list *const nt = &timer->it.cpu;
        struct cpu_timer_list *next;
-       unsigned long i;
 
-       head = (CPUCLOCK_PERTHREAD(timer->it_clock) ?
-               p->cpu_timers : p->signal->cpu_timers);
+       if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
+               head = p->cpu_timers;
+               cputime_expires = &p->cputime_expires;
+       } else {
+               head = p->signal->cpu_timers;
+               cputime_expires = &p->signal->cputime_expires;
+       }
        head += CPUCLOCK_WHICH(timer->it_clock);
 
-       BUG_ON(!irqs_disabled());
-       spin_lock(&p->sighand->siglock);
-
        listpos = head;
-       if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) {
-               list_for_each_entry(next, head, entry) {
-                       if (next->expires.sched > nt->expires.sched)
-                               break;
-                       listpos = &next->entry;
-               }
-       } else {
-               list_for_each_entry(next, head, entry) {
-                       if (cputime_gt(next->expires.cpu, nt->expires.cpu))
-                               break;
-                       listpos = &next->entry;
-               }
+       list_for_each_entry(next, head, entry) {
+               if (cpu_time_before(timer->it_clock, nt->expires, next->expires))
+                       break;
+               listpos = &next->entry;
        }
        list_add(&nt->entry, listpos);
 
        if (listpos == head) {
+               union cpu_time_count *exp = &nt->expires;
+
                /*
-                * We are the new earliest-expiring timer.
-                * If we are a thread timer, there can always
-                * be a process timer telling us to stop earlier.
+                * We are the new earliest-expiring POSIX 1.b timer, hence
+                * need to update expiration cache. Take into account that
+                * for process timers we share expiration cache with itimers
+                * and RLIMIT_CPU and for thread timers with RLIMIT_RTTIME.
                 */
 
-               if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
-                       union cpu_time_count *exp = &nt->expires;
-
-                       switch (CPUCLOCK_WHICH(timer->it_clock)) {
-                       default:
-                               BUG();
-                       case CPUCLOCK_PROF:
-                               if (expires_gt(p->cputime_expires.prof_exp,
-                                              exp->cpu))
-                                       p->cputime_expires.prof_exp = exp->cpu;
-                               break;
-                       case CPUCLOCK_VIRT:
-                               if (expires_gt(p->cputime_expires.virt_exp,
-                                              exp->cpu))
-                                       p->cputime_expires.virt_exp = exp->cpu;
-                               break;
-                       case CPUCLOCK_SCHED:
-                               if (p->cputime_expires.sched_exp == 0 ||
-                                   p->cputime_expires.sched_exp > exp->sched)
-                                       p->cputime_expires.sched_exp =
-                                                               exp->sched;
-                               break;
-                       }
-               } else {
-                       struct signal_struct *const sig = p->signal;
-                       union cpu_time_count *exp = &timer->it.cpu.expires;
-
-                       /*
-                        * For a process timer, set the cached expiration time.
-                        */
-                       switch (CPUCLOCK_WHICH(timer->it_clock)) {
-                       default:
-                               BUG();
-                       case CPUCLOCK_VIRT:
-                               if (expires_le(sig->it[CPUCLOCK_VIRT].expires,
-                                              exp->cpu))
-                                       break;
-                               sig->cputime_expires.virt_exp = exp->cpu;
-                               break;
-                       case CPUCLOCK_PROF:
-                               if (expires_le(sig->it[CPUCLOCK_PROF].expires,
-                                              exp->cpu))
-                                       break;
-                               i = sig->rlim[RLIMIT_CPU].rlim_cur;
-                               if (i != RLIM_INFINITY &&
-                                   i <= cputime_to_secs(exp->cpu))
-                                       break;
-                               sig->cputime_expires.prof_exp = exp->cpu;
-                               break;
-                       case CPUCLOCK_SCHED:
-                               sig->cputime_expires.sched_exp = exp->sched;
-                               break;
-                       }
+               switch (CPUCLOCK_WHICH(timer->it_clock)) {
+               case CPUCLOCK_PROF:
+                       if (expires_gt(cputime_expires->prof_exp, exp->cpu))
+                               cputime_expires->prof_exp = exp->cpu;
+                       break;
+               case CPUCLOCK_VIRT:
+                       if (expires_gt(cputime_expires->virt_exp, exp->cpu))
+                               cputime_expires->virt_exp = exp->cpu;
+                       break;
+               case CPUCLOCK_SCHED:
+                       if (cputime_expires->sched_exp == 0 ||
+                           cputime_expires->sched_exp > exp->sched)
+                               cputime_expires->sched_exp = exp->sched;
+                       break;
                }
        }
-
-       spin_unlock(&p->sighand->siglock);
 }
 
 /*
@@ -660,7 +610,12 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
  */
 static void cpu_timer_fire(struct k_itimer *timer)
 {
-       if (unlikely(timer->sigq == NULL)) {
+       if ((timer->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
+               /*
+                * User don't want any signal.
+                */
+               timer->it.cpu.expires.sched = 0;
+       } else if (unlikely(timer->sigq == NULL)) {
                /*
                 * This a special case for clock_nanosleep,
                 * not a normal timer from sys_timer_create.
@@ -721,7 +676,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
                        struct itimerspec *new, struct itimerspec *old)
 {
        struct task_struct *p = timer->it.cpu.task;
-       union cpu_time_count old_expires, new_expires, val;
+       union cpu_time_count old_expires, new_expires, old_incr, val;
        int ret;
 
        if (unlikely(p == NULL)) {
@@ -752,6 +707,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
        BUG_ON(!irqs_disabled());
 
        ret = 0;
+       old_incr = timer->it.cpu.incr;
        spin_lock(&p->sighand->siglock);
        old_expires = timer->it.cpu.expires;
        if (unlikely(timer->it.cpu.firing)) {
@@ -759,7 +715,6 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
                ret = TIMER_RETRY;
        } else
                list_del_init(&timer->it.cpu.entry);
-       spin_unlock(&p->sighand->siglock);
 
        /*
         * We need to sample the current value to convert the new
@@ -813,6 +768,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
                 * disable this firing since we are already reporting
                 * it as an overrun (thanks to bump_cpu_timer above).
                 */
+               spin_unlock(&p->sighand->siglock);
                read_unlock(&tasklist_lock);
                goto out;
        }
@@ -828,11 +784,11 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
         */
        timer->it.cpu.expires = new_expires;
        if (new_expires.sched != 0 &&
-           (timer->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE &&
            cpu_time_before(timer->it_clock, val, new_expires)) {
-               arm_timer(timer, val);
+               arm_timer(timer);
        }
 
+       spin_unlock(&p->sighand->siglock);
        read_unlock(&tasklist_lock);
 
        /*
@@ -853,7 +809,6 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
        timer->it_overrun = -1;
 
        if (new_expires.sched != 0 &&
-           (timer->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE &&
            !cpu_time_before(timer->it_clock, val, new_expires)) {
                /*
                 * The designated time already passed, so we notify
@@ -867,7 +822,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
  out:
        if (old) {
                sample_to_timespec(timer->it_clock,
-                                  timer->it.cpu.incr, &old->it_interval);
+                                  old_incr, &old->it_interval);
        }
        return ret;
 }
@@ -927,25 +882,6 @@ void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
                read_unlock(&tasklist_lock);
        }
 
-       if ((timer->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE) {
-               if (timer->it.cpu.incr.sched == 0 &&
-                   cpu_time_before(timer->it_clock,
-                                   timer->it.cpu.expires, now)) {
-                       /*
-                        * Do-nothing timer expired and has no reload,
-                        * so it's as if it was never set.
-                        */
-                       timer->it.cpu.expires.sched = 0;
-                       itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
-                       return;
-               }
-               /*
-                * Account for any expirations and reloads that should
-                * have happened.
-                */
-               bump_cpu_timer(timer, now);
-       }
-
        if (unlikely(clear_dead)) {
                /*
                 * We've noticed that the thread is dead, but
@@ -1066,16 +1002,9 @@ static void stop_process_timers(struct signal_struct *sig)
        struct thread_group_cputimer *cputimer = &sig->cputimer;
        unsigned long flags;
 
-       if (!cputimer->running)
-               return;
-
        spin_lock_irqsave(&cputimer->lock, flags);
        cputimer->running = 0;
        spin_unlock_irqrestore(&cputimer->lock, flags);
-
-       sig->cputime_expires.prof_exp = cputime_zero;
-       sig->cputime_expires.virt_exp = cputime_zero;
-       sig->cputime_expires.sched_exp = 0;
 }
 
 static u32 onecputick;
@@ -1112,6 +1041,23 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
        }
 }
 
+/**
+ * task_cputime_zero - Check a task_cputime struct for all zero fields.
+ *
+ * @cputime:   The struct to compare.
+ *
+ * Checks @cputime to see if all fields are zero.  Returns true if all fields
+ * are zero, false if any field is nonzero.
+ */
+static inline int task_cputime_zero(const struct task_cputime *cputime)
+{
+       if (cputime_eq(cputime->utime, cputime_zero) &&
+           cputime_eq(cputime->stime, cputime_zero) &&
+           cputime->sum_exec_runtime == 0)
+               return 1;
+       return 0;
+}
+
 /*
  * Check for any per-thread CPU timers that have fired and move them
  * off the tsk->*_timers list onto the firing list.  Per-thread timers
@@ -1128,19 +1074,6 @@ static void check_process_timers(struct task_struct *tsk,
        struct task_cputime cputime;
        unsigned long soft;
 
-       /*
-        * Don't sample the current process CPU clocks if there are no timers.
-        */
-       if (list_empty(&timers[CPUCLOCK_PROF]) &&
-           cputime_eq(sig->it[CPUCLOCK_PROF].expires, cputime_zero) &&
-           sig->rlim[RLIMIT_CPU].rlim_cur == RLIM_INFINITY &&
-           list_empty(&timers[CPUCLOCK_VIRT]) &&
-           cputime_eq(sig->it[CPUCLOCK_VIRT].expires, cputime_zero) &&
-           list_empty(&timers[CPUCLOCK_SCHED])) {
-               stop_process_timers(sig);
-               return;
-       }
-
        /*
         * Collect the current process totals.
         */
@@ -1230,18 +1163,11 @@ static void check_process_timers(struct task_struct *tsk,
                }
        }
 
-       if (!cputime_eq(prof_expires, cputime_zero) &&
-           (cputime_eq(sig->cputime_expires.prof_exp, cputime_zero) ||
-            cputime_gt(sig->cputime_expires.prof_exp, prof_expires)))
-               sig->cputime_expires.prof_exp = prof_expires;
-       if (!cputime_eq(virt_expires, cputime_zero) &&
-           (cputime_eq(sig->cputime_expires.virt_exp, cputime_zero) ||
-            cputime_gt(sig->cputime_expires.virt_exp, virt_expires)))
-               sig->cputime_expires.virt_exp = virt_expires;
-       if (sched_expires != 0 &&
-           (sig->cputime_expires.sched_exp == 0 ||
-            sig->cputime_expires.sched_exp > sched_expires))
-               sig->cputime_expires.sched_exp = sched_expires;
+       sig->cputime_expires.prof_exp = prof_expires;
+       sig->cputime_expires.virt_exp = virt_expires;
+       sig->cputime_expires.sched_exp = sched_expires;
+       if (task_cputime_zero(&sig->cputime_expires))
+               stop_process_timers(sig);
 }
 
 /*
@@ -1270,6 +1196,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
                        goto out;
                }
                read_lock(&tasklist_lock); /* arm_timer needs it.  */
+               spin_lock(&p->sighand->siglock);
        } else {
                read_lock(&tasklist_lock);
                if (unlikely(p->signal == NULL)) {
@@ -1290,6 +1217,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
                        clear_dead_task(timer, now);
                        goto out_unlock;
                }
+               spin_lock(&p->sighand->siglock);
                cpu_timer_sample_group(timer->it_clock, p, &now);
                bump_cpu_timer(timer, now);
                /* Leave the tasklist_lock locked for the call below.  */
@@ -1298,7 +1226,9 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
        /*
         * Now re-arm for the new expiry time.
         */
-       arm_timer(timer, now);
+       BUG_ON(!irqs_disabled());
+       arm_timer(timer);
+       spin_unlock(&p->sighand->siglock);
 
 out_unlock:
        read_unlock(&tasklist_lock);
@@ -1309,23 +1239,6 @@ out:
        ++timer->it_requeue_pending;
 }
 
-/**
- * task_cputime_zero - Check a task_cputime struct for all zero fields.
- *
- * @cputime:   The struct to compare.
- *
- * Checks @cputime to see if all fields are zero.  Returns true if all fields
- * are zero, false if any field is nonzero.
- */
-static inline int task_cputime_zero(const struct task_cputime *cputime)
-{
-       if (cputime_eq(cputime->utime, cputime_zero) &&
-           cputime_eq(cputime->stime, cputime_zero) &&
-           cputime->sum_exec_runtime == 0)
-               return 1;
-       return 0;
-}
-
 /**
  * task_cputime_expired - Compare two task_cputime entities.
  *
@@ -1382,7 +1295,7 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
        }
 
        sig = tsk->signal;
-       if (!task_cputime_zero(&sig->cputime_expires)) {
+       if (sig->cputimer.running) {
                struct task_cputime group_sample;
 
                thread_group_cputimer(tsk, &group_sample);
@@ -1390,7 +1303,7 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
                        return 1;
        }
 
-       return sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY;
+       return 0;
 }
 
 /*
@@ -1419,7 +1332,12 @@ void run_posix_cpu_timers(struct task_struct *tsk)
         * put them on the firing list.
         */
        check_thread_timers(tsk, &firing);
-       check_process_timers(tsk, &firing);
+       /*
+        * If there are any active process wide timers (POSIX 1.b, itimers,
+        * RLIMIT_CPU) cputimer must be running.
+        */
+       if (tsk->signal->cputimer.running)
+               check_process_timers(tsk, &firing);
 
        /*
         * We must release these locks before taking any timer's lock.
@@ -1456,21 +1374,23 @@ void run_posix_cpu_timers(struct task_struct *tsk)
 }
 
 /*
- * Set one of the process-wide special case CPU timers.
+ * Set one of the process-wide special case CPU timers or RLIMIT_CPU.
  * The tsk->sighand->siglock must be held by the caller.
- * The *newval argument is relative and we update it to be absolute, *oldval
- * is absolute and we update it to be relative.
  */
 void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
                           cputime_t *newval, cputime_t *oldval)
 {
        union cpu_time_count now;
-       struct list_head *head;
 
        BUG_ON(clock_idx == CPUCLOCK_SCHED);
        cpu_timer_sample_group(clock_idx, tsk, &now);
 
        if (oldval) {
+               /*
+                * We are setting itimer. The *oldval is absolute and we update
+                * it to be relative, *newval argument is relative and we update
+                * it to be absolute.
+                */
                if (!cputime_eq(*oldval, cputime_zero)) {
                        if (cputime_le(*oldval, now.cpu)) {
                                /* Just about to fire. */
@@ -1483,33 +1403,21 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
                if (cputime_eq(*newval, cputime_zero))
                        return;
                *newval = cputime_add(*newval, now.cpu);
-
-               /*
-                * If the RLIMIT_CPU timer will expire before the
-                * ITIMER_PROF timer, we have nothing else to do.
-                */
-               if (tsk->signal->rlim[RLIMIT_CPU].rlim_cur
-                   < cputime_to_secs(*newval))
-                       return;
        }
 
        /*
-        * Check whether there are any process timers already set to fire
-        * before this one.  If so, we don't have anything more to do.
+        * Update expiration cache if we are the earliest timer, or eventually
+        * RLIMIT_CPU limit is earlier than prof_exp cpu timer expire.
         */
-       head = &tsk->signal->cpu_timers[clock_idx];
-       if (list_empty(head) ||
-           cputime_ge(list_first_entry(head,
-                                 struct cpu_timer_list, entry)->expires.cpu,
-                      *newval)) {
-               switch (clock_idx) {
-               case CPUCLOCK_PROF:
+       switch (clock_idx) {
+       case CPUCLOCK_PROF:
+               if (expires_gt(tsk->signal->cputime_expires.prof_exp, *newval))
                        tsk->signal->cputime_expires.prof_exp = *newval;
-                       break;
-               case CPUCLOCK_VIRT:
+               break;
+       case CPUCLOCK_VIRT:
+               if (expires_gt(tsk->signal->cputime_expires.virt_exp, *newval))
                        tsk->signal->cputime_expires.virt_exp = *newval;
-                       break;
-               }
+               break;
        }
 }
 
index 4d22896..a8c9621 100644 (file)
@@ -420,7 +420,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                         * User space encodes device types as two-byte values,
                         * so we need to recode them
                         */
-                       swdev = old_decode_dev(swap_area.dev);
+                       swdev = new_decode_dev(swap_area.dev);
                        if (swdev) {
                                offset = swap_area.offset;
                                data->swap = swap_type_of(swdev, offset, NULL);
index a55d3a3..dfadc5b 100644 (file)
@@ -127,8 +127,10 @@ int __ref profile_init(void)
                return 0;
 
        prof_buffer = vmalloc(buffer_bytes);
-       if (prof_buffer)
+       if (prof_buffer) {
+               memset(prof_buffer, 0, buffer_bytes);
                return 0;
+       }
 
        free_cpumask_var(prof_cpu_mask);
        return -ENOMEM;
index 42ad8ae..6af9cdd 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/ptrace.h>
 #include <linux/security.h>
 #include <linux/signal.h>
@@ -76,7 +75,6 @@ void __ptrace_unlink(struct task_struct *child)
        child->parent = child->real_parent;
        list_del_init(&child->ptrace_entry);
 
-       arch_ptrace_untrace(child);
        if (task_is_traced(child))
                ptrace_untrace(child);
 }
@@ -666,10 +664,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
        struct task_struct *child;
        long ret;
 
-       /*
-        * This lock_kernel fixes a subtle race with suid exec
-        */
-       lock_kernel();
        if (request == PTRACE_TRACEME) {
                ret = ptrace_traceme();
                if (!ret)
@@ -703,7 +697,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
  out_put_task_struct:
        put_task_struct(child);
  out:
-       unlock_kernel();
        return ret;
 }
 
@@ -813,10 +806,6 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
        struct task_struct *child;
        long ret;
 
-       /*
-        * This lock_kernel fixes a subtle race with suid exec
-        */
-       lock_kernel();
        if (request == PTRACE_TRACEME) {
                ret = ptrace_traceme();
                goto out;
@@ -846,7 +835,6 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
  out_put_task_struct:
        put_task_struct(child);
  out:
-       unlock_kernel();
        return ret;
 }
 #endif /* CONFIG_COMPAT */
index 63fe254..72a8dc9 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
-#include <linux/kernel_stat.h>
 #include <linux/hardirq.h>
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -64,11 +63,15 @@ struct lockdep_map rcu_sched_lock_map =
 EXPORT_SYMBOL_GPL(rcu_sched_lock_map);
 #endif
 
-int rcu_scheduler_active __read_mostly;
-EXPORT_SYMBOL_GPL(rcu_scheduler_active);
-
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
+int debug_lockdep_rcu_enabled(void)
+{
+       return rcu_scheduler_active && debug_locks &&
+              current->lockdep_recursion == 0;
+}
+EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
+
 /**
  * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section?
  *
@@ -89,21 +92,6 @@ EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held);
 
 #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
 
-/*
- * This function is invoked towards the end of the scheduler's initialization
- * process.  Before this is called, the idle task might contain
- * RCU read-side critical sections (during which time, this idle
- * task is booting the system).  After this function is called, the
- * idle tasks are prohibited from containing RCU read-side critical
- * sections.
- */
-void rcu_scheduler_starting(void)
-{
-       WARN_ON(num_online_cpus() != 1);
-       WARN_ON(nr_context_switches() > 0);
-       rcu_scheduler_active = 1;
-}
-
 /*
  * Awaken the corresponding synchronize_rcu() instance now that a
  * grace period has elapsed.
@@ -115,3 +103,14 @@ void wakeme_after_rcu(struct rcu_head  *head)
        rcu = container_of(head, struct rcu_synchronize, head);
        complete(&rcu->completion);
 }
+
+#ifdef CONFIG_PROVE_RCU
+/*
+ * wrapper function to avoid #include problems.
+ */
+int rcu_my_thread_group_empty(void)
+{
+       return thread_group_empty(current);
+}
+EXPORT_SYMBOL_GPL(rcu_my_thread_group_empty);
+#endif /* #ifdef CONFIG_PROVE_RCU */
index 9f6d9ff..38729d3 100644 (file)
@@ -44,9 +44,9 @@ struct rcu_ctrlblk {
 };
 
 /* Definition for rcupdate control block. */
-static struct rcu_ctrlblk rcu_ctrlblk = {
-       .donetail       = &rcu_ctrlblk.rcucblist,
-       .curtail        = &rcu_ctrlblk.rcucblist,
+static struct rcu_ctrlblk rcu_sched_ctrlblk = {
+       .donetail       = &rcu_sched_ctrlblk.rcucblist,
+       .curtail        = &rcu_sched_ctrlblk.rcucblist,
 };
 
 static struct rcu_ctrlblk rcu_bh_ctrlblk = {
@@ -54,6 +54,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk = {
        .curtail        = &rcu_bh_ctrlblk.rcucblist,
 };
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+int rcu_scheduler_active __read_mostly;
+EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+
 #ifdef CONFIG_NO_HZ
 
 static long rcu_dynticks_nesting = 1;
@@ -108,7 +113,8 @@ static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
  */
 void rcu_sched_qs(int cpu)
 {
-       if (rcu_qsctr_help(&rcu_ctrlblk) + rcu_qsctr_help(&rcu_bh_ctrlblk))
+       if (rcu_qsctr_help(&rcu_sched_ctrlblk) +
+           rcu_qsctr_help(&rcu_bh_ctrlblk))
                raise_softirq(RCU_SOFTIRQ);
 }
 
@@ -173,7 +179,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
  */
 static void rcu_process_callbacks(struct softirq_action *unused)
 {
-       __rcu_process_callbacks(&rcu_ctrlblk);
+       __rcu_process_callbacks(&rcu_sched_ctrlblk);
        __rcu_process_callbacks(&rcu_bh_ctrlblk);
 }
 
@@ -187,7 +193,8 @@ static void rcu_process_callbacks(struct softirq_action *unused)
  *
  * Cool, huh?  (Due to Josh Triplett.)
  *
- * But we want to make this a static inline later.
+ * But we want to make this a static inline later.  The cond_resched()
+ * currently makes this problematic.
  */
 void synchronize_sched(void)
 {
@@ -195,12 +202,6 @@ void synchronize_sched(void)
 }
 EXPORT_SYMBOL_GPL(synchronize_sched);
 
-void synchronize_rcu_bh(void)
-{
-       synchronize_sched();
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
-
 /*
  * Helper function for call_rcu() and call_rcu_bh().
  */
@@ -226,7 +227,7 @@ static void __call_rcu(struct rcu_head *head,
  */
 void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 {
-       __call_rcu(head, func, &rcu_ctrlblk);
+       __call_rcu(head, func, &rcu_sched_ctrlblk);
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
@@ -244,11 +245,13 @@ void rcu_barrier(void)
 {
        struct rcu_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu(&rcu.head, wakeme_after_rcu);
        /* Wait for it. */
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier);
 
@@ -256,11 +259,13 @@ void rcu_barrier_bh(void)
 {
        struct rcu_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu_bh(&rcu.head, wakeme_after_rcu);
        /* Wait for it. */
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_bh);
 
@@ -268,11 +273,13 @@ void rcu_barrier_sched(void)
 {
        struct rcu_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu_sched(&rcu.head, wakeme_after_rcu);
        /* Wait for it. */
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_sched);
 
@@ -280,3 +287,5 @@ void __init rcu_init(void)
 {
        open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
 }
+
+#include "rcutiny_plugin.h"
diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h
new file mode 100644 (file)
index 0000000..d223a92
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion (tree-based version)
+ * Internal non-public definitions that provide either classic
+ * or preemptable semantics.
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2009
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+
+#include <linux/kernel_stat.h>
+
+/*
+ * During boot, we forgive RCU lockdep issues.  After this function is
+ * invoked, we start taking RCU lockdep issues seriously.
+ */
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
+#endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
index 58df55b..6535ac8 100644 (file)
@@ -464,9 +464,11 @@ static void rcu_bh_torture_synchronize(void)
 {
        struct rcu_bh_torture_synchronize rcu;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        call_rcu_bh(&rcu.head, rcu_bh_torture_wakeme_after_cb);
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 
 static struct rcu_torture_ops rcu_bh_ops = {
@@ -669,7 +671,7 @@ static struct rcu_torture_ops sched_expedited_ops = {
        .sync           = synchronize_sched_expedited,
        .cb_barrier     = NULL,
        .fqs            = rcu_sched_force_quiescent_state,
-       .stats          = rcu_expedited_torture_stats,
+       .stats          = NULL,
        .irq_capable    = 1,
        .name           = "sched_expedited"
 };
index 3ec8160..d443734 100644 (file)
@@ -46,6 +46,7 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
+#include <linux/kernel_stat.h>
 
 #include "rcutree.h"
 
@@ -53,8 +54,8 @@
 
 static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
 
-#define RCU_STATE_INITIALIZER(name) { \
-       .level = { &name.node[0] }, \
+#define RCU_STATE_INITIALIZER(structname) { \
+       .level = { &structname.node[0] }, \
        .levelcnt = { \
                NUM_RCU_LVL_0,  /* root of hierarchy. */ \
                NUM_RCU_LVL_1, \
@@ -65,13 +66,14 @@ static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
        .signaled = RCU_GP_IDLE, \
        .gpnum = -300, \
        .completed = -300, \
-       .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&name.onofflock), \
+       .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&structname.onofflock), \
        .orphan_cbs_list = NULL, \
-       .orphan_cbs_tail = &name.orphan_cbs_list, \
+       .orphan_cbs_tail = &structname.orphan_cbs_list, \
        .orphan_qlen = 0, \
-       .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&name.fqslock), \
+       .fqslock = __RAW_SPIN_LOCK_UNLOCKED(&structname.fqslock), \
        .n_force_qs = 0, \
        .n_force_qs_ngp = 0, \
+       .name = #structname, \
 }
 
 struct rcu_state rcu_sched_state = RCU_STATE_INITIALIZER(rcu_sched_state);
@@ -80,6 +82,9 @@ DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
 struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
 DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
 
+int rcu_scheduler_active __read_mostly;
+EXPORT_SYMBOL_GPL(rcu_scheduler_active);
+
 /*
  * Return true if an RCU grace period is in progress.  The ACCESS_ONCE()s
  * permit this function to be invoked without holding the root rcu_node
@@ -97,25 +102,32 @@ static int rcu_gp_in_progress(struct rcu_state *rsp)
  */
 void rcu_sched_qs(int cpu)
 {
-       struct rcu_data *rdp;
+       struct rcu_data *rdp = &per_cpu(rcu_sched_data, cpu);
 
-       rdp = &per_cpu(rcu_sched_data, cpu);
        rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
-       rcu_preempt_note_context_switch(cpu);
 }
 
 void rcu_bh_qs(int cpu)
 {
-       struct rcu_data *rdp;
+       struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
 
-       rdp = &per_cpu(rcu_bh_data, cpu);
        rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
 }
 
+/*
+ * Note a context switch.  This is a quiescent state for RCU-sched,
+ * and requires special handling for preemptible RCU.
+ */
+void rcu_note_context_switch(int cpu)
+{
+       rcu_sched_qs(cpu);
+       rcu_preempt_note_context_switch(cpu);
+}
+
 #ifdef CONFIG_NO_HZ
 DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
        .dynticks_nesting = 1,
@@ -438,6 +450,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
 
 #ifdef CONFIG_RCU_CPU_STALL_DETECTOR
 
+int rcu_cpu_stall_panicking __read_mostly;
+
 static void record_gp_stall_check_time(struct rcu_state *rsp)
 {
        rsp->gp_start = jiffies;
@@ -470,7 +484,8 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
 
        /* OK, time to rat on our buddy... */
 
-       printk(KERN_ERR "INFO: RCU detected CPU stalls:");
+       printk(KERN_ERR "INFO: %s detected stalls on CPUs/tasks: {",
+              rsp->name);
        rcu_for_each_leaf_node(rsp, rnp) {
                raw_spin_lock_irqsave(&rnp->lock, flags);
                rcu_print_task_stall(rnp);
@@ -481,7 +496,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
                        if (rnp->qsmask & (1UL << cpu))
                                printk(" %d", rnp->grplo + cpu);
        }
-       printk(" (detected by %d, t=%ld jiffies)\n",
+       printk("} (detected by %d, t=%ld jiffies)\n",
               smp_processor_id(), (long)(jiffies - rsp->gp_start));
        trigger_all_cpu_backtrace();
 
@@ -497,8 +512,8 @@ static void print_cpu_stall(struct rcu_state *rsp)
        unsigned long flags;
        struct rcu_node *rnp = rcu_get_root(rsp);
 
-       printk(KERN_ERR "INFO: RCU detected CPU %d stall (t=%lu jiffies)\n",
-                       smp_processor_id(), jiffies - rsp->gp_start);
+       printk(KERN_ERR "INFO: %s detected stall on CPU %d (t=%lu jiffies)\n",
+              rsp->name, smp_processor_id(), jiffies - rsp->gp_start);
        trigger_all_cpu_backtrace();
 
        raw_spin_lock_irqsave(&rnp->lock, flags);
@@ -515,6 +530,8 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
        long delta;
        struct rcu_node *rnp;
 
+       if (rcu_cpu_stall_panicking)
+               return;
        delta = jiffies - rsp->jiffies_stall;
        rnp = rdp->mynode;
        if ((rnp->qsmask & rdp->grpmask) && delta >= 0) {
@@ -529,6 +546,21 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
        }
 }
 
+static int rcu_panic(struct notifier_block *this, unsigned long ev, void *ptr)
+{
+       rcu_cpu_stall_panicking = 1;
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block rcu_panic_block = {
+       .notifier_call = rcu_panic,
+};
+
+static void __init check_cpu_stall_init(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list, &rcu_panic_block);
+}
+
 #else /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 
 static void record_gp_stall_check_time(struct rcu_state *rsp)
@@ -539,6 +571,10 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
 {
 }
 
+static void __init check_cpu_stall_init(void)
+{
+}
+
 #endif /* #else #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 
 /*
@@ -1125,8 +1161,6 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
  */
 void rcu_check_callbacks(int cpu, int user)
 {
-       if (!rcu_pending(cpu))
-               return; /* if nothing for RCU to do. */
        if (user ||
            (idle_cpu(cpu) && rcu_scheduler_active &&
             !in_softirq() && hardirq_count() <= (1 << HARDIRQ_SHIFT))) {
@@ -1158,7 +1192,8 @@ void rcu_check_callbacks(int cpu, int user)
                rcu_bh_qs(cpu);
        }
        rcu_preempt_check_callbacks(cpu);
-       raise_softirq(RCU_SOFTIRQ);
+       if (rcu_pending(cpu))
+               raise_softirq(RCU_SOFTIRQ);
 }
 
 #ifdef CONFIG_SMP
@@ -1236,11 +1271,11 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
                break; /* grace period idle or initializing, ignore. */
 
        case RCU_SAVE_DYNTICK:
-
-               raw_spin_unlock(&rnp->lock);  /* irqs remain disabled */
                if (RCU_SIGNAL_INIT != RCU_SAVE_DYNTICK)
                        break; /* So gcc recognizes the dead code. */
 
+               raw_spin_unlock(&rnp->lock);  /* irqs remain disabled */
+
                /* Record dyntick-idle state. */
                force_qs_rnp(rsp, dyntick_save_progress_counter);
                raw_spin_lock(&rnp->lock);  /* irqs already disabled */
@@ -1449,11 +1484,13 @@ void synchronize_sched(void)
        if (rcu_blocking_is_gp())
                return;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu_sched(&rcu.head, wakeme_after_rcu);
        /* Wait for it. */
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_sched);
 
@@ -1473,11 +1510,13 @@ void synchronize_rcu_bh(void)
        if (rcu_blocking_is_gp())
                return;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu_bh(&rcu.head, wakeme_after_rcu);
        /* Wait for it. */
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
 
@@ -1498,8 +1537,20 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
        check_cpu_stall(rsp, rdp);
 
        /* Is the RCU core waiting for a quiescent state from this CPU? */
-       if (rdp->qs_pending) {
+       if (rdp->qs_pending && !rdp->passed_quiesc) {
+
+               /*
+                * If force_quiescent_state() coming soon and this CPU
+                * needs a quiescent state, and this is either RCU-sched
+                * or RCU-bh, force a local reschedule.
+                */
                rdp->n_rp_qs_pending++;
+               if (!rdp->preemptable &&
+                   ULONG_CMP_LT(ACCESS_ONCE(rsp->jiffies_force_qs) - 1,
+                                jiffies))
+                       set_need_resched();
+       } else if (rdp->qs_pending && rdp->passed_quiesc) {
+               rdp->n_rp_report_qs++;
                return 1;
        }
 
@@ -1766,6 +1817,21 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
        return NOTIFY_OK;
 }
 
+/*
+ * This function is invoked towards the end of the scheduler's initialization
+ * process.  Before this is called, the idle task might contain
+ * RCU read-side critical sections (during which time, this idle
+ * task is booting the system).  After this function is called, the
+ * idle tasks are prohibited from containing RCU read-side critical
+ * sections.  This function also enables RCU lockdep checking.
+ */
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(num_online_cpus() != 1);
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
 /*
  * Compute the per-level fanout, either using the exact fanout specified
  * or balancing the tree, depending on CONFIG_RCU_FANOUT_EXACT.
@@ -1849,6 +1915,14 @@ static void __init rcu_init_one(struct rcu_state *rsp)
                        INIT_LIST_HEAD(&rnp->blocked_tasks[3]);
                }
        }
+
+       rnp = rsp->level[NUM_RCU_LVLS - 1];
+       for_each_possible_cpu(i) {
+               while (i > rnp->grphi)
+                       rnp++;
+               rsp->rda[i]->mynode = rnp;
+               rcu_boot_init_percpu_data(i, rsp);
+       }
 }
 
 /*
@@ -1859,19 +1933,11 @@ static void __init rcu_init_one(struct rcu_state *rsp)
 #define RCU_INIT_FLAVOR(rsp, rcu_data) \
 do { \
        int i; \
-       int j; \
-       struct rcu_node *rnp; \
        \
-       rcu_init_one(rsp); \
-       rnp = (rsp)->level[NUM_RCU_LVLS - 1]; \
-       j = 0; \
        for_each_possible_cpu(i) { \
-               if (i > rnp[j].grphi) \
-                       j++; \
-               per_cpu(rcu_data, i).mynode = &rnp[j]; \
                (rsp)->rda[i] = &per_cpu(rcu_data, i); \
-               rcu_boot_init_percpu_data(i, rsp); \
        } \
+       rcu_init_one(rsp); \
 } while (0)
 
 void __init rcu_init(void)
@@ -1879,12 +1945,6 @@ void __init rcu_init(void)
        int cpu;
 
        rcu_bootup_announce();
-#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
-       printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
-#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
-#if NUM_RCU_LVL_4 != 0
-       printk(KERN_INFO "Experimental four-level hierarchy is enabled.\n");
-#endif /* #if NUM_RCU_LVL_4 != 0 */
        RCU_INIT_FLAVOR(&rcu_sched_state, rcu_sched_data);
        RCU_INIT_FLAVOR(&rcu_bh_state, rcu_bh_data);
        __rcu_init_preempt();
@@ -1898,6 +1958,7 @@ void __init rcu_init(void)
        cpu_notifier(rcu_cpu_notify, 0);
        for_each_online_cpu(cpu)
                rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)cpu);
+       check_cpu_stall_init();
 }
 
 #include "rcutree_plugin.h"
index 4a525a3..14c040b 100644 (file)
@@ -223,6 +223,7 @@ struct rcu_data {
        /* 5) __rcu_pending() statistics. */
        unsigned long n_rcu_pending;    /* rcu_pending() calls since boot. */
        unsigned long n_rp_qs_pending;
+       unsigned long n_rp_report_qs;
        unsigned long n_rp_cb_ready;
        unsigned long n_rp_cpu_needs_gp;
        unsigned long n_rp_gp_completed;
@@ -326,6 +327,7 @@ struct rcu_state {
        unsigned long jiffies_stall;            /* Time at which to check */
                                                /*  for CPU stalls. */
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+       char *name;                             /* Name of structure. */
 };
 
 /* Return values for rcu_preempt_offline_tasks(). */
index 79b53bd..0e4f420 100644 (file)
 
 #include <linux/delay.h>
 
+/*
+ * Check the RCU kernel configuration parameters and print informative
+ * messages about anything out of the ordinary.  If you like #ifdef, you
+ * will love this function.
+ */
+static void __init rcu_bootup_announce_oddness(void)
+{
+#ifdef CONFIG_RCU_TRACE
+       printk(KERN_INFO "\tRCU debugfs-based tracing is enabled.\n");
+#endif
+#if (defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 64) || (!defined(CONFIG_64BIT) && CONFIG_RCU_FANOUT != 32)
+       printk(KERN_INFO "\tCONFIG_RCU_FANOUT set to non-default value of %d\n",
+              CONFIG_RCU_FANOUT);
+#endif
+#ifdef CONFIG_RCU_FANOUT_EXACT
+       printk(KERN_INFO "\tHierarchical RCU autobalancing is disabled.\n");
+#endif
+#ifdef CONFIG_RCU_FAST_NO_HZ
+       printk(KERN_INFO
+              "\tRCU dyntick-idle grace-period acceleration is enabled.\n");
+#endif
+#ifdef CONFIG_PROVE_RCU
+       printk(KERN_INFO "\tRCU lockdep checking is enabled.\n");
+#endif
+#ifdef CONFIG_RCU_TORTURE_TEST_RUNNABLE
+       printk(KERN_INFO "\tRCU torture testing starts during boot.\n");
+#endif
+#ifndef CONFIG_RCU_CPU_STALL_DETECTOR
+       printk(KERN_INFO
+              "\tRCU-based detection of stalled CPUs is disabled.\n");
+#endif
+#ifndef CONFIG_RCU_CPU_STALL_VERBOSE
+       printk(KERN_INFO "\tVerbose stalled-CPUs detection is disabled.\n");
+#endif
+#if NUM_RCU_LVL_4 != 0
+       printk(KERN_INFO "\tExperimental four-level hierarchy is enabled.\n");
+#endif
+}
+
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
 struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state);
@@ -38,8 +77,8 @@ static int rcu_preempted_readers_exp(struct rcu_node *rnp);
  */
 static void __init rcu_bootup_announce(void)
 {
-       printk(KERN_INFO
-              "Experimental preemptable hierarchical RCU implementation.\n");
+       printk(KERN_INFO "Preemptable hierarchical RCU implementation.\n");
+       rcu_bootup_announce_oddness();
 }
 
 /*
@@ -75,13 +114,19 @@ EXPORT_SYMBOL_GPL(rcu_force_quiescent_state);
  * that this just means that the task currently running on the CPU is
  * not in a quiescent state.  There might be any number of tasks blocked
  * while in an RCU read-side critical section.
+ *
+ * Unlike the other rcu_*_qs() functions, callers to this function
+ * must disable irqs in order to protect the assignment to
+ * ->rcu_read_unlock_special.
  */
 static void rcu_preempt_qs(int cpu)
 {
        struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
+
        rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
+       current->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
 }
 
 /*
@@ -144,9 +189,8 @@ static void rcu_preempt_note_context_switch(int cpu)
         * grace period, then the fact that the task has been enqueued
         * means that we continue to block the current grace period.
         */
-       rcu_preempt_qs(cpu);
        local_irq_save(flags);
-       t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
+       rcu_preempt_qs(cpu);
        local_irq_restore(flags);
 }
 
@@ -236,7 +280,6 @@ static void rcu_read_unlock_special(struct task_struct *t)
         */
        special = t->rcu_read_unlock_special;
        if (special & RCU_READ_UNLOCK_NEED_QS) {
-               t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
                rcu_preempt_qs(smp_processor_id());
        }
 
@@ -473,7 +516,6 @@ static void rcu_preempt_check_callbacks(int cpu)
        struct task_struct *t = current;
 
        if (t->rcu_read_lock_nesting == 0) {
-               t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
                rcu_preempt_qs(cpu);
                return;
        }
@@ -515,11 +557,13 @@ void synchronize_rcu(void)
        if (!rcu_scheduler_active)
                return;
 
+       init_rcu_head_on_stack(&rcu.head);
        init_completion(&rcu.completion);
        /* Will wake me after RCU finished. */
        call_rcu(&rcu.head, wakeme_after_rcu);
        /* Wait for it. */
        wait_for_completion(&rcu.completion);
+       destroy_rcu_head_on_stack(&rcu.head);
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
@@ -754,6 +798,7 @@ void exit_rcu(void)
 static void __init rcu_bootup_announce(void)
 {
        printk(KERN_INFO "Hierarchical RCU implementation.\n");
+       rcu_bootup_announce_oddness();
 }
 
 /*
@@ -1008,6 +1053,8 @@ static DEFINE_PER_CPU(unsigned long, rcu_dyntick_holdoff);
 int rcu_needs_cpu(int cpu)
 {
        int c = 0;
+       int snap;
+       int snap_nmi;
        int thatcpu;
 
        /* Check for being in the holdoff period. */
@@ -1015,12 +1062,18 @@ int rcu_needs_cpu(int cpu)
                return rcu_needs_cpu_quick_check(cpu);
 
        /* Don't bother unless we are the last non-dyntick-idle CPU. */
-       for_each_cpu_not(thatcpu, nohz_cpu_mask)
-               if (thatcpu != cpu) {
+       for_each_online_cpu(thatcpu) {
+               if (thatcpu == cpu)
+                       continue;
+               snap = per_cpu(rcu_dynticks, thatcpu).dynticks;
+               snap_nmi = per_cpu(rcu_dynticks, thatcpu).dynticks_nmi;
+               smp_mb(); /* Order sampling of snap with end of grace period. */
+               if (((snap & 0x1) != 0) || ((snap_nmi & 0x1) != 0)) {
                        per_cpu(rcu_dyntick_drain, cpu) = 0;
                        per_cpu(rcu_dyntick_holdoff, cpu) = jiffies - 1;
                        return rcu_needs_cpu_quick_check(cpu);
                }
+       }
 
        /* Check and update the rcu_dyntick_drain sequencing. */
        if (per_cpu(rcu_dyntick_drain, cpu) <= 0) {
index d45db2e..36c95b4 100644 (file)
@@ -241,11 +241,13 @@ static const struct file_operations rcugp_fops = {
 static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp)
 {
        seq_printf(m, "%3d%cnp=%ld "
-                  "qsp=%ld cbr=%ld cng=%ld gpc=%ld gps=%ld nf=%ld nn=%ld\n",
+                  "qsp=%ld rpq=%ld cbr=%ld cng=%ld "
+                  "gpc=%ld gps=%ld nf=%ld nn=%ld\n",
                   rdp->cpu,
                   cpu_is_offline(rdp->cpu) ? '!' : ' ',
                   rdp->n_rcu_pending,
                   rdp->n_rp_qs_pending,
+                  rdp->n_rp_report_qs,
                   rdp->n_rp_cb_ready,
                   rdp->n_rp_cpu_needs_gp,
                   rdp->n_rp_gp_completed,
index 6af210a..1d93cd0 100644 (file)
@@ -55,9 +55,9 @@
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/percpu.h>
-#include <linux/kthread.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/stop_machine.h>
 #include <linux/sysctl.h>
 #include <linux/syscalls.h>
 #include <linux/times.h>
@@ -323,6 +323,15 @@ static inline struct task_group *task_group(struct task_struct *p)
 /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 {
+       /*
+        * Strictly speaking this rcu_read_lock() is not needed since the
+        * task_group is tied to the cgroup, which in turn can never go away
+        * as long as there are tasks attached to it.
+        *
+        * However since task_group() uses task_subsys_state() which is an
+        * rcu_dereference() user, this quiets CONFIG_PROVE_RCU.
+        */
+       rcu_read_lock();
 #ifdef CONFIG_FAIR_GROUP_SCHED
        p->se.cfs_rq = task_group(p)->cfs_rq[cpu];
        p->se.parent = task_group(p)->se[cpu];
@@ -332,6 +341,7 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
        p->rt.rt_rq  = task_group(p)->rt_rq[cpu];
        p->rt.parent = task_group(p)->rt_se[cpu];
 #endif
+       rcu_read_unlock();
 }
 
 #else
@@ -493,8 +503,11 @@ struct rq {
        #define CPU_LOAD_IDX_MAX 5
        unsigned long cpu_load[CPU_LOAD_IDX_MAX];
 #ifdef CONFIG_NO_HZ
+       u64 nohz_stamp;
        unsigned char in_nohz_recently;
 #endif
+       unsigned int skip_clock_update;
+
        /* capture load from *all* tasks on this cpu: */
        struct load_weight load;
        unsigned long nr_load_updates;
@@ -536,15 +549,13 @@ struct rq {
        int post_schedule;
        int active_balance;
        int push_cpu;
+       struct cpu_stop_work active_balance_work;
        /* cpu of this runqueue: */
        int cpu;
        int online;
 
        unsigned long avg_load_per_task;
 
-       struct task_struct *migration_thread;
-       struct list_head migration_queue;
-
        u64 rt_avg;
        u64 age_stamp;
        u64 idle_stamp;
@@ -592,6 +603,13 @@ static inline
 void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
 {
        rq->curr->sched_class->check_preempt_curr(rq, p, flags);
+
+       /*
+        * A queue event has occurred, and we're going to schedule.  In
+        * this case, we can save a useless back to back clock update.
+        */
+       if (test_tsk_need_resched(p))
+               rq->skip_clock_update = 1;
 }
 
 static inline int cpu_of(struct rq *rq)
@@ -626,7 +644,8 @@ static inline int cpu_of(struct rq *rq)
 
 inline void update_rq_clock(struct rq *rq)
 {
-       rq->clock = sched_clock_cpu(cpu_of(rq));
+       if (!rq->skip_clock_update)
+               rq->clock = sched_clock_cpu(cpu_of(rq));
 }
 
 /*
@@ -904,16 +923,12 @@ static inline void finish_lock_switch(struct rq *rq, struct task_struct *prev)
 #endif /* __ARCH_WANT_UNLOCKED_CTXSW */
 
 /*
- * Check whether the task is waking, we use this to synchronize against
- * ttwu() so that task_cpu() reports a stable number.
- *
- * We need to make an exception for PF_STARTING tasks because the fork
- * path might require task_rq_lock() to work, eg. it can call
- * set_cpus_allowed_ptr() from the cpuset clone_ns code.
+ * Check whether the task is waking, we use this to synchronize ->cpus_allowed
+ * against ttwu().
  */
 static inline int task_is_waking(struct task_struct *p)
 {
-       return unlikely((p->state == TASK_WAKING) && !(p->flags & PF_STARTING));
+       return unlikely(p->state == TASK_WAKING);
 }
 
 /*
@@ -926,11 +941,9 @@ static inline struct rq *__task_rq_lock(struct task_struct *p)
        struct rq *rq;
 
        for (;;) {
-               while (task_is_waking(p))
-                       cpu_relax();
                rq = task_rq(p);
                raw_spin_lock(&rq->lock);
-               if (likely(rq == task_rq(p) && !task_is_waking(p)))
+               if (likely(rq == task_rq(p)))
                        return rq;
                raw_spin_unlock(&rq->lock);
        }
@@ -947,12 +960,10 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags)
        struct rq *rq;
 
        for (;;) {
-               while (task_is_waking(p))
-                       cpu_relax();
                local_irq_save(*flags);
                rq = task_rq(p);
                raw_spin_lock(&rq->lock);
-               if (likely(rq == task_rq(p) && !task_is_waking(p)))
+               if (likely(rq == task_rq(p)))
                        return rq;
                raw_spin_unlock_irqrestore(&rq->lock, *flags);
        }
@@ -1229,6 +1240,17 @@ void wake_up_idle_cpu(int cpu)
        if (!tsk_is_polling(rq->idle))
                smp_send_reschedule(cpu);
 }
+
+int nohz_ratelimit(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+       u64 diff = rq->clock - rq->nohz_stamp;
+
+       rq->nohz_stamp = rq->clock;
+
+       return diff < (NSEC_PER_SEC / HZ) >> 1;
+}
+
 #endif /* CONFIG_NO_HZ */
 
 static u64 sched_avg_period(void)
@@ -1771,8 +1793,6 @@ static void double_rq_lock(struct rq *rq1, struct rq *rq2)
                        raw_spin_lock_nested(&rq1->lock, SINGLE_DEPTH_NESTING);
                }
        }
-       update_rq_clock(rq1);
-       update_rq_clock(rq2);
 }
 
 /*
@@ -1803,7 +1823,7 @@ static void cfs_rq_set_shares(struct cfs_rq *cfs_rq, unsigned long shares)
 }
 #endif
 
-static void calc_load_account_active(struct rq *this_rq);
+static void calc_load_account_idle(struct rq *this_rq);
 static void update_sysctl(void);
 static int get_update_sysctl_factor(void);
 
@@ -1860,62 +1880,43 @@ static void set_load_weight(struct task_struct *p)
        p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
 }
 
-static void update_avg(u64 *avg, u64 sample)
-{
-       s64 diff = sample - *avg;
-       *avg += diff >> 3;
-}
-
-static void
-enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, bool head)
+static void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
 {
-       if (wakeup)
-               p->se.start_runtime = p->se.sum_exec_runtime;
-
+       update_rq_clock(rq);
        sched_info_queued(p);
-       p->sched_class->enqueue_task(rq, p, wakeup, head);
+       p->sched_class->enqueue_task(rq, p, flags);
        p->se.on_rq = 1;
 }
 
-static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
 {
-       if (sleep) {
-               if (p->se.last_wakeup) {
-                       update_avg(&p->se.avg_overlap,
-                               p->se.sum_exec_runtime - p->se.last_wakeup);
-                       p->se.last_wakeup = 0;
-               } else {
-                       update_avg(&p->se.avg_wakeup,
-                               sysctl_sched_wakeup_granularity);
-               }
-       }
-
+       update_rq_clock(rq);
        sched_info_dequeued(p);
-       p->sched_class->dequeue_task(rq, p, sleep);
+       p->sched_class->dequeue_task(rq, p, flags);
        p->se.on_rq = 0;
 }
 
 /*
  * activate_task - move a task to the runqueue.
  */
-static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
+static void activate_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (task_contributes_to_load(p))
                rq->nr_uninterruptible--;
 
-       enqueue_task(rq, p, wakeup, false);
+       enqueue_task(rq, p, flags);
        inc_nr_running(rq);
 }
 
 /*
  * deactivate_task - remove a task from the runqueue.
  */
-static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
+static void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
 {
        if (task_contributes_to_load(p))
                rq->nr_uninterruptible++;
 
-       dequeue_task(rq, p, sleep);
+       dequeue_task(rq, p, flags);
        dec_nr_running(rq);
 }
 
@@ -2044,21 +2045,18 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
        __set_task_cpu(p, new_cpu);
 }
 
-struct migration_req {
-       struct list_head list;
-
+struct migration_arg {
        struct task_struct *task;
        int dest_cpu;
-
-       struct completion done;
 };
 
+static int migration_cpu_stop(void *data);
+
 /*
  * The task's runqueue lock must be held.
  * Returns true if you have to wait for migration thread.
  */
-static int
-migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
+static bool migrate_task(struct task_struct *p, int dest_cpu)
 {
        struct rq *rq = task_rq(p);
 
@@ -2066,58 +2064,7 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
         * If the task is not on a runqueue (and not running), then
         * the next wake-up will properly place the task.
         */
-       if (!p->se.on_rq && !task_running(rq, p))
-               return 0;
-
-       init_completion(&req->done);
-       req->task = p;
-       req->dest_cpu = dest_cpu;
-       list_add(&req->list, &rq->migration_queue);
-
-       return 1;
-}
-
-/*
- * wait_task_context_switch -  wait for a thread to complete at least one
- *                             context switch.
- *
- * @p must not be current.
- */
-void wait_task_context_switch(struct task_struct *p)
-{
-       unsigned long nvcsw, nivcsw, flags;
-       int running;
-       struct rq *rq;
-
-       nvcsw   = p->nvcsw;
-       nivcsw  = p->nivcsw;
-       for (;;) {
-               /*
-                * The runqueue is assigned before the actual context
-                * switch. We need to take the runqueue lock.
-                *
-                * We could check initially without the lock but it is
-                * very likely that we need to take the lock in every
-                * iteration.
-                */
-               rq = task_rq_lock(p, &flags);
-               running = task_running(rq, p);
-               task_rq_unlock(rq, &flags);
-
-               if (likely(!running))
-                       break;
-               /*
-                * The switch count is incremented before the actual
-                * context switch. We thus wait for two switches to be
-                * sure at least one completed.
-                */
-               if ((p->nvcsw - nvcsw) > 1)
-                       break;
-               if ((p->nivcsw - nivcsw) > 1)
-                       break;
-
-               cpu_relax();
-       }
+       return p->se.on_rq || task_running(rq, p);
 }
 
 /*
@@ -2175,7 +2122,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state)
                 * just go back and repeat.
                 */
                rq = task_rq_lock(p, &flags);
-               trace_sched_wait_task(rq, p);
+               trace_sched_wait_task(p);
                running = task_running(rq, p);
                on_rq = p->se.on_rq;
                ncsw = 0;
@@ -2273,6 +2220,9 @@ void task_oncpu_function_call(struct task_struct *p,
 }
 
 #ifdef CONFIG_SMP
+/*
+ * ->cpus_allowed is protected by either TASK_WAKING or rq->lock held.
+ */
 static int select_fallback_rq(int cpu, struct task_struct *p)
 {
        int dest_cpu;
@@ -2289,12 +2239,8 @@ static int select_fallback_rq(int cpu, struct task_struct *p)
                return dest_cpu;
 
        /* No more Mr. Nice Guy. */
-       if (dest_cpu >= nr_cpu_ids) {
-               rcu_read_lock();
-               cpuset_cpus_allowed_locked(p, &p->cpus_allowed);
-               rcu_read_unlock();
-               dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed);
-
+       if (unlikely(dest_cpu >= nr_cpu_ids)) {
+               dest_cpu = cpuset_cpus_allowed_fallback(p);
                /*
                 * Don't tell them about moving exiting tasks or
                 * kernel threads (both mm NULL), since they never
@@ -2311,17 +2257,12 @@ static int select_fallback_rq(int cpu, struct task_struct *p)
 }
 
 /*
- * Gets called from 3 sites (exec, fork, wakeup), since it is called without
- * holding rq->lock we need to ensure ->cpus_allowed is stable, this is done
- * by:
- *
- *  exec:           is unstable, retry loop
- *  fork & wake-up: serialize ->cpus_allowed against TASK_WAKING
+ * The caller (fork, wakeup) owns TASK_WAKING, ->cpus_allowed is stable.
  */
 static inline
-int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags)
+int select_task_rq(struct rq *rq, struct task_struct *p, int sd_flags, int wake_flags)
 {
-       int cpu = p->sched_class->select_task_rq(p, sd_flags, wake_flags);
+       int cpu = p->sched_class->select_task_rq(rq, p, sd_flags, wake_flags);
 
        /*
         * In order not to call set_task_cpu() on a blocking task we need
@@ -2339,6 +2280,12 @@ int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags)
 
        return cpu;
 }
+
+static void update_avg(u64 *avg, u64 sample)
+{
+       s64 diff = sample - *avg;
+       *avg += diff >> 3;
+}
 #endif
 
 /***
@@ -2360,16 +2307,13 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
 {
        int cpu, orig_cpu, this_cpu, success = 0;
        unsigned long flags;
+       unsigned long en_flags = ENQUEUE_WAKEUP;
        struct rq *rq;
 
-       if (!sched_feat(SYNC_WAKEUPS))
-               wake_flags &= ~WF_SYNC;
-
        this_cpu = get_cpu();
 
        smp_wmb();
        rq = task_rq_lock(p, &flags);
-       update_rq_clock(rq);
        if (!(p->state & state))
                goto out;
 
@@ -2389,28 +2333,26 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
         *
         * First fix up the nr_uninterruptible count:
         */
-       if (task_contributes_to_load(p))
-               rq->nr_uninterruptible--;
+       if (task_contributes_to_load(p)) {
+               if (likely(cpu_online(orig_cpu)))
+                       rq->nr_uninterruptible--;
+               else
+                       this_rq()->nr_uninterruptible--;
+       }
        p->state = TASK_WAKING;
 
-       if (p->sched_class->task_waking)
+       if (p->sched_class->task_waking) {
                p->sched_class->task_waking(rq, p);
+               en_flags |= ENQUEUE_WAKING;
+       }
 
-       __task_rq_unlock(rq);
-
-       cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
-       if (cpu != orig_cpu) {
-               /*
-                * Since we migrate the task without holding any rq->lock,
-                * we need to be careful with task_rq_lock(), since that
-                * might end up locking an invalid rq.
-                */
+       cpu = select_task_rq(rq, p, SD_BALANCE_WAKE, wake_flags);
+       if (cpu != orig_cpu)
                set_task_cpu(p, cpu);
-       }
+       __task_rq_unlock(rq);
 
        rq = cpu_rq(cpu);
        raw_spin_lock(&rq->lock);
-       update_rq_clock(rq);
 
        /*
         * We migrated the task without holding either rq->lock, however
@@ -2438,36 +2380,20 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
 
 out_activate:
 #endif /* CONFIG_SMP */
-       schedstat_inc(p, se.nr_wakeups);
+       schedstat_inc(p, se.statistics.nr_wakeups);
        if (wake_flags & WF_SYNC)
-               schedstat_inc(p, se.nr_wakeups_sync);
+               schedstat_inc(p, se.statistics.nr_wakeups_sync);
        if (orig_cpu != cpu)
-               schedstat_inc(p, se.nr_wakeups_migrate);
+               schedstat_inc(p, se.statistics.nr_wakeups_migrate);
        if (cpu == this_cpu)
-               schedstat_inc(p, se.nr_wakeups_local);
+               schedstat_inc(p, se.statistics.nr_wakeups_local);
        else
-               schedstat_inc(p, se.nr_wakeups_remote);
-       activate_task(rq, p, 1);
+               schedstat_inc(p, se.statistics.nr_wakeups_remote);
+       activate_task(rq, p, en_flags);
        success = 1;
 
-       /*
-        * Only attribute actual wakeups done by this task.
-        */
-       if (!in_interrupt()) {
-               struct sched_entity *se = &current->se;
-               u64 sample = se->sum_exec_runtime;
-
-               if (se->last_wakeup)
-                       sample -= se->last_wakeup;
-               else
-                       sample -= se->start_runtime;
-               update_avg(&se->avg_wakeup, sample);
-
-               se->last_wakeup = se->sum_exec_runtime;
-       }
-
 out_running:
-       trace_sched_wakeup(rq, p, success);
+       trace_sched_wakeup(p, success);
        check_preempt_curr(rq, p, wake_flags);
 
        p->state = TASK_RUNNING;
@@ -2527,42 +2453,9 @@ static void __sched_fork(struct task_struct *p)
        p->se.sum_exec_runtime          = 0;
        p->se.prev_sum_exec_runtime     = 0;
        p->se.nr_migrations             = 0;
-       p->se.last_wakeup               = 0;
-       p->se.avg_overlap               = 0;
-       p->se.start_runtime             = 0;
-       p->se.avg_wakeup                = sysctl_sched_wakeup_granularity;
 
 #ifdef CONFIG_SCHEDSTATS
-       p->se.wait_start                        = 0;
-       p->se.wait_max                          = 0;
-       p->se.wait_count                        = 0;
-       p->se.wait_sum                          = 0;
-
-       p->se.sleep_start                       = 0;
-       p->se.sleep_max                         = 0;
-       p->se.sum_sleep_runtime                 = 0;
-
-       p->se.block_start                       = 0;
-       p->se.block_max                         = 0;
-       p->se.exec_max                          = 0;
-       p->se.slice_max                         = 0;
-
-       p->se.nr_migrations_cold                = 0;
-       p->se.nr_failed_migrations_affine       = 0;
-       p->se.nr_failed_migrations_running      = 0;
-       p->se.nr_failed_migrations_hot          = 0;
-       p->se.nr_forced_migrations              = 0;
-
-       p->se.nr_wakeups                        = 0;
-       p->se.nr_wakeups_sync                   = 0;
-       p->se.nr_wakeups_migrate                = 0;
-       p->se.nr_wakeups_local                  = 0;
-       p->se.nr_wakeups_remote                 = 0;
-       p->se.nr_wakeups_affine                 = 0;
-       p->se.nr_wakeups_affine_attempts        = 0;
-       p->se.nr_wakeups_passive                = 0;
-       p->se.nr_wakeups_idle                   = 0;
-
+       memset(&p->se.statistics, 0, sizeof(p->se.statistics));
 #endif
 
        INIT_LIST_HEAD(&p->rt.run_list);
@@ -2583,11 +2476,11 @@ void sched_fork(struct task_struct *p, int clone_flags)
 
        __sched_fork(p);
        /*
-        * We mark the process as waking here. This guarantees that
+        * We mark the process as running here. This guarantees that
         * nobody will actually run it, and a signal or other external
         * event cannot wake it up and insert it on the runqueue either.
         */
-       p->state = TASK_WAKING;
+       p->state = TASK_RUNNING;
 
        /*
         * Revert to default priority/policy on fork if requested.
@@ -2654,31 +2547,27 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
        int cpu __maybe_unused = get_cpu();
 
 #ifdef CONFIG_SMP
+       rq = task_rq_lock(p, &flags);
+       p->state = TASK_WAKING;
+
        /*
         * Fork balancing, do it here and not earlier because:
         *  - cpus_allowed can change in the fork path
         *  - any previously selected cpu might disappear through hotplug
         *
-        * We still have TASK_WAKING but PF_STARTING is gone now, meaning
-        * ->cpus_allowed is stable, we have preemption disabled, meaning
-        * cpu_online_mask is stable.
+        * We set TASK_WAKING so that select_task_rq() can drop rq->lock
+        * without people poking at ->cpus_allowed.
         */
-       cpu = select_task_rq(p, SD_BALANCE_FORK, 0);
+       cpu = select_task_rq(rq, p, SD_BALANCE_FORK, 0);
        set_task_cpu(p, cpu);
-#endif
 
-       /*
-        * Since the task is not on the rq and we still have TASK_WAKING set
-        * nobody else will migrate this task.
-        */
-       rq = cpu_rq(cpu);
-       raw_spin_lock_irqsave(&rq->lock, flags);
-
-       BUG_ON(p->state != TASK_WAKING);
        p->state = TASK_RUNNING;
-       update_rq_clock(rq);
+       task_rq_unlock(rq, &flags);
+#endif
+
+       rq = task_rq_lock(p, &flags);
        activate_task(rq, p, 0);
-       trace_sched_wakeup_new(rq, p, 1);
+       trace_sched_wakeup_new(p, 1);
        check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
        if (p->sched_class->task_woken)
@@ -2898,7 +2787,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
        struct mm_struct *mm, *oldmm;
 
        prepare_task_switch(rq, prev, next);
-       trace_sched_switch(rq, prev, next);
+       trace_sched_switch(prev, next);
        mm = next->mm;
        oldmm = prev->active_mm;
        /*
@@ -3015,6 +2904,61 @@ static unsigned long calc_load_update;
 unsigned long avenrun[3];
 EXPORT_SYMBOL(avenrun);
 
+static long calc_load_fold_active(struct rq *this_rq)
+{
+       long nr_active, delta = 0;
+
+       nr_active = this_rq->nr_running;
+       nr_active += (long) this_rq->nr_uninterruptible;
+
+       if (nr_active != this_rq->calc_load_active) {
+               delta = nr_active - this_rq->calc_load_active;
+               this_rq->calc_load_active = nr_active;
+       }
+
+       return delta;
+}
+
+#ifdef CONFIG_NO_HZ
+/*
+ * For NO_HZ we delay the active fold to the next LOAD_FREQ update.
+ *
+ * When making the ILB scale, we should try to pull this in as well.
+ */
+static atomic_long_t calc_load_tasks_idle;
+
+static void calc_load_account_idle(struct rq *this_rq)
+{
+       long delta;
+
+       delta = calc_load_fold_active(this_rq);
+       if (delta)
+               atomic_long_add(delta, &calc_load_tasks_idle);
+}
+
+static long calc_load_fold_idle(void)
+{
+       long delta = 0;
+
+       /*
+        * Its got a race, we don't care...
+        */
+       if (atomic_long_read(&calc_load_tasks_idle))
+               delta = atomic_long_xchg(&calc_load_tasks_idle, 0);
+
+       return delta;
+}
+#else
+static void calc_load_account_idle(struct rq *this_rq)
+{
+}
+
+static inline long calc_load_fold_idle(void)
+{
+       return 0;
+}
+#endif
+
 /**
  * get_avenrun - get the load average array
  * @loads:     pointer to dest load array
@@ -3061,20 +3005,22 @@ void calc_global_load(void)
 }
 
 /*
- * Either called from update_cpu_load() or from a cpu going idle
+ * Called from update_cpu_load() to periodically update this CPU's
+ * active count.
  */
 static void calc_load_account_active(struct rq *this_rq)
 {
-       long nr_active, delta;
+       long delta;
 
-       nr_active = this_rq->nr_running;
-       nr_active += (long) this_rq->nr_uninterruptible;
+       if (time_before(jiffies, this_rq->calc_load_update))
+               return;
 
-       if (nr_active != this_rq->calc_load_active) {
-               delta = nr_active - this_rq->calc_load_active;
-               this_rq->calc_load_active = nr_active;
+       delta  = calc_load_fold_active(this_rq);
+       delta += calc_load_fold_idle();
+       if (delta)
                atomic_long_add(delta, &calc_load_tasks);
-       }
+
+       this_rq->calc_load_update += LOAD_FREQ;
 }
 
 /*
@@ -3106,10 +3052,7 @@ static void update_cpu_load(struct rq *this_rq)
                this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
        }
 
-       if (time_after_eq(jiffies, this_rq->calc_load_update)) {
-               this_rq->calc_load_update += LOAD_FREQ;
-               calc_load_account_active(this_rq);
-       }
+       calc_load_account_active(this_rq);
 }
 
 #ifdef CONFIG_SMP
@@ -3121,44 +3064,27 @@ static void update_cpu_load(struct rq *this_rq)
 void sched_exec(void)
 {
        struct task_struct *p = current;
-       struct migration_req req;
-       int dest_cpu, this_cpu;
        unsigned long flags;
        struct rq *rq;
-
-again:
-       this_cpu = get_cpu();
-       dest_cpu = select_task_rq(p, SD_BALANCE_EXEC, 0);
-       if (dest_cpu == this_cpu) {
-               put_cpu();
-               return;
-       }
+       int dest_cpu;
 
        rq = task_rq_lock(p, &flags);
-       put_cpu();
+       dest_cpu = p->sched_class->select_task_rq(rq, p, SD_BALANCE_EXEC, 0);
+       if (dest_cpu == smp_processor_id())
+               goto unlock;
 
        /*
         * select_task_rq() can race against ->cpus_allowed
         */
-       if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed)
-           || unlikely(!cpu_active(dest_cpu))) {
-               task_rq_unlock(rq, &flags);
-               goto again;
-       }
-
-       /* force the process onto the specified CPU */
-       if (migrate_task(p, dest_cpu, &req)) {
-               /* Need to wait for migration thread (might exit: take ref). */
-               struct task_struct *mt = rq->migration_thread;
+       if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed) &&
+           likely(cpu_active(dest_cpu)) && migrate_task(p, dest_cpu)) {
+               struct migration_arg arg = { p, dest_cpu };
 
-               get_task_struct(mt);
                task_rq_unlock(rq, &flags);
-               wake_up_process(mt);
-               put_task_struct(mt);
-               wait_for_completion(&req.done);
-
+               stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
                return;
        }
+unlock:
        task_rq_unlock(rq, &flags);
 }
 
@@ -3630,23 +3556,9 @@ static inline void schedule_debug(struct task_struct *prev)
 
 static void put_prev_task(struct rq *rq, struct task_struct *prev)
 {
-       if (prev->state == TASK_RUNNING) {
-               u64 runtime = prev->se.sum_exec_runtime;
-
-               runtime -= prev->se.prev_sum_exec_runtime;
-               runtime = min_t(u64, runtime, 2*sysctl_sched_migration_cost);
-
-               /*
-                * In order to avoid avg_overlap growing stale when we are
-                * indeed overlapping and hence not getting put to sleep, grow
-                * the avg_overlap on preemption.
-                *
-                * We use the average preemption runtime because that
-                * correlates to the amount of cache footprint a task can
-                * build up.
-                */
-               update_avg(&prev->se.avg_overlap, runtime);
-       }
+       if (prev->se.on_rq)
+               update_rq_clock(rq);
+       rq->skip_clock_update = 0;
        prev->sched_class->put_prev_task(rq, prev);
 }
 
@@ -3696,7 +3608,7 @@ need_resched:
        preempt_disable();
        cpu = smp_processor_id();
        rq = cpu_rq(cpu);
-       rcu_sched_qs(cpu);
+       rcu_note_context_switch(cpu);
        prev = rq->curr;
        switch_count = &prev->nivcsw;
 
@@ -3709,14 +3621,13 @@ need_resched_nonpreemptible:
                hrtick_clear(rq);
 
        raw_spin_lock_irq(&rq->lock);
-       update_rq_clock(rq);
        clear_tsk_need_resched(prev);
 
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
                if (unlikely(signal_pending_state(prev->state, prev)))
                        prev->state = TASK_RUNNING;
                else
-                       deactivate_task(rq, prev, 1);
+                       deactivate_task(rq, prev, DEQUEUE_SLEEP);
                switch_count = &prev->nvcsw;
        }
 
@@ -3780,7 +3691,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
         * the mutex owner just released it and exited.
         */
        if (probe_kernel_address(&owner->cpu, cpu))
-               goto out;
+               return 0;
 #else
        cpu = owner->cpu;
 #endif
@@ -3790,14 +3701,14 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
         * the cpu field may no longer be valid.
         */
        if (cpu >= nr_cpumask_bits)
-               goto out;
+               return 0;
 
        /*
         * We need to validate that we can do a
         * get_cpu() and that we have the percpu area.
         */
        if (!cpu_online(cpu))
-               goto out;
+               return 0;
 
        rq = cpu_rq(cpu);
 
@@ -3816,7 +3727,7 @@ int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner)
 
                cpu_relax();
        }
-out:
+
        return 1;
 }
 #endif
@@ -4039,8 +3950,7 @@ do_wait_for_common(struct completion *x, long timeout, int state)
        if (!x->done) {
                DECLARE_WAITQUEUE(wait, current);
 
-               wait.flags |= WQ_FLAG_EXCLUSIVE;
-               __add_wait_queue_tail(&x->wait, &wait);
+               __add_wait_queue_tail_exclusive(&x->wait, &wait);
                do {
                        if (signal_pending_state(state, current)) {
                                timeout = -ERESTARTSYS;
@@ -4266,7 +4176,6 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        BUG_ON(prio < 0 || prio > MAX_PRIO);
 
        rq = task_rq_lock(p, &flags);
-       update_rq_clock(rq);
 
        oldprio = p->prio;
        prev_class = p->sched_class;
@@ -4287,7 +4196,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
        if (running)
                p->sched_class->set_curr_task(rq);
        if (on_rq) {
-               enqueue_task(rq, p, 0, oldprio < prio);
+               enqueue_task(rq, p, oldprio < prio ? ENQUEUE_HEAD : 0);
 
                check_class_changed(rq, p, prev_class, oldprio, running);
        }
@@ -4309,7 +4218,6 @@ void set_user_nice(struct task_struct *p, long nice)
         * the task might be in the middle of scheduling on another CPU.
         */
        rq = task_rq_lock(p, &flags);
-       update_rq_clock(rq);
        /*
         * The RT priorities are set via sched_setscheduler(), but we still
         * allow the 'normal' nice value to be set - but as expected
@@ -4331,7 +4239,7 @@ void set_user_nice(struct task_struct *p, long nice)
        delta = p->prio - old_prio;
 
        if (on_rq) {
-               enqueue_task(rq, p, 0, false);
+               enqueue_task(rq, p, 0);
                /*
                 * If the task increased its priority or is running and
                 * lowered its priority, then reschedule its CPU:
@@ -4592,7 +4500,6 @@ recheck:
                raw_spin_unlock_irqrestore(&p->pi_lock, flags);
                goto recheck;
        }
-       update_rq_clock(rq);
        on_rq = p->se.on_rq;
        running = task_current(rq, p);
        if (on_rq)
@@ -5329,17 +5236,15 @@ static inline void sched_init_granularity(void)
 /*
  * This is how migration works:
  *
- * 1) we queue a struct migration_req structure in the source CPU's
- *    runqueue and wake up that CPU's migration thread.
- * 2) we down() the locked semaphore => thread blocks.
- * 3) migration thread wakes up (implicitly it forces the migrated
- *    thread off the CPU)
- * 4) it gets the migration request and checks whether the migrated
- *    task is still in the wrong runqueue.
- * 5) if it's in the wrong runqueue then the migration thread removes
+ * 1) we invoke migration_cpu_stop() on the target CPU using
+ *    stop_one_cpu().
+ * 2) stopper starts to run (implicitly forcing the migrated thread
+ *    off the CPU)
+ * 3) it checks whether the migrated task is still in the wrong runqueue.
+ * 4) if it's in the wrong runqueue then the migration thread removes
  *    it and puts it into the right queue.
- * 6) migration thread up()s the semaphore.
- * 7) we wake up and the migration is done.
+ * 5) stopper completes and stop_one_cpu() returns and the migration
+ *    is done.
  */
 
 /*
@@ -5353,12 +5258,23 @@ static inline void sched_init_granularity(void)
  */
 int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
 {
-       struct migration_req req;
        unsigned long flags;
        struct rq *rq;
+       unsigned int dest_cpu;
        int ret = 0;
 
+       /*
+        * Serialize against TASK_WAKING so that ttwu() and wunt() can
+        * drop the rq->lock and still rely on ->cpus_allowed.
+        */
+again:
+       while (task_is_waking(p))
+               cpu_relax();
        rq = task_rq_lock(p, &flags);
+       if (task_is_waking(p)) {
+               task_rq_unlock(rq, &flags);
+               goto again;
+       }
 
        if (!cpumask_intersects(new_mask, cpu_active_mask)) {
                ret = -EINVAL;
@@ -5382,15 +5298,12 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
        if (cpumask_test_cpu(task_cpu(p), new_mask))
                goto out;
 
-       if (migrate_task(p, cpumask_any_and(cpu_active_mask, new_mask), &req)) {
+       dest_cpu = cpumask_any_and(cpu_active_mask, new_mask);
+       if (migrate_task(p, dest_cpu)) {
+               struct migration_arg arg = { p, dest_cpu };
                /* Need help from migration thread: drop lock and wait. */
-               struct task_struct *mt = rq->migration_thread;
-
-               get_task_struct(mt);
                task_rq_unlock(rq, &flags);
-               wake_up_process(mt);
-               put_task_struct(mt);
-               wait_for_completion(&req.done);
+               stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
                tlb_migrate_finish(p->mm);
                return 0;
        }
@@ -5448,98 +5361,49 @@ fail:
        return ret;
 }
 
-#define RCU_MIGRATION_IDLE     0
-#define RCU_MIGRATION_NEED_QS  1
-#define RCU_MIGRATION_GOT_QS   2
-#define RCU_MIGRATION_MUST_SYNC        3
-
 /*
- * migration_thread - this is a highprio system thread that performs
- * thread migration by bumping thread off CPU then 'pushing' onto
- * another runqueue.
+ * migration_cpu_stop - this will be executed by a highprio stopper thread
+ * and performs thread migration by bumping thread off CPU then
+ * 'pushing' onto another runqueue.
  */
-static int migration_thread(void *data)
-{
-       int badcpu;
-       int cpu = (long)data;
-       struct rq *rq;
-
-       rq = cpu_rq(cpu);
-       BUG_ON(rq->migration_thread != current);
-
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (!kthread_should_stop()) {
-               struct migration_req *req;
-               struct list_head *head;
-
-               raw_spin_lock_irq(&rq->lock);
-
-               if (cpu_is_offline(cpu)) {
-                       raw_spin_unlock_irq(&rq->lock);
-                       break;
-               }
-
-               if (rq->active_balance) {
-                       active_load_balance(rq, cpu);
-                       rq->active_balance = 0;
-               }
-
-               head = &rq->migration_queue;
-
-               if (list_empty(head)) {
-                       raw_spin_unlock_irq(&rq->lock);
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       continue;
-               }
-               req = list_entry(head->next, struct migration_req, list);
-               list_del_init(head->next);
-
-               if (req->task != NULL) {
-                       raw_spin_unlock(&rq->lock);
-                       __migrate_task(req->task, cpu, req->dest_cpu);
-               } else if (likely(cpu == (badcpu = smp_processor_id()))) {
-                       req->dest_cpu = RCU_MIGRATION_GOT_QS;
-                       raw_spin_unlock(&rq->lock);
-               } else {
-                       req->dest_cpu = RCU_MIGRATION_MUST_SYNC;
-                       raw_spin_unlock(&rq->lock);
-                       WARN_ONCE(1, "migration_thread() on CPU %d, expected %d\n", badcpu, cpu);
-               }
-               local_irq_enable();
-
-               complete(&req->done);
-       }
-       __set_current_state(TASK_RUNNING);
-
-       return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu)
+static int migration_cpu_stop(void *data)
 {
-       int ret;
+       struct migration_arg *arg = data;
 
+       /*
+        * The original target cpu might have gone down and we might
+        * be on another cpu but it doesn't matter.
+        */
        local_irq_disable();
-       ret = __migrate_task(p, src_cpu, dest_cpu);
+       __migrate_task(arg->task, raw_smp_processor_id(), arg->dest_cpu);
        local_irq_enable();
-       return ret;
+       return 0;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Figure out where task on dead CPU should go, use force if necessary.
  */
-static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
+void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
 {
-       int dest_cpu;
+       struct rq *rq = cpu_rq(dead_cpu);
+       int needs_cpu, uninitialized_var(dest_cpu);
+       unsigned long flags;
 
-again:
-       dest_cpu = select_fallback_rq(dead_cpu, p);
+       local_irq_save(flags);
 
-       /* It can have affinity changed while we were choosing. */
-       if (unlikely(!__migrate_task_irq(p, dead_cpu, dest_cpu)))
-               goto again;
+       raw_spin_lock(&rq->lock);
+       needs_cpu = (task_cpu(p) == dead_cpu) && (p->state != TASK_WAKING);
+       if (needs_cpu)
+               dest_cpu = select_fallback_rq(dead_cpu, p);
+       raw_spin_unlock(&rq->lock);
+       /*
+        * It can only fail if we race with set_cpus_allowed(),
+        * in the racer should migrate the task anyway.
+        */
+       if (needs_cpu)
+               __migrate_task(p, dead_cpu, dest_cpu);
+       local_irq_restore(flags);
 }
 
 /*
@@ -5603,7 +5467,6 @@ void sched_idle_next(void)
 
        __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
 
-       update_rq_clock(rq);
        activate_task(rq, p, 0);
 
        raw_spin_unlock_irqrestore(&rq->lock, flags);
@@ -5658,7 +5521,6 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
        for ( ; ; ) {
                if (!rq->nr_running)
                        break;
-               update_rq_clock(rq);
                next = pick_next_task(rq);
                if (!next)
                        break;
@@ -5881,35 +5743,20 @@ static void set_rq_offline(struct rq *rq)
 static int __cpuinit
 migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
-       struct task_struct *p;
        int cpu = (long)hcpu;
        unsigned long flags;
-       struct rq *rq;
+       struct rq *rq = cpu_rq(cpu);
 
        switch (action) {
 
        case CPU_UP_PREPARE:
        case CPU_UP_PREPARE_FROZEN:
-               p = kthread_create(migration_thread, hcpu, "migration/%d", cpu);
-               if (IS_ERR(p))
-                       return NOTIFY_BAD;
-               kthread_bind(p, cpu);
-               /* Must be high prio: stop_machine expects to yield to it. */
-               rq = task_rq_lock(p, &flags);
-               __setscheduler(rq, p, SCHED_FIFO, MAX_RT_PRIO-1);
-               task_rq_unlock(rq, &flags);
-               get_task_struct(p);
-               cpu_rq(cpu)->migration_thread = p;
                rq->calc_load_update = calc_load_update;
                break;
 
        case CPU_ONLINE:
        case CPU_ONLINE_FROZEN:
-               /* Strictly unnecessary, as first user will wake it. */
-               wake_up_process(cpu_rq(cpu)->migration_thread);
-
                /* Update our root-domain */
-               rq = cpu_rq(cpu);
                raw_spin_lock_irqsave(&rq->lock, flags);
                if (rq->rd) {
                        BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span));
@@ -5920,61 +5767,24 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                break;
 
 #ifdef CONFIG_HOTPLUG_CPU
-       case CPU_UP_CANCELED:
-       case CPU_UP_CANCELED_FROZEN:
-               if (!cpu_rq(cpu)->migration_thread)
-                       break;
-               /* Unbind it from offline cpu so it can run. Fall thru. */
-               kthread_bind(cpu_rq(cpu)->migration_thread,
-                            cpumask_any(cpu_online_mask));
-               kthread_stop(cpu_rq(cpu)->migration_thread);
-               put_task_struct(cpu_rq(cpu)->migration_thread);
-               cpu_rq(cpu)->migration_thread = NULL;
-               break;
-
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
-               cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
                migrate_live_tasks(cpu);
-               rq = cpu_rq(cpu);
-               kthread_stop(rq->migration_thread);
-               put_task_struct(rq->migration_thread);
-               rq->migration_thread = NULL;
                /* Idle task back to normal (off runqueue, low prio) */
                raw_spin_lock_irq(&rq->lock);
-               update_rq_clock(rq);
                deactivate_task(rq, rq->idle, 0);
                __setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
                rq->idle->sched_class = &idle_sched_class;
                migrate_dead_tasks(cpu);
                raw_spin_unlock_irq(&rq->lock);
-               cpuset_unlock();
                migrate_nr_uninterruptible(rq);
                BUG_ON(rq->nr_running != 0);
                calc_global_load_remove(rq);
-               /*
-                * No need to migrate the tasks: it was best-effort if
-                * they didn't take sched_hotcpu_mutex. Just wake up
-                * the requestors.
-                */
-               raw_spin_lock_irq(&rq->lock);
-               while (!list_empty(&rq->migration_queue)) {
-                       struct migration_req *req;
-
-                       req = list_entry(rq->migration_queue.next,
-                                        struct migration_req, list);
-                       list_del_init(&req->list);
-                       raw_spin_unlock_irq(&rq->lock);
-                       complete(&req->done);
-                       raw_spin_lock_irq(&rq->lock);
-               }
-               raw_spin_unlock_irq(&rq->lock);
                break;
 
        case CPU_DYING:
        case CPU_DYING_FROZEN:
                /* Update our root-domain */
-               rq = cpu_rq(cpu);
                raw_spin_lock_irqsave(&rq->lock, flags);
                if (rq->rd) {
                        BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span));
@@ -6305,6 +6115,9 @@ cpu_attach_domain(struct sched_domain *sd, struct root_domain *rd, int cpu)
        struct rq *rq = cpu_rq(cpu);
        struct sched_domain *tmp;
 
+       for (tmp = sd; tmp; tmp = tmp->parent)
+               tmp->span_weight = cpumask_weight(sched_domain_span(tmp));
+
        /* Remove the sched domains which do not contribute to scheduling. */
        for (tmp = sd; tmp; ) {
                struct sched_domain *parent = tmp->parent;
@@ -7788,10 +7601,8 @@ void __init sched_init(void)
                rq->push_cpu = 0;
                rq->cpu = i;
                rq->online = 0;
-               rq->migration_thread = NULL;
                rq->idle_stamp = 0;
                rq->avg_idle = 2*sysctl_sched_migration_cost;
-               INIT_LIST_HEAD(&rq->migration_queue);
                rq_attach_root(rq, &def_root_domain);
 #endif
                init_rq_hrtick(rq);
@@ -7892,7 +7703,6 @@ static void normalize_task(struct rq *rq, struct task_struct *p)
 {
        int on_rq;
 
-       update_rq_clock(rq);
        on_rq = p->se.on_rq;
        if (on_rq)
                deactivate_task(rq, p, 0);
@@ -7919,9 +7729,9 @@ void normalize_rt_tasks(void)
 
                p->se.exec_start                = 0;
 #ifdef CONFIG_SCHEDSTATS
-               p->se.wait_start                = 0;
-               p->se.sleep_start               = 0;
-               p->se.block_start               = 0;
+               p->se.statistics.wait_start     = 0;
+               p->se.statistics.sleep_start    = 0;
+               p->se.statistics.block_start    = 0;
 #endif
 
                if (!rt_task(p)) {
@@ -8254,8 +8064,6 @@ void sched_move_task(struct task_struct *tsk)
 
        rq = task_rq_lock(tsk, &flags);
 
-       update_rq_clock(rq);
-
        running = task_current(rq, tsk);
        on_rq = tsk->se.on_rq;
 
@@ -8274,7 +8082,7 @@ void sched_move_task(struct task_struct *tsk)
        if (unlikely(running))
                tsk->sched_class->set_curr_task(rq);
        if (on_rq)
-               enqueue_task(rq, tsk, 0, false);
+               enqueue_task(rq, tsk, 0);
 
        task_rq_unlock(rq, &flags);
 }
@@ -9088,43 +8896,32 @@ struct cgroup_subsys cpuacct_subsys = {
 
 #ifndef CONFIG_SMP
 
-int rcu_expedited_torture_stats(char *page)
-{
-       return 0;
-}
-EXPORT_SYMBOL_GPL(rcu_expedited_torture_stats);
-
 void synchronize_sched_expedited(void)
 {
+       barrier();
 }
 EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
 
 #else /* #ifndef CONFIG_SMP */
 
-static DEFINE_PER_CPU(struct migration_req, rcu_migration_req);
-static DEFINE_MUTEX(rcu_sched_expedited_mutex);
+static atomic_t synchronize_sched_expedited_count = ATOMIC_INIT(0);
 
-#define RCU_EXPEDITED_STATE_POST -2
-#define RCU_EXPEDITED_STATE_IDLE -1
-
-static int rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE;
-
-int rcu_expedited_torture_stats(char *page)
+static int synchronize_sched_expedited_cpu_stop(void *data)
 {
-       int cnt = 0;
-       int cpu;
-
-       cnt += sprintf(&page[cnt], "state: %d /", rcu_expedited_state);
-       for_each_online_cpu(cpu) {
-                cnt += sprintf(&page[cnt], " %d:%d",
-                               cpu, per_cpu(rcu_migration_req, cpu).dest_cpu);
-       }
-       cnt += sprintf(&page[cnt], "\n");
-       return cnt;
+       /*
+        * There must be a full memory barrier on each affected CPU
+        * between the time that try_stop_cpus() is called and the
+        * time that it returns.
+        *
+        * In the current initial implementation of cpu_stop, the
+        * above condition is already met when the control reaches
+        * this point and the following smp_mb() is not strictly
+        * necessary.  Do smp_mb() anyway for documentation and
+        * robustness against future implementation changes.
+        */
+       smp_mb(); /* See above comment block. */
+       return 0;
 }
-EXPORT_SYMBOL_GPL(rcu_expedited_torture_stats);
-
-static long synchronize_sched_expedited_count;
 
 /*
  * Wait for an rcu-sched grace period to elapse, but use "big hammer"
@@ -9138,18 +8935,14 @@ static long synchronize_sched_expedited_count;
  */
 void synchronize_sched_expedited(void)
 {
-       int cpu;
-       unsigned long flags;
-       bool need_full_sync = 0;
-       struct rq *rq;
-       struct migration_req *req;
-       long snap;
-       int trycount = 0;
+       int snap, trycount = 0;
 
        smp_mb();  /* ensure prior mod happens before capturing snap. */
-       snap = ACCESS_ONCE(synchronize_sched_expedited_count) + 1;
+       snap = atomic_read(&synchronize_sched_expedited_count) + 1;
        get_online_cpus();
-       while (!mutex_trylock(&rcu_sched_expedited_mutex)) {
+       while (try_stop_cpus(cpu_online_mask,
+                            synchronize_sched_expedited_cpu_stop,
+                            NULL) == -EAGAIN) {
                put_online_cpus();
                if (trycount++ < 10)
                        udelay(trycount * num_online_cpus());
@@ -9157,41 +8950,15 @@ void synchronize_sched_expedited(void)
                        synchronize_sched();
                        return;
                }
-               if (ACCESS_ONCE(synchronize_sched_expedited_count) - snap > 0) {
+               if (atomic_read(&synchronize_sched_expedited_count) - snap > 0) {
                        smp_mb(); /* ensure test happens before caller kfree */
                        return;
                }
                get_online_cpus();
        }
-       rcu_expedited_state = RCU_EXPEDITED_STATE_POST;
-       for_each_online_cpu(cpu) {
-               rq = cpu_rq(cpu);
-               req = &per_cpu(rcu_migration_req, cpu);
-               init_completion(&req->done);
-               req->task = NULL;
-               req->dest_cpu = RCU_MIGRATION_NEED_QS;
-               raw_spin_lock_irqsave(&rq->lock, flags);
-               list_add(&req->list, &rq->migration_queue);
-               raw_spin_unlock_irqrestore(&rq->lock, flags);
-               wake_up_process(rq->migration_thread);
-       }
-       for_each_online_cpu(cpu) {
-               rcu_expedited_state = cpu;
-               req = &per_cpu(rcu_migration_req, cpu);
-               rq = cpu_rq(cpu);
-               wait_for_completion(&req->done);
-               raw_spin_lock_irqsave(&rq->lock, flags);
-               if (unlikely(req->dest_cpu == RCU_MIGRATION_MUST_SYNC))
-                       need_full_sync = 1;
-               req->dest_cpu = RCU_MIGRATION_IDLE;
-               raw_spin_unlock_irqrestore(&rq->lock, flags);
-       }
-       rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE;
-       synchronize_sched_expedited_count++;
-       mutex_unlock(&rcu_sched_expedited_mutex);
+       atomic_inc(&synchronize_sched_expedited_count);
+       smp_mb__after_atomic_inc(); /* ensure post-GP actions seen after GP. */
        put_online_cpus();
-       if (need_full_sync)
-               synchronize_sched();
 }
 EXPORT_SYMBOL_GPL(synchronize_sched_expedited);
 
index 9b49db1..87a330a 100644 (file)
@@ -70,16 +70,16 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu,
        PN(se->vruntime);
        PN(se->sum_exec_runtime);
 #ifdef CONFIG_SCHEDSTATS
-       PN(se->wait_start);
-       PN(se->sleep_start);
-       PN(se->block_start);
-       PN(se->sleep_max);
-       PN(se->block_max);
-       PN(se->exec_max);
-       PN(se->slice_max);
-       PN(se->wait_max);
-       PN(se->wait_sum);
-       P(se->wait_count);
+       PN(se->statistics.wait_start);
+       PN(se->statistics.sleep_start);
+       PN(se->statistics.block_start);
+       PN(se->statistics.sleep_max);
+       PN(se->statistics.block_max);
+       PN(se->statistics.exec_max);
+       PN(se->statistics.slice_max);
+       PN(se->statistics.wait_max);
+       PN(se->statistics.wait_sum);
+       P(se->statistics.wait_count);
 #endif
        P(se->load.weight);
 #undef PN
@@ -104,7 +104,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
        SEQ_printf(m, "%9Ld.%06ld %9Ld.%06ld %9Ld.%06ld",
                SPLIT_NS(p->se.vruntime),
                SPLIT_NS(p->se.sum_exec_runtime),
-               SPLIT_NS(p->se.sum_sleep_runtime));
+               SPLIT_NS(p->se.statistics.sum_sleep_runtime));
 #else
        SEQ_printf(m, "%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld",
                0LL, 0LL, 0LL, 0L, 0LL, 0L, 0LL, 0L);
@@ -114,7 +114,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
        {
                char path[64];
 
+               rcu_read_lock();
                cgroup_path(task_group(p)->css.cgroup, path, sizeof(path));
+               rcu_read_unlock();
                SEQ_printf(m, " %s", path);
        }
 #endif
@@ -173,11 +175,6 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
        task_group_path(tg, path, sizeof(path));
 
        SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, path);
-#elif defined(CONFIG_USER_SCHED) && defined(CONFIG_FAIR_GROUP_SCHED)
-       {
-               uid_t uid = cfs_rq->tg->uid;
-               SEQ_printf(m, "\ncfs_rq[%d] for UID: %u\n", cpu, uid);
-       }
 #else
        SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu);
 #endif
@@ -407,40 +404,38 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
        PN(se.exec_start);
        PN(se.vruntime);
        PN(se.sum_exec_runtime);
-       PN(se.avg_overlap);
-       PN(se.avg_wakeup);
 
        nr_switches = p->nvcsw + p->nivcsw;
 
 #ifdef CONFIG_SCHEDSTATS
-       PN(se.wait_start);
-       PN(se.sleep_start);
-       PN(se.block_start);
-       PN(se.sleep_max);
-       PN(se.block_max);
-       PN(se.exec_max);
-       PN(se.slice_max);
-       PN(se.wait_max);
-       PN(se.wait_sum);
-       P(se.wait_count);
-       PN(se.iowait_sum);
-       P(se.iowait_count);
+       PN(se.statistics.wait_start);
+       PN(se.statistics.sleep_start);
+       PN(se.statistics.block_start);
+       PN(se.statistics.sleep_max);
+       PN(se.statistics.block_max);
+       PN(se.statistics.exec_max);
+       PN(se.statistics.slice_max);
+       PN(se.statistics.wait_max);
+       PN(se.statistics.wait_sum);
+       P(se.statistics.wait_count);
+       PN(se.statistics.iowait_sum);
+       P(se.statistics.iowait_count);
        P(sched_info.bkl_count);
        P(se.nr_migrations);
-       P(se.nr_migrations_cold);
-       P(se.nr_failed_migrations_affine);
-       P(se.nr_failed_migrations_running);
-       P(se.nr_failed_migrations_hot);
-       P(se.nr_forced_migrations);
-       P(se.nr_wakeups);
-       P(se.nr_wakeups_sync);
-       P(se.nr_wakeups_migrate);
-       P(se.nr_wakeups_local);
-       P(se.nr_wakeups_remote);
-       P(se.nr_wakeups_affine);
-       P(se.nr_wakeups_affine_attempts);
-       P(se.nr_wakeups_passive);
-       P(se.nr_wakeups_idle);
+       P(se.statistics.nr_migrations_cold);
+       P(se.statistics.nr_failed_migrations_affine);
+       P(se.statistics.nr_failed_migrations_running);
+       P(se.statistics.nr_failed_migrations_hot);
+       P(se.statistics.nr_forced_migrations);
+       P(se.statistics.nr_wakeups);
+       P(se.statistics.nr_wakeups_sync);
+       P(se.statistics.nr_wakeups_migrate);
+       P(se.statistics.nr_wakeups_local);
+       P(se.statistics.nr_wakeups_remote);
+       P(se.statistics.nr_wakeups_affine);
+       P(se.statistics.nr_wakeups_affine_attempts);
+       P(se.statistics.nr_wakeups_passive);
+       P(se.statistics.nr_wakeups_idle);
 
        {
                u64 avg_atom, avg_per_cpu;
@@ -491,31 +486,6 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
 void proc_sched_set_task(struct task_struct *p)
 {
 #ifdef CONFIG_SCHEDSTATS
-       p->se.wait_max                          = 0;
-       p->se.wait_sum                          = 0;
-       p->se.wait_count                        = 0;
-       p->se.iowait_sum                        = 0;
-       p->se.iowait_count                      = 0;
-       p->se.sleep_max                         = 0;
-       p->se.sum_sleep_runtime                 = 0;
-       p->se.block_max                         = 0;
-       p->se.exec_max                          = 0;
-       p->se.slice_max                         = 0;
-       p->se.nr_migrations                     = 0;
-       p->se.nr_migrations_cold                = 0;
-       p->se.nr_failed_migrations_affine       = 0;
-       p->se.nr_failed_migrations_running      = 0;
-       p->se.nr_failed_migrations_hot          = 0;
-       p->se.nr_forced_migrations              = 0;
-       p->se.nr_wakeups                        = 0;
-       p->se.nr_wakeups_sync                   = 0;
-       p->se.nr_wakeups_migrate                = 0;
-       p->se.nr_wakeups_local                  = 0;
-       p->se.nr_wakeups_remote                 = 0;
-       p->se.nr_wakeups_affine                 = 0;
-       p->se.nr_wakeups_affine_attempts        = 0;
-       p->se.nr_wakeups_passive                = 0;
-       p->se.nr_wakeups_idle                   = 0;
-       p->sched_info.bkl_count                 = 0;
+       memset(&p->se.statistics, 0, sizeof(p->se.statistics));
 #endif
 }
index 5a5ea2c..217e4a9 100644 (file)
@@ -35,8 +35,8 @@
  * (to see the precise effective timeslice length of your workload,
  *  run vmstat and monitor the context-switches (cs) field)
  */
-unsigned int sysctl_sched_latency = 5000000ULL;
-unsigned int normalized_sysctl_sched_latency = 5000000ULL;
+unsigned int sysctl_sched_latency = 6000000ULL;
+unsigned int normalized_sysctl_sched_latency = 6000000ULL;
 
 /*
  * The initial- and re-scaling of tunables is configurable
@@ -52,15 +52,15 @@ enum sched_tunable_scaling sysctl_sched_tunable_scaling
 
 /*
  * Minimal preemption granularity for CPU-bound tasks:
- * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds)
+ * (default: 2 msec * (1 + ilog(ncpus)), units: nanoseconds)
  */
-unsigned int sysctl_sched_min_granularity = 1000000ULL;
-unsigned int normalized_sysctl_sched_min_granularity = 1000000ULL;
+unsigned int sysctl_sched_min_granularity = 2000000ULL;
+unsigned int normalized_sysctl_sched_min_granularity = 2000000ULL;
 
 /*
  * is kept at sysctl_sched_latency / sysctl_sched_min_granularity
  */
-static unsigned int sched_nr_latency = 5;
+static unsigned int sched_nr_latency = 3;
 
 /*
  * After fork, child runs first. If set to 0 (default) then
@@ -505,7 +505,8 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
 {
        unsigned long delta_exec_weighted;
 
-       schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
+       schedstat_set(curr->statistics.exec_max,
+                     max((u64)delta_exec, curr->statistics.exec_max));
 
        curr->sum_exec_runtime += delta_exec;
        schedstat_add(cfs_rq, exec_clock, delta_exec);
@@ -548,7 +549,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
 static inline void
 update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       schedstat_set(se->wait_start, rq_of(cfs_rq)->clock);
+       schedstat_set(se->statistics.wait_start, rq_of(cfs_rq)->clock);
 }
 
 /*
@@ -567,18 +568,18 @@ static void update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se)
 static void
 update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-       schedstat_set(se->wait_max, max(se->wait_max,
-                       rq_of(cfs_rq)->clock - se->wait_start));
-       schedstat_set(se->wait_count, se->wait_count + 1);
-       schedstat_set(se->wait_sum, se->wait_sum +
-                       rq_of(cfs_rq)->clock - se->wait_start);
+       schedstat_set(se->statistics.wait_max, max(se->statistics.wait_max,
+                       rq_of(cfs_rq)->clock - se->statistics.wait_start));
+       schedstat_set(se->statistics.wait_count, se->statistics.wait_count + 1);
+       schedstat_set(se->statistics.wait_sum, se->statistics.wait_sum +
+                       rq_of(cfs_rq)->clock - se->statistics.wait_start);
 #ifdef CONFIG_SCHEDSTATS
        if (entity_is_task(se)) {
                trace_sched_stat_wait(task_of(se),
-                       rq_of(cfs_rq)->clock - se->wait_start);
+                       rq_of(cfs_rq)->clock - se->statistics.wait_start);
        }
 #endif
-       schedstat_set(se->wait_start, 0);
+       schedstat_set(se->statistics.wait_start, 0);
 }
 
 static inline void
@@ -657,39 +658,39 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
        if (entity_is_task(se))
                tsk = task_of(se);
 
-       if (se->sleep_start) {
-               u64 delta = rq_of(cfs_rq)->clock - se->sleep_start;
+       if (se->statistics.sleep_start) {
+               u64 delta = rq_of(cfs_rq)->clock - se->statistics.sleep_start;
 
                if ((s64)delta < 0)
                        delta = 0;
 
-               if (unlikely(delta > se->sleep_max))
-                       se->sleep_max = delta;
+               if (unlikely(delta > se->statistics.sleep_max))
+                       se->statistics.sleep_max = delta;
 
-               se->sleep_start = 0;
-               se->sum_sleep_runtime += delta;
+               se->statistics.sleep_start = 0;
+               se->statistics.sum_sleep_runtime += delta;
 
                if (tsk) {
                        account_scheduler_latency(tsk, delta >> 10, 1);
                        trace_sched_stat_sleep(tsk, delta);
                }
        }
-       if (se->block_start) {
-               u64 delta = rq_of(cfs_rq)->clock - se->block_start;
+       if (se->statistics.block_start) {
+               u64 delta = rq_of(cfs_rq)->clock - se->statistics.block_start;
 
                if ((s64)delta < 0)
                        delta = 0;
 
-               if (unlikely(delta > se->block_max))
-                       se->block_max = delta;
+               if (unlikely(delta > se->statistics.block_max))
+                       se->statistics.block_max = delta;
 
-               se->block_start = 0;
-               se->sum_sleep_runtime += delta;
+               se->statistics.block_start = 0;
+               se->statistics.sum_sleep_runtime += delta;
 
                if (tsk) {
                        if (tsk->in_iowait) {
-                               se->iowait_sum += delta;
-                               se->iowait_count++;
+                               se->statistics.iowait_sum += delta;
+                               se->statistics.iowait_count++;
                                trace_sched_stat_iowait(tsk, delta);
                        }
 
@@ -737,19 +738,9 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
                vruntime += sched_vslice(cfs_rq, se);
 
        /* sleeps up to a single latency don't count. */
-       if (!initial && sched_feat(FAIR_SLEEPERS)) {
+       if (!initial) {
                unsigned long thresh = sysctl_sched_latency;
 
-               /*
-                * Convert the sleeper threshold into virtual time.
-                * SCHED_IDLE is a special sub-class.  We care about
-                * fairness only relative to other SCHED_IDLE tasks,
-                * all of which have the same weight.
-                */
-               if (sched_feat(NORMALIZED_SLEEPER) && (!entity_is_task(se) ||
-                                task_of(se)->policy != SCHED_IDLE))
-                       thresh = calc_delta_fair(thresh, se);
-
                /*
                 * Halve their sleep time's effect, to allow
                 * for a gentler effect of sleepers:
@@ -766,9 +757,6 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
        se->vruntime = vruntime;
 }
 
-#define ENQUEUE_WAKEUP 1
-#define ENQUEUE_MIGRATE 2
-
 static void
 enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 {
@@ -776,7 +764,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
         * Update the normalized vruntime before updating min_vruntime
         * through callig update_curr().
         */
-       if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_MIGRATE))
+       if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_WAKING))
                se->vruntime += cfs_rq->min_vruntime;
 
        /*
@@ -812,7 +800,7 @@ static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 }
 
 static void
-dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
+dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 {
        /*
         * Update run-time statistics of the 'current'.
@@ -820,15 +808,15 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
        update_curr(cfs_rq);
 
        update_stats_dequeue(cfs_rq, se);
-       if (sleep) {
+       if (flags & DEQUEUE_SLEEP) {
 #ifdef CONFIG_SCHEDSTATS
                if (entity_is_task(se)) {
                        struct task_struct *tsk = task_of(se);
 
                        if (tsk->state & TASK_INTERRUPTIBLE)
-                               se->sleep_start = rq_of(cfs_rq)->clock;
+                               se->statistics.sleep_start = rq_of(cfs_rq)->clock;
                        if (tsk->state & TASK_UNINTERRUPTIBLE)
-                               se->block_start = rq_of(cfs_rq)->clock;
+                               se->statistics.block_start = rq_of(cfs_rq)->clock;
                }
 #endif
        }
@@ -845,7 +833,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
         * update can refer to the ->curr item and we need to reflect this
         * movement in our normalized position.
         */
-       if (!sleep)
+       if (!(flags & DEQUEUE_SLEEP))
                se->vruntime -= cfs_rq->min_vruntime;
 }
 
@@ -912,7 +900,7 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
         * when there are only lesser-weight tasks around):
         */
        if (rq_of(cfs_rq)->load.weight >= 2*se->load.weight) {
-               se->slice_max = max(se->slice_max,
+               se->statistics.slice_max = max(se->statistics.slice_max,
                        se->sum_exec_runtime - se->prev_sum_exec_runtime);
        }
 #endif
@@ -1054,16 +1042,10 @@ static inline void hrtick_update(struct rq *rq)
  * then put the task into the rbtree:
  */
 static void
-enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, bool head)
+enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
-       int flags = 0;
-
-       if (wakeup)
-               flags |= ENQUEUE_WAKEUP;
-       if (p->state == TASK_WAKING)
-               flags |= ENQUEUE_MIGRATE;
 
        for_each_sched_entity(se) {
                if (se->on_rq)
@@ -1081,18 +1063,18 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, bool head)
  * decreased. We remove the task from the rbtree and
  * update the fair scheduling stats:
  */
-static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
 
        for_each_sched_entity(se) {
                cfs_rq = cfs_rq_of(se);
-               dequeue_entity(cfs_rq, se, sleep);
+               dequeue_entity(cfs_rq, se, flags);
                /* Don't dequeue parent if it has other entities besides us */
                if (cfs_rq->load.weight)
                        break;
-               sleep = 1;
+               flags |= DEQUEUE_SLEEP;
        }
 
        hrtick_update(rq);
@@ -1240,7 +1222,6 @@ static inline unsigned long effective_load(struct task_group *tg, int cpu,
 
 static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 {
-       struct task_struct *curr = current;
        unsigned long this_load, load;
        int idx, this_cpu, prev_cpu;
        unsigned long tl_per_task;
@@ -1255,18 +1236,6 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
        load      = source_load(prev_cpu, idx);
        this_load = target_load(this_cpu, idx);
 
-       if (sync) {
-              if (sched_feat(SYNC_LESS) &&
-                  (curr->se.avg_overlap > sysctl_sched_migration_cost ||
-                   p->se.avg_overlap > sysctl_sched_migration_cost))
-                      sync = 0;
-       } else {
-               if (sched_feat(SYNC_MORE) &&
-                   (curr->se.avg_overlap < sysctl_sched_migration_cost &&
-                    p->se.avg_overlap < sysctl_sched_migration_cost))
-                       sync = 1;
-       }
-
        /*
         * If sync wakeup then subtract the (maximum possible)
         * effect of the currently running task from the load
@@ -1306,7 +1275,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
        if (sync && balanced)
                return 1;
 
-       schedstat_inc(p, se.nr_wakeups_affine_attempts);
+       schedstat_inc(p, se.statistics.nr_wakeups_affine_attempts);
        tl_per_task = cpu_avg_load_per_task(this_cpu);
 
        if (balanced ||
@@ -1318,7 +1287,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
                 * there is no bad imbalance.
                 */
                schedstat_inc(sd, ttwu_move_affine);
-               schedstat_inc(p, se.nr_wakeups_affine);
+               schedstat_inc(p, se.statistics.nr_wakeups_affine);
 
                return 1;
        }
@@ -1406,29 +1375,48 @@ find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
 /*
  * Try and locate an idle CPU in the sched_domain.
  */
-static int
-select_idle_sibling(struct task_struct *p, struct sched_domain *sd, int target)
+static int select_idle_sibling(struct task_struct *p, int target)
 {
        int cpu = smp_processor_id();
        int prev_cpu = task_cpu(p);
+       struct sched_domain *sd;
        int i;
 
        /*
-        * If this domain spans both cpu and prev_cpu (see the SD_WAKE_AFFINE
-        * test in select_task_rq_fair) and the prev_cpu is idle then that's
-        * always a better target than the current cpu.
+        * If the task is going to be woken-up on this cpu and if it is
+        * already idle, then it is the right target.
         */
-       if (target == cpu && !cpu_rq(prev_cpu)->cfs.nr_running)
+       if (target == cpu && idle_cpu(cpu))
+               return cpu;
+
+       /*
+        * If the task is going to be woken-up on the cpu where it previously
+        * ran and if it is currently idle, then it the right target.
+        */
+       if (target == prev_cpu && idle_cpu(prev_cpu))
                return prev_cpu;
 
        /*
-        * Otherwise, iterate the domain and find an elegible idle cpu.
+        * Otherwise, iterate the domains and find an elegible idle cpu.
         */
-       for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) {
-               if (!cpu_rq(i)->cfs.nr_running) {
-                       target = i;
+       for_each_domain(target, sd) {
+               if (!(sd->flags & SD_SHARE_PKG_RESOURCES))
                        break;
+
+               for_each_cpu_and(i, sched_domain_span(sd), &p->cpus_allowed) {
+                       if (idle_cpu(i)) {
+                               target = i;
+                               break;
+                       }
                }
+
+               /*
+                * Lets stop looking for an idle sibling when we reached
+                * the domain that spans the current cpu and prev_cpu.
+                */
+               if (cpumask_test_cpu(cpu, sched_domain_span(sd)) &&
+                   cpumask_test_cpu(prev_cpu, sched_domain_span(sd)))
+                       break;
        }
 
        return target;
@@ -1445,7 +1433,8 @@ select_idle_sibling(struct task_struct *p, struct sched_domain *sd, int target)
  *
  * preempt must be disabled.
  */
-static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
+static int
+select_task_rq_fair(struct rq *rq, struct task_struct *p, int sd_flag, int wake_flags)
 {
        struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL;
        int cpu = smp_processor_id();
@@ -1456,8 +1445,7 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
        int sync = wake_flags & WF_SYNC;
 
        if (sd_flag & SD_BALANCE_WAKE) {
-               if (sched_feat(AFFINE_WAKEUPS) &&
-                   cpumask_test_cpu(cpu, &p->cpus_allowed))
+               if (cpumask_test_cpu(cpu, &p->cpus_allowed))
                        want_affine = 1;
                new_cpu = prev_cpu;
        }
@@ -1491,34 +1479,13 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
                }
 
                /*
-                * While iterating the domains looking for a spanning
-                * WAKE_AFFINE domain, adjust the affine target to any idle cpu
-                * in cache sharing domains along the way.
+                * If both cpu and prev_cpu are part of this domain,
+                * cpu is a valid SD_WAKE_AFFINE target.
                 */
-               if (want_affine) {
-                       int target = -1;
-
-                       /*
-                        * If both cpu and prev_cpu are part of this domain,
-                        * cpu is a valid SD_WAKE_AFFINE target.
-                        */
-                       if (cpumask_test_cpu(prev_cpu, sched_domain_span(tmp)))
-                               target = cpu;
-
-                       /*
-                        * If there's an idle sibling in this domain, make that
-                        * the wake_affine target instead of the current cpu.
-                        */
-                       if (tmp->flags & SD_SHARE_PKG_RESOURCES)
-                               target = select_idle_sibling(p, tmp, target);
-
-                       if (target >= 0) {
-                               if (tmp->flags & SD_WAKE_AFFINE) {
-                                       affine_sd = tmp;
-                                       want_affine = 0;
-                               }
-                               cpu = target;
-                       }
+               if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
+                   cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
+                       affine_sd = tmp;
+                       want_affine = 0;
                }
 
                if (!want_sd && !want_affine)
@@ -1531,22 +1498,29 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
                        sd = tmp;
        }
 
+#ifdef CONFIG_FAIR_GROUP_SCHED
        if (sched_feat(LB_SHARES_UPDATE)) {
                /*
                 * Pick the largest domain to update shares over
                 */
                tmp = sd;
-               if (affine_sd && (!tmp ||
-                                 cpumask_weight(sched_domain_span(affine_sd)) >
-                                 cpumask_weight(sched_domain_span(sd))))
+               if (affine_sd && (!tmp || affine_sd->span_weight > sd->span_weight))
                        tmp = affine_sd;
 
-               if (tmp)
+               if (tmp) {
+                       raw_spin_unlock(&rq->lock);
                        update_shares(tmp);
+                       raw_spin_lock(&rq->lock);
+               }
        }
+#endif
 
-       if (affine_sd && wake_affine(affine_sd, p, sync))
-               return cpu;
+       if (affine_sd) {
+               if (cpu == prev_cpu || wake_affine(affine_sd, p, sync))
+                       return select_idle_sibling(p, cpu);
+               else
+                       return select_idle_sibling(p, prev_cpu);
+       }
 
        while (sd) {
                int load_idx = sd->forkexec_idx;
@@ -1576,10 +1550,10 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
 
                /* Now try balancing at a lower domain level of new_cpu */
                cpu = new_cpu;
-               weight = cpumask_weight(sched_domain_span(sd));
+               weight = sd->span_weight;
                sd = NULL;
                for_each_domain(cpu, tmp) {
-                       if (weight <= cpumask_weight(sched_domain_span(tmp)))
+                       if (weight <= tmp->span_weight)
                                break;
                        if (tmp->flags & sd_flag)
                                sd = tmp;
@@ -1591,63 +1565,26 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
 }
 #endif /* CONFIG_SMP */
 
-/*
- * Adaptive granularity
- *
- * se->avg_wakeup gives the average time a task runs until it does a wakeup,
- * with the limit of wakeup_gran -- when it never does a wakeup.
- *
- * So the smaller avg_wakeup is the faster we want this task to preempt,
- * but we don't want to treat the preemptee unfairly and therefore allow it
- * to run for at least the amount of time we'd like to run.
- *
- * NOTE: we use 2*avg_wakeup to increase the probability of actually doing one
- *
- * NOTE: we use *nr_running to scale with load, this nicely matches the
- *       degrading latency on load.
- */
-static unsigned long
-adaptive_gran(struct sched_entity *curr, struct sched_entity *se)
-{
-       u64 this_run = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
-       u64 expected_wakeup = 2*se->avg_wakeup * cfs_rq_of(se)->nr_running;
-       u64 gran = 0;
-
-       if (this_run < expected_wakeup)
-               gran = expected_wakeup - this_run;
-
-       return min_t(s64, gran, sysctl_sched_wakeup_granularity);
-}
-
 static unsigned long
 wakeup_gran(struct sched_entity *curr, struct sched_entity *se)
 {
        unsigned long gran = sysctl_sched_wakeup_granularity;
 
-       if (cfs_rq_of(curr)->curr && sched_feat(ADAPTIVE_GRAN))
-               gran = adaptive_gran(curr, se);
-
        /*
         * Since its curr running now, convert the gran from real-time
         * to virtual-time in his units.
+        *
+        * By using 'se' instead of 'curr' we penalize light tasks, so
+        * they get preempted easier. That is, if 'se' < 'curr' then
+        * the resulting gran will be larger, therefore penalizing the
+        * lighter, if otoh 'se' > 'curr' then the resulting gran will
+        * be smaller, again penalizing the lighter task.
+        *
+        * This is especially important for buddies when the leftmost
+        * task is higher priority than the buddy.
         */
-       if (sched_feat(ASYM_GRAN)) {
-               /*
-                * By using 'se' instead of 'curr' we penalize light tasks, so
-                * they get preempted easier. That is, if 'se' < 'curr' then
-                * the resulting gran will be larger, therefore penalizing the
-                * lighter, if otoh 'se' > 'curr' then the resulting gran will
-                * be smaller, again penalizing the lighter task.
-                *
-                * This is especially important for buddies when the leftmost
-                * task is higher priority than the buddy.
-                */
-               if (unlikely(se->load.weight != NICE_0_LOAD))
-                       gran = calc_delta_fair(gran, se);
-       } else {
-               if (unlikely(curr->load.weight != NICE_0_LOAD))
-                       gran = calc_delta_fair(gran, curr);
-       }
+       if (unlikely(se->load.weight != NICE_0_LOAD))
+               gran = calc_delta_fair(gran, se);
 
        return gran;
 }
@@ -1705,7 +1642,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        struct task_struct *curr = rq->curr;
        struct sched_entity *se = &curr->se, *pse = &p->se;
        struct cfs_rq *cfs_rq = task_cfs_rq(curr);
-       int sync = wake_flags & WF_SYNC;
        int scale = cfs_rq->nr_running >= sched_nr_latency;
 
        if (unlikely(rt_prio(p->prio)))
@@ -1738,14 +1674,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_
        if (unlikely(curr->policy == SCHED_IDLE))
                goto preempt;
 
-       if (sched_feat(WAKEUP_SYNC) && sync)
-               goto preempt;
-
-       if (sched_feat(WAKEUP_OVERLAP) &&
-                       se->avg_overlap < sysctl_sched_migration_cost &&
-                       pse->avg_overlap < sysctl_sched_migration_cost)
-               goto preempt;
-
        if (!sched_feat(WAKEUP_PREEMPT))
                return;
 
@@ -1844,13 +1772,13 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
         * 3) are cache-hot on their current CPU.
         */
        if (!cpumask_test_cpu(this_cpu, &p->cpus_allowed)) {
-               schedstat_inc(p, se.nr_failed_migrations_affine);
+               schedstat_inc(p, se.statistics.nr_failed_migrations_affine);
                return 0;
        }
        *all_pinned = 0;
 
        if (task_running(rq, p)) {
-               schedstat_inc(p, se.nr_failed_migrations_running);
+               schedstat_inc(p, se.statistics.nr_failed_migrations_running);
                return 0;
        }
 
@@ -1866,14 +1794,14 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
 #ifdef CONFIG_SCHEDSTATS
                if (tsk_cache_hot) {
                        schedstat_inc(sd, lb_hot_gained[idle]);
-                       schedstat_inc(p, se.nr_forced_migrations);
+                       schedstat_inc(p, se.statistics.nr_forced_migrations);
                }
 #endif
                return 1;
        }
 
        if (tsk_cache_hot) {
-               schedstat_inc(p, se.nr_failed_migrations_hot);
+               schedstat_inc(p, se.statistics.nr_failed_migrations_hot);
                return 0;
        }
        return 1;
@@ -2311,7 +2239,7 @@ unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu)
 
 unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu)
 {
-       unsigned long weight = cpumask_weight(sched_domain_span(sd));
+       unsigned long weight = sd->span_weight;
        unsigned long smt_gain = sd->smt_gain;
 
        smt_gain /= weight;
@@ -2344,7 +2272,7 @@ unsigned long scale_rt_power(int cpu)
 
 static void update_cpu_power(struct sched_domain *sd, int cpu)
 {
-       unsigned long weight = cpumask_weight(sched_domain_span(sd));
+       unsigned long weight = sd->span_weight;
        unsigned long power = SCHED_LOAD_SCALE;
        struct sched_group *sdg = sd->groups;
 
@@ -2870,6 +2798,8 @@ static int need_active_balance(struct sched_domain *sd, int sd_idle, int idle)
        return unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2);
 }
 
+static int active_load_balance_cpu_stop(void *data);
+
 /*
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
@@ -2959,8 +2889,9 @@ redo:
                if (need_active_balance(sd, sd_idle, idle)) {
                        raw_spin_lock_irqsave(&busiest->lock, flags);
 
-                       /* don't kick the migration_thread, if the curr
-                        * task on busiest cpu can't be moved to this_cpu
+                       /* don't kick the active_load_balance_cpu_stop,
+                        * if the curr task on busiest cpu can't be
+                        * moved to this_cpu
                         */
                        if (!cpumask_test_cpu(this_cpu,
                                              &busiest->curr->cpus_allowed)) {
@@ -2970,14 +2901,22 @@ redo:
                                goto out_one_pinned;
                        }
 
+                       /*
+                        * ->active_balance synchronizes accesses to
+                        * ->active_balance_work.  Once set, it's cleared
+                        * only after active load balance is finished.
+                        */
                        if (!busiest->active_balance) {
                                busiest->active_balance = 1;
                                busiest->push_cpu = this_cpu;
                                active_balance = 1;
                        }
                        raw_spin_unlock_irqrestore(&busiest->lock, flags);
+
                        if (active_balance)
-                               wake_up_process(busiest->migration_thread);
+                               stop_one_cpu_nowait(cpu_of(busiest),
+                                       active_load_balance_cpu_stop, busiest,
+                                       &busiest->active_balance_work);
 
                        /*
                         * We've kicked active balancing, reset the failure
@@ -3084,24 +3023,29 @@ static void idle_balance(int this_cpu, struct rq *this_rq)
 }
 
 /*
- * active_load_balance is run by migration threads. It pushes running tasks
- * off the busiest CPU onto idle CPUs. It requires at least 1 task to be
- * running on each physical CPU where possible, and avoids physical /
- * logical imbalances.
- *
- * Called with busiest_rq locked.
+ * active_load_balance_cpu_stop is run by cpu stopper. It pushes
+ * running tasks off the busiest CPU onto idle CPUs. It requires at
+ * least 1 task to be running on each physical CPU where possible, and
+ * avoids physical / logical imbalances.
  */
-static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
+static int active_load_balance_cpu_stop(void *data)
 {
+       struct rq *busiest_rq = data;
+       int busiest_cpu = cpu_of(busiest_rq);
        int target_cpu = busiest_rq->push_cpu;
+       struct rq *target_rq = cpu_rq(target_cpu);
        struct sched_domain *sd;
-       struct rq *target_rq;
+
+       raw_spin_lock_irq(&busiest_rq->lock);
+
+       /* make sure the requested cpu hasn't gone down in the meantime */
+       if (unlikely(busiest_cpu != smp_processor_id() ||
+                    !busiest_rq->active_balance))
+               goto out_unlock;
 
        /* Is there any task to move? */
        if (busiest_rq->nr_running <= 1)
-               return;
-
-       target_rq = cpu_rq(target_cpu);
+               goto out_unlock;
 
        /*
         * This condition is "impossible", if it occurs
@@ -3112,8 +3056,6 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
 
        /* move a task from busiest_rq to target_rq */
        double_lock_balance(busiest_rq, target_rq);
-       update_rq_clock(busiest_rq);
-       update_rq_clock(target_rq);
 
        /* Search for an sd spanning us and the target CPU. */
        for_each_domain(target_cpu, sd) {
@@ -3132,6 +3074,10 @@ static void active_load_balance(struct rq *busiest_rq, int busiest_cpu)
                        schedstat_inc(sd, alb_failed);
        }
        double_unlock_balance(busiest_rq, target_rq);
+out_unlock:
+       busiest_rq->active_balance = 0;
+       raw_spin_unlock_irq(&busiest_rq->lock);
+       return 0;
 }
 
 #ifdef CONFIG_NO_HZ
index d5059fd..83c66e8 100644 (file)
@@ -1,10 +1,3 @@
-/*
- * Disregards a certain amount of sleep time (sched_latency_ns) and
- * considers the task to be running during that period. This gives it
- * a service deficit on wakeup, allowing it to run sooner.
- */
-SCHED_FEAT(FAIR_SLEEPERS, 1)
-
 /*
  * Only give sleepers 50% of their service deficit. This allows
  * them to run sooner, but does not allow tons of sleepers to
@@ -12,13 +5,6 @@ SCHED_FEAT(FAIR_SLEEPERS, 1)
  */
 SCHED_FEAT(GENTLE_FAIR_SLEEPERS, 1)
 
-/*
- * By not normalizing the sleep time, heavy tasks get an effective
- * longer period, and lighter task an effective shorter period they
- * are considered running.
- */
-SCHED_FEAT(NORMALIZED_SLEEPER, 0)
-
 /*
  * Place new tasks ahead so that they do not starve already running
  * tasks
@@ -30,37 +16,6 @@ SCHED_FEAT(START_DEBIT, 1)
  */
 SCHED_FEAT(WAKEUP_PREEMPT, 1)
 
-/*
- * Compute wakeup_gran based on task behaviour, clipped to
- *  [0, sched_wakeup_gran_ns]
- */
-SCHED_FEAT(ADAPTIVE_GRAN, 1)
-
-/*
- * When converting the wakeup granularity to virtual time, do it such
- * that heavier tasks preempting a lighter task have an edge.
- */
-SCHED_FEAT(ASYM_GRAN, 1)
-
-/*
- * Always wakeup-preempt SYNC wakeups, see SYNC_WAKEUPS.
- */
-SCHED_FEAT(WAKEUP_SYNC, 0)
-
-/*
- * Wakeup preempt based on task behaviour. Tasks that do not overlap
- * don't get preempted.
- */
-SCHED_FEAT(WAKEUP_OVERLAP, 0)
-
-/*
- * Use the SYNC wakeup hint, pipes and the likes use this to indicate
- * the remote end is likely to consume the data we just wrote, and
- * therefore has cache benefit from being placed on the same cpu, see
- * also AFFINE_WAKEUPS.
- */
-SCHED_FEAT(SYNC_WAKEUPS, 1)
-
 /*
  * Based on load and program behaviour, see if it makes sense to place
  * a newly woken task on the same cpu as the task that woke it --
@@ -69,16 +24,6 @@ SCHED_FEAT(SYNC_WAKEUPS, 1)
  */
 SCHED_FEAT(AFFINE_WAKEUPS, 1)
 
-/*
- * Weaken SYNC hint based on overlap
- */
-SCHED_FEAT(SYNC_LESS, 1)
-
-/*
- * Add SYNC hint based on overlap
- */
-SCHED_FEAT(SYNC_MORE, 0)
-
 /*
  * Prefer to schedule the task we woke last (assuming it failed
  * wakeup-preemption), since its likely going to consume data we
index a8a6d8a..9fa0f40 100644 (file)
@@ -6,7 +6,8 @@
  */
 
 #ifdef CONFIG_SMP
-static int select_task_rq_idle(struct task_struct *p, int sd_flag, int flags)
+static int
+select_task_rq_idle(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
 {
        return task_cpu(p); /* IDLE tasks as never migrated */
 }
@@ -22,8 +23,7 @@ static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int fl
 static struct task_struct *pick_next_task_idle(struct rq *rq)
 {
        schedstat_inc(rq, sched_goidle);
-       /* adjust the active tasks as we might go into a long sleep */
-       calc_load_account_active(rq);
+       calc_load_account_idle(rq);
        return rq->idle;
 }
 
@@ -32,7 +32,7 @@ static struct task_struct *pick_next_task_idle(struct rq *rq)
  * message if some code attempts to do it:
  */
 static void
-dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep)
+dequeue_task_idle(struct rq *rq, struct task_struct *p, int flags)
 {
        raw_spin_unlock_irq(&rq->lock);
        printk(KERN_ERR "bad: scheduling from the idle thread!\n");
index b5b920a..8afb953 100644 (file)
@@ -613,7 +613,7 @@ static void update_curr_rt(struct rq *rq)
        if (unlikely((s64)delta_exec < 0))
                delta_exec = 0;
 
-       schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
+       schedstat_set(curr->se.statistics.exec_max, max(curr->se.statistics.exec_max, delta_exec));
 
        curr->se.sum_exec_runtime += delta_exec;
        account_group_exec_runtime(curr, delta_exec);
@@ -888,20 +888,20 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
  * Adding/removing a task to/from a priority array:
  */
 static void
-enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, bool head)
+enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        struct sched_rt_entity *rt_se = &p->rt;
 
-       if (wakeup)
+       if (flags & ENQUEUE_WAKEUP)
                rt_se->timeout = 0;
 
-       enqueue_rt_entity(rt_se, head);
+       enqueue_rt_entity(rt_se, flags & ENQUEUE_HEAD);
 
        if (!task_current(rq, p) && p->rt.nr_cpus_allowed > 1)
                enqueue_pushable_task(rq, p);
 }
 
-static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
+static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags)
 {
        struct sched_rt_entity *rt_se = &p->rt;
 
@@ -948,10 +948,9 @@ static void yield_task_rt(struct rq *rq)
 #ifdef CONFIG_SMP
 static int find_lowest_rq(struct task_struct *task);
 
-static int select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
+static int
+select_task_rq_rt(struct rq *rq, struct task_struct *p, int sd_flag, int flags)
 {
-       struct rq *rq = task_rq(p);
-
        if (sd_flag != SD_BALANCE_WAKE)
                return smp_processor_id();
 
index 7c1a67e..0db913a 100644 (file)
@@ -716,7 +716,7 @@ static int run_ksoftirqd(void * __bind_cpu)
                        preempt_enable_no_resched();
                        cond_resched();
                        preempt_disable();
-                       rcu_sched_qs((long)__bind_cpu);
+                       rcu_note_context_switch((long)__bind_cpu);
                }
                preempt_enable();
                set_current_state(TASK_INTERRUPTIBLE);
index 9bb9fb1..b4e7431 100644 (file)
-/* Copyright 2008, 2005 Rusty Russell rusty@rustcorp.com.au IBM Corporation.
- * GPL v2 and any later version.
+/*
+ * kernel/stop_machine.c
+ *
+ * Copyright (C) 2008, 2005    IBM Corporation.
+ * Copyright (C) 2008, 2005    Rusty Russell rusty@rustcorp.com.au
+ * Copyright (C) 2010          SUSE Linux Products GmbH
+ * Copyright (C) 2010          Tejun Heo <tj@kernel.org>
+ *
+ * This file is released under the GPLv2 and any later version.
  */
+#include <linux/completion.h>
 #include <linux/cpu.h>
-#include <linux/err.h>
+#include <linux/init.h>
 #include <linux/kthread.h>
 #include <linux/module.h>
+#include <linux/percpu.h>
 #include <linux/sched.h>
 #include <linux/stop_machine.h>
-#include <linux/syscalls.h>
 #include <linux/interrupt.h>
+#include <linux/kallsyms.h>
 
 #include <asm/atomic.h>
-#include <asm/uaccess.h>
+
+/*
+ * Structure to determine completion condition and record errors.  May
+ * be shared by works on different cpus.
+ */
+struct cpu_stop_done {
+       atomic_t                nr_todo;        /* nr left to execute */
+       bool                    executed;       /* actually executed? */
+       int                     ret;            /* collected return value */
+       struct completion       completion;     /* fired if nr_todo reaches 0 */
+};
+
+/* the actual stopper, one per every possible cpu, enabled on online cpus */
+struct cpu_stopper {
+       spinlock_t              lock;
+       struct list_head        works;          /* list of pending works */
+       struct task_struct      *thread;        /* stopper thread */
+       bool                    enabled;        /* is this stopper enabled? */
+};
+
+static DEFINE_PER_CPU(struct cpu_stopper, cpu_stopper);
+
+static void cpu_stop_init_done(struct cpu_stop_done *done, unsigned int nr_todo)
+{
+       memset(done, 0, sizeof(*done));
+       atomic_set(&done->nr_todo, nr_todo);
+       init_completion(&done->completion);
+}
+
+/* signal completion unless @done is NULL */
+static void cpu_stop_signal_done(struct cpu_stop_done *done, bool executed)
+{
+       if (done) {
+               if (executed)
+                       done->executed = true;
+               if (atomic_dec_and_test(&done->nr_todo))
+                       complete(&done->completion);
+       }
+}
+
+/* queue @work to @stopper.  if offline, @work is completed immediately */
+static void cpu_stop_queue_work(struct cpu_stopper *stopper,
+                               struct cpu_stop_work *work)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&stopper->lock, flags);
+
+       if (stopper->enabled) {
+               list_add_tail(&work->list, &stopper->works);
+               wake_up_process(stopper->thread);
+       } else
+               cpu_stop_signal_done(work->done, false);
+
+       spin_unlock_irqrestore(&stopper->lock, flags);
+}
+
+/**
+ * stop_one_cpu - stop a cpu
+ * @cpu: cpu to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Execute @fn(@arg) on @cpu.  @fn is run in a process context with
+ * the highest priority preempting any task on the cpu and
+ * monopolizing it.  This function returns after the execution is
+ * complete.
+ *
+ * This function doesn't guarantee @cpu stays online till @fn
+ * completes.  If @cpu goes down in the middle, execution may happen
+ * partially or fully on different cpus.  @fn should either be ready
+ * for that or the caller should ensure that @cpu stays online until
+ * this function completes.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * -ENOENT if @fn(@arg) was not executed because @cpu was offline;
+ * otherwise, the return value of @fn.
+ */
+int stop_one_cpu(unsigned int cpu, cpu_stop_fn_t fn, void *arg)
+{
+       struct cpu_stop_done done;
+       struct cpu_stop_work work = { .fn = fn, .arg = arg, .done = &done };
+
+       cpu_stop_init_done(&done, 1);
+       cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu), &work);
+       wait_for_completion(&done.completion);
+       return done.executed ? done.ret : -ENOENT;
+}
+
+/**
+ * stop_one_cpu_nowait - stop a cpu but don't wait for completion
+ * @cpu: cpu to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Similar to stop_one_cpu() but doesn't wait for completion.  The
+ * caller is responsible for ensuring @work_buf is currently unused
+ * and will remain untouched until stopper starts executing @fn.
+ *
+ * CONTEXT:
+ * Don't care.
+ */
+void stop_one_cpu_nowait(unsigned int cpu, cpu_stop_fn_t fn, void *arg,
+                       struct cpu_stop_work *work_buf)
+{
+       *work_buf = (struct cpu_stop_work){ .fn = fn, .arg = arg, };
+       cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu), work_buf);
+}
+
+/* static data for stop_cpus */
+static DEFINE_MUTEX(stop_cpus_mutex);
+static DEFINE_PER_CPU(struct cpu_stop_work, stop_cpus_work);
+
+int __stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg)
+{
+       struct cpu_stop_work *work;
+       struct cpu_stop_done done;
+       unsigned int cpu;
+
+       /* initialize works and done */
+       for_each_cpu(cpu, cpumask) {
+               work = &per_cpu(stop_cpus_work, cpu);
+               work->fn = fn;
+               work->arg = arg;
+               work->done = &done;
+       }
+       cpu_stop_init_done(&done, cpumask_weight(cpumask));
+
+       /*
+        * Disable preemption while queueing to avoid getting
+        * preempted by a stopper which might wait for other stoppers
+        * to enter @fn which can lead to deadlock.
+        */
+       preempt_disable();
+       for_each_cpu(cpu, cpumask)
+               cpu_stop_queue_work(&per_cpu(cpu_stopper, cpu),
+                                   &per_cpu(stop_cpus_work, cpu));
+       preempt_enable();
+
+       wait_for_completion(&done.completion);
+       return done.executed ? done.ret : -ENOENT;
+}
+
+/**
+ * stop_cpus - stop multiple cpus
+ * @cpumask: cpus to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Execute @fn(@arg) on online cpus in @cpumask.  On each target cpu,
+ * @fn is run in a process context with the highest priority
+ * preempting any task on the cpu and monopolizing it.  This function
+ * returns after all executions are complete.
+ *
+ * This function doesn't guarantee the cpus in @cpumask stay online
+ * till @fn completes.  If some cpus go down in the middle, execution
+ * on the cpu may happen partially or fully on different cpus.  @fn
+ * should either be ready for that or the caller should ensure that
+ * the cpus stay online until this function completes.
+ *
+ * All stop_cpus() calls are serialized making it safe for @fn to wait
+ * for all cpus to start executing it.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * -ENOENT if @fn(@arg) was not executed at all because all cpus in
+ * @cpumask were offline; otherwise, 0 if all executions of @fn
+ * returned 0, any non zero return value if any returned non zero.
+ */
+int stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg)
+{
+       int ret;
+
+       /* static works are used, process one request at a time */
+       mutex_lock(&stop_cpus_mutex);
+       ret = __stop_cpus(cpumask, fn, arg);
+       mutex_unlock(&stop_cpus_mutex);
+       return ret;
+}
+
+/**
+ * try_stop_cpus - try to stop multiple cpus
+ * @cpumask: cpus to stop
+ * @fn: function to execute
+ * @arg: argument to @fn
+ *
+ * Identical to stop_cpus() except that it fails with -EAGAIN if
+ * someone else is already using the facility.
+ *
+ * CONTEXT:
+ * Might sleep.
+ *
+ * RETURNS:
+ * -EAGAIN if someone else is already stopping cpus, -ENOENT if
+ * @fn(@arg) was not executed at all because all cpus in @cpumask were
+ * offline; otherwise, 0 if all executions of @fn returned 0, any non
+ * zero return value if any returned non zero.
+ */
+int try_stop_cpus(const struct cpumask *cpumask, cpu_stop_fn_t fn, void *arg)
+{
+       int ret;
+
+       /* static works are used, process one request at a time */
+       if (!mutex_trylock(&stop_cpus_mutex))
+               return -EAGAIN;
+       ret = __stop_cpus(cpumask, fn, arg);
+       mutex_unlock(&stop_cpus_mutex);
+       return ret;
+}
+
+static int cpu_stopper_thread(void *data)
+{
+       struct cpu_stopper *stopper = data;
+       struct cpu_stop_work *work;
+       int ret;
+
+repeat:
+       set_current_state(TASK_INTERRUPTIBLE);  /* mb paired w/ kthread_stop */
+
+       if (kthread_should_stop()) {
+               __set_current_state(TASK_RUNNING);
+               return 0;
+       }
+
+       work = NULL;
+       spin_lock_irq(&stopper->lock);
+       if (!list_empty(&stopper->works)) {
+               work = list_first_entry(&stopper->works,
+                                       struct cpu_stop_work, list);
+               list_del_init(&work->list);
+       }
+       spin_unlock_irq(&stopper->lock);
+
+       if (work) {
+               cpu_stop_fn_t fn = work->fn;
+               void *arg = work->arg;
+               struct cpu_stop_done *done = work->done;
+               char ksym_buf[KSYM_NAME_LEN];
+
+               __set_current_state(TASK_RUNNING);
+
+               /* cpu stop callbacks are not allowed to sleep */
+               preempt_disable();
+
+               ret = fn(arg);
+               if (ret)
+                       done->ret = ret;
+
+               /* restore preemption and check it's still balanced */
+               preempt_enable();
+               WARN_ONCE(preempt_count(),
+                         "cpu_stop: %s(%p) leaked preempt count\n",
+                         kallsyms_lookup((unsigned long)fn, NULL, NULL, NULL,
+                                         ksym_buf), arg);
+
+               cpu_stop_signal_done(done, true);
+       } else
+               schedule();
+
+       goto repeat;
+}
+
+/* manage stopper for a cpu, mostly lifted from sched migration thread mgmt */
+static int __cpuinit cpu_stop_cpu_callback(struct notifier_block *nfb,
+                                          unsigned long action, void *hcpu)
+{
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+       unsigned int cpu = (unsigned long)hcpu;
+       struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
+       struct task_struct *p;
+
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_UP_PREPARE:
+               BUG_ON(stopper->thread || stopper->enabled ||
+                      !list_empty(&stopper->works));
+               p = kthread_create(cpu_stopper_thread, stopper, "migration/%d",
+                                  cpu);
+               if (IS_ERR(p))
+                       return NOTIFY_BAD;
+               sched_setscheduler_nocheck(p, SCHED_FIFO, &param);
+               get_task_struct(p);
+               stopper->thread = p;
+               break;
+
+       case CPU_ONLINE:
+               kthread_bind(stopper->thread, cpu);
+               /* strictly unnecessary, as first user will wake it */
+               wake_up_process(stopper->thread);
+               /* mark enabled */
+               spin_lock_irq(&stopper->lock);
+               stopper->enabled = true;
+               spin_unlock_irq(&stopper->lock);
+               break;
+
+#ifdef CONFIG_HOTPLUG_CPU
+       case CPU_UP_CANCELED:
+       case CPU_DEAD:
+       {
+               struct cpu_stop_work *work;
+
+               /* kill the stopper */
+               kthread_stop(stopper->thread);
+               /* drain remaining works */
+               spin_lock_irq(&stopper->lock);
+               list_for_each_entry(work, &stopper->works, list)
+                       cpu_stop_signal_done(work->done, false);
+               stopper->enabled = false;
+               spin_unlock_irq(&stopper->lock);
+               /* release the stopper */
+               put_task_struct(stopper->thread);
+               stopper->thread = NULL;
+               break;
+       }
+#endif
+       }
+
+       return NOTIFY_OK;
+}
+
+/*
+ * Give it a higher priority so that cpu stopper is available to other
+ * cpu notifiers.  It currently shares the same priority as sched
+ * migration_notifier.
+ */
+static struct notifier_block __cpuinitdata cpu_stop_cpu_notifier = {
+       .notifier_call  = cpu_stop_cpu_callback,
+       .priority       = 10,
+};
+
+static int __init cpu_stop_init(void)
+{
+       void *bcpu = (void *)(long)smp_processor_id();
+       unsigned int cpu;
+       int err;
+
+       for_each_possible_cpu(cpu) {
+               struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
+
+               spin_lock_init(&stopper->lock);
+               INIT_LIST_HEAD(&stopper->works);
+       }
+
+       /* start one for the boot cpu */
+       err = cpu_stop_cpu_callback(&cpu_stop_cpu_notifier, CPU_UP_PREPARE,
+                                   bcpu);
+       BUG_ON(err == NOTIFY_BAD);
+       cpu_stop_cpu_callback(&cpu_stop_cpu_notifier, CPU_ONLINE, bcpu);
+       register_cpu_notifier(&cpu_stop_cpu_notifier);
+
+       return 0;
+}
+early_initcall(cpu_stop_init);
+
+#ifdef CONFIG_STOP_MACHINE
 
 /* This controls the threads on each CPU. */
 enum stopmachine_state {
@@ -26,174 +393,94 @@ enum stopmachine_state {
        /* Exit */
        STOPMACHINE_EXIT,
 };
-static enum stopmachine_state state;
 
 struct stop_machine_data {
-       int (*fn)(void *);
-       void *data;
-       int fnret;
+       int                     (*fn)(void *);
+       void                    *data;
+       /* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */
+       unsigned int            num_threads;
+       const struct cpumask    *active_cpus;
+
+       enum stopmachine_state  state;
+       atomic_t                thread_ack;
 };
 
-/* Like num_online_cpus(), but hotplug cpu uses us, so we need this. */
-static unsigned int num_threads;
-static atomic_t thread_ack;
-static DEFINE_MUTEX(lock);
-/* setup_lock protects refcount, stop_machine_wq and stop_machine_work. */
-static DEFINE_MUTEX(setup_lock);
-/* Users of stop_machine. */
-static int refcount;
-static struct workqueue_struct *stop_machine_wq;
-static struct stop_machine_data active, idle;
-static const struct cpumask *active_cpus;
-static void __percpu *stop_machine_work;
-
-static void set_state(enum stopmachine_state newstate)
+static void set_state(struct stop_machine_data *smdata,
+                     enum stopmachine_state newstate)
 {
        /* Reset ack counter. */
-       atomic_set(&thread_ack, num_threads);
+       atomic_set(&smdata->thread_ack, smdata->num_threads);
        smp_wmb();
-       state = newstate;
+       smdata->state = newstate;
 }
 
 /* Last one to ack a state moves to the next state. */
-static void ack_state(void)
+static void ack_state(struct stop_machine_data *smdata)
 {
-       if (atomic_dec_and_test(&thread_ack))
-               set_state(state + 1);
+       if (atomic_dec_and_test(&smdata->thread_ack))
+               set_state(smdata, smdata->state + 1);
 }
 
-/* This is the actual function which stops the CPU. It runs
- * in the context of a dedicated stopmachine workqueue. */
-static void stop_cpu(struct work_struct *unused)
+/* This is the cpu_stop function which stops the CPU. */
+static int stop_machine_cpu_stop(void *data)
 {
+       struct stop_machine_data *smdata = data;
        enum stopmachine_state curstate = STOPMACHINE_NONE;
-       struct stop_machine_data *smdata = &idle;
-       int cpu = smp_processor_id();
-       int err;
+       int cpu = smp_processor_id(), err = 0;
+       bool is_active;
+
+       if (!smdata->active_cpus)
+               is_active = cpu == cpumask_first(cpu_online_mask);
+       else
+               is_active = cpumask_test_cpu(cpu, smdata->active_cpus);
 
-       if (!active_cpus) {
-               if (cpu == cpumask_first(cpu_online_mask))
-                       smdata = &active;
-       } else {
-               if (cpumask_test_cpu(cpu, active_cpus))
-                       smdata = &active;
-       }
        /* Simple state machine */
        do {
                /* Chill out and ensure we re-read stopmachine_state. */
                cpu_relax();
-               if (state != curstate) {
-                       curstate = state;
+               if (smdata->state != curstate) {
+                       curstate = smdata->state;
                        switch (curstate) {
                        case STOPMACHINE_DISABLE_IRQ:
                                local_irq_disable();
                                hard_irq_disable();
                                break;
                        case STOPMACHINE_RUN:
-                               /* On multiple CPUs only a single error code
-                                * is needed to tell that something failed. */
-                               err = smdata->fn(smdata->data);
-                               if (err)
-                                       smdata->fnret = err;
+                               if (is_active)
+                                       err = smdata->fn(smdata->data);
                                break;
                        default:
                                break;
                        }
-                       ack_state();
+                       ack_state(smdata);
                }
        } while (curstate != STOPMACHINE_EXIT);
 
        local_irq_enable();
+       return err;
 }
 
-/* Callback for CPUs which aren't supposed to do anything. */
-static int chill(void *unused)
-{
-       return 0;
-}
-
-int stop_machine_create(void)
-{
-       mutex_lock(&setup_lock);
-       if (refcount)
-               goto done;
-       stop_machine_wq = create_rt_workqueue("kstop");
-       if (!stop_machine_wq)
-               goto err_out;
-       stop_machine_work = alloc_percpu(struct work_struct);
-       if (!stop_machine_work)
-               goto err_out;
-done:
-       refcount++;
-       mutex_unlock(&setup_lock);
-       return 0;
-
-err_out:
-       if (stop_machine_wq)
-               destroy_workqueue(stop_machine_wq);
-       mutex_unlock(&setup_lock);
-       return -ENOMEM;
-}
-EXPORT_SYMBOL_GPL(stop_machine_create);
-
-void stop_machine_destroy(void)
-{
-       mutex_lock(&setup_lock);
-       refcount--;
-       if (refcount)
-               goto done;
-       destroy_workqueue(stop_machine_wq);
-       free_percpu(stop_machine_work);
-done:
-       mutex_unlock(&setup_lock);
-}
-EXPORT_SYMBOL_GPL(stop_machine_destroy);
-
 int __stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus)
 {
-       struct work_struct *sm_work;
-       int i, ret;
-
-       /* Set up initial state. */
-       mutex_lock(&lock);
-       num_threads = num_online_cpus();
-       active_cpus = cpus;
-       active.fn = fn;
-       active.data = data;
-       active.fnret = 0;
-       idle.fn = chill;
-       idle.data = NULL;
-
-       set_state(STOPMACHINE_PREPARE);
-
-       /* Schedule the stop_cpu work on all cpus: hold this CPU so one
-        * doesn't hit this CPU until we're ready. */
-       get_cpu();
-       for_each_online_cpu(i) {
-               sm_work = per_cpu_ptr(stop_machine_work, i);
-               INIT_WORK(sm_work, stop_cpu);
-               queue_work_on(i, stop_machine_wq, sm_work);
-       }
-       /* This will release the thread on our CPU. */
-       put_cpu();
-       flush_workqueue(stop_machine_wq);
-       ret = active.fnret;
-       mutex_unlock(&lock);
-       return ret;
+       struct stop_machine_data smdata = { .fn = fn, .data = data,
+                                           .num_threads = num_online_cpus(),
+                                           .active_cpus = cpus };
+
+       /* Set the initial state and stop all online cpus. */
+       set_state(&smdata, STOPMACHINE_PREPARE);
+       return stop_cpus(cpu_online_mask, stop_machine_cpu_stop, &smdata);
 }
 
 int stop_machine(int (*fn)(void *), void *data, const struct cpumask *cpus)
 {
        int ret;
 
-       ret = stop_machine_create();
-       if (ret)
-               return ret;
        /* No CPUs can come up or down during this. */
        get_online_cpus();
        ret = __stop_machine(fn, data, cpus);
        put_online_cpus();
-       stop_machine_destroy();
        return ret;
 }
 EXPORT_SYMBOL_GPL(stop_machine);
+
+#endif /* CONFIG_STOP_MACHINE */
index 6d1a7e0..0d36d88 100644 (file)
@@ -492,10 +492,6 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
                return -ENOMEM;
        old = current_cred();
 
-       retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE);
-       if (retval)
-               goto error;
-
        retval = -EPERM;
        if (rgid != (gid_t) -1) {
                if (old->gid == rgid ||
@@ -543,10 +539,6 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
                return -ENOMEM;
        old = current_cred();
 
-       retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
-       if (retval)
-               goto error;
-
        retval = -EPERM;
        if (capable(CAP_SETGID))
                new->gid = new->egid = new->sgid = new->fsgid = gid;
@@ -610,10 +602,6 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
                return -ENOMEM;
        old = current_cred();
 
-       retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE);
-       if (retval)
-               goto error;
-
        retval = -EPERM;
        if (ruid != (uid_t) -1) {
                new->uid = ruid;
@@ -675,10 +663,6 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
                return -ENOMEM;
        old = current_cred();
 
-       retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID);
-       if (retval)
-               goto error;
-
        retval = -EPERM;
        if (capable(CAP_SETUID)) {
                new->suid = new->uid = uid;
@@ -719,9 +703,6 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
        if (!new)
                return -ENOMEM;
 
-       retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES);
-       if (retval)
-               goto error;
        old = current_cred();
 
        retval = -EPERM;
@@ -788,10 +769,6 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
                return -ENOMEM;
        old = current_cred();
 
-       retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES);
-       if (retval)
-               goto error;
-
        retval = -EPERM;
        if (!capable(CAP_SETGID)) {
                if (rgid != (gid_t) -1 && rgid != old->gid &&
@@ -851,9 +828,6 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
        old = current_cred();
        old_fsuid = old->fsuid;
 
-       if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0)
-               goto error;
-
        if (uid == old->uid  || uid == old->euid  ||
            uid == old->suid || uid == old->fsuid ||
            capable(CAP_SETUID)) {
@@ -864,7 +838,6 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
                }
        }
 
-error:
        abort_creds(new);
        return old_fsuid;
 
@@ -888,9 +861,6 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
        old = current_cred();
        old_fsgid = old->fsgid;
 
-       if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS))
-               goto error;
-
        if (gid == old->gid  || gid == old->egid  ||
            gid == old->sgid || gid == old->fsgid ||
            capable(CAP_SETGID)) {
@@ -900,7 +870,6 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
                }
        }
 
-error:
        abort_creds(new);
        return old_fsgid;
 
@@ -1118,7 +1087,7 @@ DECLARE_RWSEM(uts_sem);
 
 #ifdef COMPAT_UTS_MACHINE
 #define override_architecture(name) \
-       (current->personality == PER_LINUX32 && \
+       (personality(current->personality) == PER_LINUX32 && \
         copy_to_user(name->machine, COMPAT_UTS_MACHINE, \
                      sizeof(COMPAT_UTS_MACHINE)))
 #else
index 8686b0f..90f536d 100644 (file)
@@ -621,7 +621,7 @@ static struct ctl_table kern_table[] = {
 #endif
        {
                .procname       = "userprocess_debug",
-               .data           = &sysctl_userprocess_debug,
+               .data           = &show_unhandled_signals,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
@@ -1431,7 +1431,8 @@ static struct ctl_table fs_table[] = {
 };
 
 static struct ctl_table debug_table[] = {
-#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
+    defined(CONFIG_S390)
        {
                .procname       = "exception-trace",
                .data           = &show_unhandled_signals,
index 656dccf..50612fa 100644 (file)
@@ -132,12 +132,11 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
  */
 static inline void warp_clock(void)
 {
-       write_seqlock_irq(&xtime_lock);
-       wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
-       xtime.tv_sec += sys_tz.tz_minuteswest * 60;
-       update_xtime_cache(0);
-       write_sequnlock_irq(&xtime_lock);
-       clock_was_set();
+       struct timespec delta, adjust;
+       delta.tv_sec = sys_tz.tz_minuteswest * 60;
+       delta.tv_nsec = 0;
+       adjust = timespec_add_safe(current_kernel_time(), delta);
+       do_settimeofday(&adjust);
 }
 
 /*
index 1f5dde6..f08e99c 100644 (file)
@@ -625,6 +625,54 @@ static void clocksource_enqueue(struct clocksource *cs)
        list_add(&cs->list, entry);
 }
 
+
+/*
+ * Maximum time we expect to go between ticks. This includes idle
+ * tickless time. It provides the trade off between selecting a
+ * mult/shift pair that is very precise but can only handle a short
+ * period of time, vs. a mult/shift pair that can handle long periods
+ * of time but isn't as precise.
+ *
+ * This is a subsystem constant, and actual hardware limitations
+ * may override it (ie: clocksources that wrap every 3 seconds).
+ */
+#define MAX_UPDATE_LENGTH 5 /* Seconds */
+
+/**
+ * __clocksource_register_scale - Used to install new clocksources
+ * @t:         clocksource to be registered
+ * @scale:     Scale factor multiplied against freq to get clocksource hz
+ * @freq:      clocksource frequency (cycles per second) divided by scale
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ *
+ * This *SHOULD NOT* be called directly! Please use the
+ * clocksource_register_hz() or clocksource_register_khz helper functions.
+ */
+int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
+{
+
+       /*
+        * Ideally we want to use  some of the limits used in
+        * clocksource_max_deferment, to provide a more informed
+        * MAX_UPDATE_LENGTH. But for now this just gets the
+        * register interface working properly.
+        */
+       clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
+                                     NSEC_PER_SEC/scale,
+                                     MAX_UPDATE_LENGTH*scale);
+       cs->max_idle_ns = clocksource_max_deferment(cs);
+
+       mutex_lock(&clocksource_mutex);
+       clocksource_enqueue(cs);
+       clocksource_select();
+       clocksource_enqueue_watchdog(cs);
+       mutex_unlock(&clocksource_mutex);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(__clocksource_register_scale);
+
+
 /**
  * clocksource_register - Used to install new clocksources
  * @t:         clocksource to be registered
index 7c0f180..c631168 100644 (file)
@@ -69,7 +69,7 @@ static s64                    time_freq;
 /* time at last adjustment (secs):                                     */
 static long                    time_reftime;
 
-long                           time_adjust;
+static long                    time_adjust;
 
 /* constant (boot-param configurable) NTP tick adjustment (upscaled)   */
 static s64                     ntp_tick_adj;
index f992762..1d7b9bc 100644 (file)
@@ -150,14 +150,32 @@ static void tick_nohz_update_jiffies(ktime_t now)
        touch_softlockup_watchdog();
 }
 
+/*
+ * Updates the per cpu time idle statistics counters
+ */
+static void
+update_ts_time_stats(struct tick_sched *ts, ktime_t now, u64 *last_update_time)
+{
+       ktime_t delta;
+
+       if (ts->idle_active) {
+               delta = ktime_sub(now, ts->idle_entrytime);
+               ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
+               if (nr_iowait_cpu() > 0)
+                       ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta);
+               ts->idle_entrytime = now;
+       }
+
+       if (last_update_time)
+               *last_update_time = ktime_to_us(now);
+
+}
+
 static void tick_nohz_stop_idle(int cpu, ktime_t now)
 {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
-       ktime_t delta;
 
-       delta = ktime_sub(now, ts->idle_entrytime);
-       ts->idle_lastupdate = now;
-       ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
+       update_ts_time_stats(ts, now, NULL);
        ts->idle_active = 0;
 
        sched_clock_idle_wakeup_event(0);
@@ -165,20 +183,32 @@ static void tick_nohz_stop_idle(int cpu, ktime_t now)
 
 static ktime_t tick_nohz_start_idle(struct tick_sched *ts)
 {
-       ktime_t now, delta;
+       ktime_t now;
 
        now = ktime_get();
-       if (ts->idle_active) {
-               delta = ktime_sub(now, ts->idle_entrytime);
-               ts->idle_lastupdate = now;
-               ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);
-       }
+
+       update_ts_time_stats(ts, now, NULL);
+
        ts->idle_entrytime = now;
        ts->idle_active = 1;
        sched_clock_idle_sleep_event();
        return now;
 }
 
+/**
+ * get_cpu_idle_time_us - get the total idle time of a cpu
+ * @cpu: CPU number to query
+ * @last_update_time: variable to store update time in
+ *
+ * Return the cummulative idle time (since boot) for a given
+ * CPU, in microseconds. The idle time returned includes
+ * the iowait time (unlike what "top" and co report).
+ *
+ * This time is measured via accounting rather than sampling,
+ * and is as accurate as ktime_get() is.
+ *
+ * This function returns -1 if NOHZ is not enabled.
+ */
 u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
 {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
@@ -186,15 +216,38 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
        if (!tick_nohz_enabled)
                return -1;
 
-       if (ts->idle_active)
-               *last_update_time = ktime_to_us(ts->idle_lastupdate);
-       else
-               *last_update_time = ktime_to_us(ktime_get());
+       update_ts_time_stats(ts, ktime_get(), last_update_time);
 
        return ktime_to_us(ts->idle_sleeptime);
 }
 EXPORT_SYMBOL_GPL(get_cpu_idle_time_us);
 
+/*
+ * get_cpu_iowait_time_us - get the total iowait time of a cpu
+ * @cpu: CPU number to query
+ * @last_update_time: variable to store update time in
+ *
+ * Return the cummulative iowait time (since boot) for a given
+ * CPU, in microseconds.
+ *
+ * This time is measured via accounting rather than sampling,
+ * and is as accurate as ktime_get() is.
+ *
+ * This function returns -1 if NOHZ is not enabled.
+ */
+u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
+{
+       struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+
+       if (!tick_nohz_enabled)
+               return -1;
+
+       update_ts_time_stats(ts, ktime_get(), last_update_time);
+
+       return ktime_to_us(ts->iowait_sleeptime);
+}
+EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);
+
 /**
  * tick_nohz_stop_sched_tick - stop the idle tick from the idle task
  *
@@ -262,6 +315,9 @@ void tick_nohz_stop_sched_tick(int inidle)
                goto end;
        }
 
+       if (nohz_ratelimit(cpu))
+               goto end;
+
        ts->idle_calls++;
        /* Read jiffies and the time when jiffies were updated last */
        do {
index 39f6177..caf8d4d 100644 (file)
@@ -165,13 +165,6 @@ struct timespec raw_time;
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
 
-static struct timespec xtime_cache __attribute__ ((aligned (16)));
-void update_xtime_cache(u64 nsec)
-{
-       xtime_cache = xtime;
-       timespec_add_ns(&xtime_cache, nsec);
-}
-
 /* must hold xtime_lock */
 void timekeeping_leap_insert(int leapsecond)
 {
@@ -332,8 +325,6 @@ int do_settimeofday(struct timespec *tv)
 
        xtime = *tv;
 
-       update_xtime_cache(0);
-
        timekeeper.ntp_error = 0;
        ntp_clear();
 
@@ -559,7 +550,6 @@ void __init timekeeping_init(void)
        }
        set_normalized_timespec(&wall_to_monotonic,
                                -boot.tv_sec, -boot.tv_nsec);
-       update_xtime_cache(0);
        total_sleep_time.tv_sec = 0;
        total_sleep_time.tv_nsec = 0;
        write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -593,7 +583,6 @@ static int timekeeping_resume(struct sys_device *dev)
                wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
                total_sleep_time = timespec_add_safe(total_sleep_time, ts);
        }
-       update_xtime_cache(0);
        /* re-base the last cycle value */
        timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
        timekeeper.ntp_error = 0;
@@ -788,7 +777,6 @@ void update_wall_time(void)
 {
        struct clocksource *clock;
        cycle_t offset;
-       u64 nsecs;
        int shift = 0, maxshift;
 
        /* Make sure we're fully resumed: */
@@ -847,7 +835,9 @@ void update_wall_time(void)
                timekeeper.ntp_error += neg << timekeeper.ntp_error_shift;
        }
 
-       /* store full nanoseconds into xtime after rounding it up and
+
+       /*
+        * Store full nanoseconds into xtime after rounding it up and
         * add the remainder to the error difference.
         */
        xtime.tv_nsec = ((s64) timekeeper.xtime_nsec >> timekeeper.shift) + 1;
@@ -855,8 +845,15 @@ void update_wall_time(void)
        timekeeper.ntp_error += timekeeper.xtime_nsec <<
                                timekeeper.ntp_error_shift;
 
-       nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
-       update_xtime_cache(nsecs);
+       /*
+        * Finally, make sure that after the rounding
+        * xtime.tv_nsec isn't larger then NSEC_PER_SEC
+        */
+       if (unlikely(xtime.tv_nsec >= NSEC_PER_SEC)) {
+               xtime.tv_nsec -= NSEC_PER_SEC;
+               xtime.tv_sec++;
+               second_overflow();
+       }
 
        /* check to see if there is a new clocksource to use */
        update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
@@ -896,13 +893,13 @@ EXPORT_SYMBOL_GPL(monotonic_to_bootbased);
 
 unsigned long get_seconds(void)
 {
-       return xtime_cache.tv_sec;
+       return xtime.tv_sec;
 }
 EXPORT_SYMBOL(get_seconds);
 
 struct timespec __current_kernel_time(void)
 {
-       return xtime_cache;
+       return xtime;
 }
 
 struct timespec current_kernel_time(void)
@@ -913,7 +910,7 @@ struct timespec current_kernel_time(void)
        do {
                seq = read_seqbegin(&xtime_lock);
 
-               now = xtime_cache;
+               now = xtime;
        } while (read_seqretry(&xtime_lock, seq));
 
        return now;
@@ -928,7 +925,7 @@ struct timespec get_monotonic_coarse(void)
        do {
                seq = read_seqbegin(&xtime_lock);
 
-               now = xtime_cache;
+               now = xtime;
                mono = wall_to_monotonic;
        } while (read_seqretry(&xtime_lock, seq));
 
index 1a4a7dd..ab8f5e3 100644 (file)
@@ -176,6 +176,7 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
                P_ns(idle_waketime);
                P_ns(idle_exittime);
                P_ns(idle_sleeptime);
+               P_ns(iowait_sleeptime);
                P(last_jiffies);
                P(next_jiffies);
                P_ns(idle_expires);
index aeb6a54..9199f3c 100644 (file)
@@ -319,6 +319,24 @@ unsigned long round_jiffies_up_relative(unsigned long j)
 }
 EXPORT_SYMBOL_GPL(round_jiffies_up_relative);
 
+/**
+ * set_timer_slack - set the allowed slack for a timer
+ * @slack_hz: the amount of time (in jiffies) allowed for rounding
+ *
+ * Set the amount of time, in jiffies, that a certain timer has
+ * in terms of slack. By setting this value, the timer subsystem
+ * will schedule the actual timer somewhere between
+ * the time mod_timer() asks for, and that time plus the slack.
+ *
+ * By setting the slack to -1, a percentage of the delay is used
+ * instead.
+ */
+void set_timer_slack(struct timer_list *timer, int slack_hz)
+{
+       timer->slack = slack_hz;
+}
+EXPORT_SYMBOL_GPL(set_timer_slack);
+
 
 static inline void set_running_timer(struct tvec_base *base,
                                        struct timer_list *timer)
@@ -550,6 +568,7 @@ static void __init_timer(struct timer_list *timer,
 {
        timer->entry.next = NULL;
        timer->base = __raw_get_cpu_var(tvec_bases);
+       timer->slack = -1;
 #ifdef CONFIG_TIMER_STATS
        timer->start_site = NULL;
        timer->start_pid = -1;
@@ -715,6 +734,41 @@ int mod_timer_pending(struct timer_list *timer, unsigned long expires)
 }
 EXPORT_SYMBOL(mod_timer_pending);
 
+/*
+ * Decide where to put the timer while taking the slack into account
+ *
+ * Algorithm:
+ *   1) calculate the maximum (absolute) time
+ *   2) calculate the highest bit where the expires and new max are different
+ *   3) use this bit to make a mask
+ *   4) use the bitmask to round down the maximum time, so that all last
+ *      bits are zeros
+ */
+static inline
+unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
+{
+       unsigned long expires_limit, mask;
+       int bit;
+
+       expires_limit = expires + timer->slack;
+
+       if (timer->slack < 0) /* auto slack: use 0.4% */
+               expires_limit = expires + (expires - jiffies)/256;
+
+       mask = expires ^ expires_limit;
+
+       if (mask == 0)
+               return expires;
+
+       bit = find_last_bit(&mask, BITS_PER_LONG);
+
+       mask = (1 << bit) - 1;
+
+       expires_limit = expires_limit & ~(mask);
+
+       return expires_limit;
+}
+
 /**
  * mod_timer - modify a timer's timeout
  * @timer: the timer to be modified
@@ -745,6 +799,8 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
        if (timer_pending(timer) && timer->expires == expires)
                return 1;
 
+       expires = apply_slack(timer, expires);
+
        return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
 }
 EXPORT_SYMBOL(mod_timer);
@@ -955,6 +1011,47 @@ static int cascade(struct tvec_base *base, struct tvec *tv, int index)
        return index;
 }
 
+static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
+                         unsigned long data)
+{
+       int preempt_count = preempt_count();
+
+#ifdef CONFIG_LOCKDEP
+       /*
+        * It is permissible to free the timer from inside the
+        * function that is called from it, this we need to take into
+        * account for lockdep too. To avoid bogus "held lock freed"
+        * warnings as well as problems when looking into
+        * timer->lockdep_map, make a copy and use that here.
+        */
+       struct lockdep_map lockdep_map = timer->lockdep_map;
+#endif
+       /*
+        * Couple the lock chain with the lock chain at
+        * del_timer_sync() by acquiring the lock_map around the fn()
+        * call here and in del_timer_sync().
+        */
+       lock_map_acquire(&lockdep_map);
+
+       trace_timer_expire_entry(timer);
+       fn(data);
+       trace_timer_expire_exit(timer);
+
+       lock_map_release(&lockdep_map);
+
+       if (preempt_count != preempt_count()) {
+               WARN_ONCE(1, "timer: %pF preempt leak: %08x -> %08x\n",
+                         fn, preempt_count, preempt_count());
+               /*
+                * Restore the preempt count. That gives us a decent
+                * chance to survive and extract information. If the
+                * callback kept a lock held, bad luck, but not worse
+                * than the BUG() we had.
+                */
+               preempt_count() = preempt_count;
+       }
+}
+
 #define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK)
 
 /**
@@ -998,45 +1095,7 @@ static inline void __run_timers(struct tvec_base *base)
                        detach_timer(timer, 1);
 
                        spin_unlock_irq(&base->lock);
-                       {
-                               int preempt_count = preempt_count();
-
-#ifdef CONFIG_LOCKDEP
-                               /*
-                                * It is permissible to free the timer from
-                                * inside the function that is called from
-                                * it, this we need to take into account for
-                                * lockdep too. To avoid bogus "held lock
-                                * freed" warnings as well as problems when
-                                * looking into timer->lockdep_map, make a
-                                * copy and use that here.
-                                */
-                               struct lockdep_map lockdep_map =
-                                       timer->lockdep_map;
-#endif
-                               /*
-                                * Couple the lock chain with the lock chain at
-                                * del_timer_sync() by acquiring the lock_map
-                                * around the fn() call here and in
-                                * del_timer_sync().
-                                */
-                               lock_map_acquire(&lockdep_map);
-
-                               trace_timer_expire_entry(timer);
-                               fn(data);
-                               trace_timer_expire_exit(timer);
-
-                               lock_map_release(&lockdep_map);
-
-                               if (preempt_count != preempt_count()) {
-                                       printk(KERN_ERR "huh, entered %p "
-                                              "with preempt_count %08x, exited"
-                                              " with %08x?\n",
-                                              fn, preempt_count,
-                                              preempt_count());
-                                       BUG();
-                               }
-                       }
+                       call_timer_fn(timer, fn, data);
                        spin_lock_irq(&base->lock);
                }
        }
index 13e13d4..8b1797c 100644 (file)
@@ -44,9 +44,6 @@ config HAVE_FTRACE_MCOUNT_RECORD
        help
          See Documentation/trace/ftrace-design.txt
 
-config HAVE_HW_BRANCH_TRACER
-       bool
-
 config HAVE_SYSCALL_TRACEPOINTS
        bool
        help
@@ -374,14 +371,6 @@ config STACK_TRACER
 
          Say N if unsure.
 
-config HW_BRANCH_TRACER
-       depends on HAVE_HW_BRANCH_TRACER
-       bool "Trace hw branches"
-       select GENERIC_TRACER
-       help
-         This tracer records all branches on the system in a circular
-         buffer, giving access to the last N branches for each cpu.
-
 config KMEMTRACE
        bool "Trace SLAB allocations"
        select GENERIC_TRACER
index 78edc64..ffb1a5b 100644 (file)
@@ -41,7 +41,6 @@ obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o
 obj-$(CONFIG_BOOT_TRACER) += trace_boot.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += trace_functions_graph.o
 obj-$(CONFIG_TRACE_BRANCH_PROFILING) += trace_branch.o
-obj-$(CONFIG_HW_BRANCH_TRACER) += trace_hw_branches.o
 obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
 obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
 obj-$(CONFIG_BLK_DEV_IO_TRACE) += blktrace.o
index 2404b59..32837e1 100644 (file)
@@ -264,6 +264,7 @@ struct ftrace_profile {
        unsigned long                   counter;
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        unsigned long long              time;
+       unsigned long long              time_squared;
 #endif
 };
 
@@ -366,9 +367,9 @@ static int function_stat_headers(struct seq_file *m)
 {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        seq_printf(m, "  Function                               "
-                  "Hit    Time            Avg\n"
+                  "Hit    Time            Avg             s^2\n"
                      "  --------                               "
-                  "---    ----            ---\n");
+                  "---    ----            ---             ---\n");
 #else
        seq_printf(m, "  Function                               Hit\n"
                      "  --------                               ---\n");
@@ -384,6 +385,7 @@ static int function_stat_show(struct seq_file *m, void *v)
        static DEFINE_MUTEX(mutex);
        static struct trace_seq s;
        unsigned long long avg;
+       unsigned long long stddev;
 #endif
 
        kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
@@ -394,11 +396,25 @@ static int function_stat_show(struct seq_file *m, void *v)
        avg = rec->time;
        do_div(avg, rec->counter);
 
+       /* Sample standard deviation (s^2) */
+       if (rec->counter <= 1)
+               stddev = 0;
+       else {
+               stddev = rec->time_squared - rec->counter * avg * avg;
+               /*
+                * Divide only 1000 for ns^2 -> us^2 conversion.
+                * trace_print_graph_duration will divide 1000 again.
+                */
+               do_div(stddev, (rec->counter - 1) * 1000);
+       }
+
        mutex_lock(&mutex);
        trace_seq_init(&s);
        trace_print_graph_duration(rec->time, &s);
        trace_seq_puts(&s, "    ");
        trace_print_graph_duration(avg, &s);
+       trace_seq_puts(&s, "    ");
+       trace_print_graph_duration(stddev, &s);
        trace_print_seq(m, &s);
        mutex_unlock(&mutex);
 #endif
@@ -650,6 +666,10 @@ static void profile_graph_return(struct ftrace_graph_ret *trace)
        if (!stat->hash || !ftrace_profile_enabled)
                goto out;
 
+       /* If the calltime was zero'd ignore it */
+       if (!trace->calltime)
+               goto out;
+
        calltime = trace->rettime - trace->calltime;
 
        if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
@@ -668,8 +688,10 @@ static void profile_graph_return(struct ftrace_graph_ret *trace)
        }
 
        rec = ftrace_find_profiled_func(stat, trace->func);
-       if (rec)
+       if (rec) {
                rec->time += calltime;
+               rec->time_squared += calltime * calltime;
+       }
 
  out:
        local_irq_restore(flags);
@@ -3212,8 +3234,7 @@ free:
 }
 
 static void
-ftrace_graph_probe_sched_switch(struct rq *__rq, struct task_struct *prev,
-                               struct task_struct *next)
+ftrace_graph_probe_sched_switch(struct task_struct *prev, struct task_struct *next)
 {
        unsigned long long timestamp;
        int index;
@@ -3339,11 +3360,11 @@ void unregister_ftrace_graph(void)
                goto out;
 
        ftrace_graph_active--;
-       unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
        ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
        ftrace_graph_entry = ftrace_graph_entry_stub;
        ftrace_shutdown(FTRACE_STOP_FUNC_RET);
        unregister_pm_notifier(&ftrace_suspend_notifier);
+       unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
 
  out:
        mutex_unlock(&ftrace_lock);
index 41ca394..7f6059c 100644 (file)
@@ -319,6 +319,11 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data);
 #define TS_MASK                ((1ULL << TS_SHIFT) - 1)
 #define TS_DELTA_TEST  (~TS_MASK)
 
+/* Flag when events were overwritten */
+#define RB_MISSED_EVENTS       (1 << 31)
+/* Missed count stored at end */
+#define RB_MISSED_STORED       (1 << 30)
+
 struct buffer_data_page {
        u64              time_stamp;    /* page time stamp */
        local_t          commit;        /* write committed index */
@@ -338,6 +343,7 @@ struct buffer_page {
        local_t          write;         /* index for next write */
        unsigned         read;          /* index for next read */
        local_t          entries;       /* entries on this page */
+       unsigned long    real_end;      /* real end of data */
        struct buffer_data_page *page;  /* Actual data page */
 };
 
@@ -417,6 +423,12 @@ int ring_buffer_print_page_header(struct trace_seq *s)
                               (unsigned int)sizeof(field.commit),
                               (unsigned int)is_signed_type(long));
 
+       ret = trace_seq_printf(s, "\tfield: int overwrite;\t"
+                              "offset:%u;\tsize:%u;\tsigned:%u;\n",
+                              (unsigned int)offsetof(typeof(field), commit),
+                              1,
+                              (unsigned int)is_signed_type(long));
+
        ret = trace_seq_printf(s, "\tfield: char data;\t"
                               "offset:%u;\tsize:%u;\tsigned:%u;\n",
                               (unsigned int)offsetof(typeof(field), data),
@@ -440,6 +452,8 @@ struct ring_buffer_per_cpu {
        struct buffer_page              *tail_page;     /* write to tail */
        struct buffer_page              *commit_page;   /* committed pages */
        struct buffer_page              *reader_page;
+       unsigned long                   lost_events;
+       unsigned long                   last_overrun;
        local_t                         commit_overrun;
        local_t                         overrun;
        local_t                         entries;
@@ -1761,6 +1775,13 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
        event = __rb_page_index(tail_page, tail);
        kmemcheck_annotate_bitfield(event, bitfield);
 
+       /*
+        * Save the original length to the meta data.
+        * This will be used by the reader to add lost event
+        * counter.
+        */
+       tail_page->real_end = tail;
+
        /*
         * If this event is bigger than the minimum size, then
         * we need to be careful that we don't subtract the
@@ -1979,17 +2000,13 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer,
                  u64 *ts, u64 *delta)
 {
        struct ring_buffer_event *event;
-       static int once;
        int ret;
 
-       if (unlikely(*delta > (1ULL << 59) && !once++)) {
-               printk(KERN_WARNING "Delta way too big! %llu"
-                      " ts=%llu write stamp = %llu\n",
-                      (unsigned long long)*delta,
-                      (unsigned long long)*ts,
-                      (unsigned long long)cpu_buffer->write_stamp);
-               WARN_ON(1);
-       }
+       WARN_ONCE(*delta > (1ULL << 59),
+                 KERN_WARNING "Delta way too big! %llu ts=%llu write stamp = %llu\n",
+                 (unsigned long long)*delta,
+                 (unsigned long long)*ts,
+                 (unsigned long long)cpu_buffer->write_stamp);
 
        /*
         * The delta is too big, we to add a
@@ -2838,6 +2855,7 @@ static struct buffer_page *
 rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
 {
        struct buffer_page *reader = NULL;
+       unsigned long overwrite;
        unsigned long flags;
        int nr_loops = 0;
        int ret;
@@ -2879,6 +2897,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        local_set(&cpu_buffer->reader_page->write, 0);
        local_set(&cpu_buffer->reader_page->entries, 0);
        local_set(&cpu_buffer->reader_page->page->commit, 0);
+       cpu_buffer->reader_page->real_end = 0;
 
  spin:
        /*
@@ -2898,6 +2917,18 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        /* The reader page will be pointing to the new head */
        rb_set_list_to_head(cpu_buffer, &cpu_buffer->reader_page->list);
 
+       /*
+        * We want to make sure we read the overruns after we set up our
+        * pointers to the next object. The writer side does a
+        * cmpxchg to cross pages which acts as the mb on the writer
+        * side. Note, the reader will constantly fail the swap
+        * while the writer is updating the pointers, so this
+        * guarantees that the overwrite recorded here is the one we
+        * want to compare with the last_overrun.
+        */
+       smp_mb();
+       overwrite = local_read(&(cpu_buffer->overrun));
+
        /*
         * Here's the tricky part.
         *
@@ -2929,6 +2960,11 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
        cpu_buffer->reader_page = reader;
        rb_reset_reader_page(cpu_buffer);
 
+       if (overwrite != cpu_buffer->last_overrun) {
+               cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun;
+               cpu_buffer->last_overrun = overwrite;
+       }
+
        goto again;
 
  out:
@@ -3005,8 +3041,14 @@ static void rb_advance_iter(struct ring_buffer_iter *iter)
                rb_advance_iter(iter);
 }
 
+static int rb_lost_events(struct ring_buffer_per_cpu *cpu_buffer)
+{
+       return cpu_buffer->lost_events;
+}
+
 static struct ring_buffer_event *
-rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
+rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts,
+              unsigned long *lost_events)
 {
        struct ring_buffer_event *event;
        struct buffer_page *reader;
@@ -3058,6 +3100,8 @@ rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
                        ring_buffer_normalize_time_stamp(cpu_buffer->buffer,
                                                         cpu_buffer->cpu, ts);
                }
+               if (lost_events)
+                       *lost_events = rb_lost_events(cpu_buffer);
                return event;
 
        default:
@@ -3168,12 +3212,14 @@ static inline int rb_ok_to_lock(void)
  * @buffer: The ring buffer to read
  * @cpu: The cpu to peak at
  * @ts: The timestamp counter of this event.
+ * @lost_events: a variable to store if events were lost (may be NULL)
  *
  * This will return the event that will be read next, but does
  * not consume the data.
  */
 struct ring_buffer_event *
-ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
+ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
+                unsigned long *lost_events)
 {
        struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
        struct ring_buffer_event *event;
@@ -3188,7 +3234,7 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
        local_irq_save(flags);
        if (dolock)
                spin_lock(&cpu_buffer->reader_lock);
-       event = rb_buffer_peek(cpu_buffer, ts);
+       event = rb_buffer_peek(cpu_buffer, ts, lost_events);
        if (event && event->type_len == RINGBUF_TYPE_PADDING)
                rb_advance_reader(cpu_buffer);
        if (dolock)
@@ -3230,13 +3276,17 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
 /**
  * ring_buffer_consume - return an event and consume it
  * @buffer: The ring buffer to get the next event from
+ * @cpu: the cpu to read the buffer from
+ * @ts: a variable to store the timestamp (may be NULL)
+ * @lost_events: a variable to store if events were lost (may be NULL)
  *
  * Returns the next event in the ring buffer, and that event is consumed.
  * Meaning, that sequential reads will keep returning a different event,
  * and eventually empty the ring buffer if the producer is slower.
  */
 struct ring_buffer_event *
-ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
+                   unsigned long *lost_events)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event = NULL;
@@ -3257,9 +3307,11 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
        if (dolock)
                spin_lock(&cpu_buffer->reader_lock);
 
-       event = rb_buffer_peek(cpu_buffer, ts);
-       if (event)
+       event = rb_buffer_peek(cpu_buffer, ts, lost_events);
+       if (event) {
+               cpu_buffer->lost_events = 0;
                rb_advance_reader(cpu_buffer);
+       }
 
        if (dolock)
                spin_unlock(&cpu_buffer->reader_lock);
@@ -3276,23 +3328,30 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
 EXPORT_SYMBOL_GPL(ring_buffer_consume);
 
 /**
- * ring_buffer_read_start - start a non consuming read of the buffer
+ * ring_buffer_read_prepare - Prepare for a non consuming read of the buffer
  * @buffer: The ring buffer to read from
  * @cpu: The cpu buffer to iterate over
  *
- * This starts up an iteration through the buffer. It also disables
- * the recording to the buffer until the reading is finished.
- * This prevents the reading from being corrupted. This is not
- * a consuming read, so a producer is not expected.
+ * This performs the initial preparations necessary to iterate
+ * through the buffer.  Memory is allocated, buffer recording
+ * is disabled, and the iterator pointer is returned to the caller.
  *
- * Must be paired with ring_buffer_finish.
+ * Disabling buffer recordng prevents the reading from being
+ * corrupted. This is not a consuming read, so a producer is not
+ * expected.
+ *
+ * After a sequence of ring_buffer_read_prepare calls, the user is
+ * expected to make at least one call to ring_buffer_prepare_sync.
+ * Afterwards, ring_buffer_read_start is invoked to get things going
+ * for real.
+ *
+ * This overall must be paired with ring_buffer_finish.
  */
 struct ring_buffer_iter *
-ring_buffer_read_start(struct ring_buffer *buffer, int cpu)
+ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_iter *iter;
-       unsigned long flags;
 
        if (!cpumask_test_cpu(cpu, buffer->cpumask))
                return NULL;
@@ -3306,15 +3365,52 @@ ring_buffer_read_start(struct ring_buffer *buffer, int cpu)
        iter->cpu_buffer = cpu_buffer;
 
        atomic_inc(&cpu_buffer->record_disabled);
+
+       return iter;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_read_prepare);
+
+/**
+ * ring_buffer_read_prepare_sync - Synchronize a set of prepare calls
+ *
+ * All previously invoked ring_buffer_read_prepare calls to prepare
+ * iterators will be synchronized.  Afterwards, read_buffer_read_start
+ * calls on those iterators are allowed.
+ */
+void
+ring_buffer_read_prepare_sync(void)
+{
        synchronize_sched();
+}
+EXPORT_SYMBOL_GPL(ring_buffer_read_prepare_sync);
+
+/**
+ * ring_buffer_read_start - start a non consuming read of the buffer
+ * @iter: The iterator returned by ring_buffer_read_prepare
+ *
+ * This finalizes the startup of an iteration through the buffer.
+ * The iterator comes from a call to ring_buffer_read_prepare and
+ * an intervening ring_buffer_read_prepare_sync must have been
+ * performed.
+ *
+ * Must be paired with ring_buffer_finish.
+ */
+void
+ring_buffer_read_start(struct ring_buffer_iter *iter)
+{
+       struct ring_buffer_per_cpu *cpu_buffer;
+       unsigned long flags;
+
+       if (!iter)
+               return;
+
+       cpu_buffer = iter->cpu_buffer;
 
        spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
        arch_spin_lock(&cpu_buffer->lock);
        rb_iter_reset(iter);
        arch_spin_unlock(&cpu_buffer->lock);
        spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
-
-       return iter;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_read_start);
 
@@ -3408,6 +3504,9 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
        cpu_buffer->write_stamp = 0;
        cpu_buffer->read_stamp = 0;
 
+       cpu_buffer->lost_events = 0;
+       cpu_buffer->last_overrun = 0;
+
        rb_head_page_activate(cpu_buffer);
 }
 
@@ -3683,6 +3782,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
        struct ring_buffer_event *event;
        struct buffer_data_page *bpage;
        struct buffer_page *reader;
+       unsigned long missed_events;
        unsigned long flags;
        unsigned int commit;
        unsigned int read;
@@ -3719,6 +3819,9 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
        read = reader->read;
        commit = rb_page_commit(reader);
 
+       /* Check if any events were dropped */
+       missed_events = cpu_buffer->lost_events;
+
        /*
         * If this page has been partially read or
         * if len is not big enough to read the rest of the page or
@@ -3779,9 +3882,35 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
                local_set(&reader->entries, 0);
                reader->read = 0;
                *data_page = bpage;
+
+               /*
+                * Use the real_end for the data size,
+                * This gives us a chance to store the lost events
+                * on the page.
+                */
+               if (reader->real_end)
+                       local_set(&bpage->commit, reader->real_end);
        }
        ret = read;
 
+       cpu_buffer->lost_events = 0;
+       /*
+        * Set a flag in the commit field if we lost events
+        */
+       if (missed_events) {
+               commit = local_read(&bpage->commit);
+
+               /* If there is room at the end of the page to save the
+                * missed events, then record it there.
+                */
+               if (BUF_PAGE_SIZE - commit >= sizeof(missed_events)) {
+                       memcpy(&bpage->data[commit], &missed_events,
+                              sizeof(missed_events));
+                       local_add(RB_MISSED_STORED, &bpage->commit);
+               }
+               local_add(RB_MISSED_EVENTS, &bpage->commit);
+       }
+
  out_unlock:
        spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
index df74c79..302f8a6 100644 (file)
@@ -81,7 +81,7 @@ static enum event_status read_event(int cpu)
        int *entry;
        u64 ts;
 
-       event = ring_buffer_consume(buffer, cpu, &ts);
+       event = ring_buffer_consume(buffer, cpu, &ts, NULL);
        if (!event)
                return EVENT_DROPPED;
 
@@ -113,7 +113,8 @@ static enum event_status read_page(int cpu)
        ret = ring_buffer_read_page(buffer, &bpage, PAGE_SIZE, cpu, 1);
        if (ret >= 0) {
                rpage = bpage;
-               commit = local_read(&rpage->commit);
+               /* The commit may have missed event flags set, clear them */
+               commit = local_read(&rpage->commit) & 0xfffff;
                for (i = 0; i < commit && !kill_test; i += inc) {
 
                        if (i >= (PAGE_SIZE - offsetof(struct rb_page, data))) {
index 44f916a..756d728 100644 (file)
@@ -117,9 +117,12 @@ static cpumask_var_t __read_mostly tracing_buffer_mask;
  *
  * It is default off, but you can enable it with either specifying
  * "ftrace_dump_on_oops" in the kernel command line, or setting
- * /proc/sys/kernel/ftrace_dump_on_oops to true.
+ * /proc/sys/kernel/ftrace_dump_on_oops
+ * Set 1 if you want to dump buffers of all CPUs
+ * Set 2 if you want to dump the buffer of the CPU that triggered oops
  */
-int ftrace_dump_on_oops;
+
+enum ftrace_dump_mode ftrace_dump_on_oops;
 
 static int tracing_set_tracer(const char *buf);
 
@@ -139,8 +142,17 @@ __setup("ftrace=", set_cmdline_ftrace);
 
 static int __init set_ftrace_dump_on_oops(char *str)
 {
-       ftrace_dump_on_oops = 1;
-       return 1;
+       if (*str++ != '=' || !*str) {
+               ftrace_dump_on_oops = DUMP_ALL;
+               return 1;
+       }
+
+       if (!strcmp("orig_cpu", str)) {
+               ftrace_dump_on_oops = DUMP_ORIG;
+                return 1;
+        }
+
+        return 0;
 }
 __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
 
@@ -1545,7 +1557,8 @@ static void trace_iterator_increment(struct trace_iterator *iter)
 }
 
 static struct trace_entry *
-peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
+peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
+               unsigned long *lost_events)
 {
        struct ring_buffer_event *event;
        struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu];
@@ -1556,7 +1569,8 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
        if (buf_iter)
                event = ring_buffer_iter_peek(buf_iter, ts);
        else
-               event = ring_buffer_peek(iter->tr->buffer, cpu, ts);
+               event = ring_buffer_peek(iter->tr->buffer, cpu, ts,
+                                        lost_events);
 
        ftrace_enable_cpu();
 
@@ -1564,10 +1578,12 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
 }
 
 static struct trace_entry *
-__find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
+__find_next_entry(struct trace_iterator *iter, int *ent_cpu,
+                 unsigned long *missing_events, u64 *ent_ts)
 {
        struct ring_buffer *buffer = iter->tr->buffer;
        struct trace_entry *ent, *next = NULL;
+       unsigned long lost_events = 0, next_lost = 0;
        int cpu_file = iter->cpu_file;
        u64 next_ts = 0, ts;
        int next_cpu = -1;
@@ -1580,7 +1596,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
        if (cpu_file > TRACE_PIPE_ALL_CPU) {
                if (ring_buffer_empty_cpu(buffer, cpu_file))
                        return NULL;
-               ent = peek_next_entry(iter, cpu_file, ent_ts);
+               ent = peek_next_entry(iter, cpu_file, ent_ts, missing_events);
                if (ent_cpu)
                        *ent_cpu = cpu_file;
 
@@ -1592,7 +1608,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
                if (ring_buffer_empty_cpu(buffer, cpu))
                        continue;
 
-               ent = peek_next_entry(iter, cpu, &ts);
+               ent = peek_next_entry(iter, cpu, &ts, &lost_events);
 
                /*
                 * Pick the entry with the smallest timestamp:
@@ -1601,6 +1617,7 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
                        next = ent;
                        next_cpu = cpu;
                        next_ts = ts;
+                       next_lost = lost_events;
                }
        }
 
@@ -1610,6 +1627,9 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
        if (ent_ts)
                *ent_ts = next_ts;
 
+       if (missing_events)
+               *missing_events = next_lost;
+
        return next;
 }
 
@@ -1617,13 +1637,14 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
 struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
                                          int *ent_cpu, u64 *ent_ts)
 {
-       return __find_next_entry(iter, ent_cpu, ent_ts);
+       return __find_next_entry(iter, ent_cpu, NULL, ent_ts);
 }
 
 /* Find the next real entry, and increment the iterator to the next entry */
 static void *find_next_entry_inc(struct trace_iterator *iter)
 {
-       iter->ent = __find_next_entry(iter, &iter->cpu, &iter->ts);
+       iter->ent = __find_next_entry(iter, &iter->cpu,
+                                     &iter->lost_events, &iter->ts);
 
        if (iter->ent)
                trace_iterator_increment(iter);
@@ -1635,7 +1656,8 @@ static void trace_consume(struct trace_iterator *iter)
 {
        /* Don't allow ftrace to trace into the ring buffers */
        ftrace_disable_cpu();
-       ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts);
+       ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts,
+                           &iter->lost_events);
        ftrace_enable_cpu();
 }
 
@@ -1786,7 +1808,7 @@ static void print_func_help_header(struct seq_file *m)
 }
 
 
-static void
+void
 print_trace_header(struct seq_file *m, struct trace_iterator *iter)
 {
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
@@ -1995,7 +2017,7 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
        return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
 }
 
-static int trace_empty(struct trace_iterator *iter)
+int trace_empty(struct trace_iterator *iter)
 {
        int cpu;
 
@@ -2030,6 +2052,10 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
 {
        enum print_line_t ret;
 
+       if (iter->lost_events)
+               trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n",
+                                iter->cpu, iter->lost_events);
+
        if (iter->trace && iter->trace->print_line) {
                ret = iter->trace->print_line(iter);
                if (ret != TRACE_TYPE_UNHANDLED)
@@ -2058,6 +2084,23 @@ static enum print_line_t print_trace_line(struct trace_iterator *iter)
        return print_trace_fmt(iter);
 }
 
+void trace_default_header(struct seq_file *m)
+{
+       struct trace_iterator *iter = m->private;
+
+       if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
+               /* print nothing if the buffers are empty */
+               if (trace_empty(iter))
+                       return;
+               print_trace_header(m, iter);
+               if (!(trace_flags & TRACE_ITER_VERBOSE))
+                       print_lat_help_header(m);
+       } else {
+               if (!(trace_flags & TRACE_ITER_VERBOSE))
+                       print_func_help_header(m);
+       }
+}
+
 static int s_show(struct seq_file *m, void *v)
 {
        struct trace_iterator *iter = v;
@@ -2070,17 +2113,9 @@ static int s_show(struct seq_file *m, void *v)
                }
                if (iter->trace && iter->trace->print_header)
                        iter->trace->print_header(m);
-               else if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
-                       /* print nothing if the buffers are empty */
-                       if (trace_empty(iter))
-                               return 0;
-                       print_trace_header(m, iter);
-                       if (!(trace_flags & TRACE_ITER_VERBOSE))
-                               print_lat_help_header(m);
-               } else {
-                       if (!(trace_flags & TRACE_ITER_VERBOSE))
-                               print_func_help_header(m);
-               }
+               else
+                       trace_default_header(m);
+
        } else if (iter->leftover) {
                /*
                 * If we filled the seq_file buffer earlier, we
@@ -2166,15 +2201,20 @@ __tracing_open(struct inode *inode, struct file *file)
 
        if (iter->cpu_file == TRACE_PIPE_ALL_CPU) {
                for_each_tracing_cpu(cpu) {
-
                        iter->buffer_iter[cpu] =
-                               ring_buffer_read_start(iter->tr->buffer, cpu);
+                               ring_buffer_read_prepare(iter->tr->buffer, cpu);
+               }
+               ring_buffer_read_prepare_sync();
+               for_each_tracing_cpu(cpu) {
+                       ring_buffer_read_start(iter->buffer_iter[cpu]);
                        tracing_iter_reset(iter, cpu);
                }
        } else {
                cpu = iter->cpu_file;
                iter->buffer_iter[cpu] =
-                               ring_buffer_read_start(iter->tr->buffer, cpu);
+                       ring_buffer_read_prepare(iter->tr->buffer, cpu);
+               ring_buffer_read_prepare_sync();
+               ring_buffer_read_start(iter->buffer_iter[cpu]);
                tracing_iter_reset(iter, cpu);
        }
 
@@ -4324,7 +4364,7 @@ static int trace_panic_handler(struct notifier_block *this,
                               unsigned long event, void *unused)
 {
        if (ftrace_dump_on_oops)
-               ftrace_dump();
+               ftrace_dump(ftrace_dump_on_oops);
        return NOTIFY_OK;
 }
 
@@ -4341,7 +4381,7 @@ static int trace_die_handler(struct notifier_block *self,
        switch (val) {
        case DIE_OOPS:
                if (ftrace_dump_on_oops)
-                       ftrace_dump();
+                       ftrace_dump(ftrace_dump_on_oops);
                break;
        default:
                break;
@@ -4382,7 +4422,8 @@ trace_printk_seq(struct trace_seq *s)
        trace_seq_init(s);
 }
 
-static void __ftrace_dump(bool disable_tracing)
+static void
+__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode)
 {
        static arch_spinlock_t ftrace_dump_lock =
                (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
@@ -4415,12 +4456,25 @@ static void __ftrace_dump(bool disable_tracing)
        /* don't look at user memory in panic mode */
        trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
 
-       printk(KERN_TRACE "Dumping ftrace buffer:\n");
-
        /* Simulate the iterator */
        iter.tr = &global_trace;
        iter.trace = current_trace;
-       iter.cpu_file = TRACE_PIPE_ALL_CPU;
+
+       switch (oops_dump_mode) {
+       case DUMP_ALL:
+               iter.cpu_file = TRACE_PIPE_ALL_CPU;
+               break;
+       case DUMP_ORIG:
+               iter.cpu_file = raw_smp_processor_id();
+               break;
+       case DUMP_NONE:
+               goto out_enable;
+       default:
+               printk(KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n");
+               iter.cpu_file = TRACE_PIPE_ALL_CPU;
+       }
+
+       printk(KERN_TRACE "Dumping ftrace buffer:\n");
 
        /*
         * We need to stop all tracing on all CPUS to read the
@@ -4459,6 +4513,7 @@ static void __ftrace_dump(bool disable_tracing)
        else
                printk(KERN_TRACE "---------------------------------\n");
 
+ out_enable:
        /* Re-enable tracing if requested */
        if (!disable_tracing) {
                trace_flags |= old_userobj;
@@ -4475,9 +4530,9 @@ static void __ftrace_dump(bool disable_tracing)
 }
 
 /* By default: disable tracing after the dump */
-void ftrace_dump(void)
+void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
 {
-       __ftrace_dump(true);
+       __ftrace_dump(true, oops_dump_mode);
 }
 
 __init static int tracer_alloc_buffers(void)
index 2825ef2..d1ce0be 100644 (file)
@@ -34,7 +34,6 @@ enum trace_type {
        TRACE_GRAPH_RET,
        TRACE_GRAPH_ENT,
        TRACE_USER_STACK,
-       TRACE_HW_BRANCHES,
        TRACE_KMEM_ALLOC,
        TRACE_KMEM_FREE,
        TRACE_BLK,
@@ -103,29 +102,17 @@ struct syscall_trace_exit {
        long                    ret;
 };
 
-struct kprobe_trace_entry {
+struct kprobe_trace_entry_head {
        struct trace_entry      ent;
        unsigned long           ip;
-       int                     nargs;
-       unsigned long           args[];
 };
 
-#define SIZEOF_KPROBE_TRACE_ENTRY(n)                   \
-       (offsetof(struct kprobe_trace_entry, args) +    \
-       (sizeof(unsigned long) * (n)))
-
-struct kretprobe_trace_entry {
+struct kretprobe_trace_entry_head {
        struct trace_entry      ent;
        unsigned long           func;
        unsigned long           ret_ip;
-       int                     nargs;
-       unsigned long           args[];
 };
 
-#define SIZEOF_KRETPROBE_TRACE_ENTRY(n)                        \
-       (offsetof(struct kretprobe_trace_entry, args) + \
-       (sizeof(unsigned long) * (n)))
-
 /*
  * trace_flag_type is an enumeration that holds different
  * states when a trace occurs. These are:
@@ -229,7 +216,6 @@ extern void __ftrace_bad_type(void);
                          TRACE_GRAPH_ENT);             \
                IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,      \
                          TRACE_GRAPH_RET);             \
-               IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
                IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry,       \
                          TRACE_KMEM_ALLOC);    \
                IF_ASSIGN(var, ent, struct kmemtrace_free_entry,        \
@@ -378,6 +364,9 @@ void trace_function(struct trace_array *tr,
                    unsigned long ip,
                    unsigned long parent_ip,
                    unsigned long flags, int pc);
+void trace_default_header(struct seq_file *m);
+void print_trace_header(struct seq_file *m, struct trace_iterator *iter);
+int trace_empty(struct trace_iterator *iter);
 
 void trace_graph_return(struct ftrace_graph_ret *trace);
 int trace_graph_entry(struct ftrace_graph_ent *trace);
@@ -467,8 +456,6 @@ extern int trace_selftest_startup_sysprof(struct tracer *trace,
                                               struct trace_array *tr);
 extern int trace_selftest_startup_branch(struct tracer *trace,
                                         struct trace_array *tr);
-extern int trace_selftest_startup_hw_branches(struct tracer *trace,
-                                             struct trace_array *tr);
 extern int trace_selftest_startup_ksym(struct tracer *trace,
                                         struct trace_array *tr);
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
@@ -491,9 +478,29 @@ extern int trace_clock_id;
 
 /* Standard output formatting function used for function return traces */
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-extern enum print_line_t print_graph_function(struct trace_iterator *iter);
+
+/* Flag options */
+#define TRACE_GRAPH_PRINT_OVERRUN       0x1
+#define TRACE_GRAPH_PRINT_CPU           0x2
+#define TRACE_GRAPH_PRINT_OVERHEAD      0x4
+#define TRACE_GRAPH_PRINT_PROC          0x8
+#define TRACE_GRAPH_PRINT_DURATION      0x10
+#define TRACE_GRAPH_PRINT_ABS_TIME      0x20
+
+extern enum print_line_t
+print_graph_function_flags(struct trace_iterator *iter, u32 flags);
+extern void print_graph_headers_flags(struct seq_file *s, u32 flags);
 extern enum print_line_t
 trace_print_graph_duration(unsigned long long duration, struct trace_seq *s);
+extern void graph_trace_open(struct trace_iterator *iter);
+extern void graph_trace_close(struct trace_iterator *iter);
+extern int __trace_graph_entry(struct trace_array *tr,
+                              struct ftrace_graph_ent *trace,
+                              unsigned long flags, int pc);
+extern void __trace_graph_return(struct trace_array *tr,
+                                struct ftrace_graph_ret *trace,
+                                unsigned long flags, int pc);
+
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 /* TODO: make this variable */
@@ -524,7 +531,7 @@ static inline int ftrace_graph_addr(unsigned long addr)
 #endif /* CONFIG_DYNAMIC_FTRACE */
 #else /* CONFIG_FUNCTION_GRAPH_TRACER */
 static inline enum print_line_t
-print_graph_function(struct trace_iterator *iter)
+print_graph_function_flags(struct trace_iterator *iter, u32 flags)
 {
        return TRACE_TYPE_UNHANDLED;
 }
index c16a08f..dc008c1 100644 (file)
@@ -318,18 +318,6 @@ FTRACE_ENTRY(branch, trace_branch,
                 __entry->func, __entry->file, __entry->correct)
 );
 
-FTRACE_ENTRY(hw_branch, hw_branch_entry,
-
-       TRACE_HW_BRANCHES,
-
-       F_STRUCT(
-               __field(        u64,    from    )
-               __field(        u64,    to      )
-       ),
-
-       F_printk("from: %llx to: %llx", __entry->from, __entry->to)
-);
-
 FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry,
 
        TRACE_KMEM_ALLOC,
index 88c0b6d..58092d8 100644 (file)
@@ -1398,7 +1398,7 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
        }
 
        err = -EINVAL;
-       if (!call)
+       if (&call->list == &ftrace_events)
                goto out_unlock;
 
        err = -EEXIST;
index 9aed1a5..dd11c83 100644 (file)
@@ -40,7 +40,7 @@ struct fgraph_data {
 #define TRACE_GRAPH_PRINT_OVERHEAD     0x4
 #define TRACE_GRAPH_PRINT_PROC         0x8
 #define TRACE_GRAPH_PRINT_DURATION     0x10
-#define TRACE_GRAPH_PRINT_ABS_TIME     0X20
+#define TRACE_GRAPH_PRINT_ABS_TIME     0x20
 
 static struct tracer_opt trace_opts[] = {
        /* Display overruns? (for self-debug purpose) */
@@ -179,7 +179,7 @@ unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
        return ret;
 }
 
-static int __trace_graph_entry(struct trace_array *tr,
+int __trace_graph_entry(struct trace_array *tr,
                                struct ftrace_graph_ent *trace,
                                unsigned long flags,
                                int pc)
@@ -246,7 +246,7 @@ int trace_graph_thresh_entry(struct ftrace_graph_ent *trace)
                return trace_graph_entry(trace);
 }
 
-static void __trace_graph_return(struct trace_array *tr,
+void __trace_graph_return(struct trace_array *tr,
                                struct ftrace_graph_ret *trace,
                                unsigned long flags,
                                int pc)
@@ -490,9 +490,10 @@ get_return_for_leaf(struct trace_iterator *iter,
                         * We need to consume the current entry to see
                         * the next one.
                         */
-                       ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
+                       ring_buffer_consume(iter->tr->buffer, iter->cpu,
+                                           NULL, NULL);
                        event = ring_buffer_peek(iter->tr->buffer, iter->cpu,
-                                                NULL);
+                                                NULL, NULL);
                }
 
                if (!event)
@@ -526,17 +527,18 @@ get_return_for_leaf(struct trace_iterator *iter,
 
 /* Signal a overhead of time execution to the output */
 static int
-print_graph_overhead(unsigned long long duration, struct trace_seq *s)
+print_graph_overhead(unsigned long long duration, struct trace_seq *s,
+                    u32 flags)
 {
        /* If duration disappear, we don't need anything */
-       if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION))
+       if (!(flags & TRACE_GRAPH_PRINT_DURATION))
                return 1;
 
        /* Non nested entry or return */
        if (duration == -1)
                return trace_seq_printf(s, "  ");
 
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
+       if (flags & TRACE_GRAPH_PRINT_OVERHEAD) {
                /* Duration exceeded 100 msecs */
                if (duration > 100000ULL)
                        return trace_seq_printf(s, "! ");
@@ -562,7 +564,7 @@ static int print_graph_abs_time(u64 t, struct trace_seq *s)
 
 static enum print_line_t
 print_graph_irq(struct trace_iterator *iter, unsigned long addr,
-               enum trace_type type, int cpu, pid_t pid)
+               enum trace_type type, int cpu, pid_t pid, u32 flags)
 {
        int ret;
        struct trace_seq *s = &iter->seq;
@@ -572,21 +574,21 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
                return TRACE_TYPE_UNHANDLED;
 
        /* Absolute time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
                ret = print_graph_abs_time(iter->ts, s);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Cpu */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
+       if (flags & TRACE_GRAPH_PRINT_CPU) {
                ret = print_graph_cpu(s, cpu);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Proc */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
+       if (flags & TRACE_GRAPH_PRINT_PROC) {
                ret = print_graph_proc(s, pid);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -596,7 +598,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
        }
 
        /* No overhead */
-       ret = print_graph_overhead(-1, s);
+       ret = print_graph_overhead(-1, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
@@ -609,7 +611,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Don't close the duration column if haven't one */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+       if (flags & TRACE_GRAPH_PRINT_DURATION)
                trace_seq_printf(s, " |");
        ret = trace_seq_printf(s, "\n");
 
@@ -679,7 +681,8 @@ print_graph_duration(unsigned long long duration, struct trace_seq *s)
 static enum print_line_t
 print_graph_entry_leaf(struct trace_iterator *iter,
                struct ftrace_graph_ent_entry *entry,
-               struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s)
+               struct ftrace_graph_ret_entry *ret_entry,
+               struct trace_seq *s, u32 flags)
 {
        struct fgraph_data *data = iter->private;
        struct ftrace_graph_ret *graph_ret;
@@ -711,12 +714,12 @@ print_graph_entry_leaf(struct trace_iterator *iter,
        }
 
        /* Overhead */
-       ret = print_graph_overhead(duration, s);
+       ret = print_graph_overhead(duration, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Duration */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = print_graph_duration(duration, s);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -739,7 +742,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
 static enum print_line_t
 print_graph_entry_nested(struct trace_iterator *iter,
                         struct ftrace_graph_ent_entry *entry,
-                        struct trace_seq *s, int cpu)
+                        struct trace_seq *s, int cpu, u32 flags)
 {
        struct ftrace_graph_ent *call = &entry->graph_ent;
        struct fgraph_data *data = iter->private;
@@ -759,12 +762,12 @@ print_graph_entry_nested(struct trace_iterator *iter,
        }
 
        /* No overhead */
-       ret = print_graph_overhead(-1, s);
+       ret = print_graph_overhead(-1, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* No time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = trace_seq_printf(s, "            |  ");
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -790,7 +793,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
 
 static enum print_line_t
 print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
-                    int type, unsigned long addr)
+                    int type, unsigned long addr, u32 flags)
 {
        struct fgraph_data *data = iter->private;
        struct trace_entry *ent = iter->ent;
@@ -803,27 +806,27 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
 
        if (type) {
                /* Interrupt */
-               ret = print_graph_irq(iter, addr, type, cpu, ent->pid);
+               ret = print_graph_irq(iter, addr, type, cpu, ent->pid, flags);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Absolute time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME) {
                ret = print_graph_abs_time(iter->ts, s);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Cpu */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
+       if (flags & TRACE_GRAPH_PRINT_CPU) {
                ret = print_graph_cpu(s, cpu);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
        /* Proc */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
+       if (flags & TRACE_GRAPH_PRINT_PROC) {
                ret = print_graph_proc(s, ent->pid);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -845,7 +848,7 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
 
 static enum print_line_t
 print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
-                       struct trace_iterator *iter)
+                       struct trace_iterator *iter, u32 flags)
 {
        struct fgraph_data *data = iter->private;
        struct ftrace_graph_ent *call = &field->graph_ent;
@@ -853,14 +856,14 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
        static enum print_line_t ret;
        int cpu = iter->cpu;
 
-       if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func))
+       if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags))
                return TRACE_TYPE_PARTIAL_LINE;
 
        leaf_ret = get_return_for_leaf(iter, field);
        if (leaf_ret)
-               ret = print_graph_entry_leaf(iter, field, leaf_ret, s);
+               ret = print_graph_entry_leaf(iter, field, leaf_ret, s, flags);
        else
-               ret = print_graph_entry_nested(iter, field, s, cpu);
+               ret = print_graph_entry_nested(iter, field, s, cpu, flags);
 
        if (data) {
                /*
@@ -879,7 +882,8 @@ print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
 
 static enum print_line_t
 print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
-                  struct trace_entry *ent, struct trace_iterator *iter)
+                  struct trace_entry *ent, struct trace_iterator *iter,
+                  u32 flags)
 {
        unsigned long long duration = trace->rettime - trace->calltime;
        struct fgraph_data *data = iter->private;
@@ -909,16 +913,16 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
                }
        }
 
-       if (print_graph_prologue(iter, s, 0, 0))
+       if (print_graph_prologue(iter, s, 0, 0, flags))
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Overhead */
-       ret = print_graph_overhead(duration, s);
+       ret = print_graph_overhead(duration, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* Duration */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = print_graph_duration(duration, s);
                if (ret == TRACE_TYPE_PARTIAL_LINE)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -948,14 +952,15 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
        }
 
        /* Overrun */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERRUN) {
+       if (flags & TRACE_GRAPH_PRINT_OVERRUN) {
                ret = trace_seq_printf(s, " (Overruns: %lu)\n",
                                        trace->overrun);
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
        }
 
-       ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, cpu, pid);
+       ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET,
+                             cpu, pid, flags);
        if (ret == TRACE_TYPE_PARTIAL_LINE)
                return TRACE_TYPE_PARTIAL_LINE;
 
@@ -963,8 +968,8 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
 }
 
 static enum print_line_t
-print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
-                   struct trace_iterator *iter)
+print_graph_comment(struct trace_seq *s, struct trace_entry *ent,
+                   struct trace_iterator *iter, u32 flags)
 {
        unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
        struct fgraph_data *data = iter->private;
@@ -976,16 +981,16 @@ print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
        if (data)
                depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth;
 
-       if (print_graph_prologue(iter, s, 0, 0))
+       if (print_graph_prologue(iter, s, 0, 0, flags))
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* No overhead */
-       ret = print_graph_overhead(-1, s);
+       ret = print_graph_overhead(-1, s, flags);
        if (!ret)
                return TRACE_TYPE_PARTIAL_LINE;
 
        /* No time */
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+       if (flags & TRACE_GRAPH_PRINT_DURATION) {
                ret = trace_seq_printf(s, "            |  ");
                if (!ret)
                        return TRACE_TYPE_PARTIAL_LINE;
@@ -1040,7 +1045,7 @@ print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
 
 
 enum print_line_t
-print_graph_function(struct trace_iterator *iter)
+print_graph_function_flags(struct trace_iterator *iter, u32 flags)
 {
        struct ftrace_graph_ent_entry *field;
        struct fgraph_data *data = iter->private;
@@ -1061,7 +1066,7 @@ print_graph_function(struct trace_iterator *iter)
        if (data && data->failed) {
                field = &data->ent;
                iter->cpu = data->cpu;
-               ret = print_graph_entry(field, s, iter);
+               ret = print_graph_entry(field, s, iter, flags);
                if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) {
                        per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1;
                        ret = TRACE_TYPE_NO_CONSUME;
@@ -1081,32 +1086,49 @@ print_graph_function(struct trace_iterator *iter)
                struct ftrace_graph_ent_entry saved;
                trace_assign_type(field, entry);
                saved = *field;
-               return print_graph_entry(&saved, s, iter);
+               return print_graph_entry(&saved, s, iter, flags);
        }
        case TRACE_GRAPH_RET: {
                struct ftrace_graph_ret_entry *field;
                trace_assign_type(field, entry);
-               return print_graph_return(&field->ret, s, entry, iter);
+               return print_graph_return(&field->ret, s, entry, iter, flags);
        }
+       case TRACE_STACK:
+       case TRACE_FN:
+               /* dont trace stack and functions as comments */
+               return TRACE_TYPE_UNHANDLED;
+
        default:
-               return print_graph_comment(s, entry, iter);
+               return print_graph_comment(s, entry, iter, flags);
        }
 
        return TRACE_TYPE_HANDLED;
 }
 
-static void print_lat_header(struct seq_file *s)
+static enum print_line_t
+print_graph_function(struct trace_iterator *iter)
+{
+       return print_graph_function_flags(iter, tracer_flags.val);
+}
+
+static enum print_line_t
+print_graph_function_event(struct trace_iterator *iter, int flags)
+{
+       return print_graph_function(iter);
+}
+
+static void print_lat_header(struct seq_file *s, u32 flags)
 {
        static const char spaces[] = "                " /* 16 spaces */
                "    "                                  /* 4 spaces */
                "                 ";                    /* 17 spaces */
        int size = 0;
 
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
                size += 16;
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+       if (flags & TRACE_GRAPH_PRINT_CPU)
                size += 4;
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+       if (flags & TRACE_GRAPH_PRINT_PROC)
                size += 17;
 
        seq_printf(s, "#%.*s  _-----=> irqs-off        \n", size, spaces);
@@ -1117,43 +1139,48 @@ static void print_lat_header(struct seq_file *s)
        seq_printf(s, "#%.*s|||| /                     \n", size, spaces);
 }
 
-static void print_graph_headers(struct seq_file *s)
+void print_graph_headers_flags(struct seq_file *s, u32 flags)
 {
        int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
 
        if (lat)
-               print_lat_header(s);
+               print_lat_header(s, flags);
 
        /* 1st line */
        seq_printf(s, "#");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
                seq_printf(s, "     TIME       ");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+       if (flags & TRACE_GRAPH_PRINT_CPU)
                seq_printf(s, " CPU");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+       if (flags & TRACE_GRAPH_PRINT_PROC)
                seq_printf(s, "  TASK/PID       ");
        if (lat)
                seq_printf(s, "|||||");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+       if (flags & TRACE_GRAPH_PRINT_DURATION)
                seq_printf(s, "  DURATION   ");
        seq_printf(s, "               FUNCTION CALLS\n");
 
        /* 2nd line */
        seq_printf(s, "#");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+       if (flags & TRACE_GRAPH_PRINT_ABS_TIME)
                seq_printf(s, "      |         ");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+       if (flags & TRACE_GRAPH_PRINT_CPU)
                seq_printf(s, " |  ");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+       if (flags & TRACE_GRAPH_PRINT_PROC)
                seq_printf(s, "   |    |        ");
        if (lat)
                seq_printf(s, "|||||");
-       if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+       if (flags & TRACE_GRAPH_PRINT_DURATION)
                seq_printf(s, "   |   |      ");
        seq_printf(s, "               |   |   |   |\n");
 }
 
-static void graph_trace_open(struct trace_iterator *iter)
+void print_graph_headers(struct seq_file *s)
+{
+       print_graph_headers_flags(s, tracer_flags.val);
+}
+
+void graph_trace_open(struct trace_iterator *iter)
 {
        /* pid and depth on the last trace processed */
        struct fgraph_data *data;
@@ -1188,7 +1215,7 @@ static void graph_trace_open(struct trace_iterator *iter)
        pr_warning("function graph tracer: not enough memory\n");
 }
 
-static void graph_trace_close(struct trace_iterator *iter)
+void graph_trace_close(struct trace_iterator *iter)
 {
        struct fgraph_data *data = iter->private;
 
@@ -1198,6 +1225,16 @@ static void graph_trace_close(struct trace_iterator *iter)
        }
 }
 
+static struct trace_event graph_trace_entry_event = {
+       .type           = TRACE_GRAPH_ENT,
+       .trace          = print_graph_function_event,
+};
+
+static struct trace_event graph_trace_ret_event = {
+       .type           = TRACE_GRAPH_RET,
+       .trace          = print_graph_function_event,
+};
+
 static struct tracer graph_trace __read_mostly = {
        .name           = "function_graph",
        .open           = graph_trace_open,
@@ -1219,6 +1256,16 @@ static __init int init_graph_trace(void)
 {
        max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1);
 
+       if (!register_ftrace_event(&graph_trace_entry_event)) {
+               pr_warning("Warning: could not register graph trace events\n");
+               return 1;
+       }
+
+       if (!register_ftrace_event(&graph_trace_ret_event)) {
+               pr_warning("Warning: could not register graph trace events\n");
+               return 1;
+       }
+
        return register_tracer(&graph_trace);
 }
 
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
deleted file mode 100644 (file)
index 7b97000..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * h/w branch tracer for x86 based on BTS
- *
- * Copyright (C) 2008-2009 Intel Corporation.
- * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
- */
-#include <linux/kallsyms.h>
-#include <linux/debugfs.h>
-#include <linux/ftrace.h>
-#include <linux/module.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <linux/fs.h>
-
-#include <asm/ds.h>
-
-#include "trace_output.h"
-#include "trace.h"
-
-
-#define BTS_BUFFER_SIZE (1 << 13)
-
-static DEFINE_PER_CPU(struct bts_tracer *, hwb_tracer);
-static DEFINE_PER_CPU(unsigned char[BTS_BUFFER_SIZE], hwb_buffer);
-
-#define this_tracer per_cpu(hwb_tracer, smp_processor_id())
-
-static int trace_hw_branches_enabled __read_mostly;
-static int trace_hw_branches_suspended __read_mostly;
-static struct trace_array *hw_branch_trace __read_mostly;
-
-
-static void bts_trace_init_cpu(int cpu)
-{
-       per_cpu(hwb_tracer, cpu) =
-               ds_request_bts_cpu(cpu, per_cpu(hwb_buffer, cpu),
-                                  BTS_BUFFER_SIZE, NULL, (size_t)-1,
-                                  BTS_KERNEL);
-
-       if (IS_ERR(per_cpu(hwb_tracer, cpu)))
-               per_cpu(hwb_tracer, cpu) = NULL;
-}
-
-static int bts_trace_init(struct trace_array *tr)
-{
-       int cpu;
-
-       hw_branch_trace = tr;
-       trace_hw_branches_enabled = 0;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               bts_trace_init_cpu(cpu);
-
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       trace_hw_branches_enabled = 1;
-       }
-       trace_hw_branches_suspended = 0;
-       put_online_cpus();
-
-       /* If we could not enable tracing on a single cpu, we fail. */
-       return trace_hw_branches_enabled ? 0 : -EOPNOTSUPP;
-}
-
-static void bts_trace_reset(struct trace_array *tr)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               if (likely(per_cpu(hwb_tracer, cpu))) {
-                       ds_release_bts(per_cpu(hwb_tracer, cpu));
-                       per_cpu(hwb_tracer, cpu) = NULL;
-               }
-       }
-       trace_hw_branches_enabled = 0;
-       trace_hw_branches_suspended = 0;
-       put_online_cpus();
-}
-
-static void bts_trace_start(struct trace_array *tr)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_resume_bts(per_cpu(hwb_tracer, cpu));
-       trace_hw_branches_suspended = 0;
-       put_online_cpus();
-}
-
-static void bts_trace_stop(struct trace_array *tr)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_suspend_bts(per_cpu(hwb_tracer, cpu));
-       trace_hw_branches_suspended = 1;
-       put_online_cpus();
-}
-
-static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
-                                    unsigned long action, void *hcpu)
-{
-       int cpu = (long)hcpu;
-
-       switch (action) {
-       case CPU_ONLINE:
-       case CPU_DOWN_FAILED:
-               /* The notification is sent with interrupts enabled. */
-               if (trace_hw_branches_enabled) {
-                       bts_trace_init_cpu(cpu);
-
-                       if (trace_hw_branches_suspended &&
-                           likely(per_cpu(hwb_tracer, cpu)))
-                               ds_suspend_bts(per_cpu(hwb_tracer, cpu));
-               }
-               break;
-
-       case CPU_DOWN_PREPARE:
-               /* The notification is sent with interrupts enabled. */
-               if (likely(per_cpu(hwb_tracer, cpu))) {
-                       ds_release_bts(per_cpu(hwb_tracer, cpu));
-                       per_cpu(hwb_tracer, cpu) = NULL;
-               }
-       }
-
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block bts_hotcpu_notifier __cpuinitdata = {
-       .notifier_call = bts_hotcpu_handler
-};
-
-static void bts_trace_print_header(struct seq_file *m)
-{
-       seq_puts(m, "# CPU#        TO  <-  FROM\n");
-}
-
-static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
-{
-       unsigned long symflags = TRACE_ITER_SYM_OFFSET;
-       struct trace_entry *entry = iter->ent;
-       struct trace_seq *seq = &iter->seq;
-       struct hw_branch_entry *it;
-
-       trace_assign_type(it, entry);
-
-       if (entry->type == TRACE_HW_BRANCHES) {
-               if (trace_seq_printf(seq, "%4d  ", iter->cpu) &&
-                   seq_print_ip_sym(seq, it->to, symflags) &&
-                   trace_seq_printf(seq, "\t  <-  ") &&
-                   seq_print_ip_sym(seq, it->from, symflags) &&
-                   trace_seq_printf(seq, "\n"))
-                       return TRACE_TYPE_HANDLED;
-               return TRACE_TYPE_PARTIAL_LINE;
-       }
-       return TRACE_TYPE_UNHANDLED;
-}
-
-void trace_hw_branch(u64 from, u64 to)
-{
-       struct ftrace_event_call *call = &event_hw_branch;
-       struct trace_array *tr = hw_branch_trace;
-       struct ring_buffer_event *event;
-       struct ring_buffer *buf;
-       struct hw_branch_entry *entry;
-       unsigned long irq1;
-       int cpu;
-
-       if (unlikely(!tr))
-               return;
-
-       if (unlikely(!trace_hw_branches_enabled))
-               return;
-
-       local_irq_save(irq1);
-       cpu = raw_smp_processor_id();
-       if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
-               goto out;
-
-       buf = tr->buffer;
-       event = trace_buffer_lock_reserve(buf, TRACE_HW_BRANCHES,
-                                         sizeof(*entry), 0, 0);
-       if (!event)
-               goto out;
-       entry   = ring_buffer_event_data(event);
-       tracing_generic_entry_update(&entry->ent, 0, from);
-       entry->ent.type = TRACE_HW_BRANCHES;
-       entry->from = from;
-       entry->to   = to;
-       if (!filter_check_discard(call, entry, buf, event))
-               trace_buffer_unlock_commit(buf, event, 0, 0);
-
- out:
-       atomic_dec(&tr->data[cpu]->disabled);
-       local_irq_restore(irq1);
-}
-
-static void trace_bts_at(const struct bts_trace *trace, void *at)
-{
-       struct bts_struct bts;
-       int err = 0;
-
-       WARN_ON_ONCE(!trace->read);
-       if (!trace->read)
-               return;
-
-       err = trace->read(this_tracer, at, &bts);
-       if (err < 0)
-               return;
-
-       switch (bts.qualifier) {
-       case BTS_BRANCH:
-               trace_hw_branch(bts.variant.lbr.from, bts.variant.lbr.to);
-               break;
-       }
-}
-
-/*
- * Collect the trace on the current cpu and write it into the ftrace buffer.
- *
- * pre: tracing must be suspended on the current cpu
- */
-static void trace_bts_cpu(void *arg)
-{
-       struct trace_array *tr = (struct trace_array *)arg;
-       const struct bts_trace *trace;
-       unsigned char *at;
-
-       if (unlikely(!tr))
-               return;
-
-       if (unlikely(atomic_read(&tr->data[raw_smp_processor_id()]->disabled)))
-               return;
-
-       if (unlikely(!this_tracer))
-               return;
-
-       trace = ds_read_bts(this_tracer);
-       if (!trace)
-               return;
-
-       for (at = trace->ds.top; (void *)at < trace->ds.end;
-            at += trace->ds.size)
-               trace_bts_at(trace, at);
-
-       for (at = trace->ds.begin; (void *)at < trace->ds.top;
-            at += trace->ds.size)
-               trace_bts_at(trace, at);
-}
-
-static void trace_bts_prepare(struct trace_iterator *iter)
-{
-       int cpu;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_suspend_bts(per_cpu(hwb_tracer, cpu));
-       /*
-        * We need to collect the trace on the respective cpu since ftrace
-        * implicitly adds the record for the current cpu.
-        * Once that is more flexible, we could collect the data from any cpu.
-        */
-       on_each_cpu(trace_bts_cpu, iter->tr, 1);
-
-       for_each_online_cpu(cpu)
-               if (likely(per_cpu(hwb_tracer, cpu)))
-                       ds_resume_bts(per_cpu(hwb_tracer, cpu));
-       put_online_cpus();
-}
-
-static void trace_bts_close(struct trace_iterator *iter)
-{
-       tracing_reset_online_cpus(iter->tr);
-}
-
-void trace_hw_branch_oops(void)
-{
-       if (this_tracer) {
-               ds_suspend_bts_noirq(this_tracer);
-               trace_bts_cpu(hw_branch_trace);
-               ds_resume_bts_noirq(this_tracer);
-       }
-}
-
-struct tracer bts_tracer __read_mostly =
-{
-       .name           = "hw-branch-tracer",
-       .init           = bts_trace_init,
-       .reset          = bts_trace_reset,
-       .print_header   = bts_trace_print_header,
-       .print_line     = bts_trace_print_line,
-       .start          = bts_trace_start,
-       .stop           = bts_trace_stop,
-       .open           = trace_bts_prepare,
-       .close          = trace_bts_close,
-#ifdef CONFIG_FTRACE_SELFTEST
-       .selftest       = trace_selftest_startup_hw_branches,
-#endif /* CONFIG_FTRACE_SELFTEST */
-};
-
-__init static int init_bts_trace(void)
-{
-       register_hotcpu_notifier(&bts_hotcpu_notifier);
-       return register_tracer(&bts_tracer);
-}
-device_initcall(init_bts_trace);
index 2974bc7..6fd486e 100644 (file)
@@ -34,6 +34,9 @@ static int trace_type __read_mostly;
 
 static int save_lat_flag;
 
+static void stop_irqsoff_tracer(struct trace_array *tr, int graph);
+static int start_irqsoff_tracer(struct trace_array *tr, int graph);
+
 #ifdef CONFIG_PREEMPT_TRACER
 static inline int
 preempt_trace(void)
@@ -55,6 +58,23 @@ irq_trace(void)
 # define irq_trace() (0)
 #endif
 
+#define TRACE_DISPLAY_GRAPH    1
+
+static struct tracer_opt trace_opts[] = {
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       /* display latency trace as call graph */
+       { TRACER_OPT(display-graph, TRACE_DISPLAY_GRAPH) },
+#endif
+       { } /* Empty entry */
+};
+
+static struct tracer_flags tracer_flags = {
+       .val  = 0,
+       .opts = trace_opts,
+};
+
+#define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH)
+
 /*
  * Sequence count - we record it when starting a measurement and
  * skip the latency if the sequence has changed - some other section
@@ -108,6 +128,202 @@ static struct ftrace_ops trace_ops __read_mostly =
 };
 #endif /* CONFIG_FUNCTION_TRACER */
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static int irqsoff_set_flag(u32 old_flags, u32 bit, int set)
+{
+       int cpu;
+
+       if (!(bit & TRACE_DISPLAY_GRAPH))
+               return -EINVAL;
+
+       if (!(is_graph() ^ set))
+               return 0;
+
+       stop_irqsoff_tracer(irqsoff_trace, !set);
+
+       for_each_possible_cpu(cpu)
+               per_cpu(tracing_cpu, cpu) = 0;
+
+       tracing_max_latency = 0;
+       tracing_reset_online_cpus(irqsoff_trace);
+
+       return start_irqsoff_tracer(irqsoff_trace, set);
+}
+
+static int irqsoff_graph_entry(struct ftrace_graph_ent *trace)
+{
+       struct trace_array *tr = irqsoff_trace;
+       struct trace_array_cpu *data;
+       unsigned long flags;
+       long disabled;
+       int ret;
+       int cpu;
+       int pc;
+
+       cpu = raw_smp_processor_id();
+       if (likely(!per_cpu(tracing_cpu, cpu)))
+               return 0;
+
+       local_save_flags(flags);
+       /* slight chance to get a false positive on tracing_cpu */
+       if (!irqs_disabled_flags(flags))
+               return 0;
+
+       data = tr->data[cpu];
+       disabled = atomic_inc_return(&data->disabled);
+
+       if (likely(disabled == 1)) {
+               pc = preempt_count();
+               ret = __trace_graph_entry(tr, trace, flags, pc);
+       } else
+               ret = 0;
+
+       atomic_dec(&data->disabled);
+       return ret;
+}
+
+static void irqsoff_graph_return(struct ftrace_graph_ret *trace)
+{
+       struct trace_array *tr = irqsoff_trace;
+       struct trace_array_cpu *data;
+       unsigned long flags;
+       long disabled;
+       int cpu;
+       int pc;
+
+       cpu = raw_smp_processor_id();
+       if (likely(!per_cpu(tracing_cpu, cpu)))
+               return;
+
+       local_save_flags(flags);
+       /* slight chance to get a false positive on tracing_cpu */
+       if (!irqs_disabled_flags(flags))
+               return;
+
+       data = tr->data[cpu];
+       disabled = atomic_inc_return(&data->disabled);
+
+       if (likely(disabled == 1)) {
+               pc = preempt_count();
+               __trace_graph_return(tr, trace, flags, pc);
+       }
+
+       atomic_dec(&data->disabled);
+}
+
+static void irqsoff_trace_open(struct trace_iterator *iter)
+{
+       if (is_graph())
+               graph_trace_open(iter);
+
+}
+
+static void irqsoff_trace_close(struct trace_iterator *iter)
+{
+       if (iter->private)
+               graph_trace_close(iter);
+}
+
+#define GRAPH_TRACER_FLAGS (TRACE_GRAPH_PRINT_CPU | \
+                           TRACE_GRAPH_PRINT_PROC)
+
+static enum print_line_t irqsoff_print_line(struct trace_iterator *iter)
+{
+       u32 flags = GRAPH_TRACER_FLAGS;
+
+       if (trace_flags & TRACE_ITER_LATENCY_FMT)
+               flags |= TRACE_GRAPH_PRINT_DURATION;
+       else
+               flags |= TRACE_GRAPH_PRINT_ABS_TIME;
+
+       /*
+        * In graph mode call the graph tracer output function,
+        * otherwise go with the TRACE_FN event handler
+        */
+       if (is_graph())
+               return print_graph_function_flags(iter, flags);
+
+       return TRACE_TYPE_UNHANDLED;
+}
+
+static void irqsoff_print_header(struct seq_file *s)
+{
+       if (is_graph()) {
+               struct trace_iterator *iter = s->private;
+               u32 flags = GRAPH_TRACER_FLAGS;
+
+               if (trace_flags & TRACE_ITER_LATENCY_FMT) {
+                       /* print nothing if the buffers are empty */
+                       if (trace_empty(iter))
+                               return;
+
+                       print_trace_header(s, iter);
+                       flags |= TRACE_GRAPH_PRINT_DURATION;
+               } else
+                       flags |= TRACE_GRAPH_PRINT_ABS_TIME;
+
+               print_graph_headers_flags(s, flags);
+       } else
+               trace_default_header(s);
+}
+
+static void
+trace_graph_function(struct trace_array *tr,
+                unsigned long ip, unsigned long flags, int pc)
+{
+       u64 time = trace_clock_local();
+       struct ftrace_graph_ent ent = {
+               .func  = ip,
+               .depth = 0,
+       };
+       struct ftrace_graph_ret ret = {
+               .func     = ip,
+               .depth    = 0,
+               .calltime = time,
+               .rettime  = time,
+       };
+
+       __trace_graph_entry(tr, &ent, flags, pc);
+       __trace_graph_return(tr, &ret, flags, pc);
+}
+
+static void
+__trace_function(struct trace_array *tr,
+                unsigned long ip, unsigned long parent_ip,
+                unsigned long flags, int pc)
+{
+       if (!is_graph())
+               trace_function(tr, ip, parent_ip, flags, pc);
+       else {
+               trace_graph_function(tr, parent_ip, flags, pc);
+               trace_graph_function(tr, ip, flags, pc);
+       }
+}
+
+#else
+#define __trace_function trace_function
+
+static int irqsoff_set_flag(u32 old_flags, u32 bit, int set)
+{
+       return -EINVAL;
+}
+
+static int irqsoff_graph_entry(struct ftrace_graph_ent *trace)
+{
+       return -1;
+}
+
+static enum print_line_t irqsoff_print_line(struct trace_iterator *iter)
+{
+       return TRACE_TYPE_UNHANDLED;
+}
+
+static void irqsoff_graph_return(struct ftrace_graph_ret *trace) { }
+static void irqsoff_print_header(struct seq_file *s) { }
+static void irqsoff_trace_open(struct trace_iterator *iter) { }
+static void irqsoff_trace_close(struct trace_iterator *iter) { }
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
 /*
  * Should this new latency be reported/recorded?
  */
@@ -150,7 +366,7 @@ check_critical_timing(struct trace_array *tr,
        if (!report_latency(delta))
                goto out_unlock;
 
-       trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
+       __trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
        /* Skip 5 functions to get to the irq/preempt enable function */
        __trace_stack(tr, flags, 5, pc);
 
@@ -172,7 +388,7 @@ out_unlock:
 out:
        data->critical_sequence = max_sequence;
        data->preempt_timestamp = ftrace_now(cpu);
-       trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
+       __trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 }
 
 static inline void
@@ -204,7 +420,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
 
        local_save_flags(flags);
 
-       trace_function(tr, ip, parent_ip, flags, preempt_count());
+       __trace_function(tr, ip, parent_ip, flags, preempt_count());
 
        per_cpu(tracing_cpu, cpu) = 1;
 
@@ -238,7 +454,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
        atomic_inc(&data->disabled);
 
        local_save_flags(flags);
-       trace_function(tr, ip, parent_ip, flags, preempt_count());
+       __trace_function(tr, ip, parent_ip, flags, preempt_count());
        check_critical_timing(tr, data, parent_ip ? : ip, cpu);
        data->critical_start = 0;
        atomic_dec(&data->disabled);
@@ -347,19 +563,32 @@ void trace_preempt_off(unsigned long a0, unsigned long a1)
 }
 #endif /* CONFIG_PREEMPT_TRACER */
 
-static void start_irqsoff_tracer(struct trace_array *tr)
+static int start_irqsoff_tracer(struct trace_array *tr, int graph)
 {
-       register_ftrace_function(&trace_ops);
-       if (tracing_is_enabled())
+       int ret = 0;
+
+       if (!graph)
+               ret = register_ftrace_function(&trace_ops);
+       else
+               ret = register_ftrace_graph(&irqsoff_graph_return,
+                                           &irqsoff_graph_entry);
+
+       if (!ret && tracing_is_enabled())
                tracer_enabled = 1;
        else
                tracer_enabled = 0;
+
+       return ret;
 }
 
-static void stop_irqsoff_tracer(struct trace_array *tr)
+static void stop_irqsoff_tracer(struct trace_array *tr, int graph)
 {
        tracer_enabled = 0;
-       unregister_ftrace_function(&trace_ops);
+
+       if (!graph)
+               unregister_ftrace_function(&trace_ops);
+       else
+               unregister_ftrace_graph();
 }
 
 static void __irqsoff_tracer_init(struct trace_array *tr)
@@ -372,12 +601,14 @@ static void __irqsoff_tracer_init(struct trace_array *tr)
        /* make sure that the tracer is visible */
        smp_wmb();
        tracing_reset_online_cpus(tr);
-       start_irqsoff_tracer(tr);
+
+       if (start_irqsoff_tracer(tr, is_graph()))
+               printk(KERN_ERR "failed to start irqsoff tracer\n");
 }
 
 static void irqsoff_tracer_reset(struct trace_array *tr)
 {
-       stop_irqsoff_tracer(tr);
+       stop_irqsoff_tracer(tr, is_graph());
 
        if (!save_lat_flag)
                trace_flags &= ~TRACE_ITER_LATENCY_FMT;
@@ -409,9 +640,15 @@ static struct tracer irqsoff_tracer __read_mostly =
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = 1,
+       .print_header   = irqsoff_print_header,
+       .print_line     = irqsoff_print_line,
+       .flags          = &tracer_flags,
+       .set_flag       = irqsoff_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_irqsoff,
 #endif
+       .open           = irqsoff_trace_open,
+       .close          = irqsoff_trace_close,
 };
 # define register_irqsoff(trace) register_tracer(&trace)
 #else
@@ -435,9 +672,15 @@ static struct tracer preemptoff_tracer __read_mostly =
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = 1,
+       .print_header   = irqsoff_print_header,
+       .print_line     = irqsoff_print_line,
+       .flags          = &tracer_flags,
+       .set_flag       = irqsoff_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_preemptoff,
 #endif
+       .open           = irqsoff_trace_open,
+       .close          = irqsoff_trace_close,
 };
 # define register_preemptoff(trace) register_tracer(&trace)
 #else
@@ -463,9 +706,15 @@ static struct tracer preemptirqsoff_tracer __read_mostly =
        .start          = irqsoff_tracer_start,
        .stop           = irqsoff_tracer_stop,
        .print_max      = 1,
+       .print_header   = irqsoff_print_header,
+       .print_line     = irqsoff_print_line,
+       .flags          = &tracer_flags,
+       .set_flag       = irqsoff_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
        .selftest    = trace_selftest_startup_preemptirqsoff,
 #endif
+       .open           = irqsoff_trace_open,
+       .close          = irqsoff_trace_close,
 };
 
 # define register_preemptirqsoff(trace) register_tracer(&trace)
index 1251e36..a751432 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/ctype.h>
 #include <linux/ptrace.h>
 #include <linux/perf_event.h>
+#include <linux/stringify.h>
+#include <asm/bitsperlong.h>
 
 #include "trace.h"
 #include "trace_output.h"
@@ -40,7 +42,6 @@
 
 /* Reserved field names */
 #define FIELD_STRING_IP "__probe_ip"
-#define FIELD_STRING_NARGS "__probe_nargs"
 #define FIELD_STRING_RETIP "__probe_ret_ip"
 #define FIELD_STRING_FUNC "__probe_func"
 
@@ -52,56 +53,102 @@ const char *reserved_field_names[] = {
        "common_tgid",
        "common_lock_depth",
        FIELD_STRING_IP,
-       FIELD_STRING_NARGS,
        FIELD_STRING_RETIP,
        FIELD_STRING_FUNC,
 };
 
-struct fetch_func {
-       unsigned long (*func)(struct pt_regs *, void *);
+/* Printing function type */
+typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *);
+#define PRINT_TYPE_FUNC_NAME(type)     print_type_##type
+#define PRINT_TYPE_FMT_NAME(type)      print_type_format_##type
+
+/* Printing  in basic type function template */
+#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)                  \
+static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,   \
+                                               const char *name, void *data)\
+{                                                                      \
+       return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
+}                                                                      \
+static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
+
+DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
+DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
+
+/* Data fetch function type */
+typedef        void (*fetch_func_t)(struct pt_regs *, void *, void *);
+
+struct fetch_param {
+       fetch_func_t    fn;
        void *data;
 };
 
-static __kprobes unsigned long call_fetch(struct fetch_func *f,
-                                         struct pt_regs *regs)
+static __kprobes void call_fetch(struct fetch_param *fprm,
+                                struct pt_regs *regs, void *dest)
 {
-       return f->func(regs, f->data);
+       return fprm->fn(regs, fprm->data, dest);
 }
 
-/* fetch handlers */
-static __kprobes unsigned long fetch_register(struct pt_regs *regs,
-                                             void *offset)
-{
-       return regs_get_register(regs, (unsigned int)((unsigned long)offset));
+#define FETCH_FUNC_NAME(kind, type)    fetch_##kind##_##type
+/*
+ * Define macro for basic types - we don't need to define s* types, because
+ * we have to care only about bitwidth at recording time.
+ */
+#define DEFINE_BASIC_FETCH_FUNCS(kind)  \
+DEFINE_FETCH_##kind(u8)                        \
+DEFINE_FETCH_##kind(u16)               \
+DEFINE_FETCH_##kind(u32)               \
+DEFINE_FETCH_##kind(u64)
+
+#define CHECK_BASIC_FETCH_FUNCS(kind, fn)      \
+       ((FETCH_FUNC_NAME(kind, u8) == fn) ||   \
+        (FETCH_FUNC_NAME(kind, u16) == fn) ||  \
+        (FETCH_FUNC_NAME(kind, u32) == fn) ||  \
+        (FETCH_FUNC_NAME(kind, u64) == fn))
+
+/* Data fetch function templates */
+#define DEFINE_FETCH_reg(type)                                         \
+static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \
+                                         void *offset, void *dest)     \
+{                                                                      \
+       *(type *)dest = (type)regs_get_register(regs,                   \
+                               (unsigned int)((unsigned long)offset)); \
 }
-
-static __kprobes unsigned long fetch_stack(struct pt_regs *regs,
-                                          void *num)
-{
-       return regs_get_kernel_stack_nth(regs,
-                                        (unsigned int)((unsigned long)num));
+DEFINE_BASIC_FETCH_FUNCS(reg)
+
+#define DEFINE_FETCH_stack(type)                                       \
+static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
+                                         void *offset, void *dest)     \
+{                                                                      \
+       *(type *)dest = (type)regs_get_kernel_stack_nth(regs,           \
+                               (unsigned int)((unsigned long)offset)); \
 }
+DEFINE_BASIC_FETCH_FUNCS(stack)
 
-static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr)
-{
-       unsigned long retval;
-
-       if (probe_kernel_address(addr, retval))
-               return 0;
-       return retval;
+#define DEFINE_FETCH_retval(type)                                      \
+static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
+                                         void *dummy, void *dest)      \
+{                                                                      \
+       *(type *)dest = (type)regs_return_value(regs);                  \
 }
-
-static __kprobes unsigned long fetch_retvalue(struct pt_regs *regs,
-                                             void *dummy)
-{
-       return regs_return_value(regs);
-}
-
-static __kprobes unsigned long fetch_stack_address(struct pt_regs *regs,
-                                                  void *dummy)
-{
-       return kernel_stack_pointer(regs);
+DEFINE_BASIC_FETCH_FUNCS(retval)
+
+#define DEFINE_FETCH_memory(type)                                      \
+static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
+                                         void *addr, void *dest)       \
+{                                                                      \
+       type retval;                                                    \
+       if (probe_kernel_address(addr, retval))                         \
+               *(type *)dest = 0;                                      \
+       else                                                            \
+               *(type *)dest = retval;                                 \
 }
+DEFINE_BASIC_FETCH_FUNCS(memory)
 
 /* Memory fetching by symbol */
 struct symbol_cache {
@@ -145,51 +192,126 @@ static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
        return sc;
 }
 
-static __kprobes unsigned long fetch_symbol(struct pt_regs *regs, void *data)
-{
-       struct symbol_cache *sc = data;
-
-       if (sc->addr)
-               return fetch_memory(regs, (void *)sc->addr);
-       else
-               return 0;
+#define DEFINE_FETCH_symbol(type)                                      \
+static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
+                                         void *data, void *dest)       \
+{                                                                      \
+       struct symbol_cache *sc = data;                                 \
+       if (sc->addr)                                                   \
+               fetch_memory_##type(regs, (void *)sc->addr, dest);      \
+       else                                                            \
+               *(type *)dest = 0;                                      \
 }
+DEFINE_BASIC_FETCH_FUNCS(symbol)
 
-/* Special indirect memory access interface */
-struct indirect_fetch_data {
-       struct fetch_func orig;
+/* Dereference memory access function */
+struct deref_fetch_param {
+       struct fetch_param orig;
        long offset;
 };
 
-static __kprobes unsigned long fetch_indirect(struct pt_regs *regs, void *data)
-{
-       struct indirect_fetch_data *ind = data;
-       unsigned long addr;
-
-       addr = call_fetch(&ind->orig, regs);
-       if (addr) {
-               addr += ind->offset;
-               return fetch_memory(regs, (void *)addr);
-       } else
-               return 0;
+#define DEFINE_FETCH_deref(type)                                       \
+static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
+                                           void *data, void *dest)     \
+{                                                                      \
+       struct deref_fetch_param *dprm = data;                          \
+       unsigned long addr;                                             \
+       call_fetch(&dprm->orig, regs, &addr);                           \
+       if (addr) {                                                     \
+               addr += dprm->offset;                                   \
+               fetch_memory_##type(regs, (void *)addr, dest);          \
+       } else                                                          \
+               *(type *)dest = 0;                                      \
 }
+DEFINE_BASIC_FETCH_FUNCS(deref)
 
-static __kprobes void free_indirect_fetch_data(struct indirect_fetch_data *data)
+static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
 {
-       if (data->orig.func == fetch_indirect)
-               free_indirect_fetch_data(data->orig.data);
-       else if (data->orig.func == fetch_symbol)
+       if (CHECK_BASIC_FETCH_FUNCS(deref, data->orig.fn))
+               free_deref_fetch_param(data->orig.data);
+       else if (CHECK_BASIC_FETCH_FUNCS(symbol, data->orig.fn))
                free_symbol_cache(data->orig.data);
        kfree(data);
 }
 
+/* Default (unsigned long) fetch type */
+#define __DEFAULT_FETCH_TYPE(t) u##t
+#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
+#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
+#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
+
+#define ASSIGN_FETCH_FUNC(kind, type)  \
+       .kind = FETCH_FUNC_NAME(kind, type)
+
+#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)  \
+       {.name = #ptype,                        \
+        .size = sizeof(ftype),                 \
+        .is_signed = sign,                     \
+        .print = PRINT_TYPE_FUNC_NAME(ptype),  \
+        .fmt = PRINT_TYPE_FMT_NAME(ptype),     \
+ASSIGN_FETCH_FUNC(reg, ftype),                 \
+ASSIGN_FETCH_FUNC(stack, ftype),               \
+ASSIGN_FETCH_FUNC(retval, ftype),              \
+ASSIGN_FETCH_FUNC(memory, ftype),              \
+ASSIGN_FETCH_FUNC(symbol, ftype),              \
+ASSIGN_FETCH_FUNC(deref, ftype),               \
+       }
+
+/* Fetch type information table */
+static const struct fetch_type {
+       const char      *name;          /* Name of type */
+       size_t          size;           /* Byte size of type */
+       int             is_signed;      /* Signed flag */
+       print_type_func_t       print;  /* Print functions */
+       const char      *fmt;           /* Fromat string */
+       /* Fetch functions */
+       fetch_func_t    reg;
+       fetch_func_t    stack;
+       fetch_func_t    retval;
+       fetch_func_t    memory;
+       fetch_func_t    symbol;
+       fetch_func_t    deref;
+} fetch_type_table[] = {
+       ASSIGN_FETCH_TYPE(u8,  u8,  0),
+       ASSIGN_FETCH_TYPE(u16, u16, 0),
+       ASSIGN_FETCH_TYPE(u32, u32, 0),
+       ASSIGN_FETCH_TYPE(u64, u64, 0),
+       ASSIGN_FETCH_TYPE(s8,  u8,  1),
+       ASSIGN_FETCH_TYPE(s16, u16, 1),
+       ASSIGN_FETCH_TYPE(s32, u32, 1),
+       ASSIGN_FETCH_TYPE(s64, u64, 1),
+};
+
+static const struct fetch_type *find_fetch_type(const char *type)
+{
+       int i;
+
+       if (!type)
+               type = DEFAULT_FETCH_TYPE_STR;
+
+       for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
+               if (strcmp(type, fetch_type_table[i].name) == 0)
+                       return &fetch_type_table[i];
+       return NULL;
+}
+
+/* Special function : only accept unsigned long */
+static __kprobes void fetch_stack_address(struct pt_regs *regs,
+                                         void *dummy, void *dest)
+{
+       *(unsigned long *)dest = kernel_stack_pointer(regs);
+}
+
 /**
  * Kprobe event core functions
  */
 
 struct probe_arg {
-       struct fetch_func       fetch;
-       const char              *name;
+       struct fetch_param      fetch;
+       unsigned int            offset; /* Offset from argument entry */
+       const char              *name;  /* Name of this argument */
+       const char              *comm;  /* Command of this argument */
+       const struct fetch_type *type;  /* Type of this argument */
 };
 
 /* Flags for trace_probe */
@@ -204,6 +326,7 @@ struct trace_probe {
        const char              *symbol;        /* symbol name */
        struct ftrace_event_call        call;
        struct trace_event              event;
+       ssize_t                 size;           /* trace entry size */
        unsigned int            nr_args;
        struct probe_arg        args[];
 };
@@ -212,6 +335,7 @@ struct trace_probe {
        (offsetof(struct trace_probe, args) +   \
        (sizeof(struct probe_arg) * (n)))
 
+
 static __kprobes int probe_is_return(struct trace_probe *tp)
 {
        return tp->rp.handler != NULL;
@@ -222,49 +346,6 @@ static __kprobes const char *probe_symbol(struct trace_probe *tp)
        return tp->symbol ? tp->symbol : "unknown";
 }
 
-static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff)
-{
-       int ret = -EINVAL;
-
-       if (ff->func == fetch_register) {
-               const char *name;
-               name = regs_query_register_name((unsigned int)((long)ff->data));
-               ret = snprintf(buf, n, "%%%s", name);
-       } else if (ff->func == fetch_stack)
-               ret = snprintf(buf, n, "$stack%lu", (unsigned long)ff->data);
-       else if (ff->func == fetch_memory)
-               ret = snprintf(buf, n, "@0x%p", ff->data);
-       else if (ff->func == fetch_symbol) {
-               struct symbol_cache *sc = ff->data;
-               if (sc->offset)
-                       ret = snprintf(buf, n, "@%s%+ld", sc->symbol,
-                                       sc->offset);
-               else
-                       ret = snprintf(buf, n, "@%s", sc->symbol);
-       } else if (ff->func == fetch_retvalue)
-               ret = snprintf(buf, n, "$retval");
-       else if (ff->func == fetch_stack_address)
-               ret = snprintf(buf, n, "$stack");
-       else if (ff->func == fetch_indirect) {
-               struct indirect_fetch_data *id = ff->data;
-               size_t l = 0;
-               ret = snprintf(buf, n, "%+ld(", id->offset);
-               if (ret >= n)
-                       goto end;
-               l += ret;
-               ret = probe_arg_string(buf + l, n - l, &id->orig);
-               if (ret < 0)
-                       goto end;
-               l += ret;
-               ret = snprintf(buf + l, n - l, ")");
-               ret += l;
-       }
-end:
-       if (ret >= n)
-               return -ENOSPC;
-       return ret;
-}
-
 static int register_probe_event(struct trace_probe *tp);
 static void unregister_probe_event(struct trace_probe *tp);
 
@@ -347,11 +428,12 @@ error:
 
 static void free_probe_arg(struct probe_arg *arg)
 {
-       if (arg->fetch.func == fetch_symbol)
+       if (CHECK_BASIC_FETCH_FUNCS(deref, arg->fetch.fn))
+               free_deref_fetch_param(arg->fetch.data);
+       else if (CHECK_BASIC_FETCH_FUNCS(symbol, arg->fetch.fn))
                free_symbol_cache(arg->fetch.data);
-       else if (arg->fetch.func == fetch_indirect)
-               free_indirect_fetch_data(arg->fetch.data);
        kfree(arg->name);
+       kfree(arg->comm);
 }
 
 static void free_trace_probe(struct trace_probe *tp)
@@ -457,28 +539,30 @@ static int split_symbol_offset(char *symbol, unsigned long *offset)
 #define PARAM_MAX_ARGS 16
 #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
 
-static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
+static int parse_probe_vars(char *arg, const struct fetch_type *t,
+                           struct fetch_param *f, int is_return)
 {
        int ret = 0;
        unsigned long param;
 
        if (strcmp(arg, "retval") == 0) {
-               if (is_return) {
-                       ff->func = fetch_retvalue;
-                       ff->data = NULL;
-               } else
+               if (is_return)
+                       f->fn = t->retval;
+               else
                        ret = -EINVAL;
        } else if (strncmp(arg, "stack", 5) == 0) {
                if (arg[5] == '\0') {
-                       ff->func = fetch_stack_address;
-                       ff->data = NULL;
+                       if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
+                               f->fn = fetch_stack_address;
+                       else
+                               ret = -EINVAL;
                } else if (isdigit(arg[5])) {
                        ret = strict_strtoul(arg + 5, 10, &param);
                        if (ret || param > PARAM_MAX_STACK)
                                ret = -EINVAL;
                        else {
-                               ff->func = fetch_stack;
-                               ff->data = (void *)param;
+                               f->fn = t->stack;
+                               f->data = (void *)param;
                        }
                } else
                        ret = -EINVAL;
@@ -488,7 +572,8 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
 }
 
 /* Recursive argument parser */
-static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
+static int __parse_probe_arg(char *arg, const struct fetch_type *t,
+                            struct fetch_param *f, int is_return)
 {
        int ret = 0;
        unsigned long param;
@@ -497,13 +582,13 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
 
        switch (arg[0]) {
        case '$':
-               ret = parse_probe_vars(arg + 1, ff, is_return);
+               ret = parse_probe_vars(arg + 1, t, f, is_return);
                break;
        case '%':       /* named register */
                ret = regs_query_register_offset(arg + 1);
                if (ret >= 0) {
-                       ff->func = fetch_register;
-                       ff->data = (void *)(unsigned long)ret;
+                       f->fn = t->reg;
+                       f->data = (void *)(unsigned long)ret;
                        ret = 0;
                }
                break;
@@ -512,26 +597,22 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
                        ret = strict_strtoul(arg + 1, 0, &param);
                        if (ret)
                                break;
-                       ff->func = fetch_memory;
-                       ff->data = (void *)param;
+                       f->fn = t->memory;
+                       f->data = (void *)param;
                } else {
                        ret = split_symbol_offset(arg + 1, &offset);
                        if (ret)
                                break;
-                       ff->data = alloc_symbol_cache(arg + 1, offset);
-                       if (ff->data)
-                               ff->func = fetch_symbol;
-                       else
-                               ret = -EINVAL;
+                       f->data = alloc_symbol_cache(arg + 1, offset);
+                       if (f->data)
+                               f->fn = t->symbol;
                }
                break;
-       case '+':       /* indirect memory */
+       case '+':       /* deref memory */
        case '-':
                tmp = strchr(arg, '(');
-               if (!tmp) {
-                       ret = -EINVAL;
+               if (!tmp)
                        break;
-               }
                *tmp = '\0';
                ret = strict_strtol(arg + 1, 0, &offset);
                if (ret)
@@ -541,38 +622,58 @@ static int __parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
                arg = tmp + 1;
                tmp = strrchr(arg, ')');
                if (tmp) {
-                       struct indirect_fetch_data *id;
+                       struct deref_fetch_param *dprm;
+                       const struct fetch_type *t2 = find_fetch_type(NULL);
                        *tmp = '\0';
-                       id = kzalloc(sizeof(struct indirect_fetch_data),
-                                    GFP_KERNEL);
-                       if (!id)
+                       dprm = kzalloc(sizeof(struct deref_fetch_param),
+                                      GFP_KERNEL);
+                       if (!dprm)
                                return -ENOMEM;
-                       id->offset = offset;
-                       ret = __parse_probe_arg(arg, &id->orig, is_return);
+                       dprm->offset = offset;
+                       ret = __parse_probe_arg(arg, t2, &dprm->orig,
+                                               is_return);
                        if (ret)
-                               kfree(id);
+                               kfree(dprm);
                        else {
-                               ff->func = fetch_indirect;
-                               ff->data = (void *)id;
+                               f->fn = t->deref;
+                               f->data = (void *)dprm;
                        }
-               } else
-                       ret = -EINVAL;
+               }
                break;
-       default:
-               /* TODO: support custom handler */
-               ret = -EINVAL;
        }
+       if (!ret && !f->fn)
+               ret = -EINVAL;
        return ret;
 }
 
 /* String length checking wrapper */
-static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
+static int parse_probe_arg(char *arg, struct trace_probe *tp,
+                          struct probe_arg *parg, int is_return)
 {
+       const char *t;
+
        if (strlen(arg) > MAX_ARGSTR_LEN) {
                pr_info("Argument is too long.: %s\n",  arg);
                return -ENOSPC;
        }
-       return __parse_probe_arg(arg, ff, is_return);
+       parg->comm = kstrdup(arg, GFP_KERNEL);
+       if (!parg->comm) {
+               pr_info("Failed to allocate memory for command '%s'.\n", arg);
+               return -ENOMEM;
+       }
+       t = strchr(parg->comm, ':');
+       if (t) {
+               arg[t - parg->comm] = '\0';
+               t++;
+       }
+       parg->type = find_fetch_type(t);
+       if (!parg->type) {
+               pr_info("Unsupported type: %s\n", t);
+               return -EINVAL;
+       }
+       parg->offset = tp->size;
+       tp->size += parg->type->size;
+       return __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
 }
 
 /* Return 1 if name is reserved or already used by another argument */
@@ -602,15 +703,18 @@ static int create_trace_probe(int argc, char **argv)
         *  @ADDR       : fetch memory at ADDR (ADDR should be in kernel)
         *  @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
         *  %REG        : fetch register REG
-        * Indirect memory fetch:
+        * Dereferencing memory fetch:
         *  +|-offs(ARG) : fetch memory at ARG +|- offs address.
         * Alias name of args:
         *  NAME=FETCHARG : set NAME as alias of FETCHARG.
+        * Type of args:
+        *  FETCHARG:TYPE : use TYPE instead of unsigned long.
         */
        struct trace_probe *tp;
        int i, ret = 0;
        int is_return = 0, is_delete = 0;
-       char *symbol = NULL, *event = NULL, *arg = NULL, *group = NULL;
+       char *symbol = NULL, *event = NULL, *group = NULL;
+       char *arg, *tmp;
        unsigned long offset = 0;
        void *addr = NULL;
        char buf[MAX_EVENT_NAME_LEN];
@@ -723,13 +827,6 @@ static int create_trace_probe(int argc, char **argv)
                else
                        arg = argv[i];
 
-               if (conflict_field_name(argv[i], tp->args, i)) {
-                       pr_info("Argument%d name '%s' conflicts with "
-                               "another field.\n", i, argv[i]);
-                       ret = -EINVAL;
-                       goto error;
-               }
-
                tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
                if (!tp->args[i].name) {
                        pr_info("Failed to allocate argument%d name '%s'.\n",
@@ -737,9 +834,19 @@ static int create_trace_probe(int argc, char **argv)
                        ret = -ENOMEM;
                        goto error;
                }
+               tmp = strchr(tp->args[i].name, ':');
+               if (tmp)
+                       *tmp = '_';     /* convert : to _ */
+
+               if (conflict_field_name(tp->args[i].name, tp->args, i)) {
+                       pr_info("Argument%d name '%s' conflicts with "
+                               "another field.\n", i, argv[i]);
+                       ret = -EINVAL;
+                       goto error;
+               }
 
                /* Parse fetch argument */
-               ret = parse_probe_arg(arg, &tp->args[i].fetch, is_return);
+               ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
                if (ret) {
                        pr_info("Parse error at argument%d. (%d)\n", i, ret);
                        kfree(tp->args[i].name);
@@ -794,8 +901,7 @@ static void probes_seq_stop(struct seq_file *m, void *v)
 static int probes_seq_show(struct seq_file *m, void *v)
 {
        struct trace_probe *tp = v;
-       int i, ret;
-       char buf[MAX_ARGSTR_LEN + 1];
+       int i;
 
        seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p');
        seq_printf(m, ":%s/%s", tp->call.system, tp->call.name);
@@ -807,15 +913,10 @@ static int probes_seq_show(struct seq_file *m, void *v)
        else
                seq_printf(m, " %s", probe_symbol(tp));
 
-       for (i = 0; i < tp->nr_args; i++) {
-               ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i].fetch);
-               if (ret < 0) {
-                       pr_warning("Argument%d decoding error(%d).\n", i, ret);
-                       return ret;
-               }
-               seq_printf(m, " %s=%s", tp->args[i].name, buf);
-       }
+       for (i = 0; i < tp->nr_args; i++)
+               seq_printf(m, " %s=%s", tp->args[i].name, tp->args[i].comm);
        seq_printf(m, "\n");
+
        return 0;
 }
 
@@ -945,9 +1046,10 @@ static const struct file_operations kprobe_profile_ops = {
 static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
 {
        struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
-       struct kprobe_trace_entry *entry;
+       struct kprobe_trace_entry_head *entry;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
+       u8 *data;
        int size, i, pc;
        unsigned long irq_flags;
        struct ftrace_event_call *call = &tp->call;
@@ -957,7 +1059,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
+       size = sizeof(*entry) + tp->size;
 
        event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
                                                  irq_flags, pc);
@@ -965,10 +1067,10 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
                return;
 
        entry = ring_buffer_event_data(event);
-       entry->nargs = tp->nr_args;
        entry->ip = (unsigned long)kp->addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
        if (!filter_current_check_discard(buffer, call, entry, event))
                trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -979,9 +1081,10 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
                                          struct pt_regs *regs)
 {
        struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
-       struct kretprobe_trace_entry *entry;
+       struct kretprobe_trace_entry_head *entry;
        struct ring_buffer_event *event;
        struct ring_buffer *buffer;
+       u8 *data;
        int size, i, pc;
        unsigned long irq_flags;
        struct ftrace_event_call *call = &tp->call;
@@ -989,7 +1092,7 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
+       size = sizeof(*entry) + tp->size;
 
        event = trace_current_buffer_lock_reserve(&buffer, call->id, size,
                                                  irq_flags, pc);
@@ -997,11 +1100,11 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
                return;
 
        entry = ring_buffer_event_data(event);
-       entry->nargs = tp->nr_args;
        entry->func = (unsigned long)tp->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
        if (!filter_current_check_discard(buffer, call, entry, event))
                trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -1011,13 +1114,14 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
 enum print_line_t
 print_kprobe_event(struct trace_iterator *iter, int flags)
 {
-       struct kprobe_trace_entry *field;
+       struct kprobe_trace_entry_head *field;
        struct trace_seq *s = &iter->seq;
        struct trace_event *event;
        struct trace_probe *tp;
+       u8 *data;
        int i;
 
-       field = (struct kprobe_trace_entry *)iter->ent;
+       field = (struct kprobe_trace_entry_head *)iter->ent;
        event = ftrace_find_event(field->ent.type);
        tp = container_of(event, struct trace_probe, event);
 
@@ -1030,9 +1134,10 @@ print_kprobe_event(struct trace_iterator *iter, int flags)
        if (!trace_seq_puts(s, ")"))
                goto partial;
 
-       for (i = 0; i < field->nargs; i++)
-               if (!trace_seq_printf(s, " %s=%lx",
-                                     tp->args[i].name, field->args[i]))
+       data = (u8 *)&field[1];
+       for (i = 0; i < tp->nr_args; i++)
+               if (!tp->args[i].type->print(s, tp->args[i].name,
+                                            data + tp->args[i].offset))
                        goto partial;
 
        if (!trace_seq_puts(s, "\n"))
@@ -1046,13 +1151,14 @@ partial:
 enum print_line_t
 print_kretprobe_event(struct trace_iterator *iter, int flags)
 {
-       struct kretprobe_trace_entry *field;
+       struct kretprobe_trace_entry_head *field;
        struct trace_seq *s = &iter->seq;
        struct trace_event *event;
        struct trace_probe *tp;
+       u8 *data;
        int i;
 
-       field = (struct kretprobe_trace_entry *)iter->ent;
+       field = (struct kretprobe_trace_entry_head *)iter->ent;
        event = ftrace_find_event(field->ent.type);
        tp = container_of(event, struct trace_probe, event);
 
@@ -1071,9 +1177,10 @@ print_kretprobe_event(struct trace_iterator *iter, int flags)
        if (!trace_seq_puts(s, ")"))
                goto partial;
 
-       for (i = 0; i < field->nargs; i++)
-               if (!trace_seq_printf(s, " %s=%lx",
-                                     tp->args[i].name, field->args[i]))
+       data = (u8 *)&field[1];
+       for (i = 0; i < tp->nr_args; i++)
+               if (!tp->args[i].type->print(s, tp->args[i].name,
+                                            data + tp->args[i].offset))
                        goto partial;
 
        if (!trace_seq_puts(s, "\n"))
@@ -1129,29 +1236,43 @@ static int probe_event_raw_init(struct ftrace_event_call *event_call)
 static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
 {
        int ret, i;
-       struct kprobe_trace_entry field;
+       struct kprobe_trace_entry_head field;
        struct trace_probe *tp = (struct trace_probe *)event_call->data;
 
        DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
-       DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
        /* Set argument names as fields */
-       for (i = 0; i < tp->nr_args; i++)
-               DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0);
+       for (i = 0; i < tp->nr_args; i++) {
+               ret = trace_define_field(event_call, tp->args[i].type->name,
+                                        tp->args[i].name,
+                                        sizeof(field) + tp->args[i].offset,
+                                        tp->args[i].type->size,
+                                        tp->args[i].type->is_signed,
+                                        FILTER_OTHER);
+               if (ret)
+                       return ret;
+       }
        return 0;
 }
 
 static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
 {
        int ret, i;
-       struct kretprobe_trace_entry field;
+       struct kretprobe_trace_entry_head field;
        struct trace_probe *tp = (struct trace_probe *)event_call->data;
 
        DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
        DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
-       DEFINE_FIELD(int, nargs, FIELD_STRING_NARGS, 1);
        /* Set argument names as fields */
-       for (i = 0; i < tp->nr_args; i++)
-               DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0);
+       for (i = 0; i < tp->nr_args; i++) {
+               ret = trace_define_field(event_call, tp->args[i].type->name,
+                                        tp->args[i].name,
+                                        sizeof(field) + tp->args[i].offset,
+                                        tp->args[i].type->size,
+                                        tp->args[i].type->is_signed,
+                                        FILTER_OTHER);
+               if (ret)
+                       return ret;
+       }
        return 0;
 }
 
@@ -1176,8 +1297,8 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len)
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
 
        for (i = 0; i < tp->nr_args; i++) {
-               pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%%lx",
-                               tp->args[i].name);
+               pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
+                               tp->args[i].name, tp->args[i].type->fmt);
        }
 
        pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
@@ -1219,12 +1340,13 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
 {
        struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
        struct ftrace_event_call *call = &tp->call;
-       struct kprobe_trace_entry *entry;
+       struct kprobe_trace_entry_head *entry;
+       u8 *data;
        int size, __size, i;
        unsigned long irq_flags;
        int rctx;
 
-       __size = SIZEOF_KPROBE_TRACE_ENTRY(tp->nr_args);
+       __size = sizeof(*entry) + tp->size;
        size = ALIGN(__size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
        if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
@@ -1235,10 +1357,10 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp,
        if (!entry)
                return;
 
-       entry->nargs = tp->nr_args;
        entry->ip = (unsigned long)kp->addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
        perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, irq_flags, regs);
 }
@@ -1249,12 +1371,13 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
 {
        struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
        struct ftrace_event_call *call = &tp->call;
-       struct kretprobe_trace_entry *entry;
+       struct kretprobe_trace_entry_head *entry;
+       u8 *data;
        int size, __size, i;
        unsigned long irq_flags;
        int rctx;
 
-       __size = SIZEOF_KRETPROBE_TRACE_ENTRY(tp->nr_args);
+       __size = sizeof(*entry) + tp->size;
        size = ALIGN(__size + sizeof(u32), sizeof(u64));
        size -= sizeof(u32);
        if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
@@ -1265,11 +1388,11 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri,
        if (!entry)
                return;
 
-       entry->nargs = tp->nr_args;
        entry->func = (unsigned long)tp->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
+       data = (u8 *)&entry[1];
        for (i = 0; i < tp->nr_args; i++)
-               entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
+               call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset);
 
        perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1,
                               irq_flags, regs);
index d59cd68..8eaf007 100644 (file)
 
 #include <asm/atomic.h>
 
-/*
- * For now, let us restrict the no. of symbols traced simultaneously to number
- * of available hardware breakpoint registers.
- */
-#define KSYM_TRACER_MAX HBP_NUM
-
 #define KSYM_TRACER_OP_LEN 3 /* rw- */
 
 struct trace_ksym {
@@ -53,7 +47,6 @@ struct trace_ksym {
 
 static struct trace_array *ksym_trace_array;
 
-static unsigned int ksym_filter_entry_count;
 static unsigned int ksym_tracing_enabled;
 
 static HLIST_HEAD(ksym_filter_head);
@@ -181,13 +174,6 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
        struct trace_ksym *entry;
        int ret = -ENOMEM;
 
-       if (ksym_filter_entry_count >= KSYM_TRACER_MAX) {
-               printk(KERN_ERR "ksym_tracer: Maximum limit:(%d) reached. No"
-               " new requests for tracing can be accepted now.\n",
-                       KSYM_TRACER_MAX);
-               return -ENOSPC;
-       }
-
        entry = kzalloc(sizeof(struct trace_ksym), GFP_KERNEL);
        if (!entry)
                return -ENOMEM;
@@ -203,13 +189,17 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
 
        if (IS_ERR(entry->ksym_hbp)) {
                ret = PTR_ERR(entry->ksym_hbp);
-               printk(KERN_INFO "ksym_tracer request failed. Try again"
-                                       " later!!\n");
+               if (ret == -ENOSPC) {
+                       printk(KERN_ERR "ksym_tracer: Maximum limit reached."
+                       " No new requests for tracing can be accepted now.\n");
+               } else {
+                       printk(KERN_INFO "ksym_tracer request failed. Try again"
+                                        " later!!\n");
+               }
                goto err;
        }
 
        hlist_add_head_rcu(&(entry->ksym_hlist), &ksym_filter_head);
-       ksym_filter_entry_count++;
 
        return 0;
 
@@ -265,7 +255,6 @@ static void __ksym_trace_reset(void)
        hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head,
                                                                ksym_hlist) {
                unregister_wide_hw_breakpoint(entry->ksym_hbp);
-               ksym_filter_entry_count--;
                hlist_del_rcu(&(entry->ksym_hlist));
                synchronize_rcu();
                kfree(entry);
@@ -338,7 +327,6 @@ static ssize_t ksym_trace_filter_write(struct file *file,
                                goto out_unlock;
                }
                /* Error or "symbol:---" case: drop it */
-               ksym_filter_entry_count--;
                hlist_del_rcu(&(entry->ksym_hlist));
                synchronize_rcu();
                kfree(entry);
index 8e46b33..2404c12 100644 (file)
@@ -253,7 +253,7 @@ void *trace_seq_reserve(struct trace_seq *s, size_t len)
        void *ret;
 
        if (s->full)
-               return 0;
+               return NULL;
 
        if (len > ((PAGE_SIZE - 1) - s->len)) {
                s->full = 1;
index 5fca0f5..a55fccf 100644 (file)
@@ -50,8 +50,7 @@ tracing_sched_switch_trace(struct trace_array *tr,
 }
 
 static void
-probe_sched_switch(struct rq *__rq, struct task_struct *prev,
-                       struct task_struct *next)
+probe_sched_switch(struct task_struct *prev, struct task_struct *next)
 {
        struct trace_array_cpu *data;
        unsigned long flags;
@@ -109,7 +108,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
 }
 
 static void
-probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee, int success)
+probe_sched_wakeup(struct task_struct *wakee, int success)
 {
        struct trace_array_cpu *data;
        unsigned long flags;
index 0271742..8052446 100644 (file)
@@ -107,8 +107,7 @@ static void probe_wakeup_migrate_task(struct task_struct *task, int cpu)
 }
 
 static void notrace
-probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
-       struct task_struct *next)
+probe_wakeup_sched_switch(struct task_struct *prev, struct task_struct *next)
 {
        struct trace_array_cpu *data;
        cycle_t T0, T1, delta;
@@ -200,7 +199,7 @@ static void wakeup_reset(struct trace_array *tr)
 }
 
 static void
-probe_wakeup(struct rq *rq, struct task_struct *p, int success)
+probe_wakeup(struct task_struct *p, int success)
 {
        struct trace_array_cpu *data;
        int cpu = smp_processor_id();
index 81003b4..250e7f9 100644 (file)
@@ -17,7 +17,6 @@ static inline int trace_valid_entry(struct trace_entry *entry)
        case TRACE_BRANCH:
        case TRACE_GRAPH_ENT:
        case TRACE_GRAPH_RET:
-       case TRACE_HW_BRANCHES:
        case TRACE_KSYM:
                return 1;
        }
@@ -30,7 +29,7 @@ static int trace_test_buffer_cpu(struct trace_array *tr, int cpu)
        struct trace_entry *entry;
        unsigned int loops = 0;
 
-       while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
+       while ((event = ring_buffer_consume(tr->buffer, cpu, NULL, NULL))) {
                entry = ring_buffer_event_data(event);
 
                /*
@@ -256,7 +255,8 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
 /* Maximum number of functions to trace before diagnosing a hang */
 #define GRAPH_MAX_FUNC_TEST    100000000
 
-static void __ftrace_dump(bool disable_tracing);
+static void
+__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode);
 static unsigned int graph_hang_thresh;
 
 /* Wrap the real function entry probe to avoid possible hanging */
@@ -267,7 +267,7 @@ static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace)
                ftrace_graph_stop();
                printk(KERN_WARNING "BUG: Function graph tracer hang!\n");
                if (ftrace_dump_on_oops)
-                       __ftrace_dump(false);
+                       __ftrace_dump(false, DUMP_ALL);
                return 0;
        }
 
@@ -755,62 +755,6 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
 }
 #endif /* CONFIG_BRANCH_TRACER */
 
-#ifdef CONFIG_HW_BRANCH_TRACER
-int
-trace_selftest_startup_hw_branches(struct tracer *trace,
-                                  struct trace_array *tr)
-{
-       struct trace_iterator *iter;
-       struct tracer tracer;
-       unsigned long count;
-       int ret;
-
-       if (!trace->open) {
-               printk(KERN_CONT "missing open function...");
-               return -1;
-       }
-
-       ret = tracer_init(trace, tr);
-       if (ret) {
-               warn_failed_init_tracer(trace, ret);
-               return ret;
-       }
-
-       /*
-        * The hw-branch tracer needs to collect the trace from the various
-        * cpu trace buffers - before tracing is stopped.
-        */
-       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
-       if (!iter)
-               return -ENOMEM;
-
-       memcpy(&tracer, trace, sizeof(tracer));
-
-       iter->trace = &tracer;
-       iter->tr = tr;
-       iter->pos = -1;
-       mutex_init(&iter->mutex);
-
-       trace->open(iter);
-
-       mutex_destroy(&iter->mutex);
-       kfree(iter);
-
-       tracing_stop();
-
-       ret = trace_test_buffer(tr, &count);
-       trace->reset(tr);
-       tracing_start();
-
-       if (!ret && !count) {
-               printk(KERN_CONT "no entries found..");
-               ret = -1;
-       }
-
-       return ret;
-}
-#endif /* CONFIG_HW_BRANCH_TRACER */
-
 #ifdef CONFIG_KSYM_TRACER
 static int ksym_selftest_dummy;
 
index 766467b..7e72614 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/user_namespace.h>
-#include "cred-internals.h"
 
 struct user_namespace init_user_ns = {
        .kref = {
@@ -137,9 +136,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
        struct hlist_head *hashent = uidhashentry(ns, uid);
        struct user_struct *up, *new;
 
-       /* Make uid_hash_find() + uids_user_create() + uid_hash_insert()
-        * atomic.
-        */
        spin_lock_irq(&uidhash_lock);
        up = uid_hash_find(uid, hashent);
        spin_unlock_irq(&uidhash_lock);
@@ -161,11 +157,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
                spin_lock_irq(&uidhash_lock);
                up = uid_hash_find(uid, hashent);
                if (up) {
-                       /* This case is not possible when CONFIG_USER_SCHED
-                        * is defined, since we serialize alloc_uid() using
-                        * uids_mutex. Hence no need to call
-                        * sched_destroy_user() or remove_user_sysfs_dir().
-                        */
                        key_put(new->uid_keyring);
                        key_put(new->session_keyring);
                        kmem_cache_free(uid_cachep, new);
@@ -178,8 +169,6 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
 
        return up;
 
-       put_user_ns(new->user_ns);
-       kmem_cache_free(uid_cachep, new);
 out_unlock:
        return NULL;
 }
index dee4865..5bfb213 100644 (file)
@@ -774,7 +774,7 @@ void flush_delayed_work(struct delayed_work *dwork)
 {
        if (del_timer_sync(&dwork->timer)) {
                struct cpu_workqueue_struct *cwq;
-               cwq = wq_per_cpu(keventd_wq, get_cpu());
+               cwq = wq_per_cpu(get_wq_data(&dwork->work)->wq, get_cpu());
                __queue_work(cwq, &dwork->work);
                put_cpu();
        }
index ff01710..d85be90 100644 (file)
@@ -356,7 +356,7 @@ config SLUB_STATS
 config DEBUG_KMEMLEAK
        bool "Kernel memory leak detector"
        depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
-               (X86 || ARM || PPC || S390 || SUPERH || MICROBLAZE)
+               (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE)
 
        select DEBUG_FS if SYSFS
        select STACKTRACE if STACKTRACE_SUPPORT
@@ -512,6 +512,18 @@ config PROVE_RCU
 
         Say N if you are unsure.
 
+config PROVE_RCU_REPEATEDLY
+       bool "RCU debugging: don't disable PROVE_RCU on first splat"
+       depends on PROVE_RCU
+       default n
+       help
+        By itself, PROVE_RCU will disable checking upon issuing the
+        first warning (or "splat").  This feature prevents such
+        disabling, allowing multiple RCU-lockdep warnings to be printed
+        on a single reboot.
+
+        Say N if you are unsure.
+
 config LOCKDEP
        bool
        depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
@@ -793,7 +805,7 @@ config RCU_CPU_STALL_DETECTOR
 config RCU_CPU_STALL_VERBOSE
        bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR"
        depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU
-       default n
+       default y
        help
          This option causes RCU to printk detailed per-task information
          for any tasks that are stalling the current RCU grace period.
@@ -1086,6 +1098,13 @@ config DMA_API_DEBUG
          This option causes a performance degredation.  Use only if you want
          to debug device drivers. If unsure, say N.
 
+config ATOMIC64_SELFTEST
+       bool "Perform an atomic64_t self-test at boot"
+       help
+         Enable this option to test the atomic64_t functions at boot.
+
+         If unsure, say N.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
index 0d40152..9e6d3c2 100644 (file)
@@ -39,7 +39,10 @@ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
 lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o
 lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
 obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o
+
+CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
+
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
 obj-$(CONFIG_BTREE) += btree.o
 obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
@@ -101,6 +104,8 @@ obj-$(CONFIG_GENERIC_CSUM) += checksum.o
 
 obj-$(CONFIG_GENERIC_ATOMIC64) += atomic64.o
 
+obj-$(CONFIG_ATOMIC64_SELFTEST) += atomic64_test.o
+
 hostprogs-y    := gen_crc32table
 clean-files    := crc32table.h
 
index 8bee16e..a21c12b 100644 (file)
@@ -162,12 +162,12 @@ int atomic64_add_unless(atomic64_t *v, long long a, long long u)
 {
        unsigned long flags;
        spinlock_t *lock = lock_addr(v);
-       int ret = 1;
+       int ret = 0;
 
        spin_lock_irqsave(lock, flags);
        if (v->counter != u) {
                v->counter += a;
-               ret = 0;
+               ret = 1;
        }
        spin_unlock_irqrestore(lock, flags);
        return ret;
diff --git a/lib/atomic64_test.c b/lib/atomic64_test.c
new file mode 100644 (file)
index 0000000..65e482c
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Testsuite for atomic64_t functions
+ *
+ * Copyright Â© 2010  Luca Barbieri
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <asm/atomic.h>
+
+#define INIT(c) do { atomic64_set(&v, c); r = c; } while (0)
+static __init int test_atomic64(void)
+{
+       long long v0 = 0xaaa31337c001d00dLL;
+       long long v1 = 0xdeadbeefdeafcafeLL;
+       long long v2 = 0xfaceabadf00df001LL;
+       long long onestwos = 0x1111111122222222LL;
+       long long one = 1LL;
+
+       atomic64_t v = ATOMIC64_INIT(v0);
+       long long r = v0;
+       BUG_ON(v.counter != r);
+
+       atomic64_set(&v, v1);
+       r = v1;
+       BUG_ON(v.counter != r);
+       BUG_ON(atomic64_read(&v) != r);
+
+       INIT(v0);
+       atomic64_add(onestwos, &v);
+       r += onestwos;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_add(-one, &v);
+       r += -one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r += onestwos;
+       BUG_ON(atomic64_add_return(onestwos, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r += -one;
+       BUG_ON(atomic64_add_return(-one, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_sub(onestwos, &v);
+       r -= onestwos;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_sub(-one, &v);
+       r -= -one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r -= onestwos;
+       BUG_ON(atomic64_sub_return(onestwos, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r -= -one;
+       BUG_ON(atomic64_sub_return(-one, &v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_inc(&v);
+       r += one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r += one;
+       BUG_ON(atomic64_inc_return(&v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       atomic64_dec(&v);
+       r -= one;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       r -= one;
+       BUG_ON(atomic64_dec_return(&v) != r);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_xchg(&v, v1) != v0);
+       r = v1;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0);
+       r = v1;
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0);
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(atomic64_add_unless(&v, one, v0));
+       BUG_ON(v.counter != r);
+
+       INIT(v0);
+       BUG_ON(!atomic64_add_unless(&v, one, v1));
+       r += one;
+       BUG_ON(v.counter != r);
+
+#if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H)
+       INIT(onestwos);
+       BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1));
+       r -= one;
+       BUG_ON(v.counter != r);
+
+       INIT(0);
+       BUG_ON(atomic64_dec_if_positive(&v) != -one);
+       BUG_ON(v.counter != r);
+
+       INIT(-one);
+       BUG_ON(atomic64_dec_if_positive(&v) != (-one - one));
+       BUG_ON(v.counter != r);
+#else
+#warning Please implement atomic64_dec_if_positive for your architecture, and add it to the IF above
+#endif
+
+       INIT(onestwos);
+       BUG_ON(!atomic64_inc_not_zero(&v));
+       r += one;
+       BUG_ON(v.counter != r);
+
+       INIT(0);
+       BUG_ON(atomic64_inc_not_zero(&v));
+       BUG_ON(v.counter != r);
+
+       INIT(-one);
+       BUG_ON(!atomic64_inc_not_zero(&v));
+       r += one;
+       BUG_ON(v.counter != r);
+
+#ifdef CONFIG_X86
+       printk(KERN_INFO "atomic64 test passed for %s platform %s CX8 and %s SSE\n",
+#ifdef CONFIG_X86_64
+              "x86-64",
+#elif defined(CONFIG_X86_CMPXCHG64)
+              "i586+",
+#else
+              "i386+",
+#endif
+              boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without",
+              boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without");
+#else
+       printk(KERN_INFO "atomic64 test passed\n");
+#endif
+
+       return 0;
+}
+
+core_initcall(test_atomic64);
index 41859a8..c9c6f03 100644 (file)
@@ -95,7 +95,8 @@ static unsigned long *btree_node_alloc(struct btree_head *head, gfp_t gfp)
        unsigned long *node;
 
        node = mempool_alloc(head->mempool, gfp);
-       memset(node, 0, NODESIZE);
+       if (likely(node))
+               memset(node, 0, NODESIZE);
        return node;
 }
 
index b862b30..deebcc5 100644 (file)
@@ -141,6 +141,7 @@ alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
                obj->object = addr;
                obj->descr  = descr;
                obj->state  = ODEBUG_STATE_NONE;
+               obj->astate = 0;
                hlist_del(&obj->node);
 
                hlist_add_head(&obj->node, &b->list);
@@ -252,8 +253,10 @@ static void debug_print_object(struct debug_obj *obj, char *msg)
 
        if (limit < 5 && obj->descr != descr_test) {
                limit++;
-               WARN(1, KERN_ERR "ODEBUG: %s %s object type: %s\n", msg,
-                      obj_states[obj->state], obj->descr->name);
+               WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) "
+                                "object type: %s\n",
+                       msg, obj_states[obj->state], obj->astate,
+                       obj->descr->name);
        }
        debug_objects_warnings++;
 }
@@ -447,7 +450,10 @@ void debug_object_deactivate(void *addr, struct debug_obj_descr *descr)
                case ODEBUG_STATE_INIT:
                case ODEBUG_STATE_INACTIVE:
                case ODEBUG_STATE_ACTIVE:
-                       obj->state = ODEBUG_STATE_INACTIVE;
+                       if (!obj->astate)
+                               obj->state = ODEBUG_STATE_INACTIVE;
+                       else
+                               debug_print_object(obj, "deactivate");
                        break;
 
                case ODEBUG_STATE_DESTROYED:
@@ -553,6 +559,53 @@ out_unlock:
        raw_spin_unlock_irqrestore(&db->lock, flags);
 }
 
+/**
+ * debug_object_active_state - debug checks object usage state machine
+ * @addr:      address of the object
+ * @descr:     pointer to an object specific debug description structure
+ * @expect:    expected state
+ * @next:      state to move to if expected state is found
+ */
+void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+                         unsigned int expect, unsigned int next)
+{
+       struct debug_bucket *db;
+       struct debug_obj *obj;
+       unsigned long flags;
+
+       if (!debug_objects_enabled)
+               return;
+
+       db = get_bucket((unsigned long) addr);
+
+       raw_spin_lock_irqsave(&db->lock, flags);
+
+       obj = lookup_object(addr, db);
+       if (obj) {
+               switch (obj->state) {
+               case ODEBUG_STATE_ACTIVE:
+                       if (obj->astate == expect)
+                               obj->astate = next;
+                       else
+                               debug_print_object(obj, "active_state");
+                       break;
+
+               default:
+                       debug_print_object(obj, "active_state");
+                       break;
+               }
+       } else {
+               struct debug_obj o = { .object = addr,
+                                      .state = ODEBUG_STATE_NOTAVAILABLE,
+                                      .descr = descr };
+
+               debug_print_object(&o, "active_state");
+       }
+
+       raw_spin_unlock_irqrestore(&db->lock, flags);
+}
+
 #ifdef CONFIG_DEBUG_OBJECTS_FREE
 static void __debug_check_no_obj_freed(const void *address, unsigned long size)
 {
@@ -774,7 +827,7 @@ static int __init fixup_free(void *addr, enum debug_obj_state state)
        }
 }
 
-static int
+static int __init
 check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
 {
        struct debug_bucket *db;
@@ -917,7 +970,7 @@ void __init debug_objects_early_init(void)
 /*
  * Convert the statically allocated objects to dynamic ones:
  */
-static int debug_objects_replace_static_objects(void)
+static int __init debug_objects_replace_static_objects(void)
 {
        struct debug_bucket *db = obj_hash;
        struct hlist_node *node, *tmp;
index db521f4..bcb3a4b 100644 (file)
@@ -97,7 +97,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
        u32 src_len, dst_len;
        size_t tmp;
        u8 *in_buf, *in_buf_save, *out_buf;
-       int obytes_processed = 0;
+       int ret = -1;
 
        set_error_fn(error_fn);
 
@@ -174,15 +174,22 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
 
                /* decompress */
                tmp = dst_len;
-               r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
+
+               /* When the input data is not compressed at all,
+                * lzo1x_decompress_safe will fail, so call memcpy()
+                * instead */
+               if (unlikely(dst_len == src_len))
+                       memcpy(out_buf, in_buf, src_len);
+               else {
+                       r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
                                                out_buf, &tmp);
 
-               if (r != LZO_E_OK || dst_len != tmp) {
-                       error("Compressed data violation");
-                       goto exit_2;
+                       if (r != LZO_E_OK || dst_len != tmp) {
+                               error("Compressed data violation");
+                               goto exit_2;
+                       }
                }
 
-               obytes_processed += dst_len;
                if (flush)
                        flush(out_buf, dst_len);
                if (output)
@@ -196,6 +203,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
                        in_buf += src_len;
        }
 
+       ret = 0;
 exit_2:
        if (!input)
                free(in_buf);
@@ -203,7 +211,7 @@ exit_1:
        if (!output)
                free(out_buf);
 exit:
-       return obytes_processed;
+       return ret;
 }
 
 #define decompress unlzo
index ba8b670..01e6427 100644 (file)
@@ -570,7 +570,7 @@ static ssize_t filter_write(struct file *file, const char __user *userbuf,
         * Now parse out the first token and use it as the name for the
         * driver to filter for.
         */
-       for (i = 0; i < NAME_MAX_LEN; ++i) {
+       for (i = 0; i < NAME_MAX_LEN - 1; ++i) {
                current_driver_name[i] = buf[i];
                if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0)
                        break;
index 66eef2e..41b1804 100644 (file)
@@ -99,7 +99,7 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
        ret->element_size = element_size;
        ret->total_nr_elements = total;
        if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO))
-               memset(ret->parts[0], FLEX_ARRAY_FREE,
+               memset(&ret->parts[0], FLEX_ARRAY_FREE,
                                                FLEX_ARRAY_BASE_BYTES_LEFT);
        return ret;
 }
index 63ee4eb..3c79d50 100644 (file)
@@ -9,7 +9,7 @@
  * The Hamming Weight of a number is the total number of bits set in it.
  */
 
-unsigned int hweight32(unsigned int w)
+unsigned int __sw_hweight32(unsigned int w)
 {
 #ifdef ARCH_HAS_FAST_MULTIPLIER
        w -= (w >> 1) & 0x55555555;
@@ -24,29 +24,30 @@ unsigned int hweight32(unsigned int w)
        return (res + (res >> 16)) & 0x000000FF;
 #endif
 }
-EXPORT_SYMBOL(hweight32);
+EXPORT_SYMBOL(__sw_hweight32);
 
-unsigned int hweight16(unsigned int w)
+unsigned int __sw_hweight16(unsigned int w)
 {
        unsigned int res = w - ((w >> 1) & 0x5555);
        res = (res & 0x3333) + ((res >> 2) & 0x3333);
        res = (res + (res >> 4)) & 0x0F0F;
        return (res + (res >> 8)) & 0x00FF;
 }
-EXPORT_SYMBOL(hweight16);
+EXPORT_SYMBOL(__sw_hweight16);
 
-unsigned int hweight8(unsigned int w)
+unsigned int __sw_hweight8(unsigned int w)
 {
        unsigned int res = w - ((w >> 1) & 0x55);
        res = (res & 0x33) + ((res >> 2) & 0x33);
        return (res + (res >> 4)) & 0x0F;
 }
-EXPORT_SYMBOL(hweight8);
+EXPORT_SYMBOL(__sw_hweight8);
 
-unsigned long hweight64(__u64 w)
+unsigned long __sw_hweight64(__u64 w)
 {
 #if BITS_PER_LONG == 32
-       return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+       return __sw_hweight32((unsigned int)(w >> 32)) +
+              __sw_hweight32((unsigned int)w);
 #elif BITS_PER_LONG == 64
 #ifdef ARCH_HAS_FAST_MULTIPLIER
        w -= (w >> 1) & 0x5555555555555555ul;
@@ -63,4 +64,4 @@ unsigned long hweight64(__u64 w)
 #endif
 #endif
 }
-EXPORT_SYMBOL(hweight64);
+EXPORT_SYMBOL(__sw_hweight64);
index e2aa3be..15e10b1 100644 (file)
@@ -44,6 +44,11 @@ static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
        else
                root->rb_node = right;
        rb_set_parent(node, right);
+
+       if (root->augment_cb) {
+               root->augment_cb(node);
+               root->augment_cb(right);
+       }
 }
 
 static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
@@ -67,12 +72,20 @@ static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
        else
                root->rb_node = left;
        rb_set_parent(node, left);
+
+       if (root->augment_cb) {
+               root->augment_cb(node);
+               root->augment_cb(left);
+       }
 }
 
 void rb_insert_color(struct rb_node *node, struct rb_root *root)
 {
        struct rb_node *parent, *gparent;
 
+       if (root->augment_cb)
+               root->augment_cb(node);
+
        while ((parent = rb_parent(node)) && rb_is_red(parent))
        {
                gparent = rb_parent(parent);
@@ -227,12 +240,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
        else
        {
                struct rb_node *old = node, *left;
+               int old_parent_cb = 0;
+               int successor_parent_cb = 0;
 
                node = node->rb_right;
                while ((left = node->rb_left) != NULL)
                        node = left;
 
                if (rb_parent(old)) {
+                       old_parent_cb = 1;
                        if (rb_parent(old)->rb_left == old)
                                rb_parent(old)->rb_left = node;
                        else
@@ -247,8 +263,10 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
                if (parent == old) {
                        parent = node;
                } else {
+                       successor_parent_cb = 1;
                        if (child)
                                rb_set_parent(child, parent);
+
                        parent->rb_left = child;
 
                        node->rb_right = old->rb_right;
@@ -259,6 +277,24 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
                node->rb_left = old->rb_left;
                rb_set_parent(old->rb_left, node);
 
+               if (root->augment_cb) {
+                       /*
+                        * Here, three different nodes can have new children.
+                        * The parent of the successor node that was selected
+                        * to replace the node to be erased.
+                        * The node that is getting erased and is now replaced
+                        * by its successor.
+                        * The parent of the node getting erased-replaced.
+                        */
+                       if (successor_parent_cb)
+                               root->augment_cb(parent);
+
+                       root->augment_cb(node);
+
+                       if (old_parent_cb)
+                               root->augment_cb(rb_parent(old));
+               }
+
                goto color;
        }
 
@@ -267,15 +303,19 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
 
        if (child)
                rb_set_parent(child, parent);
-       if (parent)
-       {
+
+       if (parent) {
                if (parent->rb_left == node)
                        parent->rb_left = child;
                else
                        parent->rb_right = child;
-       }
-       else
+
+               if (root->augment_cb)
+                       root->augment_cb(parent);
+
+       } else {
                root->rb_node = child;
+       }
 
  color:
        if (color == RB_BLACK)
index 3e3365e..ceba8e2 100644 (file)
@@ -136,9 +136,10 @@ __rwsem_do_wake(struct rw_semaphore *sem, int downgrading)
  out:
        return sem;
 
-       /* undo the change to count, but check for a transition 1->0 */
+       /* undo the change to the active count, but check for a transition
+        * 1->0 */
  undo:
-       if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) != 0)
+       if (rwsem_atomic_update(-RWSEM_ACTIVE_BIAS, sem) & RWSEM_ACTIVE_MASK)
                goto out;
        goto try_again;
 }
index 24112e5..46d34b0 100644 (file)
@@ -118,6 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
 
        return simple_strtoull(cp, endp, base);
 }
+EXPORT_SYMBOL(simple_strtoll);
 
 /**
  * strict_strtoul - convert a string to an unsigned long strictly
@@ -408,12 +409,12 @@ enum format_type {
 };
 
 struct printf_spec {
-       u16     type;
-       s16     field_width;    /* width of output field */
+       u8      type;           /* format_type enum */
        u8      flags;          /* flags to number() */
-       u8      base;
-       s8      precision;      /* # of digits/chars */
-       u8      qualifier;
+       u8      base;           /* number base, 8, 10 or 16 only */
+       u8      qualifier;      /* number qualifier, one of 'hHlLtzZ' */
+       s16     field_width;    /* width of output field */
+       s16     precision;      /* # of digits/chars */
 };
 
 static char *number(char *buf, char *end, unsigned long long num,
index f13e067..707d0dc 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/writeback.h>
 #include <linux/device.h>
 
+static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
+
 void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
 {
 }
@@ -25,6 +27,11 @@ struct backing_dev_info default_backing_dev_info = {
 };
 EXPORT_SYMBOL_GPL(default_backing_dev_info);
 
+struct backing_dev_info noop_backing_dev_info = {
+       .name           = "noop",
+};
+EXPORT_SYMBOL_GPL(noop_backing_dev_info);
+
 static struct class *bdi_class;
 
 /*
@@ -715,6 +722,33 @@ void bdi_destroy(struct backing_dev_info *bdi)
 }
 EXPORT_SYMBOL(bdi_destroy);
 
+/*
+ * For use from filesystems to quickly init and register a bdi associated
+ * with dirty writeback
+ */
+int bdi_setup_and_register(struct backing_dev_info *bdi, char *name,
+                          unsigned int cap)
+{
+       char tmp[32];
+       int err;
+
+       bdi->name = name;
+       bdi->capabilities = cap;
+       err = bdi_init(bdi);
+       if (err)
+               return err;
+
+       sprintf(tmp, "%.28s%s", name, "-%d");
+       err = bdi_register(bdi, NULL, tmp, atomic_long_inc_return(&bdi_seq));
+       if (err) {
+               bdi_destroy(bdi);
+               return err;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(bdi_setup_and_register);
+
 static wait_queue_head_t congestion_wqh[2] = {
                __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
                __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
index 6034dc9..4c9e6bb 100644 (file)
@@ -546,6 +546,7 @@ static void free_huge_page(struct page *page)
 
        mapping = (struct address_space *) page_private(page);
        set_page_private(page, 0);
+       page->mapping = NULL;
        BUG_ON(page_count(page));
        INIT_LIST_HEAD(&page->lru);
 
@@ -1038,7 +1039,7 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma,
                page = alloc_buddy_huge_page(h, vma, addr);
                if (!page) {
                        hugetlb_put_quota(inode->i_mapping, chg);
-                       return ERR_PTR(-VM_FAULT_OOM);
+                       return ERR_PTR(-VM_FAULT_SIGBUS);
                }
        }
 
@@ -2447,8 +2448,10 @@ retry:
                        spin_lock(&inode->i_lock);
                        inode->i_blocks += blocks_per_huge_page(h);
                        spin_unlock(&inode->i_lock);
-               } else
+               } else {
                        lock_page(page);
+                       page->mapping = HUGETLB_POISON;
+               }
        }
 
        /*
index 8cdfc2a..956880f 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -365,7 +365,7 @@ static int break_ksm(struct vm_area_struct *vma, unsigned long addr)
        do {
                cond_resched();
                page = follow_page(vma, addr, FOLL_GET);
-               if (!page)
+               if (IS_ERR_OR_NULL(page))
                        break;
                if (PageKsm(page))
                        ret = handle_mm_fault(vma->vm_mm, vma, addr,
@@ -447,7 +447,7 @@ static struct page *get_mergeable_page(struct rmap_item *rmap_item)
                goto out;
 
        page = follow_page(vma, addr, FOLL_GET);
-       if (!page)
+       if (IS_ERR_OR_NULL(page))
                goto out;
        if (PageAnon(page)) {
                flush_anon_page(vma, page, addr);
@@ -1086,7 +1086,7 @@ struct rmap_item *unstable_tree_search_insert(struct rmap_item *rmap_item,
                cond_resched();
                tree_rmap_item = rb_entry(*new, struct rmap_item, node);
                tree_page = get_mergeable_page(tree_rmap_item);
-               if (!tree_page)
+               if (IS_ERR_OR_NULL(tree_page))
                        return NULL;
 
                /*
@@ -1294,7 +1294,7 @@ next_mm:
                        if (ksm_test_exit(mm))
                                break;
                        *page = follow_page(vma, ksm_scan.address, FOLL_GET);
-                       if (*page && PageAnon(*page)) {
+                       if (!IS_ERR_OR_NULL(*page) && PageAnon(*page)) {
                                flush_anon_page(vma, *page, ksm_scan.address);
                                flush_dcache_page(*page);
                                rmap_item = get_next_rmap_item(slot,
@@ -1308,7 +1308,7 @@ next_mm:
                                up_read(&mm->mmap_sem);
                                return rmap_item;
                        }
-                       if (*page)
+                       if (!IS_ERR_OR_NULL(*page))
                                put_page(*page);
                        ksm_scan.address += PAGE_SIZE;
                        cond_resched();
@@ -1367,7 +1367,7 @@ next_mm:
 static void ksm_do_scan(unsigned int scan_npages)
 {
        struct rmap_item *rmap_item;
-       struct page *page;
+       struct page *uninitialized_var(page);
 
        while (scan_npages--) {
                cond_resched();
index f4ede99..8a79a6f 100644 (file)
@@ -1601,7 +1601,6 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                         * There is a small race that "from" or "to" can be
                         * freed by rmdir, so we use css_tryget().
                         */
-                       rcu_read_lock();
                        from = mc.from;
                        to = mc.to;
                        if (from && css_tryget(&from->css)) {
@@ -1622,7 +1621,6 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
                                        do_continue = (to == mem_over_limit);
                                css_put(&to->css);
                        }
-                       rcu_read_unlock();
                        if (do_continue) {
                                DEFINE_WAIT(wait);
                                prepare_to_wait(&mc.waitq, &wait,
@@ -2429,11 +2427,11 @@ int mem_cgroup_prepare_migration(struct page *page, struct mem_cgroup **ptr)
        }
        unlock_page_cgroup(pc);
 
+       *ptr = mem;
        if (mem) {
-               ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false);
+               ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, ptr, false);
                css_put(&mem->css);
        }
-       *ptr = mem;
        return ret;
 }
 
index 8f4e2df..3f82720 100644 (file)
@@ -607,44 +607,3 @@ void user_shm_unlock(size_t size, struct user_struct *user)
        spin_unlock(&shmlock_user_lock);
        free_uid(user);
 }
-
-int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim,
-                         size_t size)
-{
-       unsigned long lim, vm, pgsz;
-       int error = -ENOMEM;
-
-       pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
-
-       down_write(&mm->mmap_sem);
-
-       lim = ACCESS_ONCE(rlim[RLIMIT_AS].rlim_cur) >> PAGE_SHIFT;
-       vm   = mm->total_vm + pgsz;
-       if (lim < vm)
-               goto out;
-
-       lim = ACCESS_ONCE(rlim[RLIMIT_MEMLOCK].rlim_cur) >> PAGE_SHIFT;
-       vm   = mm->locked_vm + pgsz;
-       if (lim < vm)
-               goto out;
-
-       mm->total_vm  += pgsz;
-       mm->locked_vm += pgsz;
-
-       error = 0;
- out:
-       up_write(&mm->mmap_sem);
-       return error;
-}
-
-void refund_locked_memory(struct mm_struct *mm, size_t size)
-{
-       unsigned long pgsz = PAGE_ALIGN(size) >> PAGE_SHIFT;
-
-       down_write(&mm->mmap_sem);
-
-       mm->total_vm  -= pgsz;
-       mm->locked_vm -= pgsz;
-
-       up_write(&mm->mmap_sem);
-}
index 75557c6..456ec6f 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -507,11 +507,12 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
        struct address_space *mapping = NULL;
        struct prio_tree_root *root = NULL;
        struct file *file = vma->vm_file;
-       struct anon_vma *anon_vma = NULL;
        long adjust_next = 0;
        int remove_next = 0;
 
        if (next && !insert) {
+               struct vm_area_struct *exporter = NULL;
+
                if (end >= next->vm_end) {
                        /*
                         * vma expands, overlapping all the next, and
@@ -519,7 +520,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
                         */
 again:                 remove_next = 1 + (end > next->vm_end);
                        end = next->vm_end;
-                       anon_vma = next->anon_vma;
+                       exporter = next;
                        importer = vma;
                } else if (end > next->vm_start) {
                        /*
@@ -527,7 +528,7 @@ again:                      remove_next = 1 + (end > next->vm_end);
                         * mprotect case 5 shifting the boundary up.
                         */
                        adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
-                       anon_vma = next->anon_vma;
+                       exporter = next;
                        importer = vma;
                } else if (end < vma->vm_end) {
                        /*
@@ -536,28 +537,19 @@ again:                    remove_next = 1 + (end > next->vm_end);
                         * mprotect case 4 shifting the boundary down.
                         */
                        adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
-                       anon_vma = next->anon_vma;
+                       exporter = vma;
                        importer = next;
                }
-       }
 
-       /*
-        * When changing only vma->vm_end, we don't really need anon_vma lock.
-        */
-       if (vma->anon_vma && (insert || importer || start != vma->vm_start))
-               anon_vma = vma->anon_vma;
-       if (anon_vma) {
                /*
                 * Easily overlooked: when mprotect shifts the boundary,
                 * make sure the expanding vma has anon_vma set if the
                 * shrinking vma had, to cover any anon pages imported.
                 */
-               if (importer && !importer->anon_vma) {
-                       /* Block reverse map lookups until things are set up. */
-                       if (anon_vma_clone(importer, vma)) {
+               if (exporter && exporter->anon_vma && !importer->anon_vma) {
+                       if (anon_vma_clone(importer, exporter))
                                return -ENOMEM;
-                       }
-                       importer->anon_vma = anon_vma;
+                       importer->anon_vma = exporter->anon_vma;
                }
        }
 
@@ -824,6 +816,61 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
        return NULL;
 }
 
+/*
+ * Rough compatbility check to quickly see if it's even worth looking
+ * at sharing an anon_vma.
+ *
+ * They need to have the same vm_file, and the flags can only differ
+ * in things that mprotect may change.
+ *
+ * NOTE! The fact that we share an anon_vma doesn't _have_ to mean that
+ * we can merge the two vma's. For example, we refuse to merge a vma if
+ * there is a vm_ops->close() function, because that indicates that the
+ * driver is doing some kind of reference counting. But that doesn't
+ * really matter for the anon_vma sharing case.
+ */
+static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b)
+{
+       return a->vm_end == b->vm_start &&
+               mpol_equal(vma_policy(a), vma_policy(b)) &&
+               a->vm_file == b->vm_file &&
+               !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) &&
+               b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT);
+}
+
+/*
+ * Do some basic sanity checking to see if we can re-use the anon_vma
+ * from 'old'. The 'a'/'b' vma's are in VM order - one of them will be
+ * the same as 'old', the other will be the new one that is trying
+ * to share the anon_vma.
+ *
+ * NOTE! This runs with mm_sem held for reading, so it is possible that
+ * the anon_vma of 'old' is concurrently in the process of being set up
+ * by another page fault trying to merge _that_. But that's ok: if it
+ * is being set up, that automatically means that it will be a singleton
+ * acceptable for merging, so we can do all of this optimistically. But
+ * we do that ACCESS_ONCE() to make sure that we never re-load the pointer.
+ *
+ * IOW: that the "list_is_singular()" test on the anon_vma_chain only
+ * matters for the 'stable anon_vma' case (ie the thing we want to avoid
+ * is to return an anon_vma that is "complex" due to having gone through
+ * a fork).
+ *
+ * We also make sure that the two vma's are compatible (adjacent,
+ * and with the same memory policies). That's all stable, even with just
+ * a read lock on the mm_sem.
+ */
+static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b)
+{
+       if (anon_vma_compatible(a, b)) {
+               struct anon_vma *anon_vma = ACCESS_ONCE(old->anon_vma);
+
+               if (anon_vma && list_is_singular(&old->anon_vma_chain))
+                       return anon_vma;
+       }
+       return NULL;
+}
+
 /*
  * find_mergeable_anon_vma is used by anon_vma_prepare, to check
  * neighbouring vmas for a suitable anon_vma, before it goes off
@@ -834,28 +881,16 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
  */
 struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
 {
+       struct anon_vma *anon_vma;
        struct vm_area_struct *near;
-       unsigned long vm_flags;
 
        near = vma->vm_next;
        if (!near)
                goto try_prev;
 
-       /*
-        * Since only mprotect tries to remerge vmas, match flags
-        * which might be mprotected into each other later on.
-        * Neither mlock nor madvise tries to remerge at present,
-        * so leave their flags as obstructing a merge.
-        */
-       vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
-       vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
-       if (near->anon_vma && vma->vm_end == near->vm_start &&
-                       mpol_equal(vma_policy(vma), vma_policy(near)) &&
-                       can_vma_merge_before(near, vm_flags,
-                               NULL, vma->vm_file, vma->vm_pgoff +
-                               ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)))
-               return near->anon_vma;
+       anon_vma = reusable_anon_vma(near, vma, near);
+       if (anon_vma)
+               return anon_vma;
 try_prev:
        /*
         * It is potentially slow to have to call find_vma_prev here.
@@ -868,14 +903,9 @@ try_prev:
        if (!near)
                goto none;
 
-       vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
-       vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
-       if (near->anon_vma && near->vm_end == vma->vm_start &&
-                       mpol_equal(vma_policy(near), vma_policy(vma)) &&
-                       can_vma_merge_after(near, vm_flags,
-                               NULL, vma->vm_file, vma->vm_pgoff))
-               return near->anon_vma;
+       anon_vma = reusable_anon_vma(near, near, vma);
+       if (anon_vma)
+               return anon_vma;
 none:
        /*
         * There's no absolute need to look only at touching neighbours:
@@ -1947,7 +1977,8 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
                return 0;
 
        /* Clean everything up if vma_adjust failed. */
-       new->vm_ops->close(new);
+       if (new->vm_ops && new->vm_ops->close)
+               new->vm_ops->close(new);
        if (new->vm_file) {
                if (vma->vm_flags & VM_EXECUTABLE)
                        removed_exe_file_vma(mm);
index eaa7a09..0feeef8 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -133,8 +133,8 @@ int anon_vma_prepare(struct vm_area_struct *vma)
                                goto out_enomem_free_avc;
                        allocated = anon_vma;
                }
-               spin_lock(&anon_vma->lock);
 
+               spin_lock(&anon_vma->lock);
                /* page_table_lock to protect against threads */
                spin_lock(&mm->page_table_lock);
                if (likely(!vma->anon_vma)) {
@@ -144,14 +144,15 @@ int anon_vma_prepare(struct vm_area_struct *vma)
                        list_add(&avc->same_vma, &vma->anon_vma_chain);
                        list_add(&avc->same_anon_vma, &anon_vma->head);
                        allocated = NULL;
+                       avc = NULL;
                }
                spin_unlock(&mm->page_table_lock);
-
                spin_unlock(&anon_vma->lock);
-               if (unlikely(allocated)) {
+
+               if (unlikely(allocated))
                        anon_vma_free(allocated);
+               if (unlikely(avc))
                        anon_vma_chain_free(avc);
-               }
        }
        return 0;
 
@@ -182,7 +183,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
 {
        struct anon_vma_chain *avc, *pavc;
 
-       list_for_each_entry(pavc, &src->anon_vma_chain, same_vma) {
+       list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
                avc = anon_vma_chain_alloc();
                if (!avc)
                        goto enomem_failure;
@@ -335,14 +336,13 @@ vma_address(struct page *page, struct vm_area_struct *vma)
 
 /*
  * At what user virtual address is page expected in vma?
- * checking that the page matches the vma.
+ * Caller should check the page is actually part of the vma.
  */
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
-       if (PageAnon(page)) {
-               if (vma->anon_vma != page_anon_vma(page))
-                       return -EFAULT;
-       } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
+       if (PageAnon(page))
+               ;
+       else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
                if (!vma->vm_file ||
                    vma->vm_file->f_mapping != page->mapping)
                        return -EFAULT;
@@ -730,13 +730,29 @@ void page_move_anon_rmap(struct page *page,
  * @page:      the page to add the mapping to
  * @vma:       the vm area in which the mapping is added
  * @address:   the user virtual address mapped
+ * @exclusive: the page is exclusively owned by the current process
  */
 static void __page_set_anon_rmap(struct page *page,
-       struct vm_area_struct *vma, unsigned long address)
+       struct vm_area_struct *vma, unsigned long address, int exclusive)
 {
        struct anon_vma *anon_vma = vma->anon_vma;
 
        BUG_ON(!anon_vma);
+
+       /*
+        * If the page isn't exclusively mapped into this vma,
+        * we must use the _oldest_ possible anon_vma for the
+        * page mapping!
+        *
+        * So take the last AVC chain entry in the vma, which is
+        * the deepest ancestor, and use the anon_vma from that.
+        */
+       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;
+       }
+
        anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
        page->mapping = (struct address_space *) anon_vma;
        page->index = linear_page_index(vma, address);
@@ -791,7 +807,7 @@ void page_add_anon_rmap(struct page *page,
        VM_BUG_ON(!PageLocked(page));
        VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
        if (first)
-               __page_set_anon_rmap(page, vma, address);
+               __page_set_anon_rmap(page, vma, address, 0);
        else
                __page_check_anon_rmap(page, vma, address);
 }
@@ -813,7 +829,7 @@ void page_add_new_anon_rmap(struct page *page,
        SetPageSwapBacked(page);
        atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */
        __inc_zone_page_state(page, NR_ANON_PAGES);
-       __page_set_anon_rmap(page, vma, address);
+       __page_set_anon_rmap(page, vma, address, 1);
        if (page_evictable(page, vma))
                lru_cache_add_lru(page, LRU_ACTIVE_ANON);
        else
index 7d6c8b1..d2a54fe 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2153,7 +2153,7 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
        int local_node;
 
        if (slab_state >= UP && (s < kmalloc_caches ||
-                       s > kmalloc_caches + KMALLOC_CACHES))
+                       s >= kmalloc_caches + KMALLOC_CACHES))
                local_node = page_to_nid(virt_to_page(s));
        else
                local_node = 0;
index 99d68c3..9753b69 100644 (file)
@@ -1626,7 +1626,10 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
        /* Connectionless channel */
        if (sk->sk_type == SOCK_DGRAM) {
                skb = l2cap_create_connless_pdu(sk, msg, len);
-               err = l2cap_do_send(sk, skb);
+               if (IS_ERR(skb))
+                       err = PTR_ERR(skb);
+               else
+                       err = l2cap_do_send(sk, skb);
                goto done;
        }
 
index 6980625..eaa0e1b 100644 (file)
@@ -723,11 +723,11 @@ static int br_multicast_igmp3_report(struct net_bridge *br,
                if (!pskb_may_pull(skb, len))
                        return -EINVAL;
 
-               grec = (void *)(skb->data + len);
+               grec = (void *)(skb->data + len - sizeof(*grec));
                group = grec->grec_mca;
                type = grec->grec_type;
 
-               len += grec->grec_nsrcs * 4;
+               len += ntohs(grec->grec_nsrcs) * 4;
                if (!pskb_may_pull(skb, len))
                        return -EINVAL;
 
@@ -957,9 +957,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
        unsigned offset;
        int err;
 
-       BR_INPUT_SKB_CB(skb)->igmp = 0;
-       BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
-
        /* We treat OOM as packet loss for now. */
        if (!pskb_may_pull(skb, sizeof(*iph)))
                return -EINVAL;
@@ -1049,6 +1046,9 @@ err_out:
 int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
                     struct sk_buff *skb)
 {
+       BR_INPUT_SKB_CB(skb)->igmp = 0;
+       BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
+
        if (br->multicast_disabled)
                return 0;
 
index 3a7dffb..da99cf1 100644 (file)
@@ -445,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
                                return -EFAULT;
                        }
                } else if (count == 1) {
-                       if (copy_from_user(&sfilter, optval, optlen))
+                       if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
                                return -EFAULT;
                }
 
index 1c8a0ce..264137f 100644 (file)
@@ -1451,7 +1451,7 @@ static inline void net_timestamp(struct sk_buff *skb)
  *
  * return values:
  *     NET_RX_SUCCESS  (no congestion)
- *     NET_RX_DROP     (packet was dropped)
+ *     NET_RX_DROP     (packet was dropped, but freed)
  *
  * dev_forward_skb can be used for injecting an skb from the
  * start_xmit function of one device into the receive queue
@@ -1465,12 +1465,11 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
 {
        skb_orphan(skb);
 
-       if (!(dev->flags & IFF_UP))
-               return NET_RX_DROP;
-
-       if (skb->len > (dev->mtu + dev->hard_header_len))
+       if (!(dev->flags & IFF_UP) ||
+           (skb->len > (dev->mtu + dev->hard_header_len))) {
+               kfree_skb(skb);
                return NET_RX_DROP;
-
+       }
        skb_set_dev(skb, dev);
        skb->tstamp.tv64 = 0;
        skb->pkt_type = PACKET_HOST;
@@ -1989,8 +1988,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
                        if (dev->real_num_tx_queues > 1)
                                queue_index = skb_tx_hash(dev, skb);
 
-                       if (sk && sk->sk_dst_cache)
-                               sk_tx_queue_set(sk, queue_index);
+                       if (sk) {
+                               struct dst_entry *dst = rcu_dereference_bh(sk->sk_dst_cache);
+
+                               if (dst && skb_dst(skb) == dst)
+                                       sk_tx_queue_set(sk, queue_index);
+                       }
                }
        }
 
index 4568120..31e85d3 100644 (file)
@@ -602,12 +602,19 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
        a->tx_compressed = b->tx_compressed;
 };
 
+/* All VF info */
 static inline int rtnl_vfinfo_size(const struct net_device *dev)
 {
-       if (dev->dev.parent && dev_is_pci(dev->dev.parent))
-               return dev_num_vf(dev->dev.parent) *
-                       sizeof(struct ifla_vf_info);
-       else
+       if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
+
+               int num_vfs = dev_num_vf(dev->dev.parent);
+               size_t size = nlmsg_total_size(sizeof(struct nlattr));
+               size += nlmsg_total_size(num_vfs * sizeof(struct nlattr));
+               size += num_vfs * (sizeof(struct ifla_vf_mac) +
+                                 sizeof(struct ifla_vf_vlan) +
+                                 sizeof(struct ifla_vf_tx_rate));
+               return size;
+       } else
                return 0;
 }
 
@@ -629,7 +636,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
               + nla_total_size(1) /* IFLA_OPERSTATE */
               + nla_total_size(1) /* IFLA_LINKMODE */
               + nla_total_size(4) /* IFLA_NUM_VF */
-              + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */
+              + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
               + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
 }
 
@@ -700,14 +707,37 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 
        if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
                int i;
-               struct ifla_vf_info ivi;
 
-               NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
-               for (i = 0; i < dev_num_vf(dev->dev.parent); i++) {
+               struct nlattr *vfinfo, *vf;
+               int num_vfs = dev_num_vf(dev->dev.parent);
+
+               NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs);
+               vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
+               if (!vfinfo)
+                       goto nla_put_failure;
+               for (i = 0; i < num_vfs; i++) {
+                       struct ifla_vf_info ivi;
+                       struct ifla_vf_mac vf_mac;
+                       struct ifla_vf_vlan vf_vlan;
+                       struct ifla_vf_tx_rate vf_tx_rate;
                        if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
                                break;
-                       NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi);
+                       vf_mac.vf = vf_vlan.vf = vf_tx_rate.vf = ivi.vf;
+                       memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
+                       vf_vlan.vlan = ivi.vlan;
+                       vf_vlan.qos = ivi.qos;
+                       vf_tx_rate.rate = ivi.tx_rate;
+                       vf = nla_nest_start(skb, IFLA_VF_INFO);
+                       if (!vf) {
+                               nla_nest_cancel(skb, vfinfo);
+                               goto nla_put_failure;
+                       }
+                       NLA_PUT(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac);
+                       NLA_PUT(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan);
+                       NLA_PUT(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), &vf_tx_rate);
+                       nla_nest_end(skb, vf);
                }
+               nla_nest_end(skb, vfinfo);
        }
        if (dev->rtnl_link_ops) {
                if (rtnl_link_fill(skb, dev) < 0)
@@ -769,12 +799,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_LINKINFO]         = { .type = NLA_NESTED },
        [IFLA_NET_NS_PID]       = { .type = NLA_U32 },
        [IFLA_IFALIAS]          = { .type = NLA_STRING, .len = IFALIASZ-1 },
-       [IFLA_VF_MAC]           = { .type = NLA_BINARY,
-                                   .len = sizeof(struct ifla_vf_mac) },
-       [IFLA_VF_VLAN]          = { .type = NLA_BINARY,
-                                   .len = sizeof(struct ifla_vf_vlan) },
-       [IFLA_VF_TX_RATE]       = { .type = NLA_BINARY,
-                                   .len = sizeof(struct ifla_vf_tx_rate) },
+       [IFLA_VFINFO_LIST]      = {. type = NLA_NESTED },
 };
 EXPORT_SYMBOL(ifla_policy);
 
@@ -783,6 +808,19 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
        [IFLA_INFO_DATA]        = { .type = NLA_NESTED },
 };
 
+static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = {
+       [IFLA_VF_INFO]          = { .type = NLA_NESTED },
+};
+
+static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
+       [IFLA_VF_MAC]           = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_mac) },
+       [IFLA_VF_VLAN]          = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_vlan) },
+       [IFLA_VF_TX_RATE]       = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_tx_rate) },
+};
+
 struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
 {
        struct net *net;
@@ -812,6 +850,52 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
        return 0;
 }
 
+static int do_setvfinfo(struct net_device *dev, struct nlattr *attr)
+{
+       int rem, err = -EINVAL;
+       struct nlattr *vf;
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       nla_for_each_nested(vf, attr, rem) {
+               switch (nla_type(vf)) {
+               case IFLA_VF_MAC: {
+                       struct ifla_vf_mac *ivm;
+                       ivm = nla_data(vf);
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_set_vf_mac)
+                               err = ops->ndo_set_vf_mac(dev, ivm->vf,
+                                                         ivm->mac);
+                       break;
+               }
+               case IFLA_VF_VLAN: {
+                       struct ifla_vf_vlan *ivv;
+                       ivv = nla_data(vf);
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_set_vf_vlan)
+                               err = ops->ndo_set_vf_vlan(dev, ivv->vf,
+                                                          ivv->vlan,
+                                                          ivv->qos);
+                       break;
+               }
+               case IFLA_VF_TX_RATE: {
+                       struct ifla_vf_tx_rate *ivt;
+                       ivt = nla_data(vf);
+                       err = -EOPNOTSUPP;
+                       if (ops->ndo_set_vf_tx_rate)
+                               err = ops->ndo_set_vf_tx_rate(dev, ivt->vf,
+                                                             ivt->rate);
+                       break;
+               }
+               default:
+                       err = -EINVAL;
+                       break;
+               }
+               if (err)
+                       break;
+       }
+       return err;
+}
+
 static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                      struct nlattr **tb, char *ifname, int modified)
 {
@@ -942,40 +1026,17 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                write_unlock_bh(&dev_base_lock);
        }
 
-       if (tb[IFLA_VF_MAC]) {
-               struct ifla_vf_mac *ivm;
-               ivm = nla_data(tb[IFLA_VF_MAC]);
-               err = -EOPNOTSUPP;
-               if (ops->ndo_set_vf_mac)
-                       err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac);
-               if (err < 0)
-                       goto errout;
-               modified = 1;
-       }
-
-       if (tb[IFLA_VF_VLAN]) {
-               struct ifla_vf_vlan *ivv;
-               ivv = nla_data(tb[IFLA_VF_VLAN]);
-               err = -EOPNOTSUPP;
-               if (ops->ndo_set_vf_vlan)
-                       err = ops->ndo_set_vf_vlan(dev, ivv->vf,
-                                                  ivv->vlan,
-                                                  ivv->qos);
-               if (err < 0)
-                       goto errout;
-               modified = 1;
-       }
-       err = 0;
-
-       if (tb[IFLA_VF_TX_RATE]) {
-               struct ifla_vf_tx_rate *ivt;
-               ivt = nla_data(tb[IFLA_VF_TX_RATE]);
-               err = -EOPNOTSUPP;
-               if (ops->ndo_set_vf_tx_rate)
-                       err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate);
-               if (err < 0)
-                       goto errout;
-               modified = 1;
+       if (tb[IFLA_VFINFO_LIST]) {
+               struct nlattr *attr;
+               int rem;
+               nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
+                       if (nla_type(attr) != IFLA_VF_INFO)
+                               goto errout;
+                       err = do_setvfinfo(dev, attr);
+                       if (err < 0)
+                               goto errout;
+                       modified = 1;
+               }
        }
        err = 0;
 
@@ -1270,10 +1331,11 @@ replay:
                        err = ops->newlink(net, dev, tb, data);
                else
                        err = register_netdevice(dev);
-               if (err < 0 && !IS_ERR(dev)) {
+
+               if (err < 0 && !IS_ERR(dev))
                        free_netdev(dev);
+               if (err < 0)
                        goto out;
-               }
 
                err = rtnl_configure_link(dev, ifm);
                if (err < 0)
index c7da600..93c91b6 100644 (file)
@@ -151,6 +151,9 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
        dev_load(sock_net(sk), ifr.ifr_name);
        dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
 
+       if (!dev)
+               return -ENODEV;
+
        if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl)
                ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
 
index 6e74706..80769f1 100644 (file)
@@ -661,13 +661,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
 #endif
 #endif
 
-#ifdef CONFIG_FDDI
+#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
        case ARPHRD_FDDI:
                arp->ar_hrd = htons(ARPHRD_ETHER);
                arp->ar_pro = htons(ETH_P_IP);
                break;
 #endif
-#ifdef CONFIG_TR
+#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
        case ARPHRD_IEEE802_TR:
                arp->ar_hrd = htons(ARPHRD_IEEE802);
                arp->ar_pro = htons(ETH_P_IP);
@@ -1051,7 +1051,7 @@ static int arp_req_set(struct net *net, struct arpreq *r,
                        return -EINVAL;
        }
        switch (dev->type) {
-#ifdef CONFIG_FDDI
+#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)
        case ARPHRD_FDDI:
                /*
                 * According to RFC 1390, FDDI devices should accept ARP
index 59a8387..c98f115 100644 (file)
@@ -209,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
 {
        struct node *ret = tnode_get_child(tn, i);
 
-       return rcu_dereference(ret);
+       return rcu_dereference_check(ret,
+                                    rcu_read_lock_held() ||
+                                    lockdep_rtnl_is_held());
 }
 
 static inline int tnode_child_length(const struct tnode *tn)
index c65f18e..d1bcc9f 100644 (file)
@@ -120,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
        newskb->pkt_type = PACKET_LOOPBACK;
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
        WARN_ON(!skb_dst(newskb));
-       netif_rx(newskb);
+       netif_rx_ni(newskb);
        return 0;
 }
 
index 9d4f6d1..ec19a89 100644 (file)
@@ -754,7 +754,8 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)
                c->next = mfc_unres_queue;
                mfc_unres_queue = c;
 
-               mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
+               if (atomic_read(&net->ipv4.cache_resolve_queue_len) == 1)
+                       mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);
        }
 
        /*
index 0f8caf6..296150b 100644 (file)
@@ -2839,7 +2839,6 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool * __percpu *pool)
                        if (p->md5_desc.tfm)
                                crypto_free_hash(p->md5_desc.tfm);
                        kfree(p);
-                       p = NULL;
                }
        }
        free_percpu(pool);
@@ -2937,25 +2936,40 @@ retry:
 
 EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
 
-struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu)
+
+/**
+ *     tcp_get_md5sig_pool - get md5sig_pool for this user
+ *
+ *     We use percpu structure, so if we succeed, we exit with preemption
+ *     and BH disabled, to make sure another thread or softirq handling
+ *     wont try to get same context.
+ */
+struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
 {
        struct tcp_md5sig_pool * __percpu *p;
-       spin_lock_bh(&tcp_md5sig_pool_lock);
+
+       local_bh_disable();
+
+       spin_lock(&tcp_md5sig_pool_lock);
        p = tcp_md5sig_pool;
        if (p)
                tcp_md5sig_users++;
-       spin_unlock_bh(&tcp_md5sig_pool_lock);
-       return (p ? *per_cpu_ptr(p, cpu) : NULL);
-}
+       spin_unlock(&tcp_md5sig_pool_lock);
+
+       if (p)
+               return *per_cpu_ptr(p, smp_processor_id());
 
-EXPORT_SYMBOL(__tcp_get_md5sig_pool);
+       local_bh_enable();
+       return NULL;
+}
+EXPORT_SYMBOL(tcp_get_md5sig_pool);
 
-void __tcp_put_md5sig_pool(void)
+void tcp_put_md5sig_pool(void)
 {
+       local_bh_enable();
        tcp_free_md5sig_pool();
 }
-
-EXPORT_SYMBOL(__tcp_put_md5sig_pool);
+EXPORT_SYMBOL(tcp_put_md5sig_pool);
 
 int tcp_md5_hash_header(struct tcp_md5sig_pool *hp,
                        struct tcphdr *th)
index 954bbfb..c36522a 100644 (file)
@@ -472,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp4_lib_lookup2(net, INADDR_ANY, sport,
-                                                 daddr, hnum, dif,
+                       result = udp4_lib_lookup2(net, saddr, sport,
+                                                 INADDR_ANY, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
@@ -1527,6 +1527,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 
        uh   = udp_hdr(skb);
        ulen = ntohs(uh->len);
+       saddr = ip_hdr(skb)->saddr;
+       daddr = ip_hdr(skb)->daddr;
+
        if (ulen > skb->len)
                goto short_packet;
 
@@ -1540,9 +1543,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
        if (udp4_csum_init(skb, uh, proto))
                goto csum_error;
 
-       saddr = ip_hdr(skb)->saddr;
-       daddr = ip_hdr(skb)->daddr;
-
        if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
                return __udp4_lib_mcast_deliver(net, skb, uh,
                                saddr, daddr, udptable);
index 3192aa0..3f9e86b 100644 (file)
@@ -200,7 +200,7 @@ lookup_protocol:
 
        inet_sk(sk)->pinet6 = np = inet6_sk_generic(sk);
        np->hop_limit   = -1;
-       np->mcast_hops  = -1;
+       np->mcast_hops  = IPV6_DEFAULT_MCASTHOPS;
        np->mc_loop     = 1;
        np->pmtudisc    = IPV6_PMTUDISC_WANT;
        np->ipv6only    = net->ipv6.sysctl.bindv6only;
index 622dc79..6157388 100644 (file)
@@ -222,6 +222,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
        if (!skb)
                return;
 
+       skb->protocol = htons(ETH_P_IPV6);
+
        serr = SKB_EXT_ERR(skb);
        serr->ee.ee_errno = err;
        serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6;
@@ -255,6 +257,8 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)
        if (!skb)
                return;
 
+       skb->protocol = htons(ETH_P_IPV6);
+
        skb_put(skb, sizeof(struct ipv6hdr));
        skb_reset_network_header(skb);
        iph = ipv6_hdr(skb);
@@ -319,7 +323,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                sin->sin6_flowinfo = 0;
                sin->sin6_port = serr->port;
                sin->sin6_scope_id = 0;
-               if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
+               if (skb->protocol == htons(ETH_P_IPV6)) {
                        ipv6_addr_copy(&sin->sin6_addr,
                                  (struct in6_addr *)(nh + serr->addr_offset));
                        if (np->sndflow)
@@ -341,7 +345,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                sin->sin6_family = AF_INET6;
                sin->sin6_flowinfo = 0;
                sin->sin6_scope_id = 0;
-               if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
+               if (skb->protocol == htons(ETH_P_IPV6)) {
                        ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);
                        if (np->rxopt.all)
                                datagram_recv_ctl(sk, msg, skb);
index 16c4391..75d5ef8 100644 (file)
@@ -108,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
        WARN_ON(!skb_dst(newskb));
 
-       netif_rx(newskb);
+       netif_rx_ni(newskb);
        return 0;
 }
 
@@ -629,7 +629,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
        /* We must not fragment if the socket is set to force MTU discovery
         * or if the skb it not generated by a local socket.
         */
-       if (!skb->local_df) {
+       if (!skb->local_df && skb->len > mtu) {
                skb->dev = skb_dst(skb)->dev;
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
                IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
index c2438e8..05ebd78 100644 (file)
@@ -815,7 +815,7 @@ struct dst_entry * ip6_route_output(struct net *net, struct sock *sk,
 {
        int flags = 0;
 
-       if (rt6_need_strict(&fl->fl6_dst))
+       if (fl->oif || rt6_need_strict(&fl->fl6_dst))
                flags |= RT6_LOOKUP_F_IFACE;
 
        if (!ipv6_addr_any(&fl->fl6_src))
index c92ebe8..075f540 100644 (file)
@@ -1015,7 +1015,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
        skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
 
        t1 = (struct tcphdr *) skb_push(buff, tot_len);
-       skb_reset_transport_header(skb);
+       skb_reset_transport_header(buff);
 
        /* Swap the send and the receive. */
        memset(t1, 0, sizeof(*t1));
index c177aea..9082485 100644 (file)
@@ -259,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp6_lib_lookup2(net, &in6addr_any, sport,
-                                                 daddr, hnum, dif,
+                       result = udp6_lib_lookup2(net, saddr, sport,
+                                                 &in6addr_any, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
index ae18165..00bf7c9 100644 (file)
@@ -124,7 +124,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        xdst->u.dst.dev = dev;
        dev_hold(dev);
 
-       xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+       xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
        if (!xdst->u.rt6.rt6i_idev)
                return -ENODEV;
 
index a432f0e..94e7fca 100644 (file)
@@ -31,7 +31,7 @@ static int llc_mac_header_len(unsigned short devtype)
        case ARPHRD_ETHER:
        case ARPHRD_LOOPBACK:
                return sizeof(struct ethhdr);
-#ifdef CONFIG_TR
+#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)
        case ARPHRD_IEEE802_TR:
                return sizeof(struct trh_hdr);
 #endif
index 96d2534..87782a4 100644 (file)
@@ -184,7 +184,6 @@ static void sta_addba_resp_timer_expired(unsigned long data)
                       HT_AGG_STATE_REQ_STOP_BA_MSK)) !=
                                                HT_ADDBA_REQUESTED_MSK) {
                spin_unlock_bh(&sta->lock);
-               *state = HT_AGG_STATE_IDLE;
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "timer expired on tid %d but we are not "
                                "(or no longer) expecting addBA response there",
index 06c33b6..b887e48 100644 (file)
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                        switch (sdata->vif.type) {
                        case NL80211_IFTYPE_AP:
                                sdata->vif.bss_conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ap.beacon);
+                                       !!sdata->u.ap.beacon;
                                break;
                        case NL80211_IFTYPE_ADHOC:
                                sdata->vif.bss_conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ibss.presp);
+                                       !!sdata->u.ibss.presp;
                                break;
                        case NL80211_IFTYPE_MESH_POINT:
                                sdata->vif.bss_conf.enable_beacon = true;
index 58e3e3a..859ee5f 100644 (file)
@@ -750,9 +750,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_ACTION:
-               if (skb->len < IEEE80211_MIN_ACTION_SIZE)
-                       return RX_DROP_MONITOR;
-               /* fall through */
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
                skb_queue_tail(&ifmsh->skb_queue, skb);
index c8cd169..875c8de 100644 (file)
@@ -168,6 +168,8 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
        ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
                     channel_type != local->hw.conf.channel_type;
 
+       if (local->tmp_channel)
+               local->tmp_channel_type = channel_type;
        local->oper_channel_type = channel_type;
 
        if (ht_changed) {
@@ -2028,7 +2030,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
                                continue;
 
                        if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
-                           wk->type != IEEE80211_WORK_AUTH)
+                           wk->type != IEEE80211_WORK_AUTH &&
+                           wk->type != IEEE80211_WORK_ASSOC)
                                continue;
 
                        if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
index f0accf6..04ea07f 100644 (file)
@@ -1974,6 +1974,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        goto handled;
                }
                break;
+       case MESH_PLINK_CATEGORY:
+       case MESH_PATH_SEL_CATEGORY:
+               if (ieee80211_vif_is_mesh(&sdata->vif))
+                       return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
+               break;
        }
 
        /*
index 56422d8..fb12cec 100644 (file)
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+                                   rcu_read_lock_held() ||
+                                   lockdep_is_held(&local->sta_lock) ||
+                                   lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if (sta->sdata == sdata &&
                    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
                        break;
-               sta = rcu_dereference(sta->hnext);
+               sta = rcu_dereference_check(sta->hnext,
+                                           rcu_read_lock_held() ||
+                                           lockdep_is_held(&local->sta_lock) ||
+                                           lockdep_is_held(&local->sta_mtx));
        }
        return sta;
 }
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+                                   rcu_read_lock_held() ||
+                                   lockdep_is_held(&local->sta_lock) ||
+                                   lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if ((sta->sdata == sdata ||
                     sta->sdata->bss == sdata->bss) &&
                    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
                        break;
-               sta = rcu_dereference(sta->hnext);
+               sta = rcu_dereference_check(sta->hnext,
+                                           rcu_read_lock_held() ||
+                                           lockdep_is_held(&local->sta_lock) ||
+                                           lockdep_is_held(&local->sta_mtx));
        }
        return sta;
 }
index cc90363..243946d 100644 (file)
@@ -2169,8 +2169,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
        case SIOCGIFDSTADDR:
        case SIOCSIFDSTADDR:
        case SIOCSIFFLAGS:
-               if (!net_eq(sock_net(sk), &init_net))
-                       return -ENOIOCTLCMD;
                return inet_dgram_ops.ioctl(sock, cmd, arg);
 #endif
 
index 9ece910..7b15508 100644 (file)
@@ -134,7 +134,7 @@ static int __init rds_rdma_listen_init(void)
                ret = PTR_ERR(cm_id);
                printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
                       "rdma_create_id() returned %d\n", ret);
-               goto out;
+               return ret;
        }
 
        sin.sin_family = AF_INET,
index df5abbf..99c93ee 100644 (file)
@@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_association *asoc,
        /* Remove any peer addresses not present in the new association. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
                trans = list_entry(pos, struct sctp_transport, transports);
-               if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr))
-                       sctp_assoc_del_peer(asoc, &trans->ipaddr);
+               if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) {
+                       sctp_assoc_rm_peer(asoc, trans);
+                       continue;
+               }
 
                if (asoc->state >= SCTP_STATE_ESTABLISHED)
                        sctp_transport_reset(trans);
index 905fda5..7ec09ba 100644 (file)
@@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
        /* Use SCTP specific send buffer space queues.  */
        ep->sndbuf_policy = sctp_sndbuf_policy;
 
+       sk->sk_data_ready = sctp_data_ready;
        sk->sk_write_space = sctp_write_space;
        sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
index 2a57018..ea21924 100644 (file)
@@ -440,11 +440,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
 {
        SCTP_DEBUG_PRINTK("%s\n",  __func__);
 
-       sctp_do_sm(SCTP_EVENT_T_OTHER,
-                  SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
-                  asoc->state, asoc->ep, asoc, t,
-                  GFP_ATOMIC);
+       if (sock_owned_by_user(sk)) {
+               if (timer_pending(&t->proto_unreach_timer))
+                       return;
+               else {
+                       if (!mod_timer(&t->proto_unreach_timer,
+                                               jiffies + (HZ/20)))
+                               sctp_association_hold(asoc);
+               }
+                       
+       } else {
+               if (timer_pending(&t->proto_unreach_timer) &&
+                   del_timer(&t->proto_unreach_timer))
+                       sctp_association_put(asoc);
 
+               sctp_do_sm(SCTP_EVENT_T_OTHER,
+                          SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+                          asoc->state, asoc->ep, asoc, t,
+                          GFP_ATOMIC);
+       }
 }
 
 /* Common lookup code for icmp/icmpv6 error handler. */
index 17cb400..30c1767 100644 (file)
@@ -108,7 +108,7 @@ static const struct sctp_paramhdr prsctp_param = {
        cpu_to_be16(sizeof(struct sctp_paramhdr)),
 };
 
-/* A helper to initialize to initialize an op error inside a
+/* A helper to initialize an op error inside a
  * provided chunk, as most cause codes will be embedded inside an
  * abort chunk.
  */
@@ -125,6 +125,29 @@ void  sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
        chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err);
 }
 
+/* A helper to initialize an op error inside a
+ * provided chunk, as most cause codes will be embedded inside an
+ * abort chunk.  Differs from sctp_init_cause in that it won't oops
+ * if there isn't enough space in the op error chunk
+ */
+int sctp_init_cause_fixed(struct sctp_chunk *chunk, __be16 cause_code,
+                     size_t paylen)
+{
+       sctp_errhdr_t err;
+       __u16 len;
+
+       /* Cause code constants are now defined in network order.  */
+       err.cause = cause_code;
+       len = sizeof(sctp_errhdr_t) + paylen;
+       err.length  = htons(len);
+
+       if (skb_tailroom(chunk->skb) >  len)
+               return -ENOSPC;
+       chunk->subh.err_hdr = sctp_addto_chunk_fixed(chunk,
+                                                    sizeof(sctp_errhdr_t),
+                                                    &err);
+       return 0;
+}
 /* 3.3.2 Initiation (INIT) (1)
  *
  * This chunk is used to initiate a SCTP association between two
@@ -208,7 +231,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
        sp = sctp_sk(asoc->base.sk);
        num_types = sp->pf->supported_addrs(sp, types);
 
-       chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types);
+       chunksize = sizeof(init) + addrs_len;
+       chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types));
        chunksize += sizeof(ecap_param);
 
        if (sctp_prsctp_enable)
@@ -238,14 +262,14 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
                /* Add HMACS parameter length if any were defined */
                auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
                if (auth_hmacs->length)
-                       chunksize += ntohs(auth_hmacs->length);
+                       chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
                else
                        auth_hmacs = NULL;
 
                /* Add CHUNKS parameter length */
                auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
                if (auth_chunks->length)
-                       chunksize += ntohs(auth_chunks->length);
+                       chunksize += WORD_ROUND(ntohs(auth_chunks->length));
                else
                        auth_chunks = NULL;
 
@@ -255,7 +279,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
 
        /* If we have any extensions to report, account for that */
        if (num_ext)
-               chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+               chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
+                                       num_ext);
 
        /* RFC 2960 3.3.2 Initiation (INIT) (1)
         *
@@ -397,13 +422,13 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
 
                auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs;
                if (auth_hmacs->length)
-                       chunksize += ntohs(auth_hmacs->length);
+                       chunksize += WORD_ROUND(ntohs(auth_hmacs->length));
                else
                        auth_hmacs = NULL;
 
                auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks;
                if (auth_chunks->length)
-                       chunksize += ntohs(auth_chunks->length);
+                       chunksize += WORD_ROUND(ntohs(auth_chunks->length));
                else
                        auth_chunks = NULL;
 
@@ -412,7 +437,8 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
        }
 
        if (num_ext)
-               chunksize += sizeof(sctp_supported_ext_param_t) + num_ext;
+               chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) +
+                                       num_ext);
 
        /* Now allocate and fill out the chunk.  */
        retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
@@ -1129,6 +1155,24 @@ nodata:
        return retval;
 }
 
+/* Create an Operation Error chunk of a fixed size,
+ * specifically, max(asoc->pathmtu, SCTP_DEFAULT_MAXSEGMENT)
+ * This is a helper function to allocate an error chunk for
+ * for those invalid parameter codes in which we may not want
+ * to report all the errors, if the incomming chunk is large
+ */
+static inline struct sctp_chunk *sctp_make_op_error_fixed(
+       const struct sctp_association *asoc,
+       const struct sctp_chunk *chunk)
+{
+       size_t size = asoc ? asoc->pathmtu : 0;
+
+       if (!size)
+               size = SCTP_DEFAULT_MAXSEGMENT;
+
+       return sctp_make_op_error_space(asoc, chunk, size);
+}
+
 /* Create an Operation Error chunk.  */
 struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
                                 const struct sctp_chunk *chunk,
@@ -1371,6 +1415,18 @@ void *sctp_addto_chunk(struct sctp_chunk *chunk, int len, const void *data)
        return target;
 }
 
+/* Append bytes to the end of a chunk. Returns NULL if there isn't sufficient
+ * space in the chunk
+ */
+void *sctp_addto_chunk_fixed(struct sctp_chunk *chunk,
+                            int len, const void *data)
+{
+       if (skb_tailroom(chunk->skb) > len)
+               return sctp_addto_chunk(chunk, len, data);
+       else
+               return NULL;
+}
+
 /* Append bytes from user space to the end of a chunk.  Will panic if
  * chunk is not big enough.
  * Returns a kernel err value.
@@ -1974,13 +2030,12 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
                 * returning multiple unknown parameters.
                 */
                if (NULL == *errp)
-                       *errp = sctp_make_op_error_space(asoc, chunk,
-                                       ntohs(chunk->chunk_hdr->length));
+                       *errp = sctp_make_op_error_fixed(asoc, chunk);
 
                if (*errp) {
-                       sctp_init_cause(*errp, SCTP_ERROR_UNKNOWN_PARAM,
+                       sctp_init_cause_fixed(*errp, SCTP_ERROR_UNKNOWN_PARAM,
                                        WORD_ROUND(ntohs(param.p->length)));
-                       sctp_addto_chunk(*errp,
+                       sctp_addto_chunk_fixed(*errp,
                                        WORD_ROUND(ntohs(param.p->length)),
                                        param.v);
                } else {
@@ -3315,21 +3370,6 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
        sctp_chunk_free(asconf);
        asoc->addip_last_asconf = NULL;
 
-       /* Send the next asconf chunk from the addip chunk queue. */
-       if (!list_empty(&asoc->addip_chunk_list)) {
-               struct list_head *entry = asoc->addip_chunk_list.next;
-               asconf = list_entry(entry, struct sctp_chunk, list);
-
-               list_del_init(entry);
-
-               /* Hold the chunk until an ASCONF_ACK is received. */
-               sctp_chunk_hold(asconf);
-               if (sctp_primitive_ASCONF(asoc, asconf))
-                       sctp_chunk_free(asconf);
-               else
-                       asoc->addip_last_asconf = asconf;
-       }
-
        return retval;
 }
 
index 4c5bed9..eb1f42f 100644 (file)
@@ -397,6 +397,41 @@ out_unlock:
        sctp_transport_put(transport);
 }
 
+/* Handle the timeout of the ICMP protocol unreachable timer.  Trigger
+ * the correct state machine transition that will close the association.
+ */
+void sctp_generate_proto_unreach_event(unsigned long data)
+{
+       struct sctp_transport *transport = (struct sctp_transport *) data;
+       struct sctp_association *asoc = transport->asoc;
+       
+       sctp_bh_lock_sock(asoc->base.sk);
+       if (sock_owned_by_user(asoc->base.sk)) {
+               SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);
+
+               /* Try again later.  */
+               if (!mod_timer(&transport->proto_unreach_timer,
+                               jiffies + (HZ/20)))
+                       sctp_association_hold(asoc);
+               goto out_unlock;
+       }
+
+       /* Is this structure just waiting around for us to actually
+        * get destroyed?
+        */
+       if (asoc->base.dead)
+               goto out_unlock;
+
+       sctp_do_sm(SCTP_EVENT_T_OTHER,
+                  SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
+                  asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);
+
+out_unlock:
+       sctp_bh_unlock_sock(asoc->base.sk);
+       sctp_association_put(asoc);
+}
+
+
 /* Inject a SACK Timeout event into the state machine.  */
 static void sctp_generate_sack_event(unsigned long data)
 {
@@ -962,6 +997,29 @@ static int sctp_cmd_send_msg(struct sctp_association *asoc,
 }
 
 
+/* Sent the next ASCONF packet currently stored in the association.
+ * This happens after the ASCONF_ACK was succeffully processed.
+ */
+static void sctp_cmd_send_asconf(struct sctp_association *asoc)
+{
+       /* Send the next asconf chunk from the addip chunk
+        * queue.
+        */
+       if (!list_empty(&asoc->addip_chunk_list)) {
+               struct list_head *entry = asoc->addip_chunk_list.next;
+               struct sctp_chunk *asconf = list_entry(entry,
+                                               struct sctp_chunk, list);
+               list_del_init(entry);
+
+               /* Hold the chunk until an ASCONF_ACK is received. */
+               sctp_chunk_hold(asconf);
+               if (sctp_primitive_ASCONF(asoc, asconf))
+                       sctp_chunk_free(asconf);
+               else
+                       asoc->addip_last_asconf = asconf;
+       }
+}
+
 
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
@@ -1617,6 +1675,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        }
                        error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
                        break;
+               case SCTP_CMD_SEND_NEXT_ASCONF:
+                       sctp_cmd_send_asconf(asoc);
+                       break;
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
                               cmd->verb, cmd->obj.ptr);
index abf601a..24b2cd5 100644 (file)
@@ -3676,8 +3676,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
 
                if (!sctp_process_asconf_ack((struct sctp_association *)asoc,
-                                            asconf_ack))
+                                            asconf_ack)) {
+                       /* Successfully processed ASCONF_ACK.  We can
+                        * release the next asconf if we have one.
+                        */
+                       sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF,
+                                       SCTP_NULL());
                        return SCTP_DISPOSITION_CONSUME;
+               }
 
                abort = sctp_make_abort(asoc, asconf_ack,
                                        sizeof(sctp_errhdr_t));
index 007e8ba..44a1ab0 100644 (file)
@@ -3719,12 +3719,12 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
        sp->hmac = NULL;
 
        SCTP_DBG_OBJCNT_INC(sock);
-       percpu_counter_inc(&sctp_sockets_allocated);
 
        /* Set socket backlog limit. */
        sk->sk_backlog.limit = sysctl_sctp_rmem[1];
 
        local_bh_disable();
+       percpu_counter_inc(&sctp_sockets_allocated);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        local_bh_enable();
 
@@ -3741,8 +3741,8 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
        /* Release our hold on the endpoint. */
        ep = sctp_sk(sk)->ep;
        sctp_endpoint_free(ep);
-       percpu_counter_dec(&sctp_sockets_allocated);
        local_bh_disable();
+       percpu_counter_dec(&sctp_sockets_allocated);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        local_bh_enable();
 }
@@ -6189,6 +6189,16 @@ do_nonblock:
        goto out;
 }
 
+void sctp_data_ready(struct sock *sk, int len)
+{
+       read_lock_bh(&sk->sk_callback_lock);
+       if (sk_has_sleeper(sk))
+               wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
+                                               POLLRDNORM | POLLRDBAND);
+       sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
+       read_unlock_bh(&sk->sk_callback_lock);
+}
+
 /* If socket sndbuf has changed, wake up all per association waiters.  */
 void sctp_write_space(struct sock *sk)
 {
index be4d63d..165d54e 100644 (file)
@@ -108,6 +108,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
                        (unsigned long)peer);
        setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
                        (unsigned long)peer);
+       setup_timer(&peer->proto_unreach_timer,
+                   sctp_generate_proto_unreach_event, (unsigned long)peer);
 
        /* Initialize the 64-bit random nonce sent with heartbeat. */
        get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
@@ -171,6 +173,10 @@ void sctp_transport_free(struct sctp_transport *transport)
            del_timer(&transport->T3_rtx_timer))
                sctp_transport_put(transport);
 
+       /* Delete the ICMP proto unreachable timer if it's active. */
+       if (timer_pending(&transport->proto_unreach_timer) &&
+           del_timer(&transport->proto_unreach_timer))
+               sctp_association_put(transport->asoc);
 
        sctp_transport_put(transport);
 }
index f394fc1..73affb8 100644 (file)
@@ -236,10 +236,15 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
 
        list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
 
-               /* Enforce a 60 second garbage collection moratorium */
-               if (time_in_range_open(cred->cr_expire, expired, jiffies) &&
+               if (nr_to_scan-- == 0)
+                       break;
+               /*
+                * Enforce a 60 second garbage collection moratorium
+                * Note that the cred_unused list must be time-ordered.
+                */
+               if (time_in_range(cred->cr_expire, expired, jiffies) &&
                    test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
-                       continue;
+                       return 0;
 
                list_del_init(&cred->cr_lru);
                number_cred_unused--;
@@ -252,13 +257,10 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
                        get_rpccred(cred);
                        list_add_tail(&cred->cr_lru, free);
                        rpcauth_unhash_cred_locked(cred);
-                       nr_to_scan--;
                }
                spin_unlock(cache_lock);
-               if (nr_to_scan == 0)
-                       break;
        }
-       return nr_to_scan;
+       return (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
 }
 
 /*
@@ -270,11 +272,12 @@ rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask)
        LIST_HEAD(free);
        int res;
 
+       if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
+               return (nr_to_scan == 0) ? 0 : -1;
        if (list_empty(&cred_unused))
                return 0;
        spin_lock(&rpc_credcache_lock);
-       nr_to_scan = rpcauth_prune_expired(&free, nr_to_scan);
-       res = (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
+       res = rpcauth_prune_expired(&free, nr_to_scan);
        spin_unlock(&rpc_credcache_lock);
        rpcauth_destroy_credlist(&free);
        return res;
index 4de8bcf..74a2317 100644 (file)
@@ -10,7 +10,7 @@ auth_rpcgss-objs := auth_gss.o gss_generic_token.o \
 obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
 
 rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
-       gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o
+       gss_krb5_seqnum.o gss_krb5_wrap.o gss_krb5_crypto.o gss_krb5_keys.o
 
 obj-$(CONFIG_RPCSEC_GSS_SPKM3) += rpcsec_gss_spkm3.o
 
index c389ccf..8da2a0e 100644 (file)
@@ -57,11 +57,14 @@ static const struct rpc_authops authgss_ops;
 static const struct rpc_credops gss_credops;
 static const struct rpc_credops gss_nullops;
 
+#define GSS_RETRY_EXPIRED 5
+static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
+
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY       RPCDBG_AUTH
 #endif
 
-#define GSS_CRED_SLACK         1024
+#define GSS_CRED_SLACK         (RPC_MAX_AUTH_SIZE * 2)
 /* length of a krb5 verifier (48), plus data added before arguments when
  * using integrity (two 4-byte integers): */
 #define GSS_VERF_SLACK         100
@@ -229,7 +232,7 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct
                p = ERR_PTR(-EFAULT);
                goto err;
        }
-       ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx);
+       ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, GFP_NOFS);
        if (ret < 0) {
                p = ERR_PTR(ret);
                goto err;
@@ -349,6 +352,24 @@ gss_unhash_msg(struct gss_upcall_msg *gss_msg)
        spin_unlock(&inode->i_lock);
 }
 
+static void
+gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss_msg)
+{
+       switch (gss_msg->msg.errno) {
+       case 0:
+               if (gss_msg->ctx == NULL)
+                       break;
+               clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
+               gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx);
+               break;
+       case -EKEYEXPIRED:
+               set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
+       }
+       gss_cred->gc_upcall_timestamp = jiffies;
+       gss_cred->gc_upcall = NULL;
+       rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
+}
+
 static void
 gss_upcall_callback(struct rpc_task *task)
 {
@@ -358,13 +379,9 @@ gss_upcall_callback(struct rpc_task *task)
        struct inode *inode = &gss_msg->inode->vfs_inode;
 
        spin_lock(&inode->i_lock);
-       if (gss_msg->ctx)
-               gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_msg->ctx);
-       else
-               task->tk_status = gss_msg->msg.errno;
-       gss_cred->gc_upcall = NULL;
-       rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
+       gss_handle_downcall_result(gss_cred, gss_msg);
        spin_unlock(&inode->i_lock);
+       task->tk_status = gss_msg->msg.errno;
        gss_release_msg(gss_msg);
 }
 
@@ -377,11 +394,12 @@ static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
 static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
                                struct rpc_clnt *clnt, int machine_cred)
 {
+       struct gss_api_mech *mech = gss_msg->auth->mech;
        char *p = gss_msg->databuf;
        int len = 0;
 
        gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
-                                  gss_msg->auth->mech->gm_name,
+                                  mech->gm_name,
                                   gss_msg->uid);
        p += gss_msg->msg.len;
        if (clnt->cl_principal) {
@@ -398,6 +416,11 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
                p += len;
                gss_msg->msg.len += len;
        }
+       if (mech->gm_upcall_enctypes) {
+               len = sprintf(p, mech->gm_upcall_enctypes);
+               p += len;
+               gss_msg->msg.len += len;
+       }
        len = sprintf(p, "\n");
        gss_msg->msg.len += len;
 
@@ -507,18 +530,16 @@ gss_refresh_upcall(struct rpc_task *task)
        spin_lock(&inode->i_lock);
        if (gss_cred->gc_upcall != NULL)
                rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
-       else if (gss_msg->ctx != NULL) {
-               gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_msg->ctx);
-               gss_cred->gc_upcall = NULL;
-               rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
-       } else if (gss_msg->msg.errno >= 0) {
+       else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
                task->tk_timeout = 0;
                gss_cred->gc_upcall = gss_msg;
                /* gss_upcall_callback will release the reference to gss_upcall_msg */
                atomic_inc(&gss_msg->count);
                rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback);
-       } else
+       } else {
+               gss_handle_downcall_result(gss_cred, gss_msg);
                err = gss_msg->msg.errno;
+       }
        spin_unlock(&inode->i_lock);
        gss_release_msg(gss_msg);
 out:
@@ -1117,6 +1138,23 @@ static int gss_renew_cred(struct rpc_task *task)
        return 0;
 }
 
+static int gss_cred_is_negative_entry(struct rpc_cred *cred)
+{
+       if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) {
+               unsigned long now = jiffies;
+               unsigned long begin, expire;
+               struct gss_cred *gss_cred; 
+
+               gss_cred = container_of(cred, struct gss_cred, gc_base);
+               begin = gss_cred->gc_upcall_timestamp;
+               expire = begin + gss_expired_cred_retry_delay * HZ;
+
+               if (time_in_range_open(now, begin, expire))
+                       return 1;
+       }
+       return 0;
+}
+
 /*
 * Refresh credentials. XXX - finish
 */
@@ -1126,6 +1164,9 @@ gss_refresh(struct rpc_task *task)
        struct rpc_cred *cred = task->tk_msg.rpc_cred;
        int ret = 0;
 
+       if (gss_cred_is_negative_entry(cred))
+               return -EKEYEXPIRED;
+
        if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
                        !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) {
                ret = gss_renew_cred(task);
@@ -1316,15 +1357,21 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
        inpages = snd_buf->pages + first;
        snd_buf->pages = rqstp->rq_enc_pages;
        snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
-       /* Give the tail its own page, in case we need extra space in the
-        * head when wrapping: */
+       /*
+        * Give the tail its own page, in case we need extra space in the
+        * head when wrapping:
+        *
+        * call_allocate() allocates twice the slack space required
+        * by the authentication flavor to rq_callsize.
+        * For GSS, slack is GSS_CRED_SLACK.
+        */
        if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
                tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
                memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
                snd_buf->tail[0].iov_base = tmp;
        }
        maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
-       /* RPC_SLACK_SPACE should prevent this ever happening: */
+       /* slack space should prevent this ever happening: */
        BUG_ON(snd_buf->len > snd_buf->buflen);
        status = -EIO;
        /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
@@ -1573,5 +1620,11 @@ static void __exit exit_rpcsec_gss(void)
 }
 
 MODULE_LICENSE("GPL");
+module_param_named(expired_cred_retry_delay,
+                  gss_expired_cred_retry_delay,
+                  uint, 0644);
+MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until "
+               "the RPC engine retries an expired credential");
+
 module_init(init_rpcsec_gss)
 module_exit(exit_rpcsec_gss)
index e9b6361..75ee993 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/net/sunrpc/gss_krb5_crypto.c
  *
- *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  Copyright (c) 2000-2008 The Regents of the University of Michigan.
  *  All rights reserved.
  *
  *  Andy Adamson   <andros@umich.edu>
@@ -41,6 +41,7 @@
 #include <linux/crypto.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/random.h>
 #include <linux/sunrpc/gss_krb5.h>
 #include <linux/sunrpc/xdr.h>
 
@@ -58,13 +59,13 @@ krb5_encrypt(
 {
        u32 ret = -EINVAL;
        struct scatterlist sg[1];
-       u8 local_iv[16] = {0};
+       u8 local_iv[GSS_KRB5_MAX_BLOCKSIZE] = {0};
        struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
 
        if (length % crypto_blkcipher_blocksize(tfm) != 0)
                goto out;
 
-       if (crypto_blkcipher_ivsize(tfm) > 16) {
+       if (crypto_blkcipher_ivsize(tfm) > GSS_KRB5_MAX_BLOCKSIZE) {
                dprintk("RPC:       gss_k5encrypt: tfm iv size too large %d\n",
                        crypto_blkcipher_ivsize(tfm));
                goto out;
@@ -92,13 +93,13 @@ krb5_decrypt(
 {
        u32 ret = -EINVAL;
        struct scatterlist sg[1];
-       u8 local_iv[16] = {0};
+       u8 local_iv[GSS_KRB5_MAX_BLOCKSIZE] = {0};
        struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
 
        if (length % crypto_blkcipher_blocksize(tfm) != 0)
                goto out;
 
-       if (crypto_blkcipher_ivsize(tfm) > 16) {
+       if (crypto_blkcipher_ivsize(tfm) > GSS_KRB5_MAX_BLOCKSIZE) {
                dprintk("RPC:       gss_k5decrypt: tfm iv size too large %d\n",
                        crypto_blkcipher_ivsize(tfm));
                goto out;
@@ -123,21 +124,155 @@ checksummer(struct scatterlist *sg, void *data)
        return crypto_hash_update(desc, sg, sg->length);
 }
 
-/* checksum the plaintext data and hdrlen bytes of the token header */
-s32
-make_checksum(char *cksumname, char *header, int hdrlen, struct xdr_buf *body,
-                  int body_offset, struct xdr_netobj *cksum)
+static int
+arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4])
+{
+       unsigned int ms_usage;
+
+       switch (usage) {
+       case KG_USAGE_SIGN:
+               ms_usage = 15;
+               break;
+       case KG_USAGE_SEAL:
+               ms_usage = 13;
+               break;
+       default:
+               return EINVAL;;
+       }
+       salt[0] = (ms_usage >> 0) & 0xff;
+       salt[1] = (ms_usage >> 8) & 0xff;
+       salt[2] = (ms_usage >> 16) & 0xff;
+       salt[3] = (ms_usage >> 24) & 0xff;
+
+       return 0;
+}
+
+static u32
+make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
+                      struct xdr_buf *body, int body_offset, u8 *cksumkey,
+                      unsigned int usage, struct xdr_netobj *cksumout)
 {
-       struct hash_desc                desc; /* XXX add to ctx? */
+       struct hash_desc                desc;
        struct scatterlist              sg[1];
        int err;
+       u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       u8 rc4salt[4];
+       struct crypto_hash *md5;
+       struct crypto_hash *hmac_md5;
+
+       if (cksumkey == NULL)
+               return GSS_S_FAILURE;
+
+       if (cksumout->len < kctx->gk5e->cksumlength) {
+               dprintk("%s: checksum buffer length, %u, too small for %s\n",
+                       __func__, cksumout->len, kctx->gk5e->name);
+               return GSS_S_FAILURE;
+       }
+
+       if (arcfour_hmac_md5_usage_to_salt(usage, rc4salt)) {
+               dprintk("%s: invalid usage value %u\n", __func__, usage);
+               return GSS_S_FAILURE;
+       }
+
+       md5 = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(md5))
+               return GSS_S_FAILURE;
+
+       hmac_md5 = crypto_alloc_hash(kctx->gk5e->cksum_name, 0,
+                                    CRYPTO_ALG_ASYNC);
+       if (IS_ERR(hmac_md5)) {
+               crypto_free_hash(md5);
+               return GSS_S_FAILURE;
+       }
+
+       desc.tfm = md5;
+       desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+       err = crypto_hash_init(&desc);
+       if (err)
+               goto out;
+       sg_init_one(sg, rc4salt, 4);
+       err = crypto_hash_update(&desc, sg, 4);
+       if (err)
+               goto out;
+
+       sg_init_one(sg, header, hdrlen);
+       err = crypto_hash_update(&desc, sg, hdrlen);
+       if (err)
+               goto out;
+       err = xdr_process_buf(body, body_offset, body->len - body_offset,
+                             checksummer, &desc);
+       if (err)
+               goto out;
+       err = crypto_hash_final(&desc, checksumdata);
+       if (err)
+               goto out;
+
+       desc.tfm = hmac_md5;
+       desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+       err = crypto_hash_init(&desc);
+       if (err)
+               goto out;
+       err = crypto_hash_setkey(hmac_md5, cksumkey, kctx->gk5e->keylength);
+       if (err)
+               goto out;
+
+       sg_init_one(sg, checksumdata, crypto_hash_digestsize(md5));
+       err = crypto_hash_digest(&desc, sg, crypto_hash_digestsize(md5),
+                                checksumdata);
+       if (err)
+               goto out;
+
+       memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength);
+       cksumout->len = kctx->gk5e->cksumlength;
+out:
+       crypto_free_hash(md5);
+       crypto_free_hash(hmac_md5);
+       return err ? GSS_S_FAILURE : 0;
+}
+
+/*
+ * checksum the plaintext data and hdrlen bytes of the token header
+ * The checksum is performed over the first 8 bytes of the
+ * gss token header and then over the data body
+ */
+u32
+make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen,
+             struct xdr_buf *body, int body_offset, u8 *cksumkey,
+             unsigned int usage, struct xdr_netobj *cksumout)
+{
+       struct hash_desc                desc;
+       struct scatterlist              sg[1];
+       int err;
+       u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       unsigned int checksumlen;
+
+       if (kctx->gk5e->ctype == CKSUMTYPE_HMAC_MD5_ARCFOUR)
+               return make_checksum_hmac_md5(kctx, header, hdrlen,
+                                             body, body_offset,
+                                             cksumkey, usage, cksumout);
+
+       if (cksumout->len < kctx->gk5e->cksumlength) {
+               dprintk("%s: checksum buffer length, %u, too small for %s\n",
+                       __func__, cksumout->len, kctx->gk5e->name);
+               return GSS_S_FAILURE;
+       }
 
-       desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
+       desc.tfm = crypto_alloc_hash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(desc.tfm))
                return GSS_S_FAILURE;
-       cksum->len = crypto_hash_digestsize(desc.tfm);
        desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 
+       checksumlen = crypto_hash_digestsize(desc.tfm);
+
+       if (cksumkey != NULL) {
+               err = crypto_hash_setkey(desc.tfm, cksumkey,
+                                        kctx->gk5e->keylength);
+               if (err)
+                       goto out;
+       }
+
        err = crypto_hash_init(&desc);
        if (err)
                goto out;
@@ -149,15 +284,109 @@ make_checksum(char *cksumname, char *header, int hdrlen, struct xdr_buf *body,
                              checksummer, &desc);
        if (err)
                goto out;
-       err = crypto_hash_final(&desc, cksum->data);
+       err = crypto_hash_final(&desc, checksumdata);
+       if (err)
+               goto out;
 
+       switch (kctx->gk5e->ctype) {
+       case CKSUMTYPE_RSA_MD5:
+               err = kctx->gk5e->encrypt(kctx->seq, NULL, checksumdata,
+                                         checksumdata, checksumlen);
+               if (err)
+                       goto out;
+               memcpy(cksumout->data,
+                      checksumdata + checksumlen - kctx->gk5e->cksumlength,
+                      kctx->gk5e->cksumlength);
+               break;
+       case CKSUMTYPE_HMAC_SHA1_DES3:
+               memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength);
+               break;
+       default:
+               BUG();
+               break;
+       }
+       cksumout->len = kctx->gk5e->cksumlength;
+out:
+       crypto_free_hash(desc.tfm);
+       return err ? GSS_S_FAILURE : 0;
+}
+
+/*
+ * checksum the plaintext data and hdrlen bytes of the token header
+ * Per rfc4121, sec. 4.2.4, the checksum is performed over the data
+ * body then over the first 16 octets of the MIC token
+ * Inclusion of the header data in the calculation of the
+ * checksum is optional.
+ */
+u32
+make_checksum_v2(struct krb5_ctx *kctx, char *header, int hdrlen,
+                struct xdr_buf *body, int body_offset, u8 *cksumkey,
+                unsigned int usage, struct xdr_netobj *cksumout)
+{
+       struct hash_desc desc;
+       struct scatterlist sg[1];
+       int err;
+       u8 checksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       unsigned int checksumlen;
+
+       if (kctx->gk5e->keyed_cksum == 0) {
+               dprintk("%s: expected keyed hash for %s\n",
+                       __func__, kctx->gk5e->name);
+               return GSS_S_FAILURE;
+       }
+       if (cksumkey == NULL) {
+               dprintk("%s: no key supplied for %s\n",
+                       __func__, kctx->gk5e->name);
+               return GSS_S_FAILURE;
+       }
+
+       desc.tfm = crypto_alloc_hash(kctx->gk5e->cksum_name, 0,
+                                                       CRYPTO_ALG_ASYNC);
+       if (IS_ERR(desc.tfm))
+               return GSS_S_FAILURE;
+       checksumlen = crypto_hash_digestsize(desc.tfm);
+       desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+       err = crypto_hash_setkey(desc.tfm, cksumkey, kctx->gk5e->keylength);
+       if (err)
+               goto out;
+
+       err = crypto_hash_init(&desc);
+       if (err)
+               goto out;
+       err = xdr_process_buf(body, body_offset, body->len - body_offset,
+                             checksummer, &desc);
+       if (err)
+               goto out;
+       if (header != NULL) {
+               sg_init_one(sg, header, hdrlen);
+               err = crypto_hash_update(&desc, sg, hdrlen);
+               if (err)
+                       goto out;
+       }
+       err = crypto_hash_final(&desc, checksumdata);
+       if (err)
+               goto out;
+
+       cksumout->len = kctx->gk5e->cksumlength;
+
+       switch (kctx->gk5e->ctype) {
+       case CKSUMTYPE_HMAC_SHA1_96_AES128:
+       case CKSUMTYPE_HMAC_SHA1_96_AES256:
+               /* note that this truncates the hash */
+               memcpy(cksumout->data, checksumdata, kctx->gk5e->cksumlength);
+               break;
+       default:
+               BUG();
+               break;
+       }
 out:
        crypto_free_hash(desc.tfm);
        return err ? GSS_S_FAILURE : 0;
 }
 
 struct encryptor_desc {
-       u8 iv[8]; /* XXX hard-coded blocksize */
+       u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
        struct blkcipher_desc desc;
        int pos;
        struct xdr_buf *outbuf;
@@ -198,7 +427,7 @@ encryptor(struct scatterlist *sg, void *data)
        desc->fraglen += sg->length;
        desc->pos += sg->length;
 
-       fraglen = thislen & 7; /* XXX hardcoded blocksize */
+       fraglen = thislen & (crypto_blkcipher_blocksize(desc->desc.tfm) - 1);
        thislen -= fraglen;
 
        if (thislen == 0)
@@ -256,7 +485,7 @@ gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
 }
 
 struct decryptor_desc {
-       u8 iv[8]; /* XXX hard-coded blocksize */
+       u8 iv[GSS_KRB5_MAX_BLOCKSIZE];
        struct blkcipher_desc desc;
        struct scatterlist frags[4];
        int fragno;
@@ -278,7 +507,7 @@ decryptor(struct scatterlist *sg, void *data)
        desc->fragno++;
        desc->fraglen += sg->length;
 
-       fraglen = thislen & 7; /* XXX hardcoded blocksize */
+       fraglen = thislen & (crypto_blkcipher_blocksize(desc->desc.tfm) - 1);
        thislen -= fraglen;
 
        if (thislen == 0)
@@ -325,3 +554,437 @@ gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
 
        return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc);
 }
+
+/*
+ * This function makes the assumption that it was ultimately called
+ * from gss_wrap().
+ *
+ * The client auth_gss code moves any existing tail data into a
+ * separate page before calling gss_wrap.
+ * The server svcauth_gss code ensures that both the head and the
+ * tail have slack space of RPC_MAX_AUTH_SIZE before calling gss_wrap.
+ *
+ * Even with that guarantee, this function may be called more than
+ * once in the processing of gss_wrap().  The best we can do is
+ * verify at compile-time (see GSS_KRB5_SLACK_CHECK) that the
+ * largest expected shift will fit within RPC_MAX_AUTH_SIZE.
+ * At run-time we can verify that a single invocation of this
+ * function doesn't attempt to use more the RPC_MAX_AUTH_SIZE.
+ */
+
+int
+xdr_extend_head(struct xdr_buf *buf, unsigned int base, unsigned int shiftlen)
+{
+       u8 *p;
+
+       if (shiftlen == 0)
+               return 0;
+
+       BUILD_BUG_ON(GSS_KRB5_MAX_SLACK_NEEDED > RPC_MAX_AUTH_SIZE);
+       BUG_ON(shiftlen > RPC_MAX_AUTH_SIZE);
+
+       p = buf->head[0].iov_base + base;
+
+       memmove(p + shiftlen, p, buf->head[0].iov_len - base);
+
+       buf->head[0].iov_len += shiftlen;
+       buf->len += shiftlen;
+
+       return 0;
+}
+
+static u32
+gss_krb5_cts_crypt(struct crypto_blkcipher *cipher, struct xdr_buf *buf,
+                  u32 offset, u8 *iv, struct page **pages, int encrypt)
+{
+       u32 ret;
+       struct scatterlist sg[1];
+       struct blkcipher_desc desc = { .tfm = cipher, .info = iv };
+       u8 data[crypto_blkcipher_blocksize(cipher) * 2];
+       struct page **save_pages;
+       u32 len = buf->len - offset;
+
+       BUG_ON(len > crypto_blkcipher_blocksize(cipher) * 2);
+
+       /*
+        * For encryption, we want to read from the cleartext
+        * page cache pages, and write the encrypted data to
+        * the supplied xdr_buf pages.
+        */
+       save_pages = buf->pages;
+       if (encrypt)
+               buf->pages = pages;
+
+       ret = read_bytes_from_xdr_buf(buf, offset, data, len);
+       buf->pages = save_pages;
+       if (ret)
+               goto out;
+
+       sg_init_one(sg, data, len);
+
+       if (encrypt)
+               ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, len);
+       else
+               ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, len);
+
+       if (ret)
+               goto out;
+
+       ret = write_bytes_to_xdr_buf(buf, offset, data, len);
+
+out:
+       return ret;
+}
+
+u32
+gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset,
+                    struct xdr_buf *buf, int ec, struct page **pages)
+{
+       u32 err;
+       struct xdr_netobj hmac;
+       u8 *cksumkey;
+       u8 *ecptr;
+       struct crypto_blkcipher *cipher, *aux_cipher;
+       int blocksize;
+       struct page **save_pages;
+       int nblocks, nbytes;
+       struct encryptor_desc desc;
+       u32 cbcbytes;
+       unsigned int usage;
+
+       if (kctx->initiate) {
+               cipher = kctx->initiator_enc;
+               aux_cipher = kctx->initiator_enc_aux;
+               cksumkey = kctx->initiator_integ;
+               usage = KG_USAGE_INITIATOR_SEAL;
+       } else {
+               cipher = kctx->acceptor_enc;
+               aux_cipher = kctx->acceptor_enc_aux;
+               cksumkey = kctx->acceptor_integ;
+               usage = KG_USAGE_ACCEPTOR_SEAL;
+       }
+       blocksize = crypto_blkcipher_blocksize(cipher);
+
+       /* hide the gss token header and insert the confounder */
+       offset += GSS_KRB5_TOK_HDR_LEN;
+       if (xdr_extend_head(buf, offset, kctx->gk5e->conflen))
+               return GSS_S_FAILURE;
+       gss_krb5_make_confounder(buf->head[0].iov_base + offset, kctx->gk5e->conflen);
+       offset -= GSS_KRB5_TOK_HDR_LEN;
+
+       if (buf->tail[0].iov_base != NULL) {
+               ecptr = buf->tail[0].iov_base + buf->tail[0].iov_len;
+       } else {
+               buf->tail[0].iov_base = buf->head[0].iov_base
+                                                       + buf->head[0].iov_len;
+               buf->tail[0].iov_len = 0;
+               ecptr = buf->tail[0].iov_base;
+       }
+
+       memset(ecptr, 'X', ec);
+       buf->tail[0].iov_len += ec;
+       buf->len += ec;
+
+       /* copy plaintext gss token header after filler (if any) */
+       memcpy(ecptr + ec, buf->head[0].iov_base + offset,
+                                               GSS_KRB5_TOK_HDR_LEN);
+       buf->tail[0].iov_len += GSS_KRB5_TOK_HDR_LEN;
+       buf->len += GSS_KRB5_TOK_HDR_LEN;
+
+       /* Do the HMAC */
+       hmac.len = GSS_KRB5_MAX_CKSUM_LEN;
+       hmac.data = buf->tail[0].iov_base + buf->tail[0].iov_len;
+
+       /*
+        * When we are called, pages points to the real page cache
+        * data -- which we can't go and encrypt!  buf->pages points
+        * to scratch pages which we are going to send off to the
+        * client/server.  Swap in the plaintext pages to calculate
+        * the hmac.
+        */
+       save_pages = buf->pages;
+       buf->pages = pages;
+
+       err = make_checksum_v2(kctx, NULL, 0, buf,
+                              offset + GSS_KRB5_TOK_HDR_LEN,
+                              cksumkey, usage, &hmac);
+       buf->pages = save_pages;
+       if (err)
+               return GSS_S_FAILURE;
+
+       nbytes = buf->len - offset - GSS_KRB5_TOK_HDR_LEN;
+       nblocks = (nbytes + blocksize - 1) / blocksize;
+       cbcbytes = 0;
+       if (nblocks > 2)
+               cbcbytes = (nblocks - 2) * blocksize;
+
+       memset(desc.iv, 0, sizeof(desc.iv));
+
+       if (cbcbytes) {
+               desc.pos = offset + GSS_KRB5_TOK_HDR_LEN;
+               desc.fragno = 0;
+               desc.fraglen = 0;
+               desc.pages = pages;
+               desc.outbuf = buf;
+               desc.desc.info = desc.iv;
+               desc.desc.flags = 0;
+               desc.desc.tfm = aux_cipher;
+
+               sg_init_table(desc.infrags, 4);
+               sg_init_table(desc.outfrags, 4);
+
+               err = xdr_process_buf(buf, offset + GSS_KRB5_TOK_HDR_LEN,
+                                     cbcbytes, encryptor, &desc);
+               if (err)
+                       goto out_err;
+       }
+
+       /* Make sure IV carries forward from any CBC results. */
+       err = gss_krb5_cts_crypt(cipher, buf,
+                                offset + GSS_KRB5_TOK_HDR_LEN + cbcbytes,
+                                desc.iv, pages, 1);
+       if (err) {
+               err = GSS_S_FAILURE;
+               goto out_err;
+       }
+
+       /* Now update buf to account for HMAC */
+       buf->tail[0].iov_len += kctx->gk5e->cksumlength;
+       buf->len += kctx->gk5e->cksumlength;
+
+out_err:
+       if (err)
+               err = GSS_S_FAILURE;
+       return err;
+}
+
+u32
+gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf,
+                    u32 *headskip, u32 *tailskip)
+{
+       struct xdr_buf subbuf;
+       u32 ret = 0;
+       u8 *cksum_key;
+       struct crypto_blkcipher *cipher, *aux_cipher;
+       struct xdr_netobj our_hmac_obj;
+       u8 our_hmac[GSS_KRB5_MAX_CKSUM_LEN];
+       u8 pkt_hmac[GSS_KRB5_MAX_CKSUM_LEN];
+       int nblocks, blocksize, cbcbytes;
+       struct decryptor_desc desc;
+       unsigned int usage;
+
+       if (kctx->initiate) {
+               cipher = kctx->acceptor_enc;
+               aux_cipher = kctx->acceptor_enc_aux;
+               cksum_key = kctx->acceptor_integ;
+               usage = KG_USAGE_ACCEPTOR_SEAL;
+       } else {
+               cipher = kctx->initiator_enc;
+               aux_cipher = kctx->initiator_enc_aux;
+               cksum_key = kctx->initiator_integ;
+               usage = KG_USAGE_INITIATOR_SEAL;
+       }
+       blocksize = crypto_blkcipher_blocksize(cipher);
+
+
+       /* create a segment skipping the header and leaving out the checksum */
+       xdr_buf_subsegment(buf, &subbuf, offset + GSS_KRB5_TOK_HDR_LEN,
+                                   (buf->len - offset - GSS_KRB5_TOK_HDR_LEN -
+                                    kctx->gk5e->cksumlength));
+
+       nblocks = (subbuf.len + blocksize - 1) / blocksize;
+
+       cbcbytes = 0;
+       if (nblocks > 2)
+               cbcbytes = (nblocks - 2) * blocksize;
+
+       memset(desc.iv, 0, sizeof(desc.iv));
+
+       if (cbcbytes) {
+               desc.fragno = 0;
+               desc.fraglen = 0;
+               desc.desc.info = desc.iv;
+               desc.desc.flags = 0;
+               desc.desc.tfm = aux_cipher;
+
+               sg_init_table(desc.frags, 4);
+
+               ret = xdr_process_buf(&subbuf, 0, cbcbytes, decryptor, &desc);
+               if (ret)
+                       goto out_err;
+       }
+
+       /* Make sure IV carries forward from any CBC results. */
+       ret = gss_krb5_cts_crypt(cipher, &subbuf, cbcbytes, desc.iv, NULL, 0);
+       if (ret)
+               goto out_err;
+
+
+       /* Calculate our hmac over the plaintext data */
+       our_hmac_obj.len = sizeof(our_hmac);
+       our_hmac_obj.data = our_hmac;
+
+       ret = make_checksum_v2(kctx, NULL, 0, &subbuf, 0,
+                              cksum_key, usage, &our_hmac_obj);
+       if (ret)
+               goto out_err;
+
+       /* Get the packet's hmac value */
+       ret = read_bytes_from_xdr_buf(buf, buf->len - kctx->gk5e->cksumlength,
+                                     pkt_hmac, kctx->gk5e->cksumlength);
+       if (ret)
+               goto out_err;
+
+       if (memcmp(pkt_hmac, our_hmac, kctx->gk5e->cksumlength) != 0) {
+               ret = GSS_S_BAD_SIG;
+               goto out_err;
+       }
+       *headskip = kctx->gk5e->conflen;
+       *tailskip = kctx->gk5e->cksumlength;
+out_err:
+       if (ret && ret != GSS_S_BAD_SIG)
+               ret = GSS_S_FAILURE;
+       return ret;
+}
+
+/*
+ * Compute Kseq given the initial session key and the checksum.
+ * Set the key of the given cipher.
+ */
+int
+krb5_rc4_setup_seq_key(struct krb5_ctx *kctx, struct crypto_blkcipher *cipher,
+                      unsigned char *cksum)
+{
+       struct crypto_hash *hmac;
+       struct hash_desc desc;
+       struct scatterlist sg[1];
+       u8 Kseq[GSS_KRB5_MAX_KEYLEN];
+       u32 zeroconstant = 0;
+       int err;
+
+       dprintk("%s: entered\n", __func__);
+
+       hmac = crypto_alloc_hash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(hmac)) {
+               dprintk("%s: error %ld, allocating hash '%s'\n",
+                       __func__, PTR_ERR(hmac), kctx->gk5e->cksum_name);
+               return PTR_ERR(hmac);
+       }
+
+       desc.tfm = hmac;
+       desc.flags = 0;
+
+       err = crypto_hash_init(&desc);
+       if (err)
+               goto out_err;
+
+       /* Compute intermediate Kseq from session key */
+       err = crypto_hash_setkey(hmac, kctx->Ksess, kctx->gk5e->keylength);
+       if (err)
+               goto out_err;
+
+       sg_init_table(sg, 1);
+       sg_set_buf(sg, &zeroconstant, 4);
+
+       err = crypto_hash_digest(&desc, sg, 4, Kseq);
+       if (err)
+               goto out_err;
+
+       /* Compute final Kseq from the checksum and intermediate Kseq */
+       err = crypto_hash_setkey(hmac, Kseq, kctx->gk5e->keylength);
+       if (err)
+               goto out_err;
+
+       sg_set_buf(sg, cksum, 8);
+
+       err = crypto_hash_digest(&desc, sg, 8, Kseq);
+       if (err)
+               goto out_err;
+
+       err = crypto_blkcipher_setkey(cipher, Kseq, kctx->gk5e->keylength);
+       if (err)
+               goto out_err;
+
+       err = 0;
+
+out_err:
+       crypto_free_hash(hmac);
+       dprintk("%s: returning %d\n", __func__, err);
+       return err;
+}
+
+/*
+ * Compute Kcrypt given the initial session key and the plaintext seqnum.
+ * Set the key of cipher kctx->enc.
+ */
+int
+krb5_rc4_setup_enc_key(struct krb5_ctx *kctx, struct crypto_blkcipher *cipher,
+                      s32 seqnum)
+{
+       struct crypto_hash *hmac;
+       struct hash_desc desc;
+       struct scatterlist sg[1];
+       u8 Kcrypt[GSS_KRB5_MAX_KEYLEN];
+       u8 zeroconstant[4] = {0};
+       u8 seqnumarray[4];
+       int err, i;
+
+       dprintk("%s: entered, seqnum %u\n", __func__, seqnum);
+
+       hmac = crypto_alloc_hash(kctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(hmac)) {
+               dprintk("%s: error %ld, allocating hash '%s'\n",
+                       __func__, PTR_ERR(hmac), kctx->gk5e->cksum_name);
+               return PTR_ERR(hmac);
+       }
+
+       desc.tfm = hmac;
+       desc.flags = 0;
+
+       err = crypto_hash_init(&desc);
+       if (err)
+               goto out_err;
+
+       /* Compute intermediate Kcrypt from session key */
+       for (i = 0; i < kctx->gk5e->keylength; i++)
+               Kcrypt[i] = kctx->Ksess[i] ^ 0xf0;
+
+       err = crypto_hash_setkey(hmac, Kcrypt, kctx->gk5e->keylength);
+       if (err)
+               goto out_err;
+
+       sg_init_table(sg, 1);
+       sg_set_buf(sg, zeroconstant, 4);
+
+       err = crypto_hash_digest(&desc, sg, 4, Kcrypt);
+       if (err)
+               goto out_err;
+
+       /* Compute final Kcrypt from the seqnum and intermediate Kcrypt */
+       err = crypto_hash_setkey(hmac, Kcrypt, kctx->gk5e->keylength);
+       if (err)
+               goto out_err;
+
+       seqnumarray[0] = (unsigned char) ((seqnum >> 24) & 0xff);
+       seqnumarray[1] = (unsigned char) ((seqnum >> 16) & 0xff);
+       seqnumarray[2] = (unsigned char) ((seqnum >> 8) & 0xff);
+       seqnumarray[3] = (unsigned char) ((seqnum >> 0) & 0xff);
+
+       sg_set_buf(sg, seqnumarray, 4);
+
+       err = crypto_hash_digest(&desc, sg, 4, Kcrypt);
+       if (err)
+               goto out_err;
+
+       err = crypto_blkcipher_setkey(cipher, Kcrypt, kctx->gk5e->keylength);
+       if (err)
+               goto out_err;
+
+       err = 0;
+
+out_err:
+       crypto_free_hash(hmac);
+       dprintk("%s: returning %d\n", __func__, err);
+       return err;
+}
+
diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
new file mode 100644 (file)
index 0000000..76e42e6
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * COPYRIGHT (c) 2008
+ * The Regents of the University of Michigan
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization.  If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  FundsXpress makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/err.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/sunrpc/xdr.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+/*
+ * This is the n-fold function as described in rfc3961, sec 5.1
+ * Taken from MIT Kerberos and modified.
+ */
+
+static void krb5_nfold(u32 inbits, const u8 *in,
+                      u32 outbits, u8 *out)
+{
+       int a, b, c, lcm;
+       int byte, i, msbit;
+
+       /* the code below is more readable if I make these bytes
+          instead of bits */
+
+       inbits >>= 3;
+       outbits >>= 3;
+
+       /* first compute lcm(n,k) */
+
+       a = outbits;
+       b = inbits;
+
+       while (b != 0) {
+               c = b;
+               b = a%b;
+               a = c;
+       }
+
+       lcm = outbits*inbits/a;
+
+       /* now do the real work */
+
+       memset(out, 0, outbits);
+       byte = 0;
+
+       /* this will end up cycling through k lcm(k,n)/k times, which
+          is correct */
+       for (i = lcm-1; i >= 0; i--) {
+               /* compute the msbit in k which gets added into this byte */
+               msbit = (
+                       /* first, start with the msbit in the first,
+                        * unrotated byte */
+                        ((inbits << 3) - 1)
+                        /* then, for each byte, shift to the right
+                         * for each repetition */
+                        + (((inbits << 3) + 13) * (i/inbits))
+                        /* last, pick out the correct byte within
+                         * that shifted repetition */
+                        + ((inbits - (i % inbits)) << 3)
+                        ) % (inbits << 3);
+
+               /* pull out the byte value itself */
+               byte += (((in[((inbits - 1) - (msbit >> 3)) % inbits] << 8)|
+                                 (in[((inbits) - (msbit >> 3)) % inbits]))
+                                >> ((msbit & 7) + 1)) & 0xff;
+
+               /* do the addition */
+               byte += out[i % outbits];
+               out[i % outbits] = byte & 0xff;
+
+               /* keep around the carry bit, if any */
+               byte >>= 8;
+
+       }
+
+       /* if there's a carry bit left over, add it back in */
+       if (byte) {
+               for (i = outbits - 1; i >= 0; i--) {
+                       /* do the addition */
+                       byte += out[i];
+                       out[i] = byte & 0xff;
+
+                       /* keep around the carry bit, if any */
+                       byte >>= 8;
+               }
+       }
+}
+
+/*
+ * This is the DK (derive_key) function as described in rfc3961, sec 5.1
+ * Taken from MIT Kerberos and modified.
+ */
+
+u32 krb5_derive_key(const struct gss_krb5_enctype *gk5e,
+                   const struct xdr_netobj *inkey,
+                   struct xdr_netobj *outkey,
+                   const struct xdr_netobj *in_constant,
+                   gfp_t gfp_mask)
+{
+       size_t blocksize, keybytes, keylength, n;
+       unsigned char *inblockdata, *outblockdata, *rawkey;
+       struct xdr_netobj inblock, outblock;
+       struct crypto_blkcipher *cipher;
+       u32 ret = EINVAL;
+
+       blocksize = gk5e->blocksize;
+       keybytes = gk5e->keybytes;
+       keylength = gk5e->keylength;
+
+       if ((inkey->len != keylength) || (outkey->len != keylength))
+               goto err_return;
+
+       cipher = crypto_alloc_blkcipher(gk5e->encrypt_name, 0,
+                                       CRYPTO_ALG_ASYNC);
+       if (IS_ERR(cipher))
+               goto err_return;
+       if (crypto_blkcipher_setkey(cipher, inkey->data, inkey->len))
+               goto err_return;
+
+       /* allocate and set up buffers */
+
+       ret = ENOMEM;
+       inblockdata = kmalloc(blocksize, gfp_mask);
+       if (inblockdata == NULL)
+               goto err_free_cipher;
+
+       outblockdata = kmalloc(blocksize, gfp_mask);
+       if (outblockdata == NULL)
+               goto err_free_in;
+
+       rawkey = kmalloc(keybytes, gfp_mask);
+       if (rawkey == NULL)
+               goto err_free_out;
+
+       inblock.data = (char *) inblockdata;
+       inblock.len = blocksize;
+
+       outblock.data = (char *) outblockdata;
+       outblock.len = blocksize;
+
+       /* initialize the input block */
+
+       if (in_constant->len == inblock.len) {
+               memcpy(inblock.data, in_constant->data, inblock.len);
+       } else {
+               krb5_nfold(in_constant->len * 8, in_constant->data,
+                          inblock.len * 8, inblock.data);
+       }
+
+       /* loop encrypting the blocks until enough key bytes are generated */
+
+       n = 0;
+       while (n < keybytes) {
+               (*(gk5e->encrypt))(cipher, NULL, inblock.data,
+                                  outblock.data, inblock.len);
+
+               if ((keybytes - n) <= outblock.len) {
+                       memcpy(rawkey + n, outblock.data, (keybytes - n));
+                       break;
+               }
+
+               memcpy(rawkey + n, outblock.data, outblock.len);
+               memcpy(inblock.data, outblock.data, outblock.len);
+               n += outblock.len;
+       }
+
+       /* postprocess the key */
+
+       inblock.data = (char *) rawkey;
+       inblock.len = keybytes;
+
+       BUG_ON(gk5e->mk_key == NULL);
+       ret = (*(gk5e->mk_key))(gk5e, &inblock, outkey);
+       if (ret) {
+               dprintk("%s: got %d from mk_key function for '%s'\n",
+                       __func__, ret, gk5e->encrypt_name);
+               goto err_free_raw;
+       }
+
+       /* clean memory, free resources and exit */
+
+       ret = 0;
+
+err_free_raw:
+       memset(rawkey, 0, keybytes);
+       kfree(rawkey);
+err_free_out:
+       memset(outblockdata, 0, blocksize);
+       kfree(outblockdata);
+err_free_in:
+       memset(inblockdata, 0, blocksize);
+       kfree(inblockdata);
+err_free_cipher:
+       crypto_free_blkcipher(cipher);
+err_return:
+       return ret;
+}
+
+#define smask(step) ((1<<step)-1)
+#define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step)))
+#define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1)
+
+static void mit_des_fixup_key_parity(u8 key[8])
+{
+       int i;
+       for (i = 0; i < 8; i++) {
+               key[i] &= 0xfe;
+               key[i] |= 1^parity_char(key[i]);
+       }
+}
+
+/*
+ * This is the des3 key derivation postprocess function
+ */
+u32 gss_krb5_des3_make_key(const struct gss_krb5_enctype *gk5e,
+                          struct xdr_netobj *randombits,
+                          struct xdr_netobj *key)
+{
+       int i;
+       u32 ret = EINVAL;
+
+       if (key->len != 24) {
+               dprintk("%s: key->len is %d\n", __func__, key->len);
+               goto err_out;
+       }
+       if (randombits->len != 21) {
+               dprintk("%s: randombits->len is %d\n",
+                       __func__, randombits->len);
+               goto err_out;
+       }
+
+       /* take the seven bytes, move them around into the top 7 bits of the
+          8 key bytes, then compute the parity bits.  Do this three times. */
+
+       for (i = 0; i < 3; i++) {
+               memcpy(key->data + i*8, randombits->data + i*7, 7);
+               key->data[i*8+7] = (((key->data[i*8]&1)<<1) |
+                                   ((key->data[i*8+1]&1)<<2) |
+                                   ((key->data[i*8+2]&1)<<3) |
+                                   ((key->data[i*8+3]&1)<<4) |
+                                   ((key->data[i*8+4]&1)<<5) |
+                                   ((key->data[i*8+5]&1)<<6) |
+                                   ((key->data[i*8+6]&1)<<7));
+
+               mit_des_fixup_key_parity(key->data + i*8);
+       }
+       ret = 0;
+err_out:
+       return ret;
+}
+
+/*
+ * This is the aes key derivation postprocess function
+ */
+u32 gss_krb5_aes_make_key(const struct gss_krb5_enctype *gk5e,
+                         struct xdr_netobj *randombits,
+                         struct xdr_netobj *key)
+{
+       u32 ret = EINVAL;
+
+       if (key->len != 16 && key->len != 32) {
+               dprintk("%s: key->len is %d\n", __func__, key->len);
+               goto err_out;
+       }
+       if (randombits->len != 16 && randombits->len != 32) {
+               dprintk("%s: randombits->len is %d\n",
+                       __func__, randombits->len);
+               goto err_out;
+       }
+       if (randombits->len != key->len) {
+               dprintk("%s: randombits->len is %d, key->len is %d\n",
+                       __func__, randombits->len, key->len);
+               goto err_out;
+       }
+       memcpy(key->data, randombits->data, key->len);
+       ret = 0;
+err_out:
+       return ret;
+}
+
index 2deb0ed..0326446 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/net/sunrpc/gss_krb5_mech.c
  *
- *  Copyright (c) 2001 The Regents of the University of Michigan.
+ *  Copyright (c) 2001-2008 The Regents of the University of Michigan.
  *  All rights reserved.
  *
  *  Andy Adamson <andros@umich.edu>
 # define RPCDBG_FACILITY       RPCDBG_AUTH
 #endif
 
+static struct gss_api_mech gss_kerberos_mech;  /* forward declaration */
+
+static const struct gss_krb5_enctype supported_gss_krb5_enctypes[] = {
+       /*
+        * DES (All DES enctypes are mapped to the same gss functionality)
+        */
+       {
+         .etype = ENCTYPE_DES_CBC_RAW,
+         .ctype = CKSUMTYPE_RSA_MD5,
+         .name = "des-cbc-crc",
+         .encrypt_name = "cbc(des)",
+         .cksum_name = "md5",
+         .encrypt = krb5_encrypt,
+         .decrypt = krb5_decrypt,
+         .mk_key = NULL,
+         .signalg = SGN_ALG_DES_MAC_MD5,
+         .sealalg = SEAL_ALG_DES,
+         .keybytes = 7,
+         .keylength = 8,
+         .blocksize = 8,
+         .conflen = 8,
+         .cksumlength = 8,
+         .keyed_cksum = 0,
+       },
+       /*
+        * RC4-HMAC
+        */
+       {
+         .etype = ENCTYPE_ARCFOUR_HMAC,
+         .ctype = CKSUMTYPE_HMAC_MD5_ARCFOUR,
+         .name = "rc4-hmac",
+         .encrypt_name = "ecb(arc4)",
+         .cksum_name = "hmac(md5)",
+         .encrypt = krb5_encrypt,
+         .decrypt = krb5_decrypt,
+         .mk_key = NULL,
+         .signalg = SGN_ALG_HMAC_MD5,
+         .sealalg = SEAL_ALG_MICROSOFT_RC4,
+         .keybytes = 16,
+         .keylength = 16,
+         .blocksize = 1,
+         .conflen = 8,
+         .cksumlength = 8,
+         .keyed_cksum = 1,
+       },
+       /*
+        * 3DES
+        */
+       {
+         .etype = ENCTYPE_DES3_CBC_RAW,
+         .ctype = CKSUMTYPE_HMAC_SHA1_DES3,
+         .name = "des3-hmac-sha1",
+         .encrypt_name = "cbc(des3_ede)",
+         .cksum_name = "hmac(sha1)",
+         .encrypt = krb5_encrypt,
+         .decrypt = krb5_decrypt,
+         .mk_key = gss_krb5_des3_make_key,
+         .signalg = SGN_ALG_HMAC_SHA1_DES3_KD,
+         .sealalg = SEAL_ALG_DES3KD,
+         .keybytes = 21,
+         .keylength = 24,
+         .blocksize = 8,
+         .conflen = 8,
+         .cksumlength = 20,
+         .keyed_cksum = 1,
+       },
+       /*
+        * AES128
+        */
+       {
+         .etype = ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+         .ctype = CKSUMTYPE_HMAC_SHA1_96_AES128,
+         .name = "aes128-cts",
+         .encrypt_name = "cts(cbc(aes))",
+         .cksum_name = "hmac(sha1)",
+         .encrypt = krb5_encrypt,
+         .decrypt = krb5_decrypt,
+         .mk_key = gss_krb5_aes_make_key,
+         .encrypt_v2 = gss_krb5_aes_encrypt,
+         .decrypt_v2 = gss_krb5_aes_decrypt,
+         .signalg = -1,
+         .sealalg = -1,
+         .keybytes = 16,
+         .keylength = 16,
+         .blocksize = 16,
+         .conflen = 16,
+         .cksumlength = 12,
+         .keyed_cksum = 1,
+       },
+       /*
+        * AES256
+        */
+       {
+         .etype = ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+         .ctype = CKSUMTYPE_HMAC_SHA1_96_AES256,
+         .name = "aes256-cts",
+         .encrypt_name = "cts(cbc(aes))",
+         .cksum_name = "hmac(sha1)",
+         .encrypt = krb5_encrypt,
+         .decrypt = krb5_decrypt,
+         .mk_key = gss_krb5_aes_make_key,
+         .encrypt_v2 = gss_krb5_aes_encrypt,
+         .decrypt_v2 = gss_krb5_aes_decrypt,
+         .signalg = -1,
+         .sealalg = -1,
+         .keybytes = 32,
+         .keylength = 32,
+         .blocksize = 16,
+         .conflen = 16,
+         .cksumlength = 12,
+         .keyed_cksum = 1,
+       },
+};
+
+static const int num_supported_enctypes =
+       ARRAY_SIZE(supported_gss_krb5_enctypes);
+
+static int
+supported_gss_krb5_enctype(int etype)
+{
+       int i;
+       for (i = 0; i < num_supported_enctypes; i++)
+               if (supported_gss_krb5_enctypes[i].etype == etype)
+                       return 1;
+       return 0;
+}
+
+static const struct gss_krb5_enctype *
+get_gss_krb5_enctype(int etype)
+{
+       int i;
+       for (i = 0; i < num_supported_enctypes; i++)
+               if (supported_gss_krb5_enctypes[i].etype == etype)
+                       return &supported_gss_krb5_enctypes[i];
+       return NULL;
+}
+
 static const void *
 simple_get_bytes(const void *p, const void *end, void *res, int len)
 {
@@ -78,35 +215,45 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
 }
 
 static inline const void *
-get_key(const void *p, const void *end, struct crypto_blkcipher **res)
+get_key(const void *p, const void *end,
+       struct krb5_ctx *ctx, struct crypto_blkcipher **res)
 {
        struct xdr_netobj       key;
        int                     alg;
-       char                    *alg_name;
 
        p = simple_get_bytes(p, end, &alg, sizeof(alg));
        if (IS_ERR(p))
                goto out_err;
+
+       switch (alg) {
+       case ENCTYPE_DES_CBC_CRC:
+       case ENCTYPE_DES_CBC_MD4:
+       case ENCTYPE_DES_CBC_MD5:
+               /* Map all these key types to ENCTYPE_DES_CBC_RAW */
+               alg = ENCTYPE_DES_CBC_RAW;
+               break;
+       }
+
+       if (!supported_gss_krb5_enctype(alg)) {
+               printk(KERN_WARNING "gss_kerberos_mech: unsupported "
+                       "encryption key algorithm %d\n", alg);
+               goto out_err;
+       }
        p = simple_get_netobj(p, end, &key);
        if (IS_ERR(p))
                goto out_err;
 
-       switch (alg) {
-               case ENCTYPE_DES_CBC_RAW:
-                       alg_name = "cbc(des)";
-                       break;
-               default:
-                       printk("gss_kerberos_mech: unsupported algorithm %d\n", alg);
-                       goto out_err_free_key;
-       }
-       *res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
+       *res = crypto_alloc_blkcipher(ctx->gk5e->encrypt_name, 0,
+                                                       CRYPTO_ALG_ASYNC);
        if (IS_ERR(*res)) {
-               printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name);
+               printk(KERN_WARNING "gss_kerberos_mech: unable to initialize "
+                       "crypto algorithm %s\n", ctx->gk5e->encrypt_name);
                *res = NULL;
                goto out_err_free_key;
        }
        if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
-               printk("gss_kerberos_mech: error setting key for crypto algorithm %s\n", alg_name);
+               printk(KERN_WARNING "gss_kerberos_mech: error setting key for "
+                       "crypto algorithm %s\n", ctx->gk5e->encrypt_name);
                goto out_err_free_tfm;
        }
 
@@ -123,56 +270,55 @@ out_err:
 }
 
 static int
-gss_import_sec_context_kerberos(const void *p,
-                               size_t len,
-                               struct gss_ctx *ctx_id)
+gss_import_v1_context(const void *p, const void *end, struct krb5_ctx *ctx)
 {
-       const void *end = (const void *)((const char *)p + len);
-       struct  krb5_ctx *ctx;
        int tmp;
 
-       if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) {
-               p = ERR_PTR(-ENOMEM);
-               goto out_err;
-       }
-
        p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
        if (IS_ERR(p))
-               goto out_err_free_ctx;
+               goto out_err;
+
+       /* Old format supports only DES!  Any other enctype uses new format */
+       ctx->enctype = ENCTYPE_DES_CBC_RAW;
+
+       ctx->gk5e = get_gss_krb5_enctype(ctx->enctype);
+       if (ctx->gk5e == NULL)
+               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))
-               goto out_err_free_ctx;
+               goto out_err;
        p += 20;
        p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
        if (IS_ERR(p))
-               goto out_err_free_ctx;
+               goto out_err;
        if (tmp != SGN_ALG_DES_MAC_MD5) {
                p = ERR_PTR(-ENOSYS);
-               goto out_err_free_ctx;
+               goto out_err;
        }
        p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
        if (IS_ERR(p))
-               goto out_err_free_ctx;
+               goto out_err;
        if (tmp != SEAL_ALG_DES) {
                p = ERR_PTR(-ENOSYS);
-               goto out_err_free_ctx;
+               goto out_err;
        }
        p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
        if (IS_ERR(p))
-               goto out_err_free_ctx;
+               goto out_err;
        p = simple_get_bytes(p, end, &ctx->seq_send, sizeof(ctx->seq_send));
        if (IS_ERR(p))
-               goto out_err_free_ctx;
+               goto out_err;
        p = simple_get_netobj(p, end, &ctx->mech_used);
        if (IS_ERR(p))
-               goto out_err_free_ctx;
-       p = get_key(p, end, &ctx->enc);
+               goto out_err;
+       p = get_key(p, end, ctx, &ctx->enc);
        if (IS_ERR(p))
                goto out_err_free_mech;
-       p = get_key(p, end, &ctx->seq);
+       p = get_key(p, end, ctx, &ctx->seq);
        if (IS_ERR(p))
                goto out_err_free_key1;
        if (p != end) {
@@ -180,9 +326,6 @@ gss_import_sec_context_kerberos(const void *p,
                goto out_err_free_key2;
        }
 
-       ctx_id->internal_ctx_id = ctx;
-
-       dprintk("RPC:       Successfully imported new context.\n");
        return 0;
 
 out_err_free_key2:
@@ -191,18 +334,378 @@ out_err_free_key1:
        crypto_free_blkcipher(ctx->enc);
 out_err_free_mech:
        kfree(ctx->mech_used.data);
-out_err_free_ctx:
-       kfree(ctx);
 out_err:
        return PTR_ERR(p);
 }
 
+struct crypto_blkcipher *
+context_v2_alloc_cipher(struct krb5_ctx *ctx, const char *cname, u8 *key)
+{
+       struct crypto_blkcipher *cp;
+
+       cp = crypto_alloc_blkcipher(cname, 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(cp)) {
+               dprintk("gss_kerberos_mech: unable to initialize "
+                       "crypto algorithm %s\n", cname);
+               return NULL;
+       }
+       if (crypto_blkcipher_setkey(cp, key, ctx->gk5e->keylength)) {
+               dprintk("gss_kerberos_mech: error setting key for "
+                       "crypto algorithm %s\n", cname);
+               crypto_free_blkcipher(cp);
+               return NULL;
+       }
+       return cp;
+}
+
+static inline void
+set_cdata(u8 cdata[GSS_KRB5_K5CLENGTH], u32 usage, u8 seed)
+{
+       cdata[0] = (usage>>24)&0xff;
+       cdata[1] = (usage>>16)&0xff;
+       cdata[2] = (usage>>8)&0xff;
+       cdata[3] = usage&0xff;
+       cdata[4] = seed;
+}
+
+static int
+context_derive_keys_des3(struct krb5_ctx *ctx, gfp_t gfp_mask)
+{
+       struct xdr_netobj c, keyin, keyout;
+       u8 cdata[GSS_KRB5_K5CLENGTH];
+       u32 err;
+
+       c.len = GSS_KRB5_K5CLENGTH;
+       c.data = cdata;
+
+       keyin.data = ctx->Ksess;
+       keyin.len = ctx->gk5e->keylength;
+       keyout.len = ctx->gk5e->keylength;
+
+       /* seq uses the raw key */
+       ctx->seq = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name,
+                                          ctx->Ksess);
+       if (ctx->seq == NULL)
+               goto out_err;
+
+       ctx->enc = context_v2_alloc_cipher(ctx, ctx->gk5e->encrypt_name,
+                                          ctx->Ksess);
+       if (ctx->enc == NULL)
+               goto out_free_seq;
+
+       /* derive cksum */
+       set_cdata(cdata, KG_USAGE_SIGN, KEY_USAGE_SEED_CHECKSUM);
+       keyout.data = ctx->cksum;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving cksum key\n",
+                       __func__, err);
+               goto out_free_enc;
+       }
+
+       return 0;
+
+out_free_enc:
+       crypto_free_blkcipher(ctx->enc);
+out_free_seq:
+       crypto_free_blkcipher(ctx->seq);
+out_err:
+       return -EINVAL;
+}
+
+/*
+ * Note that RC4 depends on deriving keys using the sequence
+ * number or the checksum of a token.  Therefore, the final keys
+ * cannot be calculated until the token is being constructed!
+ */
+static int
+context_derive_keys_rc4(struct krb5_ctx *ctx)
+{
+       struct crypto_hash *hmac;
+       char sigkeyconstant[] = "signaturekey";
+       int slen = strlen(sigkeyconstant) + 1;  /* include null terminator */
+       struct hash_desc desc;
+       struct scatterlist sg[1];
+       int err;
+
+       dprintk("RPC:       %s: entered\n", __func__);
+       /*
+        * derive cksum (aka Ksign) key
+        */
+       hmac = crypto_alloc_hash(ctx->gk5e->cksum_name, 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(hmac)) {
+               dprintk("%s: error %ld allocating hash '%s'\n",
+                       __func__, PTR_ERR(hmac), ctx->gk5e->cksum_name);
+               err = PTR_ERR(hmac);
+               goto out_err;
+       }
+
+       err = crypto_hash_setkey(hmac, ctx->Ksess, ctx->gk5e->keylength);
+       if (err)
+               goto out_err_free_hmac;
+
+       sg_init_table(sg, 1);
+       sg_set_buf(sg, sigkeyconstant, slen);
+
+       desc.tfm = hmac;
+       desc.flags = 0;
+
+       err = crypto_hash_init(&desc);
+       if (err)
+               goto out_err_free_hmac;
+
+       err = crypto_hash_digest(&desc, sg, slen, ctx->cksum);
+       if (err)
+               goto out_err_free_hmac;
+       /*
+        * allocate hash, and blkciphers for data and seqnum encryption
+        */
+       ctx->enc = crypto_alloc_blkcipher(ctx->gk5e->encrypt_name, 0,
+                                         CRYPTO_ALG_ASYNC);
+       if (IS_ERR(ctx->enc)) {
+               err = PTR_ERR(ctx->enc);
+               goto out_err_free_hmac;
+       }
+
+       ctx->seq = crypto_alloc_blkcipher(ctx->gk5e->encrypt_name, 0,
+                                         CRYPTO_ALG_ASYNC);
+       if (IS_ERR(ctx->seq)) {
+               crypto_free_blkcipher(ctx->enc);
+               err = PTR_ERR(ctx->seq);
+               goto out_err_free_hmac;
+       }
+
+       dprintk("RPC:       %s: returning success\n", __func__);
+
+       err = 0;
+
+out_err_free_hmac:
+       crypto_free_hash(hmac);
+out_err:
+       dprintk("RPC:       %s: returning %d\n", __func__, err);
+       return err;
+}
+
+static int
+context_derive_keys_new(struct krb5_ctx *ctx, gfp_t gfp_mask)
+{
+       struct xdr_netobj c, keyin, keyout;
+       u8 cdata[GSS_KRB5_K5CLENGTH];
+       u32 err;
+
+       c.len = GSS_KRB5_K5CLENGTH;
+       c.data = cdata;
+
+       keyin.data = ctx->Ksess;
+       keyin.len = ctx->gk5e->keylength;
+       keyout.len = ctx->gk5e->keylength;
+
+       /* initiator seal encryption */
+       set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_ENCRYPTION);
+       keyout.data = ctx->initiator_seal;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving initiator_seal key\n",
+                       __func__, err);
+               goto out_err;
+       }
+       ctx->initiator_enc = context_v2_alloc_cipher(ctx,
+                                                    ctx->gk5e->encrypt_name,
+                                                    ctx->initiator_seal);
+       if (ctx->initiator_enc == NULL)
+               goto out_err;
+
+       /* acceptor seal encryption */
+       set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_ENCRYPTION);
+       keyout.data = ctx->acceptor_seal;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving acceptor_seal key\n",
+                       __func__, err);
+               goto out_free_initiator_enc;
+       }
+       ctx->acceptor_enc = context_v2_alloc_cipher(ctx,
+                                                   ctx->gk5e->encrypt_name,
+                                                   ctx->acceptor_seal);
+       if (ctx->acceptor_enc == NULL)
+               goto out_free_initiator_enc;
+
+       /* initiator sign checksum */
+       set_cdata(cdata, KG_USAGE_INITIATOR_SIGN, KEY_USAGE_SEED_CHECKSUM);
+       keyout.data = ctx->initiator_sign;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving initiator_sign key\n",
+                       __func__, err);
+               goto out_free_acceptor_enc;
+       }
+
+       /* acceptor sign checksum */
+       set_cdata(cdata, KG_USAGE_ACCEPTOR_SIGN, KEY_USAGE_SEED_CHECKSUM);
+       keyout.data = ctx->acceptor_sign;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving acceptor_sign key\n",
+                       __func__, err);
+               goto out_free_acceptor_enc;
+       }
+
+       /* initiator seal integrity */
+       set_cdata(cdata, KG_USAGE_INITIATOR_SEAL, KEY_USAGE_SEED_INTEGRITY);
+       keyout.data = ctx->initiator_integ;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving initiator_integ key\n",
+                       __func__, err);
+               goto out_free_acceptor_enc;
+       }
+
+       /* acceptor seal integrity */
+       set_cdata(cdata, KG_USAGE_ACCEPTOR_SEAL, KEY_USAGE_SEED_INTEGRITY);
+       keyout.data = ctx->acceptor_integ;
+       err = krb5_derive_key(ctx->gk5e, &keyin, &keyout, &c, gfp_mask);
+       if (err) {
+               dprintk("%s: Error %d deriving acceptor_integ key\n",
+                       __func__, err);
+               goto out_free_acceptor_enc;
+       }
+
+       switch (ctx->enctype) {
+       case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+       case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+               ctx->initiator_enc_aux =
+                       context_v2_alloc_cipher(ctx, "cbc(aes)",
+                                               ctx->initiator_seal);
+               if (ctx->initiator_enc_aux == NULL)
+                       goto out_free_acceptor_enc;
+               ctx->acceptor_enc_aux =
+                       context_v2_alloc_cipher(ctx, "cbc(aes)",
+                                               ctx->acceptor_seal);
+               if (ctx->acceptor_enc_aux == NULL) {
+                       crypto_free_blkcipher(ctx->initiator_enc_aux);
+                       goto out_free_acceptor_enc;
+               }
+       }
+
+       return 0;
+
+out_free_acceptor_enc:
+       crypto_free_blkcipher(ctx->acceptor_enc);
+out_free_initiator_enc:
+       crypto_free_blkcipher(ctx->initiator_enc);
+out_err:
+       return -EINVAL;
+}
+
+static int
+gss_import_v2_context(const void *p, const void *end, struct krb5_ctx *ctx,
+               gfp_t gfp_mask)
+{
+       int keylen;
+
+       p = simple_get_bytes(p, end, &ctx->flags, sizeof(ctx->flags));
+       if (IS_ERR(p))
+               goto out_err;
+       ctx->initiate = ctx->flags & KRB5_CTX_FLAG_INITIATOR;
+
+       p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
+       if (IS_ERR(p))
+               goto out_err;
+       p = simple_get_bytes(p, end, &ctx->seq_send64, sizeof(ctx->seq_send64));
+       if (IS_ERR(p))
+               goto out_err;
+       /* set seq_send for use by "older" enctypes */
+       ctx->seq_send = ctx->seq_send64;
+       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);
+               goto out_err;
+       }
+       p = simple_get_bytes(p, end, &ctx->enctype, sizeof(ctx->enctype));
+       if (IS_ERR(p))
+               goto out_err;
+       /* Map ENCTYPE_DES3_CBC_SHA1 to ENCTYPE_DES3_CBC_RAW */
+       if (ctx->enctype == ENCTYPE_DES3_CBC_SHA1)
+               ctx->enctype = ENCTYPE_DES3_CBC_RAW;
+       ctx->gk5e = get_gss_krb5_enctype(ctx->enctype);
+       if (ctx->gk5e == NULL) {
+               dprintk("gss_kerberos_mech: unsupported krb5 enctype %u\n",
+                       ctx->enctype);
+               p = ERR_PTR(-EINVAL);
+               goto out_err;
+       }
+       keylen = ctx->gk5e->keylength;
+
+       p = simple_get_bytes(p, end, ctx->Ksess, keylen);
+       if (IS_ERR(p))
+               goto out_err;
+
+       if (p != end) {
+               p = ERR_PTR(-EINVAL);
+               goto out_err;
+       }
+
+       ctx->mech_used.data = kmemdup(gss_kerberos_mech.gm_oid.data,
+                                     gss_kerberos_mech.gm_oid.len, gfp_mask);
+       if (unlikely(ctx->mech_used.data == NULL)) {
+               p = ERR_PTR(-ENOMEM);
+               goto out_err;
+       }
+       ctx->mech_used.len = gss_kerberos_mech.gm_oid.len;
+
+       switch (ctx->enctype) {
+       case ENCTYPE_DES3_CBC_RAW:
+               return context_derive_keys_des3(ctx, gfp_mask);
+       case ENCTYPE_ARCFOUR_HMAC:
+               return context_derive_keys_rc4(ctx);
+       case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+       case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+               return context_derive_keys_new(ctx, gfp_mask);
+       default:
+               return -EINVAL;
+       }
+
+out_err:
+       return PTR_ERR(p);
+}
+
+static int
+gss_import_sec_context_kerberos(const void *p, size_t len,
+                               struct gss_ctx *ctx_id,
+                               gfp_t gfp_mask)
+{
+       const void *end = (const void *)((const char *)p + len);
+       struct  krb5_ctx *ctx;
+       int ret;
+
+       ctx = kzalloc(sizeof(*ctx), gfp_mask);
+       if (ctx == NULL)
+               return -ENOMEM;
+
+       if (len == 85)
+               ret = gss_import_v1_context(p, end, ctx);
+       else
+               ret = gss_import_v2_context(p, end, ctx, gfp_mask);
+
+       if (ret == 0)
+               ctx_id->internal_ctx_id = ctx;
+       else
+               kfree(ctx);
+
+       dprintk("RPC:       %s: returning %d\n", __func__, ret);
+       return ret;
+}
+
 static void
 gss_delete_sec_context_kerberos(void *internal_ctx) {
        struct krb5_ctx *kctx = internal_ctx;
 
        crypto_free_blkcipher(kctx->seq);
        crypto_free_blkcipher(kctx->enc);
+       crypto_free_blkcipher(kctx->acceptor_enc);
+       crypto_free_blkcipher(kctx->initiator_enc);
+       crypto_free_blkcipher(kctx->acceptor_enc_aux);
+       crypto_free_blkcipher(kctx->initiator_enc_aux);
        kfree(kctx->mech_used.data);
        kfree(kctx);
 }
@@ -241,6 +744,7 @@ static struct gss_api_mech gss_kerberos_mech = {
        .gm_ops         = &gss_kerberos_ops,
        .gm_pf_num      = ARRAY_SIZE(gss_kerberos_pfs),
        .gm_pfs         = gss_kerberos_pfs,
+       .gm_upcall_enctypes = "enctypes=18,17,16,23,3,1,2 ",
 };
 
 static int __init init_kerberos_module(void)
index 88fe6e7..d7941ea 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5seal.c
  *
- *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  Copyright (c) 2000-2008 The Regents of the University of Michigan.
  *  All rights reserved.
  *
  *  Andy Adamson       <andros@umich.edu>
 
 DEFINE_SPINLOCK(krb5_seq_lock);
 
-u32
-gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
+static char *
+setup_token(struct krb5_ctx *ctx, struct xdr_netobj *token)
+{
+       __be16 *ptr, *krb5_hdr;
+       int body_size = GSS_KRB5_TOK_HDR_LEN + ctx->gk5e->cksumlength;
+
+       token->len = g_token_size(&ctx->mech_used, body_size);
+
+       ptr = (__be16 *)token->data;
+       g_make_token_header(&ctx->mech_used, body_size, (unsigned char **)&ptr);
+
+       /* ptr now at start of header described in rfc 1964, section 1.2.1: */
+       krb5_hdr = ptr;
+       *ptr++ = KG_TOK_MIC_MSG;
+       *ptr++ = cpu_to_le16(ctx->gk5e->signalg);
+       *ptr++ = SEAL_ALG_NONE;
+       *ptr++ = 0xffff;
+
+       return (char *)krb5_hdr;
+}
+
+static void *
+setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token)
+{
+       __be16 *ptr, *krb5_hdr;
+       u8 *p, flags = 0x00;
+
+       if ((ctx->flags & KRB5_CTX_FLAG_INITIATOR) == 0)
+               flags |= 0x01;
+       if (ctx->flags & KRB5_CTX_FLAG_ACCEPTOR_SUBKEY)
+               flags |= 0x04;
+
+       /* Per rfc 4121, sec 4.2.6.1, there is no header,
+        * just start the token */
+       krb5_hdr = ptr = (__be16 *)token->data;
+
+       *ptr++ = KG2_TOK_MIC;
+       p = (u8 *)ptr;
+       *p++ = flags;
+       *p++ = 0xff;
+       ptr = (__be16 *)p;
+       *ptr++ = 0xffff;
+       *ptr++ = 0xffff;
+
+       token->len = GSS_KRB5_TOK_HDR_LEN + ctx->gk5e->cksumlength;
+       return krb5_hdr;
+}
+
+static u32
+gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
                struct xdr_netobj *token)
 {
-       struct krb5_ctx         *ctx = gss_ctx->internal_ctx_id;
-       char                    cksumdata[16];
-       struct xdr_netobj       md5cksum = {.len = 0, .data = cksumdata};
-       unsigned char           *ptr, *msg_start;
+       char                    cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       struct xdr_netobj       md5cksum = {.len = sizeof(cksumdata),
+                                           .data = cksumdata};
+       void                    *ptr;
        s32                     now;
        u32                     seq_send;
+       u8                      *cksumkey;
 
-       dprintk("RPC:       gss_krb5_seal\n");
+       dprintk("RPC:       %s\n", __func__);
        BUG_ON(ctx == NULL);
 
        now = get_seconds();
 
-       token->len = g_token_size(&ctx->mech_used, GSS_KRB5_TOK_HDR_LEN + 8);
+       ptr = setup_token(ctx, token);
 
-       ptr = token->data;
-       g_make_token_header(&ctx->mech_used, GSS_KRB5_TOK_HDR_LEN + 8, &ptr);
+       if (ctx->gk5e->keyed_cksum)
+               cksumkey = ctx->cksum;
+       else
+               cksumkey = NULL;
 
-       /* ptr now at header described in rfc 1964, section 1.2.1: */
-       ptr[0] = (unsigned char) ((KG_TOK_MIC_MSG >> 8) & 0xff);
-       ptr[1] = (unsigned char) (KG_TOK_MIC_MSG & 0xff);
+       if (make_checksum(ctx, ptr, 8, text, 0, cksumkey,
+                         KG_USAGE_SIGN, &md5cksum))
+               return GSS_S_FAILURE;
 
-       msg_start = ptr + GSS_KRB5_TOK_HDR_LEN + 8;
+       memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
 
-       *(__be16 *)(ptr + 2) = htons(SGN_ALG_DES_MAC_MD5);
-       memset(ptr + 4, 0xff, 4);
+       spin_lock(&krb5_seq_lock);
+       seq_send = ctx->seq_send++;
+       spin_unlock(&krb5_seq_lock);
 
-       if (make_checksum("md5", ptr, 8, text, 0, &md5cksum))
+       if (krb5_make_seq_num(ctx, ctx->seq, ctx->initiate ? 0 : 0xff,
+                             seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8))
                return GSS_S_FAILURE;
 
-       if (krb5_encrypt(ctx->seq, NULL, md5cksum.data,
-                         md5cksum.data, md5cksum.len))
-               return GSS_S_FAILURE;
+       return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
+}
+
+u32
+gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
+               struct xdr_netobj *token)
+{
+       char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       struct xdr_netobj cksumobj = { .len = sizeof(cksumdata),
+                                      .data = cksumdata};
+       void *krb5_hdr;
+       s32 now;
+       u64 seq_send;
+       u8 *cksumkey;
+       unsigned int cksum_usage;
 
-       memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data + md5cksum.len - 8, 8);
+       dprintk("RPC:       %s\n", __func__);
 
+       krb5_hdr = setup_token_v2(ctx, token);
+
+       /* Set up the sequence number. Now 64-bits in clear
+        * text and w/o direction indicator */
        spin_lock(&krb5_seq_lock);
-       seq_send = ctx->seq_send++;
+       seq_send = ctx->seq_send64++;
        spin_unlock(&krb5_seq_lock);
-
-       if (krb5_make_seq_num(ctx->seq, ctx->initiate ? 0 : 0xff,
-                             seq_send, ptr + GSS_KRB5_TOK_HDR_LEN,
-                             ptr + 8))
+       *((u64 *)(krb5_hdr + 8)) = cpu_to_be64(seq_send);
+
+       if (ctx->initiate) {
+               cksumkey = ctx->initiator_sign;
+               cksum_usage = KG_USAGE_INITIATOR_SIGN;
+       } else {
+               cksumkey = ctx->acceptor_sign;
+               cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
+       }
+
+       if (make_checksum_v2(ctx, krb5_hdr, GSS_KRB5_TOK_HDR_LEN,
+                            text, 0, cksumkey, cksum_usage, &cksumobj))
                return GSS_S_FAILURE;
 
+       memcpy(krb5_hdr + GSS_KRB5_TOK_HDR_LEN, cksumobj.data, cksumobj.len);
+
+       now = get_seconds();
+
        return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
 }
+
+u32
+gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
+                    struct xdr_netobj *token)
+{
+       struct krb5_ctx         *ctx = gss_ctx->internal_ctx_id;
+
+       switch (ctx->enctype) {
+       default:
+               BUG();
+       case ENCTYPE_DES_CBC_RAW:
+       case ENCTYPE_DES3_CBC_RAW:
+       case ENCTYPE_ARCFOUR_HMAC:
+               return gss_get_mic_v1(ctx, text, token);
+       case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+       case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+               return gss_get_mic_v2(ctx, text, token);
+       }
+}
+
index 6331cd6..415c013 100644 (file)
 # define RPCDBG_FACILITY        RPCDBG_AUTH
 #endif
 
+static s32
+krb5_make_rc4_seq_num(struct krb5_ctx *kctx, int direction, s32 seqnum,
+                     unsigned char *cksum, unsigned char *buf)
+{
+       struct crypto_blkcipher *cipher;
+       unsigned char plain[8];
+       s32 code;
+
+       dprintk("RPC:       %s:\n", __func__);
+       cipher = crypto_alloc_blkcipher(kctx->gk5e->encrypt_name, 0,
+                                       CRYPTO_ALG_ASYNC);
+       if (IS_ERR(cipher))
+               return PTR_ERR(cipher);
+
+       plain[0] = (unsigned char) ((seqnum >> 24) & 0xff);
+       plain[1] = (unsigned char) ((seqnum >> 16) & 0xff);
+       plain[2] = (unsigned char) ((seqnum >> 8) & 0xff);
+       plain[3] = (unsigned char) ((seqnum >> 0) & 0xff);
+       plain[4] = direction;
+       plain[5] = direction;
+       plain[6] = direction;
+       plain[7] = direction;
+
+       code = krb5_rc4_setup_seq_key(kctx, cipher, cksum);
+       if (code)
+               goto out;
+
+       code = krb5_encrypt(cipher, cksum, plain, buf, 8);
+out:
+       crypto_free_blkcipher(cipher);
+       return code;
+}
 s32
-krb5_make_seq_num(struct crypto_blkcipher *key,
+krb5_make_seq_num(struct krb5_ctx *kctx,
+               struct crypto_blkcipher *key,
                int direction,
                u32 seqnum,
                unsigned char *cksum, unsigned char *buf)
 {
        unsigned char plain[8];
 
+       if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
+               return krb5_make_rc4_seq_num(kctx, direction, seqnum,
+                                            cksum, buf);
+
        plain[0] = (unsigned char) (seqnum & 0xff);
        plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
        plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
@@ -60,17 +97,59 @@ krb5_make_seq_num(struct crypto_blkcipher *key,
        return krb5_encrypt(key, cksum, plain, buf, 8);
 }
 
+static s32
+krb5_get_rc4_seq_num(struct krb5_ctx *kctx, unsigned char *cksum,
+                    unsigned char *buf, int *direction, s32 *seqnum)
+{
+       struct crypto_blkcipher *cipher;
+       unsigned char plain[8];
+       s32 code;
+
+       dprintk("RPC:       %s:\n", __func__);
+       cipher = crypto_alloc_blkcipher(kctx->gk5e->encrypt_name, 0,
+                                       CRYPTO_ALG_ASYNC);
+       if (IS_ERR(cipher))
+               return PTR_ERR(cipher);
+
+       code = krb5_rc4_setup_seq_key(kctx, cipher, cksum);
+       if (code)
+               goto out;
+
+       code = krb5_decrypt(cipher, cksum, buf, plain, 8);
+       if (code)
+               goto out;
+
+       if ((plain[4] != plain[5]) || (plain[4] != plain[6])
+                                  || (plain[4] != plain[7])) {
+               code = (s32)KG_BAD_SEQ;
+               goto out;
+       }
+
+       *direction = plain[4];
+
+       *seqnum = ((plain[0] << 24) | (plain[1] << 16) |
+                                       (plain[2] << 8) | (plain[3]));
+out:
+       crypto_free_blkcipher(cipher);
+       return code;
+}
+
 s32
-krb5_get_seq_num(struct crypto_blkcipher *key,
+krb5_get_seq_num(struct krb5_ctx *kctx,
               unsigned char *cksum,
               unsigned char *buf,
               int *direction, u32 *seqnum)
 {
        s32 code;
        unsigned char plain[8];
+       struct crypto_blkcipher *key = kctx->seq;
 
        dprintk("RPC:       krb5_get_seq_num:\n");
 
+       if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC)
+               return krb5_get_rc4_seq_num(kctx, cksum, buf,
+                                           direction, seqnum);
+
        if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
                return code;
 
index ce6c247..6cd930f 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.c
  *
- *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  Copyright (c) 2000-2008 The Regents of the University of Michigan.
  *  All rights reserved.
  *
  *  Andy Adamson   <andros@umich.edu>
 /* read_token is a mic token, and message_buffer is the data that the mic was
  * supposedly taken over. */
 
-u32
-gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
+static u32
+gss_verify_mic_v1(struct krb5_ctx *ctx,
                struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
 {
-       struct krb5_ctx         *ctx = gss_ctx->internal_ctx_id;
        int                     signalg;
        int                     sealalg;
-       char                    cksumdata[16];
-       struct xdr_netobj       md5cksum = {.len = 0, .data = cksumdata};
+       char                    cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       struct xdr_netobj       md5cksum = {.len = sizeof(cksumdata),
+                                           .data = cksumdata};
        s32                     now;
        int                     direction;
        u32                     seqnum;
        unsigned char           *ptr = (unsigned char *)read_token->data;
        int                     bodysize;
+       u8                      *cksumkey;
 
        dprintk("RPC:       krb5_read_token\n");
 
@@ -98,7 +99,7 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
        /* XXX sanity-check bodysize?? */
 
        signalg = ptr[2] + (ptr[3] << 8);
-       if (signalg != SGN_ALG_DES_MAC_MD5)
+       if (signalg != ctx->gk5e->signalg)
                return GSS_S_DEFECTIVE_TOKEN;
 
        sealalg = ptr[4] + (ptr[5] << 8);
@@ -108,13 +109,17 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
        if ((ptr[6] != 0xff) || (ptr[7] != 0xff))
                return GSS_S_DEFECTIVE_TOKEN;
 
-       if (make_checksum("md5", ptr, 8, message_buffer, 0, &md5cksum))
-               return GSS_S_FAILURE;
+       if (ctx->gk5e->keyed_cksum)
+               cksumkey = ctx->cksum;
+       else
+               cksumkey = NULL;
 
-       if (krb5_encrypt(ctx->seq, NULL, md5cksum.data, md5cksum.data, 16))
+       if (make_checksum(ctx, ptr, 8, message_buffer, 0,
+                         cksumkey, KG_USAGE_SIGN, &md5cksum))
                return GSS_S_FAILURE;
 
-       if (memcmp(md5cksum.data + 8, ptr + GSS_KRB5_TOK_HDR_LEN, 8))
+       if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,
+                                       ctx->gk5e->cksumlength))
                return GSS_S_BAD_SIG;
 
        /* it got through unscathed.  Make sure the context is unexpired */
@@ -126,7 +131,8 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
 
        /* do sequencing checks */
 
-       if (krb5_get_seq_num(ctx->seq, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8, &direction, &seqnum))
+       if (krb5_get_seq_num(ctx, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8,
+                            &direction, &seqnum))
                return GSS_S_FAILURE;
 
        if ((ctx->initiate && direction != 0xff) ||
@@ -135,3 +141,86 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
 
        return GSS_S_COMPLETE;
 }
+
+static u32
+gss_verify_mic_v2(struct krb5_ctx *ctx,
+               struct xdr_buf *message_buffer, struct xdr_netobj *read_token)
+{
+       char cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       struct xdr_netobj cksumobj = {.len = sizeof(cksumdata),
+                                     .data = cksumdata};
+       s32 now;
+       u64 seqnum;
+       u8 *ptr = read_token->data;
+       u8 *cksumkey;
+       u8 flags;
+       int i;
+       unsigned int cksum_usage;
+
+       dprintk("RPC:       %s\n", __func__);
+
+       if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_MIC)
+               return GSS_S_DEFECTIVE_TOKEN;
+
+       flags = ptr[2];
+       if ((!ctx->initiate && (flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)) ||
+           (ctx->initiate && !(flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)))
+               return GSS_S_BAD_SIG;
+
+       if (flags & KG2_TOKEN_FLAG_SEALED) {
+               dprintk("%s: token has unexpected sealed flag\n", __func__);
+               return GSS_S_FAILURE;
+       }
+
+       for (i = 3; i < 8; i++)
+               if (ptr[i] != 0xff)
+                       return GSS_S_DEFECTIVE_TOKEN;
+
+       if (ctx->initiate) {
+               cksumkey = ctx->acceptor_sign;
+               cksum_usage = KG_USAGE_ACCEPTOR_SIGN;
+       } else {
+               cksumkey = ctx->initiator_sign;
+               cksum_usage = KG_USAGE_INITIATOR_SIGN;
+       }
+
+       if (make_checksum_v2(ctx, ptr, GSS_KRB5_TOK_HDR_LEN, message_buffer, 0,
+                            cksumkey, cksum_usage, &cksumobj))
+               return GSS_S_FAILURE;
+
+       if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN,
+                               ctx->gk5e->cksumlength))
+               return GSS_S_BAD_SIG;
+
+       /* it got through unscathed.  Make sure the context is unexpired */
+       now = get_seconds();
+       if (now > ctx->endtime)
+               return GSS_S_CONTEXT_EXPIRED;
+
+       /* do sequencing checks */
+
+       seqnum = be64_to_cpup((__be64 *)ptr + 8);
+
+       return GSS_S_COMPLETE;
+}
+
+u32
+gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
+                       struct xdr_buf *message_buffer,
+                       struct xdr_netobj *read_token)
+{
+       struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
+
+       switch (ctx->enctype) {
+       default:
+               BUG();
+       case ENCTYPE_DES_CBC_RAW:
+       case ENCTYPE_DES3_CBC_RAW:
+       case ENCTYPE_ARCFOUR_HMAC:
+               return gss_verify_mic_v1(ctx, message_buffer, read_token);
+       case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+       case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+               return gss_verify_mic_v2(ctx, message_buffer, read_token);
+       }
+}
+
index a6e9056..2763e3e 100644 (file)
@@ -1,3 +1,33 @@
+/*
+ * COPYRIGHT (c) 2008
+ * The Regents of the University of Michigan
+ * ALL RIGHTS RESERVED
+ *
+ * Permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of The University of
+ * Michigan is not used in any advertising or publicity
+ * pertaining to the use of distribution of this software
+ * without specific, written prior authorization.  If the
+ * above copyright notice or any other identification of the
+ * University of Michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
+ * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
+ * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
+ * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
+ * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
+ * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
+ * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGES.
+ */
+
 #include <linux/types.h>
 #include <linux/jiffies.h>
 #include <linux/sunrpc/gss_krb5.h>
 static inline int
 gss_krb5_padding(int blocksize, int length)
 {
-       /* Most of the code is block-size independent but currently we
-        * use only 8: */
-       BUG_ON(blocksize != 8);
-       return 8 - (length & 7);
+       return blocksize - (length % blocksize);
 }
 
 static inline void
@@ -86,8 +113,8 @@ out:
        return 0;
 }
 
-static void
-make_confounder(char *p, u32 conflen)
+void
+gss_krb5_make_confounder(char *p, u32 conflen)
 {
        static u64 i = 0;
        u64 *q = (u64 *)p;
@@ -127,69 +154,73 @@ make_confounder(char *p, u32 conflen)
 
 /* XXX factor out common code with seal/unseal. */
 
-u32
-gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
+static u32
+gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,
                struct xdr_buf *buf, struct page **pages)
 {
-       struct krb5_ctx         *kctx = ctx->internal_ctx_id;
-       char                    cksumdata[16];
-       struct xdr_netobj       md5cksum = {.len = 0, .data = cksumdata};
+       char                    cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       struct xdr_netobj       md5cksum = {.len = sizeof(cksumdata),
+                                           .data = cksumdata};
        int                     blocksize = 0, plainlen;
        unsigned char           *ptr, *msg_start;
        s32                     now;
        int                     headlen;
        struct page             **tmp_pages;
        u32                     seq_send;
+       u8                      *cksumkey;
+       u32                     conflen = kctx->gk5e->conflen;
 
-       dprintk("RPC:       gss_wrap_kerberos\n");
+       dprintk("RPC:       %s\n", __func__);
 
        now = get_seconds();
 
        blocksize = crypto_blkcipher_blocksize(kctx->enc);
        gss_krb5_add_padding(buf, offset, blocksize);
        BUG_ON((buf->len - offset) % blocksize);
-       plainlen = blocksize + buf->len - offset;
+       plainlen = conflen + buf->len - offset;
 
-       headlen = g_token_size(&kctx->mech_used, 24 + plainlen) -
-                                               (buf->len - offset);
+       headlen = g_token_size(&kctx->mech_used,
+               GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength + plainlen) -
+               (buf->len - offset);
 
        ptr = buf->head[0].iov_base + offset;
        /* shift data to make room for header. */
+       xdr_extend_head(buf, offset, headlen);
+
        /* XXX Would be cleverer to encrypt while copying. */
-       /* XXX bounds checking, slack, etc. */
-       memmove(ptr + headlen, ptr, buf->head[0].iov_len - offset);
-       buf->head[0].iov_len += headlen;
-       buf->len += headlen;
        BUG_ON((buf->len - offset - headlen) % blocksize);
 
        g_make_token_header(&kctx->mech_used,
-                               GSS_KRB5_TOK_HDR_LEN + 8 + plainlen, &ptr);
+                               GSS_KRB5_TOK_HDR_LEN +
+                               kctx->gk5e->cksumlength + plainlen, &ptr);
 
 
        /* ptr now at header described in rfc 1964, section 1.2.1: */
        ptr[0] = (unsigned char) ((KG_TOK_WRAP_MSG >> 8) & 0xff);
        ptr[1] = (unsigned char) (KG_TOK_WRAP_MSG & 0xff);
 
-       msg_start = ptr + 24;
+       msg_start = ptr + GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength;
 
-       *(__be16 *)(ptr + 2) = htons(SGN_ALG_DES_MAC_MD5);
+       *(__be16 *)(ptr + 2) = cpu_to_le16(kctx->gk5e->signalg);
        memset(ptr + 4, 0xff, 4);
-       *(__be16 *)(ptr + 4) = htons(SEAL_ALG_DES);
+       *(__be16 *)(ptr + 4) = cpu_to_le16(kctx->gk5e->sealalg);
 
-       make_confounder(msg_start, blocksize);
+       gss_krb5_make_confounder(msg_start, conflen);
+
+       if (kctx->gk5e->keyed_cksum)
+               cksumkey = kctx->cksum;
+       else
+               cksumkey = NULL;
 
        /* XXXJBF: UGH!: */
        tmp_pages = buf->pages;
        buf->pages = pages;
-       if (make_checksum("md5", ptr, 8, buf,
-                               offset + headlen - blocksize, &md5cksum))
+       if (make_checksum(kctx, ptr, 8, buf, offset + headlen - conflen,
+                                       cksumkey, KG_USAGE_SEAL, &md5cksum))
                return GSS_S_FAILURE;
        buf->pages = tmp_pages;
 
-       if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
-                         md5cksum.data, md5cksum.len))
-               return GSS_S_FAILURE;
-       memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data + md5cksum.len - 8, 8);
+       memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
 
        spin_lock(&krb5_seq_lock);
        seq_send = kctx->seq_send++;
@@ -197,25 +228,42 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
 
        /* XXX would probably be more efficient to compute checksum
         * and encrypt at the same time: */
-       if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff,
+       if ((krb5_make_seq_num(kctx, kctx->seq, kctx->initiate ? 0 : 0xff,
                               seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8)))
                return GSS_S_FAILURE;
 
-       if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
-                                                                       pages))
-               return GSS_S_FAILURE;
+       if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC) {
+               struct crypto_blkcipher *cipher;
+               int err;
+               cipher = crypto_alloc_blkcipher(kctx->gk5e->encrypt_name, 0,
+                                               CRYPTO_ALG_ASYNC);
+               if (IS_ERR(cipher))
+                       return GSS_S_FAILURE;
+
+               krb5_rc4_setup_enc_key(kctx, cipher, seq_send);
+
+               err = gss_encrypt_xdr_buf(cipher, buf,
+                                         offset + headlen - conflen, pages);
+               crypto_free_blkcipher(cipher);
+               if (err)
+                       return GSS_S_FAILURE;
+       } else {
+               if (gss_encrypt_xdr_buf(kctx->enc, buf,
+                                       offset + headlen - conflen, pages))
+                       return GSS_S_FAILURE;
+       }
 
        return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
 }
 
-u32
-gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
+static u32
+gss_unwrap_kerberos_v1(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
 {
-       struct krb5_ctx         *kctx = ctx->internal_ctx_id;
        int                     signalg;
        int                     sealalg;
-       char                    cksumdata[16];
-       struct xdr_netobj       md5cksum = {.len = 0, .data = cksumdata};
+       char                    cksumdata[GSS_KRB5_MAX_CKSUM_LEN];
+       struct xdr_netobj       md5cksum = {.len = sizeof(cksumdata),
+                                           .data = cksumdata};
        s32                     now;
        int                     direction;
        s32                     seqnum;
@@ -224,6 +272,9 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
        void                    *data_start, *orig_start;
        int                     data_len;
        int                     blocksize;
+       u32                     conflen = kctx->gk5e->conflen;
+       int                     crypt_offset;
+       u8                      *cksumkey;
 
        dprintk("RPC:       gss_unwrap_kerberos\n");
 
@@ -241,29 +292,65 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
        /* get the sign and seal algorithms */
 
        signalg = ptr[2] + (ptr[3] << 8);
-       if (signalg != SGN_ALG_DES_MAC_MD5)
+       if (signalg != kctx->gk5e->signalg)
                return GSS_S_DEFECTIVE_TOKEN;
 
        sealalg = ptr[4] + (ptr[5] << 8);
-       if (sealalg != SEAL_ALG_DES)
+       if (sealalg != kctx->gk5e->sealalg)
                return GSS_S_DEFECTIVE_TOKEN;
 
        if ((ptr[6] != 0xff) || (ptr[7] != 0xff))
                return GSS_S_DEFECTIVE_TOKEN;
 
-       if (gss_decrypt_xdr_buf(kctx->enc, buf,
-                       ptr + GSS_KRB5_TOK_HDR_LEN + 8 - (unsigned char *)buf->head[0].iov_base))
-               return GSS_S_DEFECTIVE_TOKEN;
+       /*
+        * Data starts after token header and checksum.  ptr points
+        * to the beginning of the token header
+        */
+       crypt_offset = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) -
+                                       (unsigned char *)buf->head[0].iov_base;
+
+       /*
+        * Need plaintext seqnum to derive encryption key for arcfour-hmac
+        */
+       if (krb5_get_seq_num(kctx, ptr + GSS_KRB5_TOK_HDR_LEN,
+                            ptr + 8, &direction, &seqnum))
+               return GSS_S_BAD_SIG;
 
-       if (make_checksum("md5", ptr, 8, buf,
-                ptr + GSS_KRB5_TOK_HDR_LEN + 8 - (unsigned char *)buf->head[0].iov_base, &md5cksum))
-               return GSS_S_FAILURE;
+       if ((kctx->initiate && direction != 0xff) ||
+           (!kctx->initiate && direction != 0))
+               return GSS_S_BAD_SIG;
+
+       if (kctx->enctype == ENCTYPE_ARCFOUR_HMAC) {
+               struct crypto_blkcipher *cipher;
+               int err;
+
+               cipher = crypto_alloc_blkcipher(kctx->gk5e->encrypt_name, 0,
+                                               CRYPTO_ALG_ASYNC);
+               if (IS_ERR(cipher))
+                       return GSS_S_FAILURE;
+
+               krb5_rc4_setup_enc_key(kctx, cipher, seqnum);
 
-       if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
-                          md5cksum.data, md5cksum.len))
+               err = gss_decrypt_xdr_buf(cipher, buf, crypt_offset);
+               crypto_free_blkcipher(cipher);
+               if (err)
+                       return GSS_S_DEFECTIVE_TOKEN;
+       } else {
+               if (gss_decrypt_xdr_buf(kctx->enc, buf, crypt_offset))
+                       return GSS_S_DEFECTIVE_TOKEN;
+       }
+
+       if (kctx->gk5e->keyed_cksum)
+               cksumkey = kctx->cksum;
+       else
+               cksumkey = NULL;
+
+       if (make_checksum(kctx, ptr, 8, buf, crypt_offset,
+                                       cksumkey, KG_USAGE_SEAL, &md5cksum))
                return GSS_S_FAILURE;
 
-       if (memcmp(md5cksum.data + 8, ptr + GSS_KRB5_TOK_HDR_LEN, 8))
+       if (memcmp(md5cksum.data, ptr + GSS_KRB5_TOK_HDR_LEN,
+                                               kctx->gk5e->cksumlength))
                return GSS_S_BAD_SIG;
 
        /* it got through unscathed.  Make sure the context is unexpired */
@@ -275,19 +362,12 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
 
        /* do sequencing checks */
 
-       if (krb5_get_seq_num(kctx->seq, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8,
-                                   &direction, &seqnum))
-               return GSS_S_BAD_SIG;
-
-       if ((kctx->initiate && direction != 0xff) ||
-           (!kctx->initiate && direction != 0))
-               return GSS_S_BAD_SIG;
-
        /* Copy the data back to the right position.  XXX: Would probably be
         * better to copy and encrypt at the same time. */
 
        blocksize = crypto_blkcipher_blocksize(kctx->enc);
-       data_start = ptr + GSS_KRB5_TOK_HDR_LEN + 8 + blocksize;
+       data_start = ptr + (GSS_KRB5_TOK_HDR_LEN + kctx->gk5e->cksumlength) +
+                                       conflen;
        orig_start = buf->head[0].iov_base + offset;
        data_len = (buf->head[0].iov_base + buf->head[0].iov_len) - data_start;
        memmove(orig_start, data_start, data_len);
@@ -299,3 +379,209 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
 
        return GSS_S_COMPLETE;
 }
+
+/*
+ * We cannot currently handle tokens with rotated data.  We need a
+ * generalized routine to rotate the data in place.  It is anticipated
+ * that we won't encounter rotated data in the general case.
+ */
+static u32
+rotate_left(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, u16 rrc)
+{
+       unsigned int realrrc = rrc % (buf->len - offset - GSS_KRB5_TOK_HDR_LEN);
+
+       if (realrrc == 0)
+               return 0;
+
+       dprintk("%s: cannot process token with rotated data: "
+               "rrc %u, realrrc %u\n", __func__, rrc, realrrc);
+       return 1;
+}
+
+static u32
+gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
+                    struct xdr_buf *buf, struct page **pages)
+{
+       int             blocksize;
+       u8              *ptr, *plainhdr;
+       s32             now;
+       u8              flags = 0x00;
+       __be16          *be16ptr, ec = 0;
+       __be64          *be64ptr;
+       u32             err;
+
+       dprintk("RPC:       %s\n", __func__);
+
+       if (kctx->gk5e->encrypt_v2 == NULL)
+               return GSS_S_FAILURE;
+
+       /* make room for gss token header */
+       if (xdr_extend_head(buf, offset, GSS_KRB5_TOK_HDR_LEN))
+               return GSS_S_FAILURE;
+
+       /* construct gss token header */
+       ptr = plainhdr = buf->head[0].iov_base + offset;
+       *ptr++ = (unsigned char) ((KG2_TOK_WRAP>>8) & 0xff);
+       *ptr++ = (unsigned char) (KG2_TOK_WRAP & 0xff);
+
+       if ((kctx->flags & KRB5_CTX_FLAG_INITIATOR) == 0)
+               flags |= KG2_TOKEN_FLAG_SENTBYACCEPTOR;
+       if ((kctx->flags & KRB5_CTX_FLAG_ACCEPTOR_SUBKEY) != 0)
+               flags |= KG2_TOKEN_FLAG_ACCEPTORSUBKEY;
+       /* We always do confidentiality in wrap tokens */
+       flags |= KG2_TOKEN_FLAG_SEALED;
+
+       *ptr++ = flags;
+       *ptr++ = 0xff;
+       be16ptr = (__be16 *)ptr;
+
+       blocksize = crypto_blkcipher_blocksize(kctx->acceptor_enc);
+       *be16ptr++ = cpu_to_be16(ec);
+       /* "inner" token header always uses 0 for RRC */
+       *be16ptr++ = cpu_to_be16(0);
+
+       be64ptr = (__be64 *)be16ptr;
+       spin_lock(&krb5_seq_lock);
+       *be64ptr = cpu_to_be64(kctx->seq_send64++);
+       spin_unlock(&krb5_seq_lock);
+
+       err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, ec, pages);
+       if (err)
+               return err;
+
+       now = get_seconds();
+       return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
+}
+
+static u32
+gss_unwrap_kerberos_v2(struct krb5_ctx *kctx, int offset, struct xdr_buf *buf)
+{
+       s32             now;
+       u64             seqnum;
+       u8              *ptr;
+       u8              flags = 0x00;
+       u16             ec, rrc;
+       int             err;
+       u32             headskip, tailskip;
+       u8              decrypted_hdr[GSS_KRB5_TOK_HDR_LEN];
+       unsigned int    movelen;
+
+
+       dprintk("RPC:       %s\n", __func__);
+
+       if (kctx->gk5e->decrypt_v2 == NULL)
+               return GSS_S_FAILURE;
+
+       ptr = buf->head[0].iov_base + offset;
+
+       if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_WRAP)
+               return GSS_S_DEFECTIVE_TOKEN;
+
+       flags = ptr[2];
+       if ((!kctx->initiate && (flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)) ||
+           (kctx->initiate && !(flags & KG2_TOKEN_FLAG_SENTBYACCEPTOR)))
+               return GSS_S_BAD_SIG;
+
+       if ((flags & KG2_TOKEN_FLAG_SEALED) == 0) {
+               dprintk("%s: token missing expected sealed flag\n", __func__);
+               return GSS_S_DEFECTIVE_TOKEN;
+       }
+
+       if (ptr[3] != 0xff)
+               return GSS_S_DEFECTIVE_TOKEN;
+
+       ec = be16_to_cpup((__be16 *)(ptr + 4));
+       rrc = be16_to_cpup((__be16 *)(ptr + 6));
+
+       seqnum = be64_to_cpup((__be64 *)(ptr + 8));
+
+       if (rrc != 0) {
+               err = rotate_left(kctx, offset, buf, rrc);
+               if (err)
+                       return GSS_S_FAILURE;
+       }
+
+       err = (*kctx->gk5e->decrypt_v2)(kctx, offset, buf,
+                                       &headskip, &tailskip);
+       if (err)
+               return GSS_S_FAILURE;
+
+       /*
+        * Retrieve the decrypted gss token header and verify
+        * it against the original
+        */
+       err = read_bytes_from_xdr_buf(buf,
+                               buf->len - GSS_KRB5_TOK_HDR_LEN - tailskip,
+                               decrypted_hdr, GSS_KRB5_TOK_HDR_LEN);
+       if (err) {
+               dprintk("%s: error %u getting decrypted_hdr\n", __func__, err);
+               return GSS_S_FAILURE;
+       }
+       if (memcmp(ptr, decrypted_hdr, 6)
+                               || memcmp(ptr + 8, decrypted_hdr + 8, 8)) {
+               dprintk("%s: token hdr, plaintext hdr mismatch!\n", __func__);
+               return GSS_S_FAILURE;
+       }
+
+       /* do sequencing checks */
+
+       /* it got through unscathed.  Make sure the context is unexpired */
+       now = get_seconds();
+       if (now > kctx->endtime)
+               return GSS_S_CONTEXT_EXPIRED;
+
+       /*
+        * Move the head data back to the right position in xdr_buf.
+        * We ignore any "ec" data since it might be in the head or
+        * the tail, and we really don't need to deal with it.
+        * Note that buf->head[0].iov_len may indicate the available
+        * head buffer space rather than that actually occupied.
+        */
+       movelen = min_t(unsigned int, buf->head[0].iov_len, buf->len);
+       movelen -= offset + GSS_KRB5_TOK_HDR_LEN + headskip;
+       BUG_ON(offset + GSS_KRB5_TOK_HDR_LEN + headskip + movelen >
+                                                       buf->head[0].iov_len);
+       memmove(ptr, ptr + GSS_KRB5_TOK_HDR_LEN + headskip, movelen);
+       buf->head[0].iov_len -= GSS_KRB5_TOK_HDR_LEN + headskip;
+       buf->len -= GSS_KRB5_TOK_HDR_LEN + headskip;
+
+       return GSS_S_COMPLETE;
+}
+
+u32
+gss_wrap_kerberos(struct gss_ctx *gctx, int offset,
+                 struct xdr_buf *buf, struct page **pages)
+{
+       struct krb5_ctx *kctx = gctx->internal_ctx_id;
+
+       switch (kctx->enctype) {
+       default:
+               BUG();
+       case ENCTYPE_DES_CBC_RAW:
+       case ENCTYPE_DES3_CBC_RAW:
+       case ENCTYPE_ARCFOUR_HMAC:
+               return gss_wrap_kerberos_v1(kctx, offset, buf, pages);
+       case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+       case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+               return gss_wrap_kerberos_v2(kctx, offset, buf, pages);
+       }
+}
+
+u32
+gss_unwrap_kerberos(struct gss_ctx *gctx, int offset, struct xdr_buf *buf)
+{
+       struct krb5_ctx *kctx = gctx->internal_ctx_id;
+
+       switch (kctx->enctype) {
+       default:
+               BUG();
+       case ENCTYPE_DES_CBC_RAW:
+       case ENCTYPE_DES3_CBC_RAW:
+       case ENCTYPE_ARCFOUR_HMAC:
+               return gss_unwrap_kerberos_v1(kctx, offset, buf);
+       case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+       case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
+               return gss_unwrap_kerberos_v2(kctx, offset, buf);
+       }
+}
+
index 76e4c6f..2689de3 100644 (file)
@@ -249,14 +249,15 @@ EXPORT_SYMBOL_GPL(gss_mech_put);
 int
 gss_import_sec_context(const void *input_token, size_t bufsize,
                       struct gss_api_mech      *mech,
-                      struct gss_ctx           **ctx_id)
+                      struct gss_ctx           **ctx_id,
+                      gfp_t gfp_mask)
 {
-       if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL)))
+       if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask)))
                return -ENOMEM;
        (*ctx_id)->mech_type = gss_mech_get(mech);
 
        return mech->gm_ops
-               ->gss_import_sec_context(input_token, bufsize, *ctx_id);
+               ->gss_import_sec_context(input_token, bufsize, *ctx_id, gfp_mask);
 }
 
 /* gss_get_mic: compute a mic over message and return mic_token. */
@@ -285,6 +286,20 @@ gss_verify_mic(struct gss_ctx              *context_handle,
                                 mic_token);
 }
 
+/*
+ * This function is called from both the client and server code.
+ * Each makes guarantees about how much "slack" space is available
+ * for the underlying function in "buf"'s head and tail while
+ * performing the wrap.
+ *
+ * The client and server code allocate RPC_MAX_AUTH_SIZE extra
+ * space in both the head and tail which is available for use by
+ * the wrap function.
+ *
+ * Underlying functions should verify they do not use more than
+ * RPC_MAX_AUTH_SIZE of extra space in either the head or tail
+ * when performing the wrap.
+ */
 u32
 gss_wrap(struct gss_ctx        *ctx_id,
         int            offset,
index 035e1dd..dc3f1f5 100644 (file)
@@ -84,13 +84,14 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
 
 static int
 gss_import_sec_context_spkm3(const void *p, size_t len,
-                               struct gss_ctx *ctx_id)
+                               struct gss_ctx *ctx_id,
+                               gfp_t gfp_mask)
 {
        const void *end = (const void *)((const char *)p + len);
        struct  spkm3_ctx *ctx;
        int     version;
 
-       if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS)))
+       if (!(ctx = kzalloc(sizeof(*ctx), gfp_mask)))
                goto out_err;
 
        p = simple_get_bytes(p, end, &version, sizeof(version));
index b81e790..cc385b3 100644 (file)
@@ -494,7 +494,7 @@ static int rsc_parse(struct cache_detail *cd,
                len = qword_get(&mesg, buf, mlen);
                if (len < 0)
                        goto out;
-               status = gss_import_sec_context(buf, len, gm, &rsci.mechctx);
+               status = gss_import_sec_context(buf, len, gm, &rsci.mechctx, GFP_KERNEL);
                if (status)
                        goto out;
 
@@ -1315,6 +1315,14 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
        inpages = resbuf->pages;
        /* XXX: Would be better to write some xdr helper functions for
         * nfs{2,3,4}xdr.c that place the data right, instead of copying: */
+
+       /*
+        * If there is currently tail data, make sure there is
+        * room for the head, tail, and 2 * RPC_MAX_AUTH_SIZE in
+        * the page, and move the current tail data such that
+        * there is RPC_MAX_AUTH_SIZE slack space available in
+        * both the head and tail.
+        */
        if (resbuf->tail[0].iov_base) {
                BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base
                                                        + PAGE_SIZE);
@@ -1327,6 +1335,13 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp)
                        resbuf->tail[0].iov_len);
                resbuf->tail[0].iov_base += RPC_MAX_AUTH_SIZE;
        }
+       /*
+        * If there is no current tail data, make sure there is
+        * room for the head data, and 2 * RPC_MAX_AUTH_SIZE in the
+        * allotted page, and set up tail information such that there
+        * is RPC_MAX_AUTH_SIZE slack space available in both the
+        * head and tail.
+        */
        if (resbuf->tail[0].iov_base == NULL) {
                if (resbuf->head[0].iov_len + 2*RPC_MAX_AUTH_SIZE > PAGE_SIZE)
                        return -ENOMEM;
index 39bddba..c2173eb 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
+#include <linux/smp_lock.h>
 #include <asm/ioctls.h>
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/cache.h>
@@ -49,11 +50,17 @@ static void cache_init(struct cache_head *h)
        h->last_refresh = now;
 }
 
+static inline int cache_is_expired(struct cache_detail *detail, struct cache_head *h)
+{
+       return  (h->expiry_time < get_seconds()) ||
+               (detail->flush_time > h->last_refresh);
+}
+
 struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
                                       struct cache_head *key, int hash)
 {
        struct cache_head **head,  **hp;
-       struct cache_head *new = NULL;
+       struct cache_head *new = NULL, *freeme = NULL;
 
        head = &detail->hash_table[hash];
 
@@ -62,6 +69,9 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
        for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
                struct cache_head *tmp = *hp;
                if (detail->match(tmp, key)) {
+                       if (cache_is_expired(detail, tmp))
+                               /* This entry is expired, we will discard it. */
+                               break;
                        cache_get(tmp);
                        read_unlock(&detail->hash_lock);
                        return tmp;
@@ -86,6 +96,13 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
        for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
                struct cache_head *tmp = *hp;
                if (detail->match(tmp, key)) {
+                       if (cache_is_expired(detail, tmp)) {
+                               *hp = tmp->next;
+                               tmp->next = NULL;
+                               detail->entries --;
+                               freeme = tmp;
+                               break;
+                       }
                        cache_get(tmp);
                        write_unlock(&detail->hash_lock);
                        cache_put(new, detail);
@@ -98,6 +115,8 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
        cache_get(new);
        write_unlock(&detail->hash_lock);
 
+       if (freeme)
+               cache_put(freeme, detail);
        return new;
 }
 EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
@@ -183,10 +202,7 @@ static int cache_make_upcall(struct cache_detail *cd, struct cache_head *h)
 
 static inline int cache_is_valid(struct cache_detail *detail, struct cache_head *h)
 {
-       if (!test_bit(CACHE_VALID, &h->flags) ||
-           h->expiry_time < get_seconds())
-               return -EAGAIN;
-       else if (detail->flush_time > h->last_refresh)
+       if (!test_bit(CACHE_VALID, &h->flags))
                return -EAGAIN;
        else {
                /* entry is valid */
@@ -397,31 +413,27 @@ static int cache_clean(void)
                /* Ok, now to clean this strand */
 
                cp = & current_detail->hash_table[current_index];
-               ch = *cp;
-               for (; ch; cp= & ch->next, ch= *cp) {
+               for (ch = *cp ; ch ; cp = & ch->next, ch = *cp) {
                        if (current_detail->nextcheck > ch->expiry_time)
                                current_detail->nextcheck = ch->expiry_time+1;
-                       if (ch->expiry_time >= get_seconds() &&
-                           ch->last_refresh >= current_detail->flush_time)
+                       if (!cache_is_expired(current_detail, ch))
                                continue;
-                       if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
-                               cache_dequeue(current_detail, ch);
 
-                       if (atomic_read(&ch->ref.refcount) == 1)
-                               break;
-               }
-               if (ch) {
                        *cp = ch->next;
                        ch->next = NULL;
                        current_detail->entries--;
                        rv = 1;
+                       break;
                }
+
                write_unlock(&current_detail->hash_lock);
                d = current_detail;
                if (!ch)
                        current_index ++;
                spin_unlock(&cache_list_lock);
                if (ch) {
+                       if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
+                               cache_dequeue(current_detail, ch);
                        cache_revisit_request(ch);
                        cache_put(ch, d);
                }
@@ -1233,8 +1245,10 @@ static int content_open(struct inode *inode, struct file *file,
        if (!cd || !try_module_get(cd->owner))
                return -EACCES;
        han = __seq_open_private(file, &cache_content_op, sizeof(*han));
-       if (han == NULL)
+       if (han == NULL) {
+               module_put(cd->owner);
                return -ENOMEM;
+       }
 
        han->cd = cd;
        return 0;
@@ -1331,12 +1345,18 @@ static unsigned int cache_poll_procfs(struct file *filp, poll_table *wait)
        return cache_poll(filp, wait, cd);
 }
 
-static int cache_ioctl_procfs(struct inode *inode, struct file *filp,
-                             unsigned int cmd, unsigned long arg)
+static long cache_ioctl_procfs(struct file *filp,
+                              unsigned int cmd, unsigned long arg)
 {
+       long ret;
+       struct inode *inode = filp->f_path.dentry->d_inode;
        struct cache_detail *cd = PDE(inode)->data;
 
-       return cache_ioctl(inode, filp, cmd, arg, cd);
+       lock_kernel();
+       ret = cache_ioctl(inode, filp, cmd, arg, cd);
+       unlock_kernel();
+
+       return ret;
 }
 
 static int cache_open_procfs(struct inode *inode, struct file *filp)
@@ -1359,7 +1379,7 @@ static const struct file_operations cache_file_operations_procfs = {
        .read           = cache_read_procfs,
        .write          = cache_write_procfs,
        .poll           = cache_poll_procfs,
-       .ioctl          = cache_ioctl_procfs, /* for FIONREAD */
+       .unlocked_ioctl = cache_ioctl_procfs, /* for FIONREAD */
        .open           = cache_open_procfs,
        .release        = cache_release_procfs,
 };
index 19c9983..8c7b543 100644 (file)
@@ -556,26 +556,16 @@ static const struct rpc_call_ops rpc_default_ops = {
  */
 struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
 {
-       struct rpc_task *task, *ret;
+       struct rpc_task *task;
 
        task = rpc_new_task(task_setup_data);
-       if (task == NULL) {
-               rpc_release_calldata(task_setup_data->callback_ops,
-                               task_setup_data->callback_data);
-               ret = ERR_PTR(-ENOMEM);
+       if (IS_ERR(task))
                goto out;
-       }
 
-       if (task->tk_status != 0) {
-               ret = ERR_PTR(task->tk_status);
-               rpc_put_task(task);
-               goto out;
-       }
        atomic_inc(&task->tk_count);
        rpc_execute(task);
-       ret = task;
 out:
-       return ret;
+       return task;
 }
 EXPORT_SYMBOL_GPL(rpc_run_task);
 
@@ -657,9 +647,8 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
         * Create an rpc_task to send the data
         */
        task = rpc_new_task(&task_setup_data);
-       if (!task) {
+       if (IS_ERR(task)) {
                xprt_free_bc_request(req);
-               task = ERR_PTR(-ENOMEM);
                goto out;
        }
        task->tk_rqstp = req;
index aae6907..4a843b8 100644 (file)
@@ -25,7 +25,6 @@
 
 #ifdef RPC_DEBUG
 #define RPCDBG_FACILITY                RPCDBG_SCHED
-#define RPC_TASK_MAGIC_ID      0xf00baa
 #endif
 
 /*
@@ -237,7 +236,6 @@ static void rpc_task_set_debuginfo(struct rpc_task *task)
 {
        static atomic_t rpc_pid;
 
-       task->tk_magic = RPC_TASK_MAGIC_ID;
        task->tk_pid = atomic_inc_return(&rpc_pid);
 }
 #else
@@ -360,9 +358,6 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task
        dprintk("RPC: %5u __rpc_wake_up_task (now %lu)\n",
                        task->tk_pid, jiffies);
 
-#ifdef RPC_DEBUG
-       BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
-#endif
        /* Has the task been executed yet? If not, we cannot wake it up! */
        if (!RPC_IS_ACTIVATED(task)) {
                printk(KERN_ERR "RPC: Inactive task (%p) being woken up!\n", task);
@@ -834,7 +829,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
        }
 
        /* starting timestamp */
-       task->tk_start = jiffies;
+       task->tk_start = ktime_get();
 
        dprintk("RPC:       new task initialized, procpid %u\n",
                                task_pid_nr(current));
@@ -856,16 +851,23 @@ struct rpc_task *rpc_new_task(const struct rpc_task_setup *setup_data)
 
        if (task == NULL) {
                task = rpc_alloc_task();
-               if (task == NULL)
-                       goto out;
+               if (task == NULL) {
+                       rpc_release_calldata(setup_data->callback_ops,
+                                       setup_data->callback_data);
+                       return ERR_PTR(-ENOMEM);
+               }
                flags = RPC_TASK_DYNAMIC;
        }
 
        rpc_init_task(task, setup_data);
+       if (task->tk_status < 0) {
+               int err = task->tk_status;
+               rpc_put_task(task);
+               return ERR_PTR(err);
+       }
 
        task->tk_flags |= flags;
        dprintk("RPC:       allocated task %p\n", task);
-out:
        return task;
 }
 
@@ -909,9 +911,6 @@ EXPORT_SYMBOL_GPL(rpc_put_task);
 
 static void rpc_release_task(struct rpc_task *task)
 {
-#ifdef RPC_DEBUG
-       BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
-#endif
        dprintk("RPC: %5u release task\n", task->tk_pid);
 
        if (!list_empty(&task->tk_task)) {
@@ -923,9 +922,6 @@ static void rpc_release_task(struct rpc_task *task)
        }
        BUG_ON (RPC_IS_QUEUED(task));
 
-#ifdef RPC_DEBUG
-       task->tk_magic = 0;
-#endif
        /* Wake up anyone who is waiting for task completion */
        rpc_mark_complete_task(task);
 
index 5785d20..ea1046f 100644 (file)
@@ -144,7 +144,7 @@ void rpc_count_iostats(struct rpc_task *task)
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_iostats *stats;
        struct rpc_iostats *op_metrics;
-       long rtt, execute, queue;
+       ktime_t delta;
 
        if (!task->tk_client || !task->tk_client->cl_metrics || !req)
                return;
@@ -156,23 +156,16 @@ void rpc_count_iostats(struct rpc_task *task)
        op_metrics->om_ntrans += req->rq_ntrans;
        op_metrics->om_timeouts += task->tk_timeouts;
 
-       op_metrics->om_bytes_sent += task->tk_bytes_sent;
+       op_metrics->om_bytes_sent += req->rq_xmit_bytes_sent;
        op_metrics->om_bytes_recv += req->rq_reply_bytes_recvd;
 
-       queue = (long)req->rq_xtime - task->tk_start;
-       if (queue < 0)
-               queue = -queue;
-       op_metrics->om_queue += queue;
+       delta = ktime_sub(req->rq_xtime, task->tk_start);
+       op_metrics->om_queue = ktime_add(op_metrics->om_queue, delta);
 
-       rtt = task->tk_rtt;
-       if (rtt < 0)
-               rtt = -rtt;
-       op_metrics->om_rtt += rtt;
+       op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt);
 
-       execute = (long)jiffies - task->tk_start;
-       if (execute < 0)
-               execute = -execute;
-       op_metrics->om_execute += execute;
+       delta = ktime_sub(ktime_get(), task->tk_start);
+       op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
 }
 
 static void _print_name(struct seq_file *seq, unsigned int op,
@@ -186,8 +179,6 @@ static void _print_name(struct seq_file *seq, unsigned int op,
                seq_printf(seq, "\t%12u: ", op);
 }
 
-#define MILLISECS_PER_JIFFY    (1000 / HZ)
-
 void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
 {
        struct rpc_iostats *stats = clnt->cl_metrics;
@@ -214,9 +205,9 @@ void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt)
                                metrics->om_timeouts,
                                metrics->om_bytes_sent,
                                metrics->om_bytes_recv,
-                               metrics->om_queue * MILLISECS_PER_JIFFY,
-                               metrics->om_rtt * MILLISECS_PER_JIFFY,
-                               metrics->om_execute * MILLISECS_PER_JIFFY);
+                               ktime_to_ms(metrics->om_queue),
+                               ktime_to_ms(metrics->om_rtt),
+                               ktime_to_ms(metrics->om_execute));
        }
 }
 EXPORT_SYMBOL_GPL(rpc_print_iostats);
index 061b2e0..cbc0849 100644 (file)
@@ -744,8 +744,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
                if (rqstp->rq_deferred) {
                        svc_xprt_received(xprt);
                        len = svc_deferred_recv(rqstp);
-               } else
+               } else {
                        len = xprt->xpt_ops->xpo_recvfrom(rqstp);
+                       svc_xprt_received(xprt);
+               }
                dprintk("svc: got len=%d\n", len);
        }
 
@@ -893,12 +895,12 @@ void svc_delete_xprt(struct svc_xprt *xprt)
         */
        if (test_bit(XPT_TEMP, &xprt->xpt_flags))
                serv->sv_tmpcnt--;
+       spin_unlock_bh(&serv->sv_lock);
 
        while ((dr = svc_deferred_dequeue(xprt)) != NULL)
                kfree(dr);
 
        svc_xprt_put(xprt);
-       spin_unlock_bh(&serv->sv_lock);
 }
 
 void svc_close_xprt(struct svc_xprt *xprt)
index a29f259..a338927 100644 (file)
@@ -547,7 +547,6 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
                        dprintk("svc: recvfrom returned error %d\n", -err);
                        set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
                }
-               svc_xprt_received(&svsk->sk_xprt);
                return -EAGAIN;
        }
        len = svc_addr_len(svc_addr(rqstp));
@@ -562,11 +561,6 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
        svsk->sk_sk->sk_stamp = skb->tstamp;
        set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
 
-       /*
-        * Maybe more packets - kick another thread ASAP.
-        */
-       svc_xprt_received(&svsk->sk_xprt);
-
        len  = skb->len - sizeof(struct udphdr);
        rqstp->rq_arg.len = len;
 
@@ -917,7 +911,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
                if (len < want) {
                        dprintk("svc: short recvfrom while reading record "
                                "length (%d of %d)\n", len, want);
-                       svc_xprt_received(&svsk->sk_xprt);
                        goto err_again; /* record header not complete */
                }
 
@@ -953,7 +946,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
        if (len < svsk->sk_reclen) {
                dprintk("svc: incomplete TCP record (%d of %d)\n",
                        len, svsk->sk_reclen);
-               svc_xprt_received(&svsk->sk_xprt);
                goto err_again; /* record not complete */
        }
        len = svsk->sk_reclen;
@@ -961,14 +953,11 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp)
 
        return len;
  error:
-       if (len == -EAGAIN) {
+       if (len == -EAGAIN)
                dprintk("RPC: TCP recv_record got EAGAIN\n");
-               svc_xprt_received(&svsk->sk_xprt);
-       }
        return len;
  err_delete:
        set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
-       svc_xprt_received(&svsk->sk_xprt);
  err_again:
        return -EAGAIN;
 }
@@ -1110,7 +1099,6 @@ out:
        svsk->sk_tcplen = 0;
 
        svc_xprt_copy_addrs(rqstp, &svsk->sk_xprt);
-       svc_xprt_received(&svsk->sk_xprt);
        if (serv->sv_stats)
                serv->sv_stats->nettcpcnt++;
 
@@ -1119,7 +1107,6 @@ out:
 err_again:
        if (len == -EAGAIN) {
                dprintk("RPC: TCP recvfrom got EAGAIN\n");
-               svc_xprt_received(&svsk->sk_xprt);
                return len;
        }
 error:
index 2763fde..a1f82a8 100644 (file)
@@ -762,6 +762,7 @@ int write_bytes_to_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, un
        __write_bytes_to_xdr_buf(&subbuf, obj, len);
        return 0;
 }
+EXPORT_SYMBOL_GPL(write_bytes_to_xdr_buf);
 
 int
 xdr_decode_word(struct xdr_buf *buf, unsigned int base, u32 *obj)
index 42f09ad..65fe2e4 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
 #include <linux/net.h>
+#include <linux/ktime.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/metrics.h>
@@ -62,7 +63,6 @@
  * Local functions
  */
 static void    xprt_request_init(struct rpc_task *, struct rpc_xprt *);
-static inline void     do_xprt_reserve(struct rpc_task *);
 static void    xprt_connect_status(struct rpc_task *task);
 static int      __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
 
@@ -711,12 +711,16 @@ void xprt_connect(struct rpc_task *task)
                if (task->tk_rqstp)
                        task->tk_rqstp->rq_bytes_sent = 0;
 
-               task->tk_timeout = xprt->connect_timeout;
+               task->tk_timeout = task->tk_rqstp->rq_timeout;
                rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
+
+               if (test_bit(XPRT_CLOSING, &xprt->state))
+                       return;
+               if (xprt_test_and_set_connecting(xprt))
+                       return;
                xprt->stat.connect_start = jiffies;
                xprt->ops->connect(task);
        }
-       return;
 }
 
 static void xprt_connect_status(struct rpc_task *task)
@@ -771,25 +775,19 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid)
 }
 EXPORT_SYMBOL_GPL(xprt_lookup_rqst);
 
-/**
- * xprt_update_rtt - update an RPC client's RTT state after receiving a reply
- * @task: RPC request that recently completed
- *
- */
-void xprt_update_rtt(struct rpc_task *task)
+static void xprt_update_rtt(struct rpc_task *task)
 {
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_rtt *rtt = task->tk_client->cl_rtt;
        unsigned timer = task->tk_msg.rpc_proc->p_timer;
+       long m = usecs_to_jiffies(ktime_to_us(req->rq_rtt));
 
        if (timer) {
                if (req->rq_ntrans == 1)
-                       rpc_update_rtt(rtt, timer,
-                                       (long)jiffies - req->rq_xtime);
+                       rpc_update_rtt(rtt, timer, m);
                rpc_set_timeo(rtt, timer, req->rq_ntrans - 1);
        }
 }
-EXPORT_SYMBOL_GPL(xprt_update_rtt);
 
 /**
  * xprt_complete_rqst - called when reply processing is complete
@@ -807,7 +805,9 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
                        task->tk_pid, ntohl(req->rq_xid), copied);
 
        xprt->stat.recvs++;
-       task->tk_rtt = (long)jiffies - req->rq_xtime;
+       req->rq_rtt = ktime_sub(ktime_get(), req->rq_xtime);
+       if (xprt->ops->timer != NULL)
+               xprt_update_rtt(task);
 
        list_del_init(&req->rq_list);
        req->rq_private_buf.len = copied;
@@ -906,7 +906,7 @@ void xprt_transmit(struct rpc_task *task)
                return;
 
        req->rq_connect_cookie = xprt->connect_cookie;
-       req->rq_xtime = jiffies;
+       req->rq_xtime = ktime_get();
        status = xprt->ops->send_request(task);
        if (status != 0) {
                task->tk_status = status;
@@ -935,7 +935,7 @@ void xprt_transmit(struct rpc_task *task)
        spin_unlock_bh(&xprt->transport_lock);
 }
 
-static inline void do_xprt_reserve(struct rpc_task *task)
+static void xprt_alloc_slot(struct rpc_task *task)
 {
        struct rpc_xprt *xprt = task->tk_xprt;
 
@@ -955,6 +955,16 @@ static inline void do_xprt_reserve(struct rpc_task *task)
        rpc_sleep_on(&xprt->backlog, task, NULL);
 }
 
+static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req)
+{
+       memset(req, 0, sizeof(*req));   /* mark unused */
+
+       spin_lock(&xprt->reserve_lock);
+       list_add(&req->rq_list, &xprt->free);
+       rpc_wake_up_next(&xprt->backlog);
+       spin_unlock(&xprt->reserve_lock);
+}
+
 /**
  * xprt_reserve - allocate an RPC request slot
  * @task: RPC task requesting a slot allocation
@@ -968,7 +978,7 @@ void xprt_reserve(struct rpc_task *task)
 
        task->tk_status = -EIO;
        spin_lock(&xprt->reserve_lock);
-       do_xprt_reserve(task);
+       xprt_alloc_slot(task);
        spin_unlock(&xprt->reserve_lock);
 }
 
@@ -1006,14 +1016,10 @@ void xprt_release(struct rpc_task *task)
 {
        struct rpc_xprt *xprt;
        struct rpc_rqst *req;
-       int is_bc_request;
 
        if (!(req = task->tk_rqstp))
                return;
 
-       /* Preallocated backchannel request? */
-       is_bc_request = bc_prealloc(req);
-
        xprt = req->rq_xprt;
        rpc_count_iostats(task);
        spin_lock_bh(&xprt->transport_lock);
@@ -1027,21 +1033,16 @@ void xprt_release(struct rpc_task *task)
                mod_timer(&xprt->timer,
                                xprt->last_used + xprt->idle_timeout);
        spin_unlock_bh(&xprt->transport_lock);
-       if (!bc_prealloc(req))
+       if (req->rq_buffer)
                xprt->ops->buf_free(req->rq_buffer);
        task->tk_rqstp = NULL;
        if (req->rq_release_snd_buf)
                req->rq_release_snd_buf(req);
 
        dprintk("RPC: %5u release request %p\n", task->tk_pid, req);
-       if (likely(!is_bc_request)) {
-               memset(req, 0, sizeof(*req));   /* mark unused */
-
-               spin_lock(&xprt->reserve_lock);
-               list_add(&req->rq_list, &xprt->free);
-               rpc_wake_up_next(&xprt->backlog);
-               spin_unlock(&xprt->reserve_lock);
-       } else
+       if (likely(!bc_prealloc(req)))
+               xprt_free_slot(xprt, req);
+       else
                xprt_free_bc_request(req);
 }
 
index f92e37e..0194de8 100644 (file)
@@ -566,7 +566,6 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
                ret, rqstp->rq_arg.len, rqstp->rq_arg.head[0].iov_base,
                rqstp->rq_arg.head[0].iov_len);
 
-       svc_xprt_received(rqstp->rq_xprt);
        return ret;
 }
 
@@ -665,7 +664,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
                rqstp->rq_arg.head[0].iov_len);
        rqstp->rq_prot = IPPROTO_MAX;
        svc_xprt_copy_addrs(rqstp, xprt);
-       svc_xprt_received(xprt);
        return ret;
 
  close_out:
@@ -678,6 +676,5 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
         */
        set_bit(XPT_CLOSE, &xprt->xpt_flags);
 defer:
-       svc_xprt_received(xprt);
        return 0;
 }
index fd90eb8..edea15a 100644 (file)
@@ -679,7 +679,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
        int ret;
 
        dprintk("svcrdma: Creating RDMA socket\n");
-
+       if (sa->sa_family != AF_INET) {
+               dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family);
+               return ERR_PTR(-EAFNOSUPPORT);
+       }
        cma_xprt = rdma_create_xprt(serv, 1);
        if (!cma_xprt)
                return ERR_PTR(-ENOMEM);
index 187257b..a85e866 100644 (file)
@@ -305,7 +305,6 @@ xprt_setup_rdma(struct xprt_create *args)
        /* 60 second timeout, no retries */
        xprt->timeout = &xprt_rdma_default_timeout;
        xprt->bind_timeout = (60U * HZ);
-       xprt->connect_timeout = (60U * HZ);
        xprt->reestablish_timeout = (5U * HZ);
        xprt->idle_timeout = (5U * 60 * HZ);
 
@@ -449,21 +448,19 @@ xprt_rdma_connect(struct rpc_task *task)
        struct rpc_xprt *xprt = (struct rpc_xprt *)task->tk_xprt;
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
 
-       if (!xprt_test_and_set_connecting(xprt)) {
-               if (r_xprt->rx_ep.rep_connected != 0) {
-                       /* Reconnect */
-                       schedule_delayed_work(&r_xprt->rdma_connect,
-                               xprt->reestablish_timeout);
-                       xprt->reestablish_timeout <<= 1;
-                       if (xprt->reestablish_timeout > (30 * HZ))
-                               xprt->reestablish_timeout = (30 * HZ);
-                       else if (xprt->reestablish_timeout < (5 * HZ))
-                               xprt->reestablish_timeout = (5 * HZ);
-               } else {
-                       schedule_delayed_work(&r_xprt->rdma_connect, 0);
-                       if (!RPC_IS_ASYNC(task))
-                               flush_scheduled_work();
-               }
+       if (r_xprt->rx_ep.rep_connected != 0) {
+               /* Reconnect */
+               schedule_delayed_work(&r_xprt->rdma_connect,
+                       xprt->reestablish_timeout);
+               xprt->reestablish_timeout <<= 1;
+               if (xprt->reestablish_timeout > (30 * HZ))
+                       xprt->reestablish_timeout = (30 * HZ);
+               else if (xprt->reestablish_timeout < (5 * HZ))
+                       xprt->reestablish_timeout = (5 * HZ);
+       } else {
+               schedule_delayed_work(&r_xprt->rdma_connect, 0);
+               if (!RPC_IS_ASYNC(task))
+                       flush_scheduled_work();
        }
 }
 
@@ -677,7 +674,7 @@ xprt_rdma_send_request(struct rpc_task *task)
        if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req))
                goto drop_connection;
 
-       task->tk_bytes_sent += rqst->rq_snd_buf.len;
+       rqst->rq_xmit_bytes_sent += rqst->rq_snd_buf.len;
        rqst->rq_bytes_sent = 0;
        return 0;
 
index 9847c30..02fc7f0 100644 (file)
@@ -137,20 +137,6 @@ static ctl_table sunrpc_table[] = {
 
 #endif
 
-/*
- * Time out for an RPC UDP socket connect.  UDP socket connects are
- * synchronous, but we set a timeout anyway in case of resource
- * exhaustion on the local host.
- */
-#define XS_UDP_CONN_TO         (5U * HZ)
-
-/*
- * Wait duration for an RPC TCP connection to be established.  Solaris
- * NFS over TCP uses 60 seconds, for example, which is in line with how
- * long a server takes to reboot.
- */
-#define XS_TCP_CONN_TO         (60U * HZ)
-
 /*
  * Wait duration for a reply from the RPC portmapper.
  */
@@ -542,7 +528,7 @@ static int xs_udp_send_request(struct rpc_task *task)
                        xdr->len - req->rq_bytes_sent, status);
 
        if (status >= 0) {
-               task->tk_bytes_sent += status;
+               req->rq_xmit_bytes_sent += status;
                if (status >= req->rq_slen)
                        return 0;
                /* Still some bytes left; set up for a retry later. */
@@ -638,7 +624,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
                /* If we've sent the entire packet, immediately
                 * reset the count of bytes sent. */
                req->rq_bytes_sent += status;
-               task->tk_bytes_sent += status;
+               req->rq_xmit_bytes_sent += status;
                if (likely(req->rq_bytes_sent >= req->rq_slen)) {
                        req->rq_bytes_sent = 0;
                        return 0;
@@ -858,7 +844,6 @@ static void xs_udp_data_ready(struct sock *sk, int len)
        dst_confirm(skb_dst(skb));
 
        xprt_adjust_cwnd(task, copied);
-       xprt_update_rtt(task);
        xprt_complete_rqst(task, copied);
 
  out_unlock:
@@ -2016,9 +2001,6 @@ static void xs_connect(struct rpc_task *task)
        struct rpc_xprt *xprt = task->tk_xprt;
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
 
-       if (xprt_test_and_set_connecting(xprt))
-               return;
-
        if (transport->sock != NULL && !RPC_IS_SOFTCONN(task)) {
                dprintk("RPC:       xs_connect delayed xprt %p for %lu "
                                "seconds\n",
@@ -2038,16 +2020,6 @@ static void xs_connect(struct rpc_task *task)
        }
 }
 
-static void xs_tcp_connect(struct rpc_task *task)
-{
-       struct rpc_xprt *xprt = task->tk_xprt;
-
-       /* Exit if we need to wait for socket shutdown to complete */
-       if (test_bit(XPRT_CLOSING, &xprt->state))
-               return;
-       xs_connect(task);
-}
-
 /**
  * xs_udp_print_stats - display UDP socket-specifc stats
  * @xprt: rpc_xprt struct containing statistics
@@ -2246,7 +2218,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
        .release_xprt           = xs_tcp_release_xprt,
        .rpcbind                = rpcb_getport_async,
        .set_port               = xs_set_port,
-       .connect                = xs_tcp_connect,
+       .connect                = xs_connect,
        .buf_alloc              = rpc_malloc,
        .buf_free               = rpc_free,
        .send_request           = xs_tcp_send_request,
@@ -2337,7 +2309,6 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
        xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
 
        xprt->bind_timeout = XS_BIND_TO;
-       xprt->connect_timeout = XS_UDP_CONN_TO;
        xprt->reestablish_timeout = XS_UDP_REEST_TO;
        xprt->idle_timeout = XS_IDLE_DISC_TO;
 
@@ -2412,7 +2383,6 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
        xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
 
        xprt->bind_timeout = XS_BIND_TO;
-       xprt->connect_timeout = XS_TCP_CONN_TO;
        xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
        xprt->idle_timeout = XS_IDLE_DISC_TO;
 
@@ -2472,9 +2442,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
        struct sock_xprt *transport;
        struct svc_sock *bc_sock;
 
-       if (!args->bc_xprt)
-               ERR_PTR(-EINVAL);
-
        xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries);
        if (IS_ERR(xprt))
                return xprt;
@@ -2488,7 +2455,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
        /* backchannel */
        xprt_set_bound(xprt);
        xprt->bind_timeout = 0;
-       xprt->connect_timeout = 0;
        xprt->reestablish_timeout = 0;
        xprt->idle_timeout = 0;
 
index e56f711..36e84e1 100644 (file)
@@ -83,6 +83,41 @@ struct compat_x25_subscrip_struct {
 };
 #endif
 
+
+int x25_parse_address_block(struct sk_buff *skb,
+               struct x25_address *called_addr,
+               struct x25_address *calling_addr)
+{
+       unsigned char len;
+       int needed;
+       int rc;
+
+       if (skb->len < 1) {
+               /* packet has no address block */
+               rc = 0;
+               goto empty;
+       }
+
+       len = *skb->data;
+       needed = 1 + (len >> 4) + (len & 0x0f);
+
+       if (skb->len < needed) {
+               /* packet is too short to hold the addresses it claims
+                  to hold */
+               rc = -1;
+               goto empty;
+       }
+
+       return x25_addr_ntoa(skb->data, called_addr, calling_addr);
+
+empty:
+       *called_addr->x25_addr = 0;
+       *calling_addr->x25_addr = 0;
+
+       return rc;
+}
+
+
 int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
                  struct x25_address *calling_addr)
 {
@@ -367,6 +402,7 @@ static void __x25_destroy_socket(struct sock *sk)
                        /*
                         * Queue the unaccepted socket for death
                         */
+                       skb->sk->sk_state = TCP_LISTEN;
                        sock_set_flag(skb->sk, SOCK_DEAD);
                        x25_start_heartbeat(skb->sk);
                        x25_sk(skb->sk)->state = X25_STATE_0;
@@ -554,7 +590,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
        x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
        x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
        x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
-       x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
+       x25->facilities.throughput  = 0;        /* by default don't negotiate
+                                                  throughput */
        x25->facilities.reverse     = X25_DEFAULT_REVERSE;
        x25->dte_facilities.calling_len = 0;
        x25->dte_facilities.called_len = 0;
@@ -922,16 +959,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
        /*
         *      Extract the X.25 addresses and convert them to ASCII strings,
         *      and remove them.
+        *
+        *      Address block is mandatory in call request packets
         */
-       addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
+       addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
+       if (addr_len <= 0)
+               goto out_clear_request;
        skb_pull(skb, addr_len);
 
        /*
         *      Get the length of the facilities, skip past them for the moment
         *      get the call user data because this is needed to determine
         *      the correct listener
+        *
+        *      Facilities length is mandatory in call request packets
         */
+       if (skb->len < 1)
+               goto out_clear_request;
        len = skb->data[0] + 1;
+       if (skb->len < len)
+               goto out_clear_request;
        skb_pull(skb,len);
 
        /*
@@ -1415,9 +1462,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        if (facilities.winsize_in < 1 ||
                            facilities.winsize_in > 127)
                                break;
-                       if (facilities.throughput < 0x03 ||
-                           facilities.throughput > 0xDD)
-                               break;
+                       if (facilities.throughput) {
+                               int out = facilities.throughput & 0xf0;
+                               int in  = facilities.throughput & 0x0f;
+                               if (!out)
+                                       facilities.throughput |=
+                                               X25_DEFAULT_THROUGHPUT << 4;
+                               else if (out < 0x30 || out > 0xD0)
+                                       break;
+                               if (!in)
+                                       facilities.throughput |=
+                                               X25_DEFAULT_THROUGHPUT;
+                               else if (in < 0x03 || in > 0x0D)
+                                       break;
+                       }
                        if (facilities.reverse &&
                                (facilities.reverse & 0x81) != 0x81)
                                break;
index a21f664..771bab0 100644 (file)
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
 {
        unsigned char *p = skb->data;
-       unsigned int len = *p++;
+       unsigned int len;
 
        *vc_fac_mask = 0;
 
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
        memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
        memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
 
+       if (skb->len < 1)
+               return 0;
+
+       len = *p++;
+
+       if (len >= skb->len)
+               return -1;
+
        while (len > 0) {
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
        memcpy(new, ours, sizeof(*new));
 
        len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
+       if (len < 0)
+               return len;
 
        /*
         *      They want reverse charging, we won't accept it.
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
        new->reverse = theirs.reverse;
 
        if (theirs.throughput) {
-               if (theirs.throughput < ours->throughput) {
-                       SOCK_DEBUG(sk, "X.25: throughput negotiated down\n");
-                       new->throughput = theirs.throughput;
+               int theirs_in =  theirs.throughput & 0x0f;
+               int theirs_out = theirs.throughput & 0xf0;
+               int ours_in  = ours->throughput & 0x0f;
+               int ours_out = ours->throughput & 0xf0;
+               if (!ours_in || theirs_in < ours_in) {
+                       SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n");
+                       new->throughput = (new->throughput & 0xf0) | theirs_in;
+               }
+               if (!ours_out || theirs_out < ours_out) {
+                       SOCK_DEBUG(sk,
+                               "X.25: outbound throughput negotiated\n");
+                       new->throughput = (new->throughput & 0x0f) | theirs_out;
                }
        }
 
index a31b3b9..372ac22 100644 (file)
@@ -90,6 +90,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
 static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
 {
        struct x25_address source_addr, dest_addr;
+       int len;
 
        switch (frametype) {
                case X25_CALL_ACCEPTED: {
@@ -107,11 +108,17 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                         *      Parse the data in the frame.
                         */
                        skb_pull(skb, X25_STD_MIN_LEN);
-                       skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
-                       skb_pull(skb,
-                                x25_parse_facilities(skb, &x25->facilities,
+
+                       len = x25_parse_address_block(skb, &source_addr,
+                                               &dest_addr);
+                       if (len > 0)
+                               skb_pull(skb, len);
+
+                       len = x25_parse_facilities(skb, &x25->facilities,
                                                &x25->dte_facilities,
-                                               &x25->vc_facil_mask));
+                                               &x25->vc_facil_mask);
+                       if (len > 0)
+                               skb_pull(skb, len);
                        /*
                         *      Copy any Call User Data.
                         */
index f9bdf26..cbcd654 100644 (file)
@@ -245,3 +245,7 @@ quiet_cmd_lzo = LZO    $@
 cmd_lzo = (cat $(filter-out FORCE,$^) | \
        lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
        (rm -f $@ ; false)
+
+# misc stuff
+# ---------------------------------------------------------------------------
+quote:="
index 220213e..df90f31 100644 (file)
@@ -796,6 +796,16 @@ static int do_platform_entry(const char *filename,
        return 1;
 }
 
+/* Looks like: zorro:iN. */
+static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
+                         char *alias)
+{
+       id->id = TO_NATIVE(id->id);
+       strcpy(alias, "zorro:");
+       ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
+       return 1;
+}
+
 /* Ignore any prefix, eg. some architectures prepend _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -943,6 +953,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                do_table(symval, sym->st_size,
                         sizeof(struct platform_device_id), "platform",
                         do_platform_entry, mod);
+       else if (sym_is(symname, "__mod_zorro_device_table"))
+               do_table(symval, sym->st_size,
+                        sizeof(struct zorro_device_id), "zorro",
+                        do_zorro_entry, mod);
        free(zeros);
 }
 
index 2462696..58a12c2 100644 (file)
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
        fprintf(fout, "\n");
 
        for (i = 1; i < isids_len; i++) {
-               char *s = initial_sid_to_string[i];
+               const char *s = initial_sid_to_string[i];
                fprintf(fout, "#define SECINITSID_%s", s);
                for (j = 0; j < max(1, 40 - strlen(s)); j++)
                        fprintf(fout, " ");
index 4875142..8168e3e 100644 (file)
 
 #include <linux/security.h>
 
-static int cap_acct(struct file *file)
-{
-       return 0;
-}
-
 static int cap_sysctl(ctl_table *table, int op)
 {
        return 0;
@@ -80,42 +75,16 @@ static int cap_sb_mount(char *dev_name, struct path *path, char *type,
        return 0;
 }
 
-static int cap_sb_check_sb(struct vfsmount *mnt, struct path *path)
-{
-       return 0;
-}
-
 static int cap_sb_umount(struct vfsmount *mnt, int flags)
 {
        return 0;
 }
 
-static void cap_sb_umount_close(struct vfsmount *mnt)
-{
-}
-
-static void cap_sb_umount_busy(struct vfsmount *mnt)
-{
-}
-
-static void cap_sb_post_remount(struct vfsmount *mnt, unsigned long flags,
-                               void *data)
-{
-}
-
-static void cap_sb_post_addmount(struct vfsmount *mnt, struct path *path)
-{
-}
-
 static int cap_sb_pivotroot(struct path *old_path, struct path *new_path)
 {
        return 0;
 }
 
-static void cap_sb_post_pivotroot(struct path *old_path, struct path *new_path)
-{
-}
-
 static int cap_sb_set_mnt_opts(struct super_block *sb,
                               struct security_mnt_opts *opts)
 {
@@ -221,10 +190,6 @@ static int cap_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
        return 0;
 }
 
-static void cap_inode_delete(struct inode *ino)
-{
-}
-
 static void cap_inode_post_setxattr(struct dentry *dentry, const char *name,
                                    const void *value, size_t size, int flags)
 {
@@ -403,10 +368,6 @@ static int cap_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp)
        return 0;
 }
 
-static void cap_cred_commit(struct cred *new, const struct cred *old)
-{
-}
-
 static void cap_cred_transfer(struct cred *new, const struct cred *old)
 {
 }
@@ -426,16 +387,6 @@ static int cap_kernel_module_request(char *kmod_name)
        return 0;
 }
 
-static int cap_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
-{
-       return 0;
-}
-
-static int cap_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
-{
-       return 0;
-}
-
 static int cap_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return 0;
@@ -456,11 +407,6 @@ static void cap_task_getsecid(struct task_struct *p, u32 *secid)
        *secid = 0;
 }
 
-static int cap_task_setgroups(struct group_info *group_info)
-{
-       return 0;
-}
-
 static int cap_task_getioprio(struct task_struct *p)
 {
        return 0;
@@ -875,13 +821,6 @@ static int cap_key_getsecurity(struct key *key, char **_buffer)
        return 0;
 }
 
-static int cap_key_session_to_parent(const struct cred *cred,
-                                    const struct cred *parent_cred,
-                                    struct key *key)
-{
-       return 0;
-}
-
 #endif /* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
@@ -915,13 +854,12 @@ static void cap_audit_rule_free(void *lsmrule)
                        }                                               \
        } while (0)
 
-void security_fixup_ops(struct security_operations *ops)
+void __init security_fixup_ops(struct security_operations *ops)
 {
        set_to_cap_if_null(ops, ptrace_access_check);
        set_to_cap_if_null(ops, ptrace_traceme);
        set_to_cap_if_null(ops, capget);
        set_to_cap_if_null(ops, capset);
-       set_to_cap_if_null(ops, acct);
        set_to_cap_if_null(ops, capable);
        set_to_cap_if_null(ops, quotactl);
        set_to_cap_if_null(ops, quota_on);
@@ -941,14 +879,8 @@ void security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, sb_show_options);
        set_to_cap_if_null(ops, sb_statfs);
        set_to_cap_if_null(ops, sb_mount);
-       set_to_cap_if_null(ops, sb_check_sb);
        set_to_cap_if_null(ops, sb_umount);
-       set_to_cap_if_null(ops, sb_umount_close);
-       set_to_cap_if_null(ops, sb_umount_busy);
-       set_to_cap_if_null(ops, sb_post_remount);
-       set_to_cap_if_null(ops, sb_post_addmount);
        set_to_cap_if_null(ops, sb_pivotroot);
-       set_to_cap_if_null(ops, sb_post_pivotroot);
        set_to_cap_if_null(ops, sb_set_mnt_opts);
        set_to_cap_if_null(ops, sb_clone_mnt_opts);
        set_to_cap_if_null(ops, sb_parse_opts_str);
@@ -968,7 +900,6 @@ void security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, inode_permission);
        set_to_cap_if_null(ops, inode_setattr);
        set_to_cap_if_null(ops, inode_getattr);
-       set_to_cap_if_null(ops, inode_delete);
        set_to_cap_if_null(ops, inode_setxattr);
        set_to_cap_if_null(ops, inode_post_setxattr);
        set_to_cap_if_null(ops, inode_getxattr);
@@ -1009,19 +940,15 @@ void security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, cred_alloc_blank);
        set_to_cap_if_null(ops, cred_free);
        set_to_cap_if_null(ops, cred_prepare);
-       set_to_cap_if_null(ops, cred_commit);
        set_to_cap_if_null(ops, cred_transfer);
        set_to_cap_if_null(ops, kernel_act_as);
        set_to_cap_if_null(ops, kernel_create_files_as);
        set_to_cap_if_null(ops, kernel_module_request);
-       set_to_cap_if_null(ops, task_setuid);
        set_to_cap_if_null(ops, task_fix_setuid);
-       set_to_cap_if_null(ops, task_setgid);
        set_to_cap_if_null(ops, task_setpgid);
        set_to_cap_if_null(ops, task_getpgid);
        set_to_cap_if_null(ops, task_getsid);
        set_to_cap_if_null(ops, task_getsecid);
-       set_to_cap_if_null(ops, task_setgroups);
        set_to_cap_if_null(ops, task_setnice);
        set_to_cap_if_null(ops, task_setioprio);
        set_to_cap_if_null(ops, task_getioprio);
@@ -1113,7 +1040,6 @@ void security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, key_free);
        set_to_cap_if_null(ops, key_permission);
        set_to_cap_if_null(ops, key_getsecurity);
-       set_to_cap_if_null(ops, key_session_to_parent);
 #endif /* CONFIG_KEYS */
 #ifdef CONFIG_AUDIT
        set_to_cap_if_null(ops, audit_rule_init);
index 6166973..4e01599 100644 (file)
@@ -570,7 +570,7 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name,
        }
 
        if (!strncmp(name, XATTR_SECURITY_PREFIX,
-                    sizeof(XATTR_SECURITY_PREFIX) - 1)  &&
+                    sizeof(XATTR_SECURITY_PREFIX) - 1) &&
            !capable(CAP_SYS_ADMIN))
                return -EPERM;
        return 0;
@@ -596,7 +596,7 @@ int cap_inode_removexattr(struct dentry *dentry, const char *name)
        }
 
        if (!strncmp(name, XATTR_SECURITY_PREFIX,
-                    sizeof(XATTR_SECURITY_PREFIX) - 1)  &&
+                    sizeof(XATTR_SECURITY_PREFIX) - 1) &&
            !capable(CAP_SYS_ADMIN))
                return -EPERM;
        return 0;
@@ -931,7 +931,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
  * @addr: address attempting to be mapped
  * @addr_only: unused
  *
- * If the process is attempting to map memory below mmap_min_addr they need
+ * If the process is attempting to map memory below dac_mmap_min_addr they need
  * CAP_SYS_RAWIO.  The other parameters to this function are unused by the
  * capability security module.  Returns 0 if this mapping should be allowed
  * -EPERM if not.
index f77c604..8d9c48f 100644 (file)
@@ -470,7 +470,7 @@ struct cgroup_subsys devices_subsys = {
        .name = "devices",
        .can_attach = devcgroup_can_attach,
        .create = devcgroup_create,
-       .destroy  = devcgroup_destroy,
+       .destroy = devcgroup_destroy,
        .populate = devcgroup_populate,
        .subsys_id = devices_subsys_id,
 };
index c3a7938..1c812e8 100644 (file)
@@ -161,13 +161,13 @@ static int create_by_name(const char *name, mode_t mode,
 
        mutex_lock(&parent->d_inode->i_mutex);
        *dentry = lookup_one_len(name, parent, strlen(name));
-       if (!IS_ERR(dentry)) {
+       if (!IS_ERR(*dentry)) {
                if ((mode & S_IFMT) == S_IFDIR)
                        error = mkdir(parent->d_inode, *dentry, mode);
                else
                        error = create(parent->d_inode, *dentry, mode);
        } else
-               error = PTR_ERR(dentry);
+               error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
 
        return error;
index 3d7846d..b6ecfd4 100644 (file)
@@ -2,15 +2,14 @@
 #
 config IMA
        bool "Integrity Measurement Architecture(IMA)"
-       depends on ACPI
        depends on SECURITY
        select SECURITYFS
        select CRYPTO
        select CRYPTO_HMAC
        select CRYPTO_MD5
        select CRYPTO_SHA1
-       select TCG_TPM
-       select TCG_TIS
+       select TCG_TPM if !S390
+       select TCG_TIS if TCG_TPM
        help
          The Trusted Computing Group(TCG) runtime Integrity
          Measurement Architecture(IMA) maintains a list of hash
index 47fb65d..16d100d 100644 (file)
@@ -135,7 +135,7 @@ enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
 int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
 void ima_init_policy(void);
 void ima_update_policy(void);
-int ima_parse_add_rule(char *);
+ssize_t ima_parse_add_rule(char *);
 void ima_delete_rules(void);
 
 /* LSM based policy rules require audit */
index 5af7634..c5c5a72 100644 (file)
@@ -41,7 +41,7 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
                return;
 
        ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
-       audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u ses=%u",
+       audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u",
                         current->pid, current_cred()->uid,
                         audit_get_loginuid(current),
                         audit_get_sessionid(current));
index 952e513..9b3ade7 100644 (file)
@@ -27,7 +27,7 @@ static int init_desc(struct hash_desc *desc)
 
        desc->tfm = crypto_alloc_hash(ima_hash, 0, CRYPTO_ALG_ASYNC);
        if (IS_ERR(desc->tfm)) {
-               pr_info("failed to load %s transform: %ld\n",
+               pr_info("IMA: failed to load %s transform: %ld\n",
                        ima_hash, PTR_ERR(desc->tfm));
                rc = PTR_ERR(desc->tfm);
                return rc;
@@ -112,7 +112,7 @@ static void __init ima_pcrread(int idx, u8 *pcr)
                return;
 
        if (tpm_pcr_read(TPM_ANY_NUM, idx, pcr) != 0)
-               pr_err("Error Communicating to TPM chip\n");
+               pr_err("IMA: Error Communicating to TPM chip\n");
 }
 
 /*
index 07cb9c3..8fe736a 100644 (file)
@@ -244,32 +244,34 @@ static const struct file_operations ima_ascii_measurements_ops = {
 static ssize_t ima_write_policy(struct file *file, const char __user *buf,
                                size_t datalen, loff_t *ppos)
 {
-       char *data;
-       int rc;
+       char *data = NULL;
+       ssize_t result;
 
        if (datalen >= PAGE_SIZE)
-               return -ENOMEM;
-       if (*ppos != 0) {
-               /* No partial writes. */
-               return -EINVAL;
-       }
+               datalen = PAGE_SIZE - 1;
+
+       /* No partial writes. */
+       result = -EINVAL;
+       if (*ppos != 0)
+               goto out;
+
+       result = -ENOMEM;
        data = kmalloc(datalen + 1, GFP_KERNEL);
        if (!data)
-               return -ENOMEM;
+               goto out;
 
-       if (copy_from_user(data, buf, datalen)) {
-               kfree(data);
-               return -EFAULT;
-       }
        *(data + datalen) = '\0';
-       rc = ima_parse_add_rule(data);
-       if (rc < 0) {
-               datalen = -EINVAL;
-               valid_policy = 0;
-       }
 
+       result = -EFAULT;
+       if (copy_from_user(data, buf, datalen))
+               goto out;
+
+       result = ima_parse_add_rule(data);
+out:
+       if (result < 0)
+               valid_policy = 0;
        kfree(data);
-       return datalen;
+       return result;
 }
 
 static struct dentry *ima_dir;
index 2c744d4..2dc2d65 100644 (file)
@@ -80,17 +80,17 @@ void iint_free(struct kref *kref)
        iint->version = 0;
        iint->flags = 0UL;
        if (iint->readcount != 0) {
-               printk(KERN_INFO "%s: readcount: %ld\n", __FUNCTION__,
+               printk(KERN_INFO "%s: readcount: %ld\n", __func__,
                       iint->readcount);
                iint->readcount = 0;
        }
        if (iint->writecount != 0) {
-               printk(KERN_INFO "%s: writecount: %ld\n", __FUNCTION__,
+               printk(KERN_INFO "%s: writecount: %ld\n", __func__,
                       iint->writecount);
                iint->writecount = 0;
        }
        if (iint->opencount != 0) {
-               printk(KERN_INFO "%s: opencount: %ld\n", __FUNCTION__,
+               printk(KERN_INFO "%s: opencount: %ld\n", __func__,
                       iint->opencount);
                iint->opencount = 0;
        }
index b1bcb70..17f1f06 100644 (file)
@@ -83,7 +83,7 @@ int __init ima_init(void)
                ima_used_chip = 1;
 
        if (!ima_used_chip)
-               pr_info("No TPM chip found, activating TPM-bypass!\n");
+               pr_info("IMA: No TPM chip found, activating TPM-bypass!\n");
 
        ima_add_boot_aggregate();       /* boot aggregate must be first entry */
        ima_init_policy();
index b2c89d9..f936413 100644 (file)
@@ -195,7 +195,7 @@ static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
             (iint->writecount < 0)) &&
            !ima_limit_imbalance(file)) {
                printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
-                      __FUNCTION__, iint->readcount, iint->writecount,
+                      __func__, iint->readcount, iint->writecount,
                       iint->opencount);
                dump_stack();
        }
index 8643a93..aef8c0a 100644 (file)
@@ -246,6 +246,9 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
 {
        int result;
 
+       if (entry->lsm[lsm_rule].rule)
+               return -EINVAL;
+
        entry->lsm[lsm_rule].type = audit_type;
        result = security_filter_rule_init(entry->lsm[lsm_rule].type,
                                           Audit_equal, args,
@@ -253,6 +256,13 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
        return result;
 }
 
+static void ima_log_string(struct audit_buffer *ab, char *key, char *value)
+{
+       audit_log_format(ab, "%s=", key);
+       audit_log_untrustedstring(ab, value);
+       audit_log_format(ab, " ");
+}
+
 static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
 {
        struct audit_buffer *ab;
@@ -261,28 +271,41 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
 
        ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
 
-       entry->action = -1;
-       while ((p = strsep(&rule, " \n")) != NULL) {
+       entry->uid = -1;
+       entry->action = UNKNOWN;
+       while ((p = strsep(&rule, " \t")) != NULL) {
                substring_t args[MAX_OPT_ARGS];
                int token;
                unsigned long lnum;
 
                if (result < 0)
                        break;
-               if (!*p)
+               if ((*p == '\0') || (*p == ' ') || (*p == '\t'))
                        continue;
                token = match_token(p, policy_tokens, args);
                switch (token) {
                case Opt_measure:
-                       audit_log_format(ab, "%s ", "measure");
+                       ima_log_string(ab, "action", "measure");
+
+                       if (entry->action != UNKNOWN)
+                               result = -EINVAL;
+
                        entry->action = MEASURE;
                        break;
                case Opt_dont_measure:
-                       audit_log_format(ab, "%s ", "dont_measure");
+                       ima_log_string(ab, "action", "dont_measure");
+
+                       if (entry->action != UNKNOWN)
+                               result = -EINVAL;
+
                        entry->action = DONT_MEASURE;
                        break;
                case Opt_func:
-                       audit_log_format(ab, "func=%s ", args[0].from);
+                       ima_log_string(ab, "func", args[0].from);
+
+                       if (entry->func)
+                               result  = -EINVAL;
+
                        if (strcmp(args[0].from, "FILE_CHECK") == 0)
                                entry->func = FILE_CHECK;
                        /* PATH_CHECK is for backwards compat */
@@ -298,7 +321,11 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
                                entry->flags |= IMA_FUNC;
                        break;
                case Opt_mask:
-                       audit_log_format(ab, "mask=%s ", args[0].from);
+                       ima_log_string(ab, "mask", args[0].from);
+
+                       if (entry->mask)
+                               result = -EINVAL;
+
                        if ((strcmp(args[0].from, "MAY_EXEC")) == 0)
                                entry->mask = MAY_EXEC;
                        else if (strcmp(args[0].from, "MAY_WRITE") == 0)
@@ -313,14 +340,26 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
                                entry->flags |= IMA_MASK;
                        break;
                case Opt_fsmagic:
-                       audit_log_format(ab, "fsmagic=%s ", args[0].from);
+                       ima_log_string(ab, "fsmagic", args[0].from);
+
+                       if (entry->fsmagic) {
+                               result = -EINVAL;
+                               break;
+                       }
+
                        result = strict_strtoul(args[0].from, 16,
                                                &entry->fsmagic);
                        if (!result)
                                entry->flags |= IMA_FSMAGIC;
                        break;
                case Opt_uid:
-                       audit_log_format(ab, "uid=%s ", args[0].from);
+                       ima_log_string(ab, "uid", args[0].from);
+
+                       if (entry->uid != -1) {
+                               result = -EINVAL;
+                               break;
+                       }
+
                        result = strict_strtoul(args[0].from, 10, &lnum);
                        if (!result) {
                                entry->uid = (uid_t) lnum;
@@ -331,50 +370,51 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
                        }
                        break;
                case Opt_obj_user:
-                       audit_log_format(ab, "obj_user=%s ", args[0].from);
+                       ima_log_string(ab, "obj_user", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
                                                   LSM_OBJ_USER,
                                                   AUDIT_OBJ_USER);
                        break;
                case Opt_obj_role:
-                       audit_log_format(ab, "obj_role=%s ", args[0].from);
+                       ima_log_string(ab, "obj_role", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
                                                   LSM_OBJ_ROLE,
                                                   AUDIT_OBJ_ROLE);
                        break;
                case Opt_obj_type:
-                       audit_log_format(ab, "obj_type=%s ", args[0].from);
+                       ima_log_string(ab, "obj_type", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
                                                   LSM_OBJ_TYPE,
                                                   AUDIT_OBJ_TYPE);
                        break;
                case Opt_subj_user:
-                       audit_log_format(ab, "subj_user=%s ", args[0].from);
+                       ima_log_string(ab, "subj_user", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
                                                   LSM_SUBJ_USER,
                                                   AUDIT_SUBJ_USER);
                        break;
                case Opt_subj_role:
-                       audit_log_format(ab, "subj_role=%s ", args[0].from);
+                       ima_log_string(ab, "subj_role", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
                                                   LSM_SUBJ_ROLE,
                                                   AUDIT_SUBJ_ROLE);
                        break;
                case Opt_subj_type:
-                       audit_log_format(ab, "subj_type=%s ", args[0].from);
+                       ima_log_string(ab, "subj_type", args[0].from);
                        result = ima_lsm_rule_init(entry, args[0].from,
                                                   LSM_SUBJ_TYPE,
                                                   AUDIT_SUBJ_TYPE);
                        break;
                case Opt_err:
-                       audit_log_format(ab, "UNKNOWN=%s ", p);
+                       ima_log_string(ab, "UNKNOWN", p);
+                       result = -EINVAL;
                        break;
                }
        }
-       if (entry->action == UNKNOWN)
+       if (!result && (entry->action == UNKNOWN))
                result = -EINVAL;
 
-       audit_log_format(ab, "res=%d", !result ? 0 : 1);
+       audit_log_format(ab, "res=%d", !!result);
        audit_log_end(ab);
        return result;
 }
@@ -384,13 +424,14 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
  * @rule - ima measurement policy rule
  *
  * Uses a mutex to protect the policy list from multiple concurrent writers.
- * Returns 0 on success, an error code on failure.
+ * Returns the length of the rule parsed, an error code on failure
  */
-int ima_parse_add_rule(char *rule)
+ssize_t ima_parse_add_rule(char *rule)
 {
        const char *op = "update_policy";
+       char *p;
        struct ima_measure_rule_entry *entry;
-       int result = 0;
+       ssize_t result, len;
        int audit_info = 0;
 
        /* Prevent installed policy from changing */
@@ -410,18 +451,28 @@ int ima_parse_add_rule(char *rule)
 
        INIT_LIST_HEAD(&entry->list);
 
-       result = ima_parse_rule(rule, entry);
-       if (!result) {
-               mutex_lock(&ima_measure_mutex);
-               list_add_tail(&entry->list, &measure_policy_rules);
-               mutex_unlock(&ima_measure_mutex);
-       } else {
+       p = strsep(&rule, "\n");
+       len = strlen(p) + 1;
+
+       if (*p == '#') {
+               kfree(entry);
+               return len;
+       }
+
+       result = ima_parse_rule(p, entry);
+       if (result) {
                kfree(entry);
                integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL,
                                    NULL, op, "invalid policy", result,
                                    audit_info);
+               return result;
        }
-       return result;
+
+       mutex_lock(&ima_measure_mutex);
+       list_add_tail(&entry->list, &measure_policy_rules);
+       mutex_unlock(&ima_measure_mutex);
+
+       return len;
 }
 
 /* ima_delete_rules called to cleanup invalid policy */
index 46ba62b..8e28f04 100644 (file)
@@ -71,7 +71,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry)
 
        qe = kmalloc(sizeof(*qe), GFP_KERNEL);
        if (qe == NULL) {
-               pr_err("OUT OF MEMORY ERROR creating queue entry.\n");
+               pr_err("IMA: OUT OF MEMORY ERROR creating queue entry.\n");
                return -ENOMEM;
        }
        qe->entry = entry;
@@ -94,7 +94,7 @@ static int ima_pcr_extend(const u8 *hash)
 
        result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
        if (result != 0)
-               pr_err("Error Communicating to TPM chip\n");
+               pr_err("IMA: Error Communicating to TPM chip\n");
        return result;
 }
 
index 1990231..a46e825 100644 (file)
@@ -77,10 +77,10 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
                goto dont_gc;
 
        /* scan the keyring looking for dead keys */
-       klist = rcu_dereference_check(keyring->payload.subscriptions,
-                                     lockdep_is_held(&key_serial_lock));
+       rcu_read_lock();
+       klist = rcu_dereference(keyring->payload.subscriptions);
        if (!klist)
-               goto dont_gc;
+               goto unlock_dont_gc;
 
        for (loop = klist->nkeys - 1; loop >= 0; loop--) {
                key = klist->keys[loop];
@@ -89,11 +89,14 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
                        goto do_gc;
        }
 
+unlock_dont_gc:
+       rcu_read_unlock();
 dont_gc:
        kleave(" = false");
        return false;
 
 do_gc:
+       rcu_read_unlock();
        key_gc_cursor = keyring->serial;
        key_get(keyring);
        spin_unlock(&key_serial_lock);
index 24ba030..5d4402a 100644 (file)
@@ -87,7 +87,16 @@ extern wait_queue_head_t request_key_conswq;
 extern struct key_type *key_type_lookup(const char *type);
 extern void key_type_put(struct key_type *ktype);
 
-extern int __key_link(struct key *keyring, struct key *key);
+extern int __key_link_begin(struct key *keyring,
+                           const struct key_type *type,
+                           const char *description,
+                           struct keyring_list **_prealloc);
+extern int __key_link_check_live_key(struct key *keyring, struct key *key);
+extern void __key_link(struct key *keyring, struct key *key,
+                      struct keyring_list **_prealloc);
+extern void __key_link_end(struct key *keyring,
+                          struct key_type *type,
+                          struct keyring_list *prealloc);
 
 extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
                                      const struct key_type *type,
index e50d264..c1eac80 100644 (file)
@@ -355,7 +355,7 @@ EXPORT_SYMBOL(key_alloc);
  */
 int key_payload_reserve(struct key *key, size_t datalen)
 {
-       int delta = (int) datalen - key->datalen;
+       int delta = (int)datalen - key->datalen;
        int ret = 0;
 
        key_check(key);
@@ -398,7 +398,8 @@ static int __key_instantiate_and_link(struct key *key,
                                      const void *data,
                                      size_t datalen,
                                      struct key *keyring,
-                                     struct key *authkey)
+                                     struct key *authkey,
+                                     struct keyring_list **_prealloc)
 {
        int ret, awaken;
 
@@ -425,7 +426,7 @@ static int __key_instantiate_and_link(struct key *key,
 
                        /* and link it into the destination keyring */
                        if (keyring)
-                               ret = __key_link(keyring, key);
+                               __key_link(keyring, key, _prealloc);
 
                        /* disable the authorisation key */
                        if (authkey)
@@ -453,15 +454,21 @@ int key_instantiate_and_link(struct key *key,
                             struct key *keyring,
                             struct key *authkey)
 {
+       struct keyring_list *prealloc;
        int ret;
 
-       if (keyring)
-               down_write(&keyring->sem);
+       if (keyring) {
+               ret = __key_link_begin(keyring, key->type, key->description,
+                                      &prealloc);
+               if (ret < 0)
+                       return ret;
+       }
 
-       ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey);
+       ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey,
+                                        &prealloc);
 
        if (keyring)
-               up_write(&keyring->sem);
+               __key_link_end(keyring, key->type, prealloc);
 
        return ret;
 
@@ -478,8 +485,9 @@ int key_negate_and_link(struct key *key,
                        struct key *keyring,
                        struct key *authkey)
 {
+       struct keyring_list *prealloc;
        struct timespec now;
-       int ret, awaken;
+       int ret, awaken, link_ret = 0;
 
        key_check(key);
        key_check(keyring);
@@ -488,7 +496,8 @@ int key_negate_and_link(struct key *key,
        ret = -EBUSY;
 
        if (keyring)
-               down_write(&keyring->sem);
+               link_ret = __key_link_begin(keyring, key->type,
+                                           key->description, &prealloc);
 
        mutex_lock(&key_construction_mutex);
 
@@ -508,8 +517,8 @@ int key_negate_and_link(struct key *key,
                ret = 0;
 
                /* and link it into the destination keyring */
-               if (keyring)
-                       ret = __key_link(keyring, key);
+               if (keyring && link_ret == 0)
+                       __key_link(keyring, key, &prealloc);
 
                /* disable the authorisation key */
                if (authkey)
@@ -519,13 +528,13 @@ int key_negate_and_link(struct key *key,
        mutex_unlock(&key_construction_mutex);
 
        if (keyring)
-               up_write(&keyring->sem);
+               __key_link_end(keyring, key->type, prealloc);
 
        /* wake up anyone waiting for a key to be constructed */
        if (awaken)
                wake_up_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT);
 
-       return ret;
+       return ret == 0 ? link_ret : ret;
 
 } /* end key_negate_and_link() */
 
@@ -749,6 +758,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                               key_perm_t perm,
                               unsigned long flags)
 {
+       struct keyring_list *prealloc;
        const struct cred *cred = current_cred();
        struct key_type *ktype;
        struct key *keyring, *key = NULL;
@@ -775,7 +785,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
        if (keyring->type != &key_type_keyring)
                goto error_2;
 
-       down_write(&keyring->sem);
+       ret = __key_link_begin(keyring, ktype, description, &prealloc);
+       if (ret < 0)
+               goto error_2;
 
        /* if we're going to allocate a new key, we're going to have
         * to modify the keyring */
@@ -817,7 +829,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
        }
 
        /* instantiate it and link it into the target keyring */
-       ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
+       ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL,
+                                        &prealloc);
        if (ret < 0) {
                key_put(key);
                key_ref = ERR_PTR(ret);
@@ -827,7 +840,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
        key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
 
  error_3:
-       up_write(&keyring->sem);
+       __key_link_end(keyring, ktype, prealloc);
  error_2:
        key_type_put(ktype);
  error:
@@ -837,7 +850,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
        /* we found a matching key, so we're going to try to update it
         * - we can drop the locks first as we have the key pinned
         */
-       up_write(&keyring->sem);
+       __key_link_end(keyring, ktype, prealloc);
        key_type_put(ktype);
 
        key_ref = __key_update(key_ref, payload, plen);
index e9c2e7c..8f4dce1 100644 (file)
@@ -212,15 +212,15 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
        ret = key->serial;
 
        key_put(key);
- error5:
+error5:
        key_type_put(ktype);
- error4:
+error4:
        key_ref_put(dest_ref);
- error3:
+error3:
        kfree(callout_info);
- error2:
+error2:
        kfree(description);
- error:
+error:
        return ret;
 
 } /* end sys_request_key() */
@@ -246,7 +246,7 @@ long keyctl_get_keyring_ID(key_serial_t id, int create)
 
        ret = key_ref_to_ptr(key_ref)->serial;
        key_ref_put(key_ref);
- error:
+error:
        return ret;
 
 } /* end keyctl_get_keyring_ID() */
@@ -275,7 +275,7 @@ long keyctl_join_session_keyring(const char __user *_name)
        ret = join_session_keyring(name);
        kfree(name);
 
- error:
+error:
        return ret;
 
 } /* end keyctl_join_session_keyring() */
@@ -322,9 +322,9 @@ long keyctl_update_key(key_serial_t id,
        ret = key_update(key_ref, payload, plen);
 
        key_ref_put(key_ref);
- error2:
+error2:
        kfree(payload);
- error:
+error:
        return ret;
 
 } /* end keyctl_update_key() */
@@ -356,7 +356,7 @@ long keyctl_revoke_key(key_serial_t id)
        ret = 0;
 
        key_ref_put(key_ref);
- error:
+error:
        return ret;
 
 } /* end keyctl_revoke_key() */
@@ -381,7 +381,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
        ret = keyring_clear(key_ref_to_ptr(keyring_ref));
 
        key_ref_put(keyring_ref);
- error:
+error:
        return ret;
 
 } /* end keyctl_keyring_clear() */
@@ -413,9 +413,9 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid)
        ret = key_link(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
 
        key_ref_put(key_ref);
- error2:
+error2:
        key_ref_put(keyring_ref);
- error:
+error:
        return ret;
 
 } /* end keyctl_keyring_link() */
@@ -447,9 +447,9 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid)
        ret = key_unlink(key_ref_to_ptr(keyring_ref), key_ref_to_ptr(key_ref));
 
        key_ref_put(key_ref);
- error2:
+error2:
        key_ref_put(keyring_ref);
- error:
+error:
        return ret;
 
 } /* end keyctl_keyring_unlink() */
@@ -529,9 +529,9 @@ okay:
        }
 
        kfree(tmpbuf);
- error2:
+error2:
        key_ref_put(key_ref);
- error:
+error:
        return ret;
 
 } /* end keyctl_describe_key() */
@@ -616,17 +616,17 @@ long keyctl_keyring_search(key_serial_t ringid,
 
        ret = key_ref_to_ptr(key_ref)->serial;
 
- error6:
+error6:
        key_ref_put(key_ref);
- error5:
+error5:
        key_type_put(ktype);
- error4:
+error4:
        key_ref_put(dest_ref);
- error3:
+error3:
        key_ref_put(keyring_ref);
- error2:
+error2:
        kfree(description);
- error:
+error:
        return ret;
 
 } /* end keyctl_keyring_search() */
@@ -673,7 +673,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
        }
 
        /* the key is probably readable - now try to read it */
- can_read_key:
+can_read_key:
        ret = key_validate(key);
        if (ret == 0) {
                ret = -EOPNOTSUPP;
@@ -686,9 +686,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
                }
        }
 
- error2:
+error2:
        key_put(key);
- error:
+error:
        return ret;
 
 } /* end keyctl_read_key() */
@@ -1282,26 +1282,19 @@ long keyctl_session_to_parent(void)
 
        /* the parent must have the same effective ownership and mustn't be
         * SUID/SGID */
-       if (pcred-> uid != mycred->euid ||
+       if (pcred->uid  != mycred->euid ||
            pcred->euid != mycred->euid ||
            pcred->suid != mycred->euid ||
-           pcred-> gid != mycred->egid ||
+           pcred->gid  != mycred->egid ||
            pcred->egid != mycred->egid ||
            pcred->sgid != mycred->egid)
                goto not_permitted;
 
        /* the keyrings must have the same UID */
-       if (pcred ->tgcred->session_keyring->uid != mycred->euid ||
+       if (pcred->tgcred->session_keyring->uid != mycred->euid ||
            mycred->tgcred->session_keyring->uid != mycred->euid)
                goto not_permitted;
 
-       /* the LSM must permit the replacement of the parent's keyring with the
-        * keyring from this process */
-       ret = security_key_session_to_parent(mycred, pcred,
-                                            key_ref_to_ptr(keyring_r));
-       if (ret < 0)
-               goto not_permitted;
-
        /* if there's an already pending keyring replacement, then we replace
         * that */
        oldcred = parent->replacement_session_keyring;
index e814d21..ef03a82 100644 (file)
 #include <linux/seq_file.h>
 #include <linux/err.h>
 #include <keys/keyring-type.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "internal.h"
 
+#define rcu_dereference_locked_keyring(keyring)                                \
+       (rcu_dereference_protected(                                     \
+               (keyring)->payload.subscriptions,                       \
+               rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
+
 /*
  * when plumbing the depths of the key tree, this sets a hard limit set on how
  * deep we're willing to go
@@ -39,7 +44,7 @@ static inline unsigned keyring_hash(const char *desc)
        unsigned bucket = 0;
 
        for (; *desc; desc++)
-               bucket += (unsigned char) *desc;
+               bucket += (unsigned char)*desc;
 
        return bucket & (KEYRING_NAME_HASH_SIZE - 1);
 }
@@ -170,12 +175,10 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
 {
        struct keyring_list *klist;
 
-       if (keyring->description) {
+       if (keyring->description)
                seq_puts(m, keyring->description);
-       }
-       else {
+       else
                seq_puts(m, "[anon]");
-       }
 
        rcu_read_lock();
        klist = rcu_dereference(keyring->payload.subscriptions);
@@ -201,8 +204,7 @@ static long keyring_read(const struct key *keyring,
        int loop, ret;
 
        ret = 0;
-       klist = rcu_dereference(keyring->payload.subscriptions);
-
+       klist = rcu_dereference_locked_keyring(keyring);
        if (klist) {
                /* calculate how much data we could return */
                qty = klist->nkeys * sizeof(key_serial_t);
@@ -237,7 +239,7 @@ static long keyring_read(const struct key *keyring,
                ret = qty;
        }
 
- error:
+error:
        return ret;
 
 } /* end keyring_read() */
@@ -306,7 +308,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
        key_check(keyring);
 
        /* top keyring must have search permission to begin the search */
-        err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
+       err = key_task_permission(keyring_ref, cred, KEY_SEARCH);
        if (err < 0) {
                key_ref = ERR_PTR(err);
                goto error;
@@ -508,7 +510,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
        rcu_read_unlock();
        return ERR_PTR(-ENOKEY);
 
- found:
+found:
        atomic_inc(&key->usage);
        rcu_read_unlock();
        return make_key_ref(key, possessed);
@@ -526,9 +528,8 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
        struct key *keyring;
        int bucket;
 
-       keyring = ERR_PTR(-EINVAL);
        if (!name)
-               goto error;
+               return ERR_PTR(-EINVAL);
 
        bucket = keyring_hash(name);
 
@@ -555,17 +556,18 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
                                           KEY_SEARCH) < 0)
                                continue;
 
-                       /* we've got a match */
-                       atomic_inc(&keyring->usage);
-                       read_unlock(&keyring_name_lock);
-                       goto error;
+                       /* we've got a match but we might end up racing with
+                        * key_cleanup() if the keyring is currently 'dead'
+                        * (ie. it has a zero usage count) */
+                       if (!atomic_inc_not_zero(&keyring->usage))
+                               continue;
+                       goto out;
                }
        }
 
-       read_unlock(&keyring_name_lock);
        keyring = ERR_PTR(-ENOKEY);
-
- error:
+out:
+       read_unlock(&keyring_name_lock);
        return keyring;
 
 } /* end find_keyring_by_name() */
@@ -598,7 +600,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
        sp = 0;
 
        /* start processing a new keyring */
- descend:
+descend:
        if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
                goto not_this_keyring;
 
@@ -607,7 +609,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
                goto not_this_keyring;
        kix = 0;
 
- ascend:
+ascend:
        /* iterate through the remaining keys in this keyring */
        for (; kix < keylist->nkeys; kix++) {
                key = keylist->keys[kix];
@@ -633,7 +635,7 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
 
        /* the keyring we're looking at was disqualified or didn't contain a
         * matching key */
- not_this_keyring:
+not_this_keyring:
        if (sp > 0) {
                /* resume the checking of a keyring higher up in the tree */
                sp--;
@@ -644,34 +646,20 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
 
        ret = 0; /* no cycles detected */
 
- error:
+error:
        rcu_read_unlock();
        return ret;
 
- too_deep:
+too_deep:
        ret = -ELOOP;
        goto error;
 
- cycle_detected:
+cycle_detected:
        ret = -EDEADLK;
        goto error;
 
 } /* end keyring_detect_cycle() */
 
-/*****************************************************************************/
-/*
- * dispose of a keyring list after the RCU grace period
- */
-static void keyring_link_rcu_disposal(struct rcu_head *rcu)
-{
-       struct keyring_list *klist =
-               container_of(rcu, struct keyring_list, rcu);
-
-       kfree(klist);
-
-} /* end keyring_link_rcu_disposal() */
-
-/*****************************************************************************/
 /*
  * dispose of a keyring list after the RCU grace period, freeing the unlinked
  * key
@@ -681,56 +669,51 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
        struct keyring_list *klist =
                container_of(rcu, struct keyring_list, rcu);
 
-       key_put(klist->keys[klist->delkey]);
+       if (klist->delkey != USHORT_MAX)
+               key_put(klist->keys[klist->delkey]);
        kfree(klist);
+}
 
-} /* end keyring_unlink_rcu_disposal() */
-
-/*****************************************************************************/
 /*
- * link a key into to a keyring
- * - must be called with the keyring's semaphore write-locked
- * - discard already extant link to matching key if there is one
+ * preallocate memory so that a key can be linked into to a keyring
  */
-int __key_link(struct key *keyring, struct key *key)
+int __key_link_begin(struct key *keyring, const struct key_type *type,
+                    const char *description,
+                    struct keyring_list **_prealloc)
+       __acquires(&keyring->sem)
 {
        struct keyring_list *klist, *nklist;
        unsigned max;
        size_t size;
        int loop, ret;
 
-       ret = -EKEYREVOKED;
-       if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
-               goto error;
+       kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
 
-       ret = -ENOTDIR;
        if (keyring->type != &key_type_keyring)
-               goto error;
+               return -ENOTDIR;
 
-       /* serialise link/link calls to prevent parallel calls causing a
-        * cycle when applied to two keyring in opposite orders */
-       down_write(&keyring_serialise_link_sem);
+       down_write(&keyring->sem);
 
-       /* check that we aren't going to create a cycle adding one keyring to
-        * another */
-       if (key->type == &key_type_keyring) {
-               ret = keyring_detect_cycle(keyring, key);
-               if (ret < 0)
-                       goto error2;
-       }
+       ret = -EKEYREVOKED;
+       if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
+               goto error_krsem;
 
-       /* see if there's a matching key we can displace */
-       klist = keyring->payload.subscriptions;
+       /* serialise link/link calls to prevent parallel calls causing a cycle
+        * when linking two keyring in opposite orders */
+       if (type == &key_type_keyring)
+               down_write(&keyring_serialise_link_sem);
 
-       if (klist && klist->nkeys > 0) {
-               struct key_type *type = key->type;
+       klist = rcu_dereference_locked_keyring(keyring);
 
+       /* see if there's a matching key we can displace */
+       if (klist && klist->nkeys > 0) {
                for (loop = klist->nkeys - 1; loop >= 0; loop--) {
                        if (klist->keys[loop]->type == type &&
                            strcmp(klist->keys[loop]->description,
-                                  key->description) == 0
+                                  description) == 0
                            ) {
-                               /* found a match - replace with new key */
+                               /* found a match - we'll replace this one with
+                                * the new key */
                                size = sizeof(struct key *) * klist->maxkeys;
                                size += sizeof(*klist);
                                BUG_ON(size > PAGE_SIZE);
@@ -738,22 +721,10 @@ int __key_link(struct key *keyring, struct key *key)
                                ret = -ENOMEM;
                                nklist = kmemdup(klist, size, GFP_KERNEL);
                                if (!nklist)
-                                       goto error2;
-
-                               /* replace matched key */
-                               atomic_inc(&key->usage);
-                               nklist->keys[loop] = key;
-
-                               rcu_assign_pointer(
-                                       keyring->payload.subscriptions,
-                                       nklist);
-
-                               /* dispose of the old keyring list and the
-                                * displaced key */
-                               klist->delkey = loop;
-                               call_rcu(&klist->rcu,
-                                        keyring_unlink_rcu_disposal);
+                                       goto error_sem;
 
+                               /* note replacement slot */
+                               klist->delkey = nklist->delkey = loop;
                                goto done;
                        }
                }
@@ -763,90 +734,167 @@ int __key_link(struct key *keyring, struct key *key)
        ret = key_payload_reserve(keyring,
                                  keyring->datalen + KEYQUOTA_LINK_BYTES);
        if (ret < 0)
-               goto error2;
-
-       klist = keyring->payload.subscriptions;
+               goto error_sem;
 
        if (klist && klist->nkeys < klist->maxkeys) {
-               /* there's sufficient slack space to add directly */
-               atomic_inc(&key->usage);
-
-               klist->keys[klist->nkeys] = key;
-               smp_wmb();
-               klist->nkeys++;
-               smp_wmb();
-       }
-       else {
+               /* there's sufficient slack space to append directly */
+               nklist = NULL;
+       } else {
                /* grow the key list */
                max = 4;
                if (klist)
                        max += klist->maxkeys;
 
                ret = -ENFILE;
-               if (max > 65535)
-                       goto error3;
+               if (max > USHORT_MAX - 1)
+                       goto error_quota;
                size = sizeof(*klist) + sizeof(struct key *) * max;
                if (size > PAGE_SIZE)
-                       goto error3;
+                       goto error_quota;
 
                ret = -ENOMEM;
                nklist = kmalloc(size, GFP_KERNEL);
                if (!nklist)
-                       goto error3;
-               nklist->maxkeys = max;
-               nklist->nkeys = 0;
+                       goto error_quota;
 
+               nklist->maxkeys = max;
                if (klist) {
-                       nklist->nkeys = klist->nkeys;
-                       memcpy(nklist->keys,
-                              klist->keys,
+                       memcpy(nklist->keys, klist->keys,
                               sizeof(struct key *) * klist->nkeys);
+                       nklist->delkey = klist->nkeys;
+                       nklist->nkeys = klist->nkeys + 1;
+                       klist->delkey = USHORT_MAX;
+               } else {
+                       nklist->nkeys = 1;
+                       nklist->delkey = 0;
                }
 
                /* add the key into the new space */
-               atomic_inc(&key->usage);
-               nklist->keys[nklist->nkeys++] = key;
-
-               rcu_assign_pointer(keyring->payload.subscriptions, nklist);
-
-               /* dispose of the old keyring list */
-               if (klist)
-                       call_rcu(&klist->rcu, keyring_link_rcu_disposal);
+               nklist->keys[nklist->delkey] = NULL;
        }
 
 done:
-       ret = 0;
-error2:
-       up_write(&keyring_serialise_link_sem);
-error:
-       return ret;
+       *_prealloc = nklist;
+       kleave(" = 0");
+       return 0;
 
-error3:
+error_quota:
        /* undo the quota changes */
        key_payload_reserve(keyring,
                            keyring->datalen - KEYQUOTA_LINK_BYTES);
-       goto error2;
+error_sem:
+       if (type == &key_type_keyring)
+               up_write(&keyring_serialise_link_sem);
+error_krsem:
+       up_write(&keyring->sem);
+       kleave(" = %d", ret);
+       return ret;
+}
 
-} /* end __key_link() */
+/*
+ * check already instantiated keys aren't going to be a problem
+ * - the caller must have called __key_link_begin()
+ * - don't need to call this for keys that were created since __key_link_begin()
+ *   was called
+ */
+int __key_link_check_live_key(struct key *keyring, struct key *key)
+{
+       if (key->type == &key_type_keyring)
+               /* check that we aren't going to create a cycle by linking one
+                * keyring to another */
+               return keyring_detect_cycle(keyring, key);
+       return 0;
+}
+
+/*
+ * link a key into to a keyring
+ * - must be called with __key_link_begin() having being called
+ * - discard already extant link to matching key if there is one
+ */
+void __key_link(struct key *keyring, struct key *key,
+               struct keyring_list **_prealloc)
+{
+       struct keyring_list *klist, *nklist;
+
+       nklist = *_prealloc;
+       *_prealloc = NULL;
+
+       kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
+
+       klist = rcu_dereference_protected(keyring->payload.subscriptions,
+                                         rwsem_is_locked(&keyring->sem));
+
+       atomic_inc(&key->usage);
+
+       /* there's a matching key we can displace or an empty slot in a newly
+        * allocated list we can fill */
+       if (nklist) {
+               kdebug("replace %hu/%hu/%hu",
+                      nklist->delkey, nklist->nkeys, nklist->maxkeys);
+
+               nklist->keys[nklist->delkey] = key;
+
+               rcu_assign_pointer(keyring->payload.subscriptions, nklist);
+
+               /* dispose of the old keyring list and, if there was one, the
+                * displaced key */
+               if (klist) {
+                       kdebug("dispose %hu/%hu/%hu",
+                              klist->delkey, klist->nkeys, klist->maxkeys);
+                       call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
+               }
+       } else {
+               /* there's sufficient slack space to append directly */
+               klist->keys[klist->nkeys] = key;
+               smp_wmb();
+               klist->nkeys++;
+       }
+}
+
+/*
+ * finish linking a key into to a keyring
+ * - must be called with __key_link_begin() having being called
+ */
+void __key_link_end(struct key *keyring, struct key_type *type,
+                   struct keyring_list *prealloc)
+       __releases(&keyring->sem)
+{
+       BUG_ON(type == NULL);
+       BUG_ON(type->name == NULL);
+       kenter("%d,%s,%p", keyring->serial, type->name, prealloc);
+
+       if (type == &key_type_keyring)
+               up_write(&keyring_serialise_link_sem);
+
+       if (prealloc) {
+               kfree(prealloc);
+               key_payload_reserve(keyring,
+                                   keyring->datalen - KEYQUOTA_LINK_BYTES);
+       }
+       up_write(&keyring->sem);
+}
 
-/*****************************************************************************/
 /*
  * link a key to a keyring
  */
 int key_link(struct key *keyring, struct key *key)
 {
+       struct keyring_list *prealloc;
        int ret;
 
        key_check(keyring);
        key_check(key);
 
-       down_write(&keyring->sem);
-       ret = __key_link(keyring, key);
-       up_write(&keyring->sem);
+       ret = __key_link_begin(keyring, key->type, key->description, &prealloc);
+       if (ret == 0) {
+               ret = __key_link_check_live_key(keyring, key);
+               if (ret == 0)
+                       __key_link(keyring, key, &prealloc);
+               __key_link_end(keyring, key->type, prealloc);
+       }
 
        return ret;
-
-} /* end key_link() */
+}
 
 EXPORT_SYMBOL(key_link);
 
@@ -868,7 +916,7 @@ int key_unlink(struct key *keyring, struct key *key)
 
        down_write(&keyring->sem);
 
-       klist = keyring->payload.subscriptions;
+       klist = rcu_dereference_locked_keyring(keyring);
        if (klist) {
                /* search the keyring for the key */
                for (loop = 0; loop < klist->nkeys; loop++)
@@ -959,7 +1007,7 @@ int keyring_clear(struct key *keyring)
                /* detach the pointer block with the locks held */
                down_write(&keyring->sem);
 
-               klist = keyring->payload.subscriptions;
+               klist = rcu_dereference_locked_keyring(keyring);
                if (klist) {
                        /* adjust the quota */
                        key_payload_reserve(keyring,
@@ -991,7 +1039,9 @@ EXPORT_SYMBOL(keyring_clear);
  */
 static void keyring_revoke(struct key *keyring)
 {
-       struct keyring_list *klist = keyring->payload.subscriptions;
+       struct keyring_list *klist;
+
+       klist = rcu_dereference_locked_keyring(keyring);
 
        /* adjust the quota */
        key_payload_reserve(keyring, 0);
@@ -1025,7 +1075,7 @@ void keyring_gc(struct key *keyring, time_t limit)
 
        down_write(&keyring->sem);
 
-       klist = keyring->payload.subscriptions;
+       klist = rcu_dereference_locked_keyring(keyring);
        if (!klist)
                goto no_klist;
 
index 0ed802c..2864550 100644 (file)
@@ -109,7 +109,7 @@ int key_validate(struct key *key)
                }
        }
 
- error:
+error:
        return ret;
 
 } /* end key_validate() */
index 706d63f..068b66e 100644 (file)
@@ -306,7 +306,7 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos)
 static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos)
 {
        (*_pos)++;
-       return key_user_next((struct rb_node *) v);
+       return key_user_next((struct rb_node *)v);
 }
 
 static void proc_key_users_stop(struct seq_file *p, void *v)
index 06c2ccf..20a38fe 100644 (file)
@@ -508,7 +508,7 @@ try_again:
 
                        ret = install_thread_keyring();
                        if (ret < 0) {
-                               key = ERR_PTR(ret);
+                               key_ref = ERR_PTR(ret);
                                goto error;
                        }
                        goto reget_creds;
@@ -526,7 +526,7 @@ try_again:
 
                        ret = install_process_keyring();
                        if (ret < 0) {
-                               key = ERR_PTR(ret);
+                               key_ref = ERR_PTR(ret);
                                goto error;
                        }
                        goto reget_creds;
@@ -585,7 +585,7 @@ try_again:
 
        case KEY_SPEC_GROUP_KEYRING:
                /* group keyrings are not yet supported */
-               key = ERR_PTR(-EINVAL);
+               key_ref = ERR_PTR(-EINVAL);
                goto error;
 
        case KEY_SPEC_REQKEY_AUTH_KEY:
index 03fe63e..f656e9c 100644 (file)
@@ -68,7 +68,8 @@ static int call_sbin_request_key(struct key_construction *cons,
 {
        const struct cred *cred = current_cred();
        key_serial_t prkey, sskey;
-       struct key *key = cons->key, *authkey = cons->authkey, *keyring;
+       struct key *key = cons->key, *authkey = cons->authkey, *keyring,
+               *session;
        char *argv[9], *envp[3], uid_str[12], gid_str[12];
        char key_str[12], keyring_str[3][12];
        char desc[20];
@@ -93,7 +94,7 @@ static int call_sbin_request_key(struct key_construction *cons,
        }
 
        /* attach the auth key to the session keyring */
-       ret = __key_link(keyring, authkey);
+       ret = key_link(keyring, authkey);
        if (ret < 0)
                goto error_link;
 
@@ -112,10 +113,12 @@ static int call_sbin_request_key(struct key_construction *cons,
        if (cred->tgcred->process_keyring)
                prkey = cred->tgcred->process_keyring->serial;
 
-       if (cred->tgcred->session_keyring)
-               sskey = rcu_dereference(cred->tgcred->session_keyring)->serial;
-       else
-               sskey = cred->user->session_keyring->serial;
+       rcu_read_lock();
+       session = rcu_dereference(cred->tgcred->session_keyring);
+       if (!session)
+               session = cred->user->session_keyring;
+       sskey = session->serial;
+       rcu_read_unlock();
 
        sprintf(keyring_str[2], "%d", sskey);
 
@@ -296,12 +299,15 @@ static int construct_alloc_key(struct key_type *type,
                               struct key_user *user,
                               struct key **_key)
 {
+       struct keyring_list *prealloc;
        const struct cred *cred = current_cred();
        struct key *key;
        key_ref_t key_ref;
+       int ret;
 
        kenter("%s,%s,,,", type->name, description);
 
+       *_key = NULL;
        mutex_lock(&user->cons_lock);
 
        key = key_alloc(type, description, cred->fsuid, cred->fsgid, cred,
@@ -311,8 +317,12 @@ static int construct_alloc_key(struct key_type *type,
 
        set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
 
-       if (dest_keyring)
-               down_write(&dest_keyring->sem);
+       if (dest_keyring) {
+               ret = __key_link_begin(dest_keyring, type, description,
+                                      &prealloc);
+               if (ret < 0)
+                       goto link_prealloc_failed;
+       }
 
        /* attach the key to the destination keyring under lock, but we do need
         * to do another check just in case someone beat us to it whilst we
@@ -324,29 +334,49 @@ static int construct_alloc_key(struct key_type *type,
                goto key_already_present;
 
        if (dest_keyring)
-               __key_link(dest_keyring, key);
+               __key_link(dest_keyring, key, &prealloc);
 
        mutex_unlock(&key_construction_mutex);
        if (dest_keyring)
-               up_write(&dest_keyring->sem);
+               __key_link_end(dest_keyring, type, prealloc);
        mutex_unlock(&user->cons_lock);
        *_key = key;
        kleave(" = 0 [%d]", key_serial(key));
        return 0;
 
+       /* the key is now present - we tell the caller that we found it by
+        * returning -EINPROGRESS  */
 key_already_present:
+       key_put(key);
        mutex_unlock(&key_construction_mutex);
-       if (dest_keyring)
-               up_write(&dest_keyring->sem);
+       key = key_ref_to_ptr(key_ref);
+       if (dest_keyring) {
+               ret = __key_link_check_live_key(dest_keyring, key);
+               if (ret == 0)
+                       __key_link(dest_keyring, key, &prealloc);
+               __key_link_end(dest_keyring, type, prealloc);
+               if (ret < 0)
+                       goto link_check_failed;
+       }
        mutex_unlock(&user->cons_lock);
-       key_put(key);
-       *_key = key = key_ref_to_ptr(key_ref);
+       *_key = key;
        kleave(" = -EINPROGRESS [%d]", key_serial(key));
        return -EINPROGRESS;
 
+link_check_failed:
+       mutex_unlock(&user->cons_lock);
+       key_put(key);
+       kleave(" = %d [linkcheck]", ret);
+       return ret;
+
+link_prealloc_failed:
+       up_write(&dest_keyring->sem);
+       mutex_unlock(&user->cons_lock);
+       kleave(" = %d [prelink]", ret);
+       return ret;
+
 alloc_failed:
        mutex_unlock(&user->cons_lock);
-       *_key = NULL;
        kleave(" = %ld", PTR_ERR(key));
        return PTR_ERR(key);
 }
@@ -385,6 +415,10 @@ static struct key *construct_key_and_link(struct key_type *type,
                        kdebug("cons failed");
                        goto construction_failed;
                }
+       } else if (ret == -EINPROGRESS) {
+               ret = 0;
+       } else {
+               key = ERR_PTR(ret);
        }
 
        key_put(dest_keyring);
@@ -417,6 +451,7 @@ struct key *request_key_and_link(struct key_type *type,
        const struct cred *cred = current_cred();
        struct key *key;
        key_ref_t key_ref;
+       int ret;
 
        kenter("%s,%s,%p,%zu,%p,%p,%lx",
               type->name, description, callout_info, callout_len, aux,
@@ -428,6 +463,16 @@ struct key *request_key_and_link(struct key_type *type,
 
        if (!IS_ERR(key_ref)) {
                key = key_ref_to_ptr(key_ref);
+               if (dest_keyring) {
+                       construct_get_dest_keyring(&dest_keyring);
+                       ret = key_link(dest_keyring, key);
+                       key_put(dest_keyring);
+                       if (ret < 0) {
+                               key_put(key);
+                               key = ERR_PTR(ret);
+                               goto error;
+                       }
+               }
        } else if (PTR_ERR(key_ref) != -EAGAIN) {
                key = ERR_CAST(key_ref);
        } else  {
index 7c687d5..e9aa079 100644 (file)
@@ -199,7 +199,8 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
        struct user_key_payload *upayload;
        long ret;
 
-       upayload = rcu_dereference(key->payload.data);
+       upayload = rcu_dereference_protected(
+               key->payload.data, rwsem_is_locked(&((struct key *)key)->sem));
        ret = upayload->datalen;
 
        /* we can return the data as is */
index 893365b..908aa71 100644 (file)
@@ -221,7 +221,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
        }
 
        switch (a->type) {
-       case LSM_AUDIT_NO_AUDIT:
+       case LSM_AUDIT_DATA_NONE:
                return;
        case LSM_AUDIT_DATA_IPC:
                audit_log_format(ab, " key=%d ", a->u.ipc_id);
index e86f297..f728728 100644 (file)
@@ -33,7 +33,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
 {
        int ret;
 
-       if (!capable(CAP_SYS_RAWIO))
+       if (write && !capable(CAP_SYS_RAWIO))
                return -EPERM;
 
        ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
index 687c6fd..351942a 100644 (file)
@@ -23,14 +23,14 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
        CONFIG_DEFAULT_SECURITY;
 
 /* things that live in capability.c */
-extern void security_fixup_ops(struct security_operations *ops);
+extern void __init security_fixup_ops(struct security_operations *ops);
 
 static struct security_operations *security_ops;
 static struct security_operations default_security_ops = {
        .name   = "default",
 };
 
-static inline int verify(struct security_operations *ops)
+static inline int __init verify(struct security_operations *ops)
 {
        /* verify the security_operations structure exists */
        if (!ops)
@@ -117,7 +117,7 @@ int __init security_module_enable(struct security_operations *ops)
  * If there is already a security module registered with the kernel,
  * an error will be returned.  Otherwise %0 is returned on success.
  */
-int register_security(struct security_operations *ops)
+int __init register_security(struct security_operations *ops)
 {
        if (verify(ops)) {
                printk(KERN_DEBUG "%s could not verify "
@@ -190,11 +190,6 @@ int security_real_capable_noaudit(struct task_struct *tsk, int cap)
        return ret;
 }
 
-int security_acct(struct file *file)
-{
-       return security_ops->acct(file);
-}
-
 int security_sysctl(struct ctl_table *table, int op)
 {
        return security_ops->sysctl(table, op);
@@ -306,46 +301,16 @@ int security_sb_mount(char *dev_name, struct path *path,
        return security_ops->sb_mount(dev_name, path, type, flags, data);
 }
 
-int security_sb_check_sb(struct vfsmount *mnt, struct path *path)
-{
-       return security_ops->sb_check_sb(mnt, path);
-}
-
 int security_sb_umount(struct vfsmount *mnt, int flags)
 {
        return security_ops->sb_umount(mnt, flags);
 }
 
-void security_sb_umount_close(struct vfsmount *mnt)
-{
-       security_ops->sb_umount_close(mnt);
-}
-
-void security_sb_umount_busy(struct vfsmount *mnt)
-{
-       security_ops->sb_umount_busy(mnt);
-}
-
-void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data)
-{
-       security_ops->sb_post_remount(mnt, flags, data);
-}
-
-void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint)
-{
-       security_ops->sb_post_addmount(mnt, mountpoint);
-}
-
 int security_sb_pivotroot(struct path *old_path, struct path *new_path)
 {
        return security_ops->sb_pivotroot(old_path, new_path);
 }
 
-void security_sb_post_pivotroot(struct path *old_path, struct path *new_path)
-{
-       security_ops->sb_post_pivotroot(old_path, new_path);
-}
-
 int security_sb_set_mnt_opts(struct super_block *sb,
                                struct security_mnt_opts *opts)
 {
@@ -580,13 +545,6 @@ int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
        return security_ops->inode_getattr(mnt, dentry);
 }
 
-void security_inode_delete(struct inode *inode)
-{
-       if (unlikely(IS_PRIVATE(inode)))
-               return;
-       security_ops->inode_delete(inode);
-}
-
 int security_inode_setxattr(struct dentry *dentry, const char *name,
                            const void *value, size_t size, int flags)
 {
@@ -749,11 +707,6 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp)
        return security_ops->cred_prepare(new, old, gfp);
 }
 
-void security_commit_creds(struct cred *new, const struct cred *old)
-{
-       security_ops->cred_commit(new, old);
-}
-
 void security_transfer_creds(struct cred *new, const struct cred *old)
 {
        security_ops->cred_transfer(new, old);
@@ -774,22 +727,12 @@ int security_kernel_module_request(char *kmod_name)
        return security_ops->kernel_module_request(kmod_name);
 }
 
-int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
-{
-       return security_ops->task_setuid(id0, id1, id2, flags);
-}
-
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags)
 {
        return security_ops->task_fix_setuid(new, old, flags);
 }
 
-int security_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
-{
-       return security_ops->task_setgid(id0, id1, id2, flags);
-}
-
 int security_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return security_ops->task_setpgid(p, pgid);
@@ -811,11 +754,6 @@ void security_task_getsecid(struct task_struct *p, u32 *secid)
 }
 EXPORT_SYMBOL(security_task_getsecid);
 
-int security_task_setgroups(struct group_info *group_info)
-{
-       return security_ops->task_setgroups(group_info);
-}
-
 int security_task_setnice(struct task_struct *p, int nice)
 {
        return security_ops->task_setnice(p, nice);
@@ -1319,13 +1257,6 @@ int security_key_getsecurity(struct key *key, char **_buffer)
        return security_ops->key_getsecurity(key, _buffer);
 }
 
-int security_key_session_to_parent(const struct cred *cred,
-                                  const struct cred *parent_cred,
-                                  struct key *key)
-{
-       return security_ops->key_session_to_parent(cred, parent_cred, key);
-}
-
 #endif /* CONFIG_KEYS */
 
 #ifdef CONFIG_AUDIT
index 989fef8..7f1a304 100644 (file)
@@ -499,8 +499,7 @@ void avc_audit(u32 ssid, u32 tsid,
                return;
        if (!a) {
                a = &stack_data;
-               memset(a, 0, sizeof(*a));
-               a->type = LSM_AUDIT_NO_AUDIT;
+               COMMON_AUDIT_DATA_INIT(a, NONE);
        }
        a->selinux_audit_data.tclass = tclass;
        a->selinux_audit_data.requested = requested;
index 5feecb4..a03fd74 100644 (file)
@@ -293,28 +293,28 @@ static void superblock_free_security(struct super_block *sb)
 
 static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
 {
-       struct sk_security_struct *ssec;
+       struct sk_security_struct *sksec;
 
-       ssec = kzalloc(sizeof(*ssec), priority);
-       if (!ssec)
+       sksec = kzalloc(sizeof(*sksec), priority);
+       if (!sksec)
                return -ENOMEM;
 
-       ssec->peer_sid = SECINITSID_UNLABELED;
-       ssec->sid = SECINITSID_UNLABELED;
-       sk->sk_security = ssec;
+       sksec->peer_sid = SECINITSID_UNLABELED;
+       sksec->sid = SECINITSID_UNLABELED;
+       sk->sk_security = sksec;
 
-       selinux_netlbl_sk_security_reset(ssec);
+       selinux_netlbl_sk_security_reset(sksec);
 
        return 0;
 }
 
 static void sk_free_security(struct sock *sk)
 {
-       struct sk_security_struct *ssec = sk->sk_security;
+       struct sk_security_struct *sksec = sk->sk_security;
 
        sk->sk_security = NULL;
-       selinux_netlbl_sk_security_free(ssec);
-       kfree(ssec);
+       selinux_netlbl_sk_security_free(sksec);
+       kfree(sksec);
 }
 
 /* The security server must be initialized before
@@ -323,7 +323,7 @@ extern int ss_initialized;
 
 /* The file system's label must be initialized prior to use. */
 
-static char *labeling_behaviors[6] = {
+static const char *labeling_behaviors[6] = {
        "uses xattr",
        "uses transition SIDs",
        "uses task SIDs",
@@ -2999,13 +2999,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
        return file_has_perm(cred, file, av);
 }
 
+static int default_noexec;
+
 static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
 {
        const struct cred *cred = current_cred();
        int rc = 0;
 
-#ifndef CONFIG_PPC32
-       if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
+       if (default_noexec &&
+           (prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
                /*
                 * We are making executable an anonymous mapping or a
                 * private file mapping that will also be writable.
@@ -3015,7 +3017,6 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
                if (rc)
                        goto error;
        }
-#endif
 
        if (file) {
                /* read access is always possible with a mapping */
@@ -3076,8 +3077,8 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
        if (selinux_checkreqprot)
                prot = reqprot;
 
-#ifndef CONFIG_PPC32
-       if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
+       if (default_noexec &&
+           (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
                int rc = 0;
                if (vma->vm_start >= vma->vm_mm->start_brk &&
                    vma->vm_end <= vma->vm_mm->brk) {
@@ -3099,7 +3100,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
                if (rc)
                        return rc;
        }
-#endif
 
        return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
 }
@@ -4002,7 +4002,7 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
                                              struct socket *other,
                                              struct sock *newsk)
 {
-       struct sk_security_struct *ssec;
+       struct sk_security_struct *sksec;
        struct inode_security_struct *isec;
        struct inode_security_struct *other_isec;
        struct common_audit_data ad;
@@ -4021,13 +4021,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
                return err;
 
        /* connecting socket */
-       ssec = sock->sk->sk_security;
-       ssec->peer_sid = other_isec->sid;
+       sksec = sock->sk->sk_security;
+       sksec->peer_sid = other_isec->sid;
 
        /* server child socket */
-       ssec = newsk->sk_security;
-       ssec->peer_sid = isec->sid;
-       err = security_sid_mls_copy(other_isec->sid, ssec->peer_sid, &ssec->sid);
+       sksec = newsk->sk_security;
+       sksec->peer_sid = isec->sid;
+       err = security_sid_mls_copy(other_isec->sid, sksec->peer_sid, &sksec->sid);
 
        return err;
 }
@@ -4190,7 +4190,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
        int err = 0;
        char *scontext;
        u32 scontext_len;
-       struct sk_security_struct *ssec;
+       struct sk_security_struct *sksec;
        struct inode_security_struct *isec;
        u32 peer_sid = SECSID_NULL;
 
@@ -4198,8 +4198,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
 
        if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
            isec->sclass == SECCLASS_TCP_SOCKET) {
-               ssec = sock->sk->sk_security;
-               peer_sid = ssec->peer_sid;
+               sksec = sock->sk->sk_security;
+               peer_sid = sksec->peer_sid;
        }
        if (peer_sid == SECSID_NULL) {
                err = -ENOPROTOOPT;
@@ -4266,14 +4266,14 @@ static void selinux_sk_free_security(struct sock *sk)
 
 static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
 {
-       struct sk_security_struct *ssec = sk->sk_security;
-       struct sk_security_struct *newssec = newsk->sk_security;
+       struct sk_security_struct *sksec = sk->sk_security;
+       struct sk_security_struct *newsksec = newsk->sk_security;
 
-       newssec->sid = ssec->sid;
-       newssec->peer_sid = ssec->peer_sid;
-       newssec->sclass = ssec->sclass;
+       newsksec->sid = sksec->sid;
+       newsksec->peer_sid = sksec->peer_sid;
+       newsksec->sclass = sksec->sclass;
 
-       selinux_netlbl_sk_security_reset(newssec);
+       selinux_netlbl_sk_security_reset(newsksec);
 }
 
 static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -5662,6 +5662,8 @@ static __init int selinux_init(void)
        /* Set the security state for the initial task. */
        cred_init_security();
 
+       default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
+
        sel_inode_cache = kmem_cache_create("selinux_inode_security",
                                            sizeof(struct inode_security_struct),
                                            0, SLAB_PANIC, NULL);
index d4fac82..a59b64e 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is automatically generated.  Do not edit. */
-static char *initial_sid_to_string[] =
+static const char *initial_sid_to_string[] =
 {
     "null",
     "kernel",
index 8d73842..cf2f628 100644 (file)
@@ -42,8 +42,8 @@ void selinux_netlbl_cache_invalidate(void);
 
 void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
 
-void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec);
-void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec);
+void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec);
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec);
 
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
                                 u16 family,
@@ -79,13 +79,13 @@ static inline void selinux_netlbl_err(struct sk_buff *skb,
 }
 
 static inline void selinux_netlbl_sk_security_free(
-                                              struct sk_security_struct *ssec)
+                                              struct sk_security_struct *sksec)
 {
        return;
 }
 
 static inline void selinux_netlbl_sk_security_reset(
-                                              struct sk_security_struct *ssec)
+                                              struct sk_security_struct *sksec)
 {
        return;
 }
index 628da72..1c2fc46 100644 (file)
@@ -132,21 +132,21 @@ void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway)
 
 /**
  * selinux_netlbl_sk_security_free - Free the NetLabel fields
- * @sssec: the sk_security_struct
+ * @sksec: the sk_security_struct
  *
  * Description:
  * Free all of the memory in the NetLabel fields of a sk_security_struct.
  *
  */
-void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
+void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec)
 {
-       if (ssec->nlbl_secattr != NULL)
-               netlbl_secattr_free(ssec->nlbl_secattr);
+       if (sksec->nlbl_secattr != NULL)
+               netlbl_secattr_free(sksec->nlbl_secattr);
 }
 
 /**
  * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
- * @ssec: the sk_security_struct
+ * @sksec: the sk_security_struct
  * @family: the socket family
  *
  * Description:
@@ -154,9 +154,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
  * The caller is responsibile for all the NetLabel sk_security_struct locking.
  *
  */
-void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec)
+void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec)
 {
-       ssec->nlbl_state = NLBL_UNSET;
+       sksec->nlbl_state = NLBL_UNSET;
 }
 
 /**
index 0e147b6..36ac257 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
-#include <linux/list.h>
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/selinux_netlink.h>
index dd7cc6d..75ec0c6 100644 (file)
@@ -11,7 +11,6 @@
  */
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/if.h>
index cd191bb..0293843 100644 (file)
@@ -503,11 +503,11 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kzalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size + 1, GFP_KERNEL);
        if (!scon)
                return length;
 
-       tcon = kzalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size + 1, GFP_KERNEL);
        if (!tcon)
                goto out;
 
@@ -515,10 +515,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out2;
 
-       length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
+       length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
        if (length < 0)
                goto out2;
-       length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
+       length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
        if (length < 0)
                goto out2;
 
@@ -550,11 +550,11 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kzalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size + 1, GFP_KERNEL);
        if (!scon)
                return length;
 
-       tcon = kzalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size + 1, GFP_KERNEL);
        if (!tcon)
                goto out;
 
@@ -562,10 +562,10 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out2;
 
-       length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
+       length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
        if (length < 0)
                goto out2;
-       length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
+       length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
        if (length < 0)
                goto out2;
 
@@ -609,11 +609,11 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kzalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size + 1, GFP_KERNEL);
        if (!scon)
                return length;
 
-       tcon = kzalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size + 1, GFP_KERNEL);
        if (!tcon)
                goto out;
 
@@ -621,10 +621,10 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out2;
 
-       length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
+       length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
        if (length < 0)
                goto out2;
-       length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
+       length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
        if (length < 0)
                goto out2;
 
@@ -666,11 +666,11 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       con = kzalloc(size+1, GFP_KERNEL);
+       con = kzalloc(size + 1, GFP_KERNEL);
        if (!con)
                return length;
 
-       user = kzalloc(size+1, GFP_KERNEL);
+       user = kzalloc(size + 1, GFP_KERNEL);
        if (!user)
                goto out;
 
@@ -678,7 +678,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s", con, user) != 2)
                goto out2;
 
-       length = security_context_to_sid(con, strlen(con)+1, &sid);
+       length = security_context_to_sid(con, strlen(con) + 1, &sid);
        if (length < 0)
                goto out2;
 
@@ -727,11 +727,11 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
                return length;
 
        length = -ENOMEM;
-       scon = kzalloc(size+1, GFP_KERNEL);
+       scon = kzalloc(size + 1, GFP_KERNEL);
        if (!scon)
                return length;
 
-       tcon = kzalloc(size+1, GFP_KERNEL);
+       tcon = kzalloc(size + 1, GFP_KERNEL);
        if (!tcon)
                goto out;
 
@@ -739,10 +739,10 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
        if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
                goto out2;
 
-       length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
+       length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
        if (length < 0)
                goto out2;
-       length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
+       length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
        if (length < 0)
                goto out2;
 
@@ -1401,7 +1401,7 @@ static int sel_make_perm_files(char *objclass, int classvalue,
                }
                inode->i_fop = &sel_perm_ops;
                /* i+1 since perm values are 1-indexed */
-               inode->i_ino = sel_perm_to_ino(classvalue, i+1);
+               inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
                d_add(dentry, inode);
        }
 
@@ -1489,7 +1489,7 @@ static int sel_make_classes(void)
                goto out;
 
        /* +2 since classes are 1-indexed */
-       last_class_ino = sel_class_to_ino(nclasses+2);
+       last_class_ino = sel_class_to_ino(nclasses + 2);
 
        for (i = 0; i < nclasses; i++) {
                struct dentry *class_name_dir;
@@ -1506,7 +1506,7 @@ static int sel_make_classes(void)
                        goto out1;
 
                /* i+1 since class values are 1-indexed */
-               rc = sel_make_class_dir_entries(classes[i], i+1,
+               rc = sel_make_class_dir_entries(classes[i], i + 1,
                                class_name_dir);
                if (rc)
                        goto out1;
index 8da6a84..cd4f734 100644 (file)
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
 void avtab_cache_init(void);
 void avtab_cache_destroy(void);
 
-#define MAX_AVTAB_HASH_BITS 13
+#define MAX_AVTAB_HASH_BITS 11
 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
 #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
 #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
index 372b773..b4eff7a 100644 (file)
@@ -255,7 +255,7 @@ int mls_context_to_sid(struct policydb *pol,
 
        if (!pol->mls_enabled) {
                if (def_sid != SECSID_NULL && oldc)
-                       *scontext += strlen(*scontext)+1;
+                       *scontext += strlen(*scontext) + 1;
                return 0;
        }
 
index 23c6e53..c57802a 100644 (file)
@@ -40,7 +40,7 @@
 #define _DEBUG_HASHES
 
 #ifdef DEBUG_HASHES
-static char *symtab_name[SYM_NUM] = {
+static const char *symtab_name[SYM_NUM] = {
        "common prefixes",
        "classes",
        "roles",
@@ -156,12 +156,11 @@ static int roles_init(struct policydb *p)
                rc = -EINVAL;
                goto out_free_role;
        }
-       key = kmalloc(strlen(OBJECT_R)+1, GFP_KERNEL);
+       key = kstrdup(OBJECT_R, GFP_KERNEL);
        if (!key) {
                rc = -ENOMEM;
                goto out_free_role;
        }
-       strcpy(key, OBJECT_R);
        rc = hashtab_insert(p->p_roles.table, key, role);
        if (rc)
                goto out_free_key;
@@ -2195,7 +2194,7 @@ int policydb_read(struct policydb *p, void *fp)
                rangetr_hash_eval(p->range_tr);
        }
 
-       p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);
+       p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL);
        if (!p->type_attr_map)
                goto bad;
 
index cf27b3e..1de60ce 100644 (file)
@@ -274,15 +274,15 @@ static int constraint_expr_eval(struct context *scontext,
                case CEXPR_AND:
                        BUG_ON(sp < 1);
                        sp--;
-                       s[sp] &= s[sp+1];
+                       s[sp] &= s[sp + 1];
                        break;
                case CEXPR_OR:
                        BUG_ON(sp < 1);
                        sp--;
-                       s[sp] |= s[sp+1];
+                       s[sp] |= s[sp + 1];
                        break;
                case CEXPR_ATTR:
-                       if (sp == (CEXPR_MAXDEPTH-1))
+                       if (sp == (CEXPR_MAXDEPTH - 1))
                                return 0;
                        switch (e->attr) {
                        case CEXPR_USER:
@@ -1216,7 +1216,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
        *sid = SECSID_NULL;
 
        /* Copy the string so that we can modify the copy as we parse it. */
-       scontext2 = kmalloc(scontext_len+1, gfp_flags);
+       scontext2 = kmalloc(scontext_len + 1, gfp_flags);
        if (!scontext2)
                return -ENOMEM;
        memcpy(scontext2, scontext, scontext_len);
@@ -1760,22 +1760,28 @@ int security_load_policy(void *data, size_t len)
 
        if (!ss_initialized) {
                avtab_cache_init();
-               if (policydb_read(&policydb, fp)) {
+               rc = policydb_read(&policydb, fp);
+               if (rc) {
                        avtab_cache_destroy();
-                       return -EINVAL;
+                       return rc;
                }
-               if (selinux_set_mapping(&policydb, secclass_map,
-                                       &current_mapping,
-                                       &current_mapping_size)) {
+
+               rc = selinux_set_mapping(&policydb, secclass_map,
+                                        &current_mapping,
+                                        &current_mapping_size);
+               if (rc) {
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
-                       return -EINVAL;
+                       return rc;
                }
-               if (policydb_load_isids(&policydb, &sidtab)) {
+
+               rc = policydb_load_isids(&policydb, &sidtab);
+               if (rc) {
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
-                       return -EINVAL;
+                       return rc;
                }
+
                security_load_policycaps();
                ss_initialized = 1;
                seqno = ++latest_granting;
@@ -1791,8 +1797,9 @@ int security_load_policy(void *data, size_t len)
        sidtab_hash_eval(&sidtab, "sids");
 #endif
 
-       if (policydb_read(&newpolicydb, fp))
-               return -EINVAL;
+       rc = policydb_read(&newpolicydb, fp);
+       if (rc)
+               return rc;
 
        /* If switching between different policy types, log MLS status */
        if (policydb.mls_enabled && !newpolicydb.mls_enabled)
@@ -1807,8 +1814,8 @@ int security_load_policy(void *data, size_t len)
                return rc;
        }
 
-       if (selinux_set_mapping(&newpolicydb, secclass_map,
-                               &map, &map_size))
+       rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size);
+       if (rc)
                goto err;
 
        rc = security_preserve_bools(&newpolicydb);
@@ -1819,10 +1826,10 @@ int security_load_policy(void *data, size_t len)
 
        /* Clone the SID table. */
        sidtab_shutdown(&sidtab);
-       if (sidtab_map(&sidtab, clone_sid, &newsidtab)) {
-               rc = -ENOMEM;
+
+       rc = sidtab_map(&sidtab, clone_sid, &newsidtab);
+       if (rc)
                goto err;
-       }
 
        /*
         * Convert the internal representations of contexts
@@ -2101,9 +2108,9 @@ int security_get_user_sids(u32 fromsid,
 
        ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
                role = policydb.role_val_to_struct[i];
-               usercon.role = i+1;
+               usercon.role = i + 1;
                ebitmap_for_each_positive_bit(&role->types, tnode, j) {
-                       usercon.type = j+1;
+                       usercon.type = j + 1;
 
                        if (mls_setup_user_range(fromcon, user, &usercon))
                                continue;
index fdfeaa2..0f2fc48 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/pagemap.h>
 #include <linux/mount.h>
 #include <linux/stat.h>
-#include <linux/ext2_fs.h>
 #include <linux/kd.h>
 #include <asm/ioctls.h>
 #include <linux/ip.h>
@@ -1118,15 +1117,6 @@ static int smack_cred_prepare(struct cred *new, const struct cred *old,
        return 0;
 }
 
-/**
- * smack_cred_commit - commit new credentials
- * @new: the new credentials
- * @old: the original credentials
- */
-static void smack_cred_commit(struct cred *new, const struct cred *old)
-{
-}
-
 /**
  * smack_cred_transfer - Transfer the old credentials to the new credentials
  * @new: the new credentials
@@ -3121,7 +3111,6 @@ struct security_operations smack_ops = {
        .cred_alloc_blank =             smack_cred_alloc_blank,
        .cred_free =                    smack_cred_free,
        .cred_prepare =                 smack_cred_prepare,
-       .cred_commit =                  smack_cred_commit,
        .cred_transfer =                smack_cred_transfer,
        .kernel_act_as =                smack_kernel_act_as,
        .kernel_create_files_as =       smack_kernel_create_files_as,
index 60a9e20..4fb3903 100644 (file)
@@ -1 +1 @@
-obj-y = common.o realpath.o tomoyo.o domain.o file.o gc.o
+obj-y = common.o realpath.o tomoyo.o domain.o file.o gc.o path_group.o
index 975c45d..b5dbdc9 100644 (file)
@@ -75,6 +75,49 @@ static int tomoyo_read_control(struct file *file, char __user *buffer,
 static int tomoyo_write_control(struct file *file, const char __user *buffer,
                                const int buffer_len);
 
+/**
+ * tomoyo_parse_name_union - Parse a tomoyo_name_union.
+ *
+ * @filename: Name or name group.
+ * @ptr:      Pointer to "struct tomoyo_name_union".
+ *
+ * Returns true on success, false otherwise.
+ */
+bool tomoyo_parse_name_union(const char *filename,
+                            struct tomoyo_name_union *ptr)
+{
+       if (!tomoyo_is_correct_path(filename, 0, 0, 0))
+               return false;
+       if (filename[0] == '@') {
+               ptr->group = tomoyo_get_path_group(filename + 1);
+               ptr->is_group = true;
+               return ptr->group != NULL;
+       }
+       ptr->filename = tomoyo_get_name(filename);
+       ptr->is_group = false;
+       return ptr->filename != NULL;
+}
+
+/**
+ * tomoyo_print_name_union - Print a tomoyo_name_union.
+ *
+ * @head: Pointer to "struct tomoyo_io_buffer".
+ * @ptr:  Pointer to "struct tomoyo_name_union".
+ *
+ * Returns true on success, false otherwise.
+ */
+static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head,
+                                const struct tomoyo_name_union *ptr)
+{
+       int pos = head->read_avail;
+       if (pos && head->read_buf[pos - 1] == ' ')
+               head->read_avail--;
+       if (ptr->is_group)
+               return tomoyo_io_printf(head, " @%s",
+                                       ptr->group->group_name->name);
+       return tomoyo_io_printf(head, " %s", ptr->filename->name);
+}
+
 /**
  * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value.
  *
@@ -171,6 +214,33 @@ static void tomoyo_normalize_line(unsigned char *buffer)
        *dp = '\0';
 }
 
+/**
+ * tomoyo_tokenize - Tokenize string.
+ *
+ * @buffer: The line to tokenize.
+ * @w:      Pointer to "char *".
+ * @size:   Sizeof @w .
+ *
+ * Returns true on success, false otherwise.
+ */
+bool tomoyo_tokenize(char *buffer, char *w[], size_t size)
+{
+       int count = size / sizeof(char *);
+       int i;
+       for (i = 0; i < count; i++)
+               w[i] = "";
+       for (i = 0; i < count; i++) {
+               char *cp = strchr(buffer, ' ');
+               if (cp)
+                       *cp = '\0';
+               w[i] = buffer;
+               if (!cp)
+                       break;
+               buffer = cp + 1;
+       }
+       return i < count || !*buffer;
+}
+
 /**
  * tomoyo_is_correct_path - Validate a pathname.
  * @filename:     The pathname to check.
@@ -874,17 +944,17 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
 static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
                                                                int profile)
 {
-       static DEFINE_MUTEX(lock);
        struct tomoyo_profile *ptr = NULL;
        int i;
 
        if (profile >= TOMOYO_MAX_PROFILES)
                return NULL;
-       mutex_lock(&lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               return NULL;
        ptr = tomoyo_profile_ptr[profile];
        if (ptr)
                goto ok;
-       ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
+       ptr = kmalloc(sizeof(*ptr), GFP_NOFS);
        if (!tomoyo_memory_ok(ptr)) {
                kfree(ptr);
                ptr = NULL;
@@ -895,7 +965,7 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
        mb(); /* Avoid out-of-order execution. */
        tomoyo_profile_ptr[profile] = ptr;
  ok:
-       mutex_unlock(&lock);
+       mutex_unlock(&tomoyo_policy_lock);
        return ptr;
 }
 
@@ -1071,44 +1141,42 @@ LIST_HEAD(tomoyo_policy_manager_list);
 static int tomoyo_update_manager_entry(const char *manager,
                                       const bool is_delete)
 {
-       struct tomoyo_policy_manager_entry *entry = NULL;
        struct tomoyo_policy_manager_entry *ptr;
-       const struct tomoyo_path_info *saved_manager;
+       struct tomoyo_policy_manager_entry e = { };
        int error = is_delete ? -ENOENT : -ENOMEM;
-       bool is_domain = false;
 
        if (tomoyo_is_domain_def(manager)) {
                if (!tomoyo_is_correct_domain(manager))
                        return -EINVAL;
-               is_domain = true;
+               e.is_domain = true;
        } else {
                if (!tomoyo_is_correct_path(manager, 1, -1, -1))
                        return -EINVAL;
        }
-       saved_manager = tomoyo_get_name(manager);
-       if (!saved_manager)
+       e.manager = tomoyo_get_name(manager);
+       if (!e.manager)
                return -ENOMEM;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
        list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
-               if (ptr->manager != saved_manager)
+               if (ptr->manager != e.manager)
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->manager = saved_manager;
-               saved_manager = NULL;
-               entry->is_domain = is_domain;
-               list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_policy_manager_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list,
+                                         &tomoyo_policy_manager_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
-       tomoyo_put_name(saved_manager);
-       kfree(entry);
+ out:
+       tomoyo_put_name(e.manager);
        return error;
 }
 
@@ -1287,7 +1355,8 @@ static int tomoyo_delete_domain(char *domainname)
 
        name.name = domainname;
        tomoyo_fill_path_info(&name);
-       mutex_lock(&tomoyo_policy_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               return 0;
        /* Is there an active domain? */
        list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
                /* Never delete tomoyo_kernel_domain */
@@ -1369,23 +1438,20 @@ static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head,
 {
        int pos;
        u8 bit;
-       const char *atmark = "";
-       const char *filename;
        const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16);
 
-       filename = ptr->filename->name;
        for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
-               const char *msg;
                if (!(perm & (1 << bit)))
                        continue;
                /* Print "read/write" instead of "read" and "write". */
                if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE)
                    && (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
                        continue;
-               msg = tomoyo_path2keyword(bit);
                pos = head->read_avail;
-               if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg,
-                                     atmark, filename))
+               if (!tomoyo_io_printf(head, "allow_%s ",
+                                     tomoyo_path2keyword(bit)) ||
+                   !tomoyo_print_name_union(head, &ptr->name) ||
+                   !tomoyo_io_printf(head, "\n"))
                        goto out;
        }
        head->read_bit = 0;
@@ -1408,23 +1474,18 @@ static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head,
                                   struct tomoyo_path2_acl *ptr)
 {
        int pos;
-       const char *atmark1 = "";
-       const char *atmark2 = "";
-       const char *filename1;
-       const char *filename2;
        const u8 perm = ptr->perm;
        u8 bit;
 
-       filename1 = ptr->filename1->name;
-       filename2 = ptr->filename2->name;
        for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
-               const char *msg;
                if (!(perm & (1 << bit)))
                        continue;
-               msg = tomoyo_path22keyword(bit);
                pos = head->read_avail;
-               if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg,
-                                     atmark1, filename1, atmark2, filename2))
+               if (!tomoyo_io_printf(head, "allow_%s ",
+                                     tomoyo_path22keyword(bit)) ||
+                   !tomoyo_print_name_union(head, &ptr->name1) ||
+                   !tomoyo_print_name_union(head, &ptr->name2) ||
+                   !tomoyo_io_printf(head, "\n"))
                        goto out;
        }
        head->read_bit = 0;
@@ -1687,6 +1748,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
                return tomoyo_write_pattern_policy(data, is_delete);
        if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE))
                return tomoyo_write_no_rewrite_policy(data, is_delete);
+       if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP))
+               return tomoyo_write_path_group_policy(data, is_delete);
        return -EINVAL;
 }
 
@@ -1743,6 +1806,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
                        head->read_var2 = NULL;
                        head->read_step = 9;
                case 9:
+                       if (!tomoyo_read_path_group_policy(head))
+                               break;
+                       head->read_var1 = NULL;
+                       head->read_var2 = NULL;
+                       head->read_step = 10;
+               case 10:
                        head->read_eof = true;
                        break;
                default:
@@ -1886,7 +1955,7 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
  */
 static int tomoyo_open_control(const u8 type, struct file *file)
 {
-       struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);
+       struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS);
 
        if (!head)
                return -ENOMEM;
@@ -1947,7 +2016,7 @@ static int tomoyo_open_control(const u8 type, struct file *file)
        } else {
                if (!head->readbuf_size)
                        head->readbuf_size = 4096 * 2;
-               head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);
+               head->read_buf = kzalloc(head->readbuf_size, GFP_NOFS);
                if (!head->read_buf) {
                        kfree(head);
                        return -ENOMEM;
@@ -1961,7 +2030,7 @@ static int tomoyo_open_control(const u8 type, struct file *file)
                head->write = NULL;
        } else if (head->write) {
                head->writebuf_size = 4096 * 2;
-               head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);
+               head->write_buf = kzalloc(head->writebuf_size, GFP_NOFS);
                if (!head->write_buf) {
                        kfree(head->read_buf);
                        kfree(head);
index 67bd22d..9f1ae5e 100644 (file)
@@ -54,6 +54,7 @@ struct linux_binprm;
 #define TOMOYO_KEYWORD_KEEP_DOMAIN               "keep_domain "
 #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN      "no_initialize_domain "
 #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN            "no_keep_domain "
+#define TOMOYO_KEYWORD_PATH_GROUP                "path_group "
 #define TOMOYO_KEYWORD_SELECT                    "select "
 #define TOMOYO_KEYWORD_USE_PROFILE               "use_profile "
 #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ  "ignore_global_allow_read"
@@ -204,6 +205,27 @@ struct tomoyo_path_info_with_data {
        char barrier2[16]; /* Safeguard for overrun. */
 };
 
+struct tomoyo_name_union {
+       const struct tomoyo_path_info *filename;
+       struct tomoyo_path_group *group;
+       u8 is_group;
+};
+
+/* Structure for "path_group" directive. */
+struct tomoyo_path_group {
+       struct list_head list;
+       const struct tomoyo_path_info *group_name;
+       struct list_head member_list;
+       atomic_t users;
+};
+
+/* Structure for "path_group" directive. */
+struct tomoyo_path_group_member {
+       struct list_head list;
+       bool is_deleted;
+       const struct tomoyo_path_info *member_name;
+};
+
 /*
  * tomoyo_acl_info is a structure which is used for holding
  *
@@ -274,7 +296,7 @@ struct tomoyo_domain_info {
  *
  *  (1) "head" which is a "struct tomoyo_acl_info".
  *  (2) "perm" which is a bitmask of permitted operations.
- *  (3) "filename" is the pathname.
+ *  (3) "name" is the pathname.
  *
  * Directives held by this structure are "allow_read/write", "allow_execute",
  * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
@@ -287,8 +309,7 @@ struct tomoyo_path_acl {
        struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
        u8 perm_high;
        u16 perm;
-       /* Pointer to single pathname. */
-       const struct tomoyo_path_info *filename;
+       struct tomoyo_name_union name;
 };
 
 /*
@@ -298,8 +319,8 @@ struct tomoyo_path_acl {
  *
  *  (1) "head" which is a "struct tomoyo_acl_info".
  *  (2) "perm" which is a bitmask of permitted operations.
- *  (3) "filename1" is the source/old pathname.
- *  (4) "filename2" is the destination/new pathname.
+ *  (3) "name1" is the source/old pathname.
+ *  (4) "name2" is the destination/new pathname.
  *
  * Directives held by this structure are "allow_rename", "allow_link" and
  * "allow_pivot_root".
@@ -307,10 +328,8 @@ struct tomoyo_path_acl {
 struct tomoyo_path2_acl {
        struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */
        u8 perm;
-       /* Pointer to single pathname. */
-       const struct tomoyo_path_info *filename1;
-       /* Pointer to single pathname. */
-       const struct tomoyo_path_info *filename2;
+       struct tomoyo_name_union name1;
+       struct tomoyo_name_union name2;
 };
 
 /*
@@ -514,6 +533,9 @@ struct tomoyo_policy_manager_entry {
 
 /********** Function prototypes. **********/
 
+/* Check whether the given name matches the given name_union. */
+bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
+                              const struct tomoyo_name_union *ptr);
 /* Check whether the domain has too many ACL entries to hold. */
 bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain);
 /* Transactional sprintf() for policy dump. */
@@ -526,6 +548,12 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
                            const s8 pattern_type, const s8 end_type);
 /* Check whether the token can be a domainname. */
 bool tomoyo_is_domain_def(const unsigned char *buffer);
+bool tomoyo_parse_name_union(const char *filename,
+                            struct tomoyo_name_union *ptr);
+/* Check whether the given filename matches the given path_group. */
+bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
+                              const struct tomoyo_path_group *group,
+                              const bool may_use_pattern);
 /* Check whether the given filename matches the given pattern. */
 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
                                 const struct tomoyo_path_info *pattern);
@@ -540,10 +568,14 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head);
 bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head);
 /* Read "file_pattern" entry in exception policy. */
 bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head);
+/* Read "path_group" entry in exception policy. */
+bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head);
 /* Read "allow_read" entry in exception policy. */
 bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head);
 /* Read "deny_rewrite" entry in exception policy. */
 bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head);
+/* Tokenize a line. */
+bool tomoyo_tokenize(char *buffer, char *w[], size_t size);
 /* Write domain policy violation warning message to console? */
 bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
 /* Convert double path operation to operation name. */
@@ -580,12 +612,18 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete);
 int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete);
 /* Create "file_pattern" entry in exception policy. */
 int tomoyo_write_pattern_policy(char *data, const bool is_delete);
+/* Create "path_group" entry in exception policy. */
+int tomoyo_write_path_group_policy(char *data, const bool is_delete);
 /* Find a domain by the given name. */
 struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname);
 /* Find or create a domain by the given name. */
 struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
                                                            domainname,
                                                            const u8 profile);
+
+/* Allocate memory for "struct tomoyo_path_group". */
+struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name);
+
 /* Check mode for specified functionality. */
 unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
                                const u8 index);
@@ -616,6 +654,7 @@ char *tomoyo_realpath_from_path(struct path *path);
 
 /* Check memory quota. */
 bool tomoyo_memory_ok(void *ptr);
+void *tomoyo_commit_ok(void *data, const unsigned int size);
 
 /*
  * Keep the given name on the RAM.
@@ -641,6 +680,9 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
 int tomoyo_check_rewrite_permission(struct file *filp);
 int tomoyo_find_next_domain(struct linux_binprm *bprm);
 
+/* Drop refcount on tomoyo_name_union. */
+void tomoyo_put_name_union(struct tomoyo_name_union *ptr);
+
 /* Run garbage collector. */
 void tomoyo_run_gc(void);
 
@@ -654,6 +696,7 @@ extern struct srcu_struct tomoyo_ss;
 /* The list for "struct tomoyo_domain_info". */
 extern struct list_head tomoyo_domain_list;
 
+extern struct list_head tomoyo_path_group_list;
 extern struct list_head tomoyo_domain_initializer_list;
 extern struct list_head tomoyo_domain_keeper_list;
 extern struct list_head tomoyo_alias_list;
@@ -662,7 +705,6 @@ extern struct list_head tomoyo_pattern_list;
 extern struct list_head tomoyo_no_rewrite_list;
 extern struct list_head tomoyo_policy_manager_list;
 extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
-extern struct mutex tomoyo_name_list_lock;
 
 /* Lock for protecting policy. */
 extern struct mutex tomoyo_policy_lock;
@@ -725,6 +767,12 @@ static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
        }
 }
 
+static inline void tomoyo_put_path_group(struct tomoyo_path_group *group)
+{
+       if (group)
+               atomic_dec(&group->users);
+}
+
 static inline struct tomoyo_domain_info *tomoyo_domain(void)
 {
        return current_cred()->security;
@@ -736,6 +784,59 @@ static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
        return task_cred_xxx(task, security);
 }
 
+static inline bool tomoyo_is_same_acl_head(const struct tomoyo_acl_info *p1,
+                                          const struct tomoyo_acl_info *p2)
+{
+       return p1->type == p2->type;
+}
+
+static inline bool tomoyo_is_same_name_union
+(const struct tomoyo_name_union *p1, const struct tomoyo_name_union *p2)
+{
+       return p1->filename == p2->filename && p1->group == p2->group &&
+               p1->is_group == p2->is_group;
+}
+
+static inline bool tomoyo_is_same_path_acl(const struct tomoyo_path_acl *p1,
+                                          const struct tomoyo_path_acl *p2)
+{
+       return tomoyo_is_same_acl_head(&p1->head, &p2->head) &&
+               tomoyo_is_same_name_union(&p1->name, &p2->name);
+}
+
+static inline bool tomoyo_is_same_path2_acl(const struct tomoyo_path2_acl *p1,
+                                           const struct tomoyo_path2_acl *p2)
+{
+       return tomoyo_is_same_acl_head(&p1->head, &p2->head) &&
+               tomoyo_is_same_name_union(&p1->name1, &p2->name1) &&
+               tomoyo_is_same_name_union(&p1->name2, &p2->name2);
+}
+
+static inline bool tomoyo_is_same_domain_initializer_entry
+(const struct tomoyo_domain_initializer_entry *p1,
+ const struct tomoyo_domain_initializer_entry *p2)
+{
+       return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
+               && p1->domainname == p2->domainname
+               && p1->program == p2->program;
+}
+
+static inline bool tomoyo_is_same_domain_keeper_entry
+(const struct tomoyo_domain_keeper_entry *p1,
+ const struct tomoyo_domain_keeper_entry *p2)
+{
+       return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
+               && p1->domainname == p2->domainname
+               && p1->program == p2->program;
+}
+
+static inline bool tomoyo_is_same_alias_entry
+(const struct tomoyo_alias_entry *p1, const struct tomoyo_alias_entry *p2)
+{
+       return p1->original_name == p2->original_name &&
+               p1->aliased_name == p2->aliased_name;
+}
+
 /**
  * list_for_each_cookie - iterate over a list with cookie.
  * @pos:        the &struct list_head to use as a loop cursor.
index acb8c39..cd8ba44 100644 (file)
@@ -130,57 +130,47 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
                                                  const bool is_not,
                                                  const bool is_delete)
 {
-       struct tomoyo_domain_initializer_entry *entry = NULL;
        struct tomoyo_domain_initializer_entry *ptr;
-       const struct tomoyo_path_info *saved_program = NULL;
-       const struct tomoyo_path_info *saved_domainname = NULL;
+       struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
        int error = is_delete ? -ENOENT : -ENOMEM;
-       bool is_last_name = false;
 
        if (!tomoyo_is_correct_path(program, 1, -1, -1))
                return -EINVAL; /* No patterns allowed. */
        if (domainname) {
                if (!tomoyo_is_domain_def(domainname) &&
                    tomoyo_is_correct_path(domainname, 1, -1, -1))
-                       is_last_name = true;
+                       e.is_last_name = true;
                else if (!tomoyo_is_correct_domain(domainname))
                        return -EINVAL;
-               saved_domainname = tomoyo_get_name(domainname);
-               if (!saved_domainname)
+               e.domainname = tomoyo_get_name(domainname);
+               if (!e.domainname)
                        goto out;
        }
-       saved_program = tomoyo_get_name(program);
-       if (!saved_program)
+       e.program = tomoyo_get_name(program);
+       if (!e.program)
+               goto out;
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
                goto out;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
        list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
-               if (ptr->is_not != is_not ||
-                   ptr->domainname != saved_domainname ||
-                   ptr->program != saved_program)
+               if (!tomoyo_is_same_domain_initializer_entry(ptr, &e))
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->domainname = saved_domainname;
-               saved_domainname = NULL;
-               entry->program = saved_program;
-               saved_program = NULL;
-               entry->is_not = is_not;
-               entry->is_last_name = is_last_name;
-               list_add_tail_rcu(&entry->list,
-                                 &tomoyo_domain_initializer_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_domain_initializer_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list,
+                                         &tomoyo_domain_initializer_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
  out:
-       tomoyo_put_name(saved_domainname);
-       tomoyo_put_name(saved_program);
-       kfree(entry);
+       tomoyo_put_name(e.domainname);
+       tomoyo_put_name(e.program);
        return error;
 }
 
@@ -350,56 +340,47 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
                                             const bool is_not,
                                             const bool is_delete)
 {
-       struct tomoyo_domain_keeper_entry *entry = NULL;
        struct tomoyo_domain_keeper_entry *ptr;
-       const struct tomoyo_path_info *saved_domainname = NULL;
-       const struct tomoyo_path_info *saved_program = NULL;
+       struct tomoyo_domain_keeper_entry e = { .is_not = is_not };
        int error = is_delete ? -ENOENT : -ENOMEM;
-       bool is_last_name = false;
 
        if (!tomoyo_is_domain_def(domainname) &&
            tomoyo_is_correct_path(domainname, 1, -1, -1))
-               is_last_name = true;
+               e.is_last_name = true;
        else if (!tomoyo_is_correct_domain(domainname))
                return -EINVAL;
        if (program) {
                if (!tomoyo_is_correct_path(program, 1, -1, -1))
                        return -EINVAL;
-               saved_program = tomoyo_get_name(program);
-               if (!saved_program)
+               e.program = tomoyo_get_name(program);
+               if (!e.program)
                        goto out;
        }
-       saved_domainname = tomoyo_get_name(domainname);
-       if (!saved_domainname)
+       e.domainname = tomoyo_get_name(domainname);
+       if (!e.domainname)
+               goto out;
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
                goto out;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
        list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
-               if (ptr->is_not != is_not ||
-                   ptr->domainname != saved_domainname ||
-                   ptr->program != saved_program)
+               if (!tomoyo_is_same_domain_keeper_entry(ptr, &e))
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->domainname = saved_domainname;
-               saved_domainname = NULL;
-               entry->program = saved_program;
-               saved_program = NULL;
-               entry->is_not = is_not;
-               entry->is_last_name = is_last_name;
-               list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_domain_keeper_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list,
+                                         &tomoyo_domain_keeper_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
  out:
-       tomoyo_put_name(saved_domainname);
-       tomoyo_put_name(saved_program);
-       kfree(entry);
+       tomoyo_put_name(e.domainname);
+       tomoyo_put_name(e.program);
        return error;
 }
 
@@ -551,44 +532,38 @@ static int tomoyo_update_alias_entry(const char *original_name,
                                     const char *aliased_name,
                                     const bool is_delete)
 {
-       struct tomoyo_alias_entry *entry = NULL;
        struct tomoyo_alias_entry *ptr;
-       const struct tomoyo_path_info *saved_original_name;
-       const struct tomoyo_path_info *saved_aliased_name;
+       struct tomoyo_alias_entry e = { };
        int error = is_delete ? -ENOENT : -ENOMEM;
 
        if (!tomoyo_is_correct_path(original_name, 1, -1, -1) ||
            !tomoyo_is_correct_path(aliased_name, 1, -1, -1))
                return -EINVAL; /* No patterns allowed. */
-       saved_original_name = tomoyo_get_name(original_name);
-       saved_aliased_name = tomoyo_get_name(aliased_name);
-       if (!saved_original_name || !saved_aliased_name)
+       e.original_name = tomoyo_get_name(original_name);
+       e.aliased_name = tomoyo_get_name(aliased_name);
+       if (!e.original_name || !e.aliased_name)
+               goto out;
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
                goto out;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
        list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
-               if (ptr->original_name != saved_original_name ||
-                   ptr->aliased_name != saved_aliased_name)
+               if (!tomoyo_is_same_alias_entry(ptr, &e))
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->original_name = saved_original_name;
-               saved_original_name = NULL;
-               entry->aliased_name = saved_aliased_name;
-               saved_aliased_name = NULL;
-               list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_alias_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
  out:
-       tomoyo_put_name(saved_original_name);
-       tomoyo_put_name(saved_aliased_name);
-       kfree(entry);
+       tomoyo_put_name(e.original_name);
+       tomoyo_put_name(e.aliased_name);
        return error;
 }
 
@@ -656,7 +631,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
                                                            const u8 profile)
 {
        struct tomoyo_domain_info *entry;
-       struct tomoyo_domain_info *domain;
+       struct tomoyo_domain_info *domain = NULL;
        const struct tomoyo_path_info *saved_domainname;
        bool found = false;
 
@@ -665,8 +640,9 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
        saved_domainname = tomoyo_get_name(domainname);
        if (!saved_domainname)
                return NULL;
-       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
+       entry = kzalloc(sizeof(*entry), GFP_NOFS);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
        list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
                if (domain->is_deleted ||
                    tomoyo_pathcmp(saved_domainname, domain->domainname))
@@ -685,6 +661,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
                found = true;
        }
        mutex_unlock(&tomoyo_policy_lock);
+ out:
        tomoyo_put_name(saved_domainname);
        kfree(entry);
        return found ? domain : NULL;
@@ -705,7 +682,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
         * This function assumes that the size of buffer returned by
         * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
         */
-       struct tomoyo_page_buffer *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+       struct tomoyo_page_buffer *tmp = kzalloc(sizeof(*tmp), GFP_NOFS);
        struct tomoyo_domain_info *old_domain = tomoyo_domain();
        struct tomoyo_domain_info *domain = NULL;
        const char *old_domain_name = old_domain->domainname->name;
index 6f3fe76..1c6f823 100644 (file)
@@ -45,6 +45,37 @@ static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
        [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
 };
 
+void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
+{
+       if (!ptr)
+               return;
+       if (ptr->is_group)
+               tomoyo_put_path_group(ptr->group);
+       else
+               tomoyo_put_name(ptr->filename);
+}
+
+bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
+                              const struct tomoyo_name_union *ptr)
+{
+       if (ptr->is_group)
+               return tomoyo_path_matches_group(name, ptr->group, 1);
+       return tomoyo_path_matches_pattern(name, ptr->filename);
+}
+
+static bool tomoyo_compare_name_union_pattern(const struct tomoyo_path_info
+                                             *name,
+                                             const struct tomoyo_name_union
+                                             *ptr, const bool may_use_pattern)
+{
+       if (ptr->is_group)
+               return tomoyo_path_matches_group(name, ptr->group,
+                                                may_use_pattern);
+       if (may_use_pattern || !ptr->filename->is_patterned)
+               return tomoyo_path_matches_pattern(name, ptr->filename);
+       return false;
+}
+
 /**
  * tomoyo_path2keyword - Get the name of single path operation.
  *
@@ -100,7 +131,7 @@ static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
 {
        int error;
        struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf),
-                                                        GFP_KERNEL);
+                                                        GFP_NOFS);
 
        if (!buf)
                return NULL;
@@ -164,36 +195,36 @@ LIST_HEAD(tomoyo_globally_readable_list);
 static int tomoyo_update_globally_readable_entry(const char *filename,
                                                 const bool is_delete)
 {
-       struct tomoyo_globally_readable_file_entry *entry = NULL;
        struct tomoyo_globally_readable_file_entry *ptr;
-       const struct tomoyo_path_info *saved_filename;
+       struct tomoyo_globally_readable_file_entry e = { };
        int error = is_delete ? -ENOENT : -ENOMEM;
 
        if (!tomoyo_is_correct_path(filename, 1, 0, -1))
                return -EINVAL;
-       saved_filename = tomoyo_get_name(filename);
-       if (!saved_filename)
+       e.filename = tomoyo_get_name(filename);
+       if (!e.filename)
                return -ENOMEM;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
        list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
-               if (ptr->filename != saved_filename)
+               if (ptr->filename != e.filename)
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->filename = saved_filename;
-               saved_filename = NULL;
-               list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_globally_readable_file_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list,
+                                         &tomoyo_globally_readable_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
-       tomoyo_put_name(saved_filename);
-       kfree(entry);
+ out:
+       tomoyo_put_name(e.filename);
        return error;
 }
 
@@ -311,37 +342,34 @@ LIST_HEAD(tomoyo_pattern_list);
 static int tomoyo_update_file_pattern_entry(const char *pattern,
                                            const bool is_delete)
 {
-       struct tomoyo_pattern_entry *entry = NULL;
        struct tomoyo_pattern_entry *ptr;
-       const struct tomoyo_path_info *saved_pattern;
+       struct tomoyo_pattern_entry e = { .pattern = tomoyo_get_name(pattern) };
        int error = is_delete ? -ENOENT : -ENOMEM;
 
-       saved_pattern = tomoyo_get_name(pattern);
-       if (!saved_pattern)
+       if (!e.pattern)
                return error;
-       if (!saved_pattern->is_patterned)
+       if (!e.pattern->is_patterned)
+               goto out;
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
                goto out;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
        list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
-               if (saved_pattern != ptr->pattern)
+               if (e.pattern != ptr->pattern)
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->pattern = saved_pattern;
-               saved_pattern = NULL;
-               list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_pattern_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
  out:
-       kfree(entry);
-       tomoyo_put_name(saved_pattern);
+       tomoyo_put_name(e.pattern);
        return error;
 }
 
@@ -464,36 +492,36 @@ LIST_HEAD(tomoyo_no_rewrite_list);
 static int tomoyo_update_no_rewrite_entry(const char *pattern,
                                          const bool is_delete)
 {
-       struct tomoyo_no_rewrite_entry *entry = NULL;
        struct tomoyo_no_rewrite_entry *ptr;
-       const struct tomoyo_path_info *saved_pattern;
+       struct tomoyo_no_rewrite_entry e = { };
        int error = is_delete ? -ENOENT : -ENOMEM;
 
        if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
                return -EINVAL;
-       saved_pattern = tomoyo_get_name(pattern);
-       if (!saved_pattern)
+       e.pattern = tomoyo_get_name(pattern);
+       if (!e.pattern)
                return error;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
        list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
-               if (ptr->pattern != saved_pattern)
+               if (ptr->pattern != e.pattern)
                        continue;
                ptr->is_deleted = is_delete;
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->pattern = saved_pattern;
-               saved_pattern = NULL;
-               list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_no_rewrite_entry *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list,
+                                         &tomoyo_no_rewrite_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
-       tomoyo_put_name(saved_pattern);
-       kfree(entry);
+ out:
+       tomoyo_put_name(e.pattern);
        return error;
 }
 
@@ -640,13 +668,9 @@ static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain,
                        if (!(acl->perm_high & (perm >> 16)))
                                continue;
                }
-               if (may_use_pattern || !acl->filename->is_patterned) {
-                       if (!tomoyo_path_matches_pattern(filename,
-                                                        acl->filename))
-                               continue;
-               } else {
+               if (!tomoyo_compare_name_union_pattern(filename, &acl->name,
+                                                       may_use_pattern))
                        continue;
-               }
                error = 0;
                break;
        }
@@ -805,70 +829,64 @@ static int tomoyo_update_path_acl(const u8 type, const char *filename,
                                  struct tomoyo_domain_info *const domain,
                                  const bool is_delete)
 {
-       static const u32 rw_mask =
+       static const u32 tomoyo_rw_mask =
                (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
-       const struct tomoyo_path_info *saved_filename;
+       const u32 perm = 1 << type;
        struct tomoyo_acl_info *ptr;
-       struct tomoyo_path_acl *entry = NULL;
+       struct tomoyo_path_acl e = {
+               .head.type = TOMOYO_TYPE_PATH_ACL,
+               .perm_high = perm >> 16,
+               .perm = perm
+       };
        int error = is_delete ? -ENOENT : -ENOMEM;
-       const u32 perm = 1 << type;
 
+       if (type == TOMOYO_TYPE_READ_WRITE)
+               e.perm |= tomoyo_rw_mask;
        if (!domain)
                return -EINVAL;
-       if (!tomoyo_is_correct_path(filename, 0, 0, 0))
+       if (!tomoyo_parse_name_union(filename, &e.name))
                return -EINVAL;
-       saved_filename = tomoyo_get_name(filename);
-       if (!saved_filename)
-               return -ENOMEM;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
        list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
                struct tomoyo_path_acl *acl =
                        container_of(ptr, struct tomoyo_path_acl, head);
-               if (ptr->type != TOMOYO_TYPE_PATH_ACL)
-                       continue;
-               if (acl->filename != saved_filename)
+               if (!tomoyo_is_same_path_acl(acl, &e))
                        continue;
                if (is_delete) {
                        if (perm <= 0xFFFF)
                                acl->perm &= ~perm;
                        else
                                acl->perm_high &= ~(perm >> 16);
-                       if ((acl->perm & rw_mask) != rw_mask)
+                       if ((acl->perm & tomoyo_rw_mask) != tomoyo_rw_mask)
                                acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
                        else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
-                               acl->perm &= ~rw_mask;
+                               acl->perm &= ~tomoyo_rw_mask;
                } else {
                        if (perm <= 0xFFFF)
                                acl->perm |= perm;
                        else
                                acl->perm_high |= (perm >> 16);
-                       if ((acl->perm & rw_mask) == rw_mask)
+                       if ((acl->perm & tomoyo_rw_mask) == tomoyo_rw_mask)
                                acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
                        else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
-                               acl->perm |= rw_mask;
+                               acl->perm |= tomoyo_rw_mask;
                }
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->head.type = TOMOYO_TYPE_PATH_ACL;
-               if (perm <= 0xFFFF)
-                       entry->perm = perm;
-               else
-                       entry->perm_high = (perm >> 16);
-               if (perm == (1 << TOMOYO_TYPE_READ_WRITE))
-                       entry->perm |= rw_mask;
-               entry->filename = saved_filename;
-               saved_filename = NULL;
-               list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_path_acl *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->head.list,
+                                         &domain->acl_info_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
-       kfree(entry);
-       tomoyo_put_name(saved_filename);
+ out:
+       tomoyo_put_name_union(&e.name);
        return error;
 }
 
@@ -890,32 +908,25 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
                                   struct tomoyo_domain_info *const domain,
                                   const bool is_delete)
 {
-       const struct tomoyo_path_info *saved_filename1;
-       const struct tomoyo_path_info *saved_filename2;
+       const u8 perm = 1 << type;
+       struct tomoyo_path2_acl e = {
+               .head.type = TOMOYO_TYPE_PATH2_ACL,
+               .perm = perm
+       };
        struct tomoyo_acl_info *ptr;
-       struct tomoyo_path2_acl *entry = NULL;
        int error = is_delete ? -ENOENT : -ENOMEM;
-       const u8 perm = 1 << type;
 
        if (!domain)
                return -EINVAL;
-       if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
-           !tomoyo_is_correct_path(filename2, 0, 0, 0))
-               return -EINVAL;
-       saved_filename1 = tomoyo_get_name(filename1);
-       saved_filename2 = tomoyo_get_name(filename2);
-       if (!saved_filename1 || !saved_filename2)
+       if (!tomoyo_parse_name_union(filename1, &e.name1) ||
+           !tomoyo_parse_name_union(filename2, &e.name2))
+               goto out;
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
                goto out;
-       if (!is_delete)
-               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
-       mutex_lock(&tomoyo_policy_lock);
        list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
                struct tomoyo_path2_acl *acl =
                        container_of(ptr, struct tomoyo_path2_acl, head);
-               if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
-                       continue;
-               if (acl->filename1 != saved_filename1 ||
-                   acl->filename2 != saved_filename2)
+               if (!tomoyo_is_same_path2_acl(acl, &e))
                        continue;
                if (is_delete)
                        acl->perm &= ~perm;
@@ -924,22 +935,19 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
                error = 0;
                break;
        }
-       if (!is_delete && error && tomoyo_memory_ok(entry)) {
-               entry->head.type = TOMOYO_TYPE_PATH2_ACL;
-               entry->perm = perm;
-               entry->filename1 = saved_filename1;
-               saved_filename1 = NULL;
-               entry->filename2 = saved_filename2;
-               saved_filename2 = NULL;
-               list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
-               entry = NULL;
-               error = 0;
+       if (!is_delete && error) {
+               struct tomoyo_path2_acl *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->head.list,
+                                         &domain->acl_info_list);
+                       error = 0;
+               }
        }
        mutex_unlock(&tomoyo_policy_lock);
  out:
-       tomoyo_put_name(saved_filename1);
-       tomoyo_put_name(saved_filename2);
-       kfree(entry);
+       tomoyo_put_name_union(&e.name1);
+       tomoyo_put_name_union(&e.name2);
        return error;
 }
 
@@ -992,9 +1000,9 @@ static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain,
                acl = container_of(ptr, struct tomoyo_path2_acl, head);
                if (!(acl->perm & perm))
                        continue;
-               if (!tomoyo_path_matches_pattern(filename1, acl->filename1))
+               if (!tomoyo_compare_name_union(filename1, &acl->name1))
                        continue;
-               if (!tomoyo_path_matches_pattern(filename2, acl->filename2))
+               if (!tomoyo_compare_name_union(filename2, &acl->name2))
                        continue;
                error = 0;
                break;
index d9ad35b..b9cc71b 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/slab.h>
 
 enum tomoyo_gc_id {
+       TOMOYO_ID_PATH_GROUP,
+       TOMOYO_ID_PATH_GROUP_MEMBER,
        TOMOYO_ID_DOMAIN_INITIALIZER,
        TOMOYO_ID_DOMAIN_KEEPER,
        TOMOYO_ID_ALIAS,
@@ -91,15 +93,15 @@ static void tomoyo_del_acl(struct tomoyo_acl_info *acl)
                {
                        struct tomoyo_path_acl *entry
                                = container_of(acl, typeof(*entry), head);
-                       tomoyo_put_name(entry->filename);
+                       tomoyo_put_name_union(&entry->name);
                }
                break;
        case TOMOYO_TYPE_PATH2_ACL:
                {
                        struct tomoyo_path2_acl *entry
                                = container_of(acl, typeof(*entry), head);
-                       tomoyo_put_name(entry->filename1);
-                       tomoyo_put_name(entry->filename2);
+                       tomoyo_put_name_union(&entry->name1);
+                       tomoyo_put_name_union(&entry->name2);
                }
                break;
        default:
@@ -149,9 +151,21 @@ static void tomoyo_del_name(const struct tomoyo_name_entry *ptr)
 {
 }
 
+static void tomoyo_del_path_group_member(struct tomoyo_path_group_member
+                                        *member)
+{
+       tomoyo_put_name(member->member_name);
+}
+
+static void tomoyo_del_path_group(struct tomoyo_path_group *group)
+{
+       tomoyo_put_name(group->group_name);
+}
+
 static void tomoyo_collect_entry(void)
 {
-       mutex_lock(&tomoyo_policy_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               return;
        {
                struct tomoyo_globally_readable_file_entry *ptr;
                list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list,
@@ -275,8 +289,6 @@ static void tomoyo_collect_entry(void)
                                break;
                }
        }
-       mutex_unlock(&tomoyo_policy_lock);
-       mutex_lock(&tomoyo_name_list_lock);
        {
                int i;
                for (i = 0; i < TOMOYO_MAX_HASH; i++) {
@@ -294,7 +306,30 @@ static void tomoyo_collect_entry(void)
                        }
                }
        }
-       mutex_unlock(&tomoyo_name_list_lock);
+       {
+               struct tomoyo_path_group *group;
+               list_for_each_entry_rcu(group, &tomoyo_path_group_list, list) {
+                       struct tomoyo_path_group_member *member;
+                       list_for_each_entry_rcu(member, &group->member_list,
+                                               list) {
+                               if (!member->is_deleted)
+                                       continue;
+                               if (tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP_MEMBER,
+                                                    member))
+                                       list_del_rcu(&member->list);
+                               else
+                                       break;
+                       }
+                       if (!list_empty(&group->member_list) ||
+                           atomic_read(&group->users))
+                               continue;
+                       if (tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP, group))
+                               list_del_rcu(&group->list);
+                       else
+                               break;
+               }
+       }
+       mutex_unlock(&tomoyo_policy_lock);
 }
 
 static void tomoyo_kfree_entry(void)
@@ -335,6 +370,12 @@ static void tomoyo_kfree_entry(void)
                        if (!tomoyo_del_domain(p->element))
                                continue;
                        break;
+               case TOMOYO_ID_PATH_GROUP_MEMBER:
+                       tomoyo_del_path_group_member(p->element);
+                       break;
+               case TOMOYO_ID_PATH_GROUP:
+                       tomoyo_del_path_group(p->element);
+                       break;
                default:
                        printk(KERN_WARNING "Unknown type\n");
                        break;
diff --git a/security/tomoyo/path_group.c b/security/tomoyo/path_group.c
new file mode 100644 (file)
index 0000000..c988041
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * security/tomoyo/path_group.c
+ *
+ * Copyright (C) 2005-2009  NTT DATA CORPORATION
+ */
+
+#include <linux/slab.h>
+#include "common.h"
+/* The list for "struct ccs_path_group". */
+LIST_HEAD(tomoyo_path_group_list);
+
+/**
+ * tomoyo_get_path_group - Allocate memory for "struct tomoyo_path_group".
+ *
+ * @group_name: The name of pathname group.
+ *
+ * Returns pointer to "struct tomoyo_path_group" on success, NULL otherwise.
+ */
+struct tomoyo_path_group *tomoyo_get_path_group(const char *group_name)
+{
+       struct tomoyo_path_group *entry = NULL;
+       struct tomoyo_path_group *group = NULL;
+       const struct tomoyo_path_info *saved_group_name;
+       int error = -ENOMEM;
+       if (!tomoyo_is_correct_path(group_name, 0, 0, 0) ||
+           !group_name[0])
+               return NULL;
+       saved_group_name = tomoyo_get_name(group_name);
+       if (!saved_group_name)
+               return NULL;
+       entry = kzalloc(sizeof(*entry), GFP_NOFS);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
+       list_for_each_entry_rcu(group, &tomoyo_path_group_list, list) {
+               if (saved_group_name != group->group_name)
+                       continue;
+               atomic_inc(&group->users);
+               error = 0;
+               break;
+       }
+       if (error && tomoyo_memory_ok(entry)) {
+               INIT_LIST_HEAD(&entry->member_list);
+               entry->group_name = saved_group_name;
+               saved_group_name = NULL;
+               atomic_set(&entry->users, 1);
+               list_add_tail_rcu(&entry->list, &tomoyo_path_group_list);
+               group = entry;
+               entry = NULL;
+               error = 0;
+       }
+       mutex_unlock(&tomoyo_policy_lock);
+ out:
+       tomoyo_put_name(saved_group_name);
+       kfree(entry);
+       return !error ? group : NULL;
+}
+
+/**
+ * tomoyo_write_path_group_policy - Write "struct tomoyo_path_group" list.
+ *
+ * @data:      String to parse.
+ * @is_delete: True if it is a delete request.
+ *
+ * Returns 0 on success, nagative value otherwise.
+ */
+int tomoyo_write_path_group_policy(char *data, const bool is_delete)
+{
+       struct tomoyo_path_group *group;
+       struct tomoyo_path_group_member *member;
+       struct tomoyo_path_group_member e = { };
+       int error = is_delete ? -ENOENT : -ENOMEM;
+       char *w[2];
+       if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
+               return -EINVAL;
+       group = tomoyo_get_path_group(w[0]);
+       if (!group)
+               return -ENOMEM;
+       e.member_name = tomoyo_get_name(w[1]);
+       if (!e.member_name)
+               goto out;
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               goto out;
+       list_for_each_entry_rcu(member, &group->member_list, list) {
+               if (member->member_name != e.member_name)
+                       continue;
+               member->is_deleted = is_delete;
+               error = 0;
+               break;
+       }
+       if (!is_delete && error) {
+               struct tomoyo_path_group_member *entry =
+                       tomoyo_commit_ok(&e, sizeof(e));
+               if (entry) {
+                       list_add_tail_rcu(&entry->list, &group->member_list);
+                       error = 0;
+               }
+       }
+       mutex_unlock(&tomoyo_policy_lock);
+ out:
+       tomoyo_put_name(e.member_name);
+       tomoyo_put_path_group(group);
+       return error;
+}
+
+/**
+ * tomoyo_read_path_group_policy - Read "struct tomoyo_path_group" list.
+ *
+ * @head: Pointer to "struct tomoyo_io_buffer".
+ *
+ * Returns true on success, false otherwise.
+ *
+ * Caller holds tomoyo_read_lock().
+ */
+bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head)
+{
+       struct list_head *gpos;
+       struct list_head *mpos;
+       list_for_each_cookie(gpos, head->read_var1, &tomoyo_path_group_list) {
+               struct tomoyo_path_group *group;
+               group = list_entry(gpos, struct tomoyo_path_group, list);
+               list_for_each_cookie(mpos, head->read_var2,
+                                    &group->member_list) {
+                       struct tomoyo_path_group_member *member;
+                       member = list_entry(mpos,
+                                           struct tomoyo_path_group_member,
+                                           list);
+                       if (member->is_deleted)
+                               continue;
+                       if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_PATH_GROUP
+                                             "%s %s\n",
+                                             group->group_name->name,
+                                             member->member_name->name))
+                               return false;
+               }
+       }
+       return true;
+}
+
+/**
+ * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
+ *
+ * @pathname:        The name of pathname.
+ * @group:           Pointer to "struct tomoyo_path_group".
+ * @may_use_pattern: True if wild card is permitted.
+ *
+ * Returns true if @pathname matches pathnames in @group, false otherwise.
+ *
+ * Caller holds tomoyo_read_lock().
+ */
+bool tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
+                              const struct tomoyo_path_group *group,
+                              const bool may_use_pattern)
+{
+       struct tomoyo_path_group_member *member;
+       bool matched = false;
+       list_for_each_entry_rcu(member, &group->member_list, list) {
+               if (member->is_deleted)
+                       continue;
+               if (!member->member_name->is_patterned) {
+                       if (tomoyo_pathcmp(pathname, member->member_name))
+                               continue;
+               } else if (may_use_pattern) {
+                       if (!tomoyo_path_matches_pattern(pathname,
+                                                        member->member_name))
+                               continue;
+               } else
+                       continue;
+               matched = true;
+               break;
+       }
+       return matched;
+}
index c225c65..d1b96f0 100644 (file)
@@ -139,7 +139,7 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
  */
 char *tomoyo_realpath_from_path(struct path *path)
 {
-       char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_KERNEL);
+       char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_NOFS);
 
        BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer)
                     <= TOMOYO_MAX_PATHNAME_LEN - 1);
@@ -222,6 +222,25 @@ bool tomoyo_memory_ok(void *ptr)
        return false;
 }
 
+/**
+ * tomoyo_commit_ok - Check memory quota.
+ *
+ * @data:   Data to copy from.
+ * @size:   Size in byte.
+ *
+ * Returns pointer to allocated memory on success, NULL otherwise.
+ */
+void *tomoyo_commit_ok(void *data, const unsigned int size)
+{
+       void *ptr = kzalloc(size, GFP_NOFS);
+       if (tomoyo_memory_ok(ptr)) {
+               memmove(ptr, data, size);
+               memset(data, 0, size);
+               return ptr;
+       }
+       return NULL;
+}
+
 /**
  * tomoyo_memory_free - Free memory for elements.
  *
@@ -240,8 +259,6 @@ void tomoyo_memory_free(void *ptr)
  * "const struct tomoyo_path_info *".
  */
 struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
-/* Lock for protecting tomoyo_name_list . */
-DEFINE_MUTEX(tomoyo_name_list_lock);
 
 /**
  * tomoyo_get_name - Allocate permanent memory for string data.
@@ -263,14 +280,15 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
        len = strlen(name) + 1;
        hash = full_name_hash((const unsigned char *) name, len - 1);
        head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
-       mutex_lock(&tomoyo_name_list_lock);
+       if (mutex_lock_interruptible(&tomoyo_policy_lock))
+               return NULL;
        list_for_each_entry(ptr, head, list) {
                if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
                        continue;
                atomic_inc(&ptr->users);
                goto out;
        }
-       ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
+       ptr = kzalloc(sizeof(*ptr) + len, GFP_NOFS);
        allocated_len = ptr ? ksize(ptr) : 0;
        if (!ptr || (tomoyo_quota_for_policy &&
                     atomic_read(&tomoyo_policy_memory_size) + allocated_len
@@ -290,7 +308,7 @@ const struct tomoyo_path_info *tomoyo_get_name(const char *name)
        tomoyo_fill_path_info(&ptr->entry);
        list_add_tail(&ptr->list, head);
  out:
-       mutex_unlock(&tomoyo_name_list_lock);
+       mutex_unlock(&tomoyo_policy_lock);
        return ptr ? &ptr->entry : NULL;
 }
 
index 656e474..91acc9a 100644 (file)
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
        struct snd_ac97 *ac97;
        int ret;
 
-       writel(0, aaci->base + AC97_POWERDOWN);
        /*
         * Assert AACIRESET for 2us
         */
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
 
        writel(0x1fff, aaci->base + AACI_INTCLR);
        writel(aaci->maincr, aaci->base + AACI_MAINCR);
-
+       /*
+        * Fix: ac97 read back fail errors by reading
+        * from any arbitrary aaci register.
+        */
+       readl(aaci->base + AACI_CSCH1);
        ret = aaci_probe_ac97(aaci);
        if (ret)
                goto out;
index 8728876..20b5982 100644 (file)
@@ -36,6 +36,9 @@
 #include <sound/timer.h>
 #include <sound/minors.h>
 #include <asm/io.h>
+#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
+#include <dma-coherence.h>
+#endif
 
 /*
  *  Compatibility
@@ -3184,6 +3187,10 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
                                         substream->runtime->dma_area,
                                         substream->runtime->dma_addr,
                                         area->vm_end - area->vm_start);
+#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
+       if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV &&
+           !plat_device_is_coherent(substream->dma_buffer.dev.dev))
+               area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
 #endif /* ARCH_HAS_DMA_MMAP_COHERENT */
        /* mmap with fault handler */
        area->vm_ops = &snd_pcm_vm_ops_data_fault;
index 7394365..5040c7b 100644 (file)
@@ -1160,6 +1160,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
 {
        struct snd_timer_user *tu = timeri->callback_data;
        struct snd_timer_tread r1;
+       unsigned long flags;
 
        if (event >= SNDRV_TIMER_EVENT_START &&
            event <= SNDRV_TIMER_EVENT_PAUSE)
@@ -1169,9 +1170,9 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
        r1.event = event;
        r1.tstamp = *tstamp;
        r1.val = resolution;
-       spin_lock(&tu->qlock);
+       spin_lock_irqsave(&tu->qlock, flags);
        snd_timer_user_append_to_tqueue(tu, &r1);
-       spin_unlock(&tu->qlock);
+       spin_unlock_irqrestore(&tu->qlock, flags);
        kill_fasync(&tu->fasync, SIGIO, POLL_IN);
        wake_up(&tu->qchange_sleep);
 }
index 1e12307..4ff6c8c 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/i8253.h>
 #else
 #include <asm/8253pit.h>
-static DEFINE_SPINLOCK(i8253_lock);
+static DEFINE_RAW_SPINLOCK(i8253_lock);
 #endif
 
 #define PCSP_SOUND_VERSION 0x400       /* read 4.00 */
index 0444cde..b5e2b54 100644 (file)
@@ -21,7 +21,7 @@ static void pcspkr_do_sound(unsigned int count)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&i8253_lock, flags);
+       raw_spin_lock_irqsave(&i8253_lock, flags);
 
        if (count) {
                /* set command for counter 2, 2 byte write */
@@ -36,7 +36,7 @@ static void pcspkr_do_sound(unsigned int count)
                outb(inb_p(0x61) & 0xFC, 0x61);
        }
 
-       spin_unlock_irqrestore(&i8253_lock, flags);
+       raw_spin_unlock_irqrestore(&i8253_lock, flags);
 }
 
 void pcspkr_stop_sound(void)
index d77ffa9..ce9e7d1 100644 (file)
@@ -66,7 +66,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
        timer_cnt = val * CUR_DIV() / 256;
 
        if (timer_cnt && chip->enable) {
-               spin_lock_irqsave(&i8253_lock, flags);
+               raw_spin_lock_irqsave(&i8253_lock, flags);
                if (!nforce_wa) {
                        outb_p(chip->val61, 0x61);
                        outb_p(timer_cnt, 0x42);
@@ -75,7 +75,7 @@ static u64 pcsp_timer_update(struct snd_pcsp *chip)
                        outb(chip->val61 ^ 2, 0x61);
                        chip->thalf = 1;
                }
-               spin_unlock_irqrestore(&i8253_lock, flags);
+               raw_spin_unlock_irqrestore(&i8253_lock, flags);
        }
 
        chip->ns_rem = PCSP_PERIOD_NS();
@@ -159,10 +159,10 @@ static int pcsp_start_playing(struct snd_pcsp *chip)
                return -EIO;
        }
 
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        chip->val61 = inb(0x61) | 0x03;
        outb_p(0x92, 0x43);     /* binary, mode 1, LSB only, ch 2 */
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
        atomic_set(&chip->timer_active, 1);
        chip->thalf = 0;
 
@@ -179,11 +179,11 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
                return;
 
        atomic_set(&chip->timer_active, 0);
-       spin_lock(&i8253_lock);
+       raw_spin_lock(&i8253_lock);
        /* restore the timer */
        outb_p(0xb6, 0x43);     /* binary, mode 3, LSB/MSB, ch 2 */
        outb(chip->val61 & 0xFC, 0x61);
-       spin_unlock(&i8253_lock);
+       raw_spin_unlock(&i8253_lock);
 }
 
 /*
index cafc3a7..ff18286 100644 (file)
@@ -93,7 +93,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
                return err;
        }
        port[dev] = pnp_port_start(pdev, 0);
-       dma8[dev] = pnp_dma(pdev, 1);
+       dma8[dev] = pnp_dma(pdev, 0);
        irq[dev] = pnp_irq(pdev, 0);
 
        return 0;
index bb14e4c..87910e9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/ioport.h>
 #include <linux/soundcard.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 
 #include <asm/uaccess.h>
 #include <asm/setup.h>
@@ -710,31 +711,41 @@ static MACHINE machAmiga = {
 /*** Config & Setup **********************************************************/
 
 
-static int __init dmasound_paula_init(void)
+static int __init amiga_audio_probe(struct platform_device *pdev)
 {
-       int err;
-
-       if (MACH_IS_AMIGA && AMIGAHW_PRESENT(AMI_AUDIO)) {
-           if (!request_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40,
-                                   "dmasound [Paula]"))
-               return -EBUSY;
-           dmasound.mach = machAmiga;
-           dmasound.mach.default_hard = def_hard ;
-           dmasound.mach.default_soft = def_soft ;
-           err = dmasound_init();
-           if (err)
-               release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
-           return err;
-       } else
-           return -ENODEV;
+       dmasound.mach = machAmiga;
+       dmasound.mach.default_hard = def_hard ;
+       dmasound.mach.default_soft = def_soft ;
+       return dmasound_init();
 }
 
-static void __exit dmasound_paula_cleanup(void)
+static int __exit amiga_audio_remove(struct platform_device *pdev)
 {
        dmasound_deinit();
-       release_mem_region(CUSTOM_PHYSADDR+0xa0, 0x40);
+       return 0;
+}
+
+static struct platform_driver amiga_audio_driver = {
+       .remove = __exit_p(amiga_audio_remove),
+       .driver   = {
+               .name   = "amiga-audio",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init amiga_audio_init(void)
+{
+       return platform_driver_probe(&amiga_audio_driver, amiga_audio_probe);
 }
 
-module_init(dmasound_paula_init);
-module_exit(dmasound_paula_cleanup);
+module_init(amiga_audio_init);
+
+static void __exit amiga_audio_exit(void)
+{
+       platform_driver_unregister(&amiga_audio_driver);
+}
+
+module_exit(amiga_audio_exit);
+
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:amiga-audio");
index f8fd586..cec6815 100644 (file)
@@ -2272,6 +2272,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
        {}
 };
index af34606..e9fdfc4 100644 (file)
@@ -519,14 +519,6 @@ static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
        ad198x_power_eapd(codec);
        return 0;
 }
-
-static int ad198x_resume(struct hda_codec *codec)
-{
-       ad198x_init(codec);
-       snd_hda_codec_resume_amp(codec);
-       snd_hda_codec_resume_cache(codec);
-       return 0;
-}
 #endif
 
 static struct hda_codec_ops ad198x_patch_ops = {
@@ -539,7 +531,6 @@ static struct hda_codec_ops ad198x_patch_ops = {
 #endif
 #ifdef SND_HDA_NEEDS_RESUME
        .suspend = ad198x_suspend,
-       .resume = ad198x_resume,
 #endif
        .reboot_notify = ad198x_shutup,
 };
index 7de782a..350ee8a 100644 (file)
@@ -766,7 +766,7 @@ static int build_input(struct hda_codec *codec)
                for (n = 0; n < AUTO_PIN_LAST; n++) {
                        if (!spec->adc_nid[n])
                                continue;
-                       err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]);
+                       err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
                        if (err < 0)
                                return err;
                }
index 61682e1..feabb44 100644 (file)
@@ -1195,10 +1195,12 @@ static int patch_cxt5045(struct hda_codec *codec)
 
        switch (codec->subsystem_id >> 16) {
        case 0x103c:
+       case 0x1631:
        case 0x1734:
-               /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB
-                * on NID 0x17. Fix max PCM level to 0 dB
-                * (originally it has 0x2b steps with 0dB offset 0x14)
+       case 0x17aa:
+               /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
+                * really bad sound over 0dB on NID 0x17. Fix max PCM level to
+                * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
                 */
                snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
                                          (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
@@ -2842,6 +2844,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
                      CXT5066_DELL_LAPTOP),
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
+       SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", 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, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
        {}
 };
index c7730db..886d8e4 100644 (file)
@@ -230,6 +230,7 @@ enum {
        ALC888_ACER_ASPIRE_7730G,
        ALC883_MEDION,
        ALC883_MEDION_MD2,
+       ALC883_MEDION_WIM2160,
        ALC883_LAPTOP_EAPD,
        ALC883_LENOVO_101E_2ch,
        ALC883_LENOVO_NB0763,
@@ -1389,22 +1390,31 @@ struct alc_fixup {
 
 static void alc_pick_fixup(struct hda_codec *codec,
                           const struct snd_pci_quirk *quirk,
-                          const struct alc_fixup *fix)
+                          const struct alc_fixup *fix,
+                          int pre_init)
 {
        const struct alc_pincfg *cfg;
 
        quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
        if (!quirk)
                return;
-
        fix += quirk->value;
        cfg = fix->pins;
-       if (cfg) {
+       if (pre_init && cfg) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+               snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
+                           codec->chip_name, quirk->name);
+#endif
                for (; cfg->nid; cfg++)
                        snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
        }
-       if (fix->verbs)
+       if (!pre_init && fix->verbs) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+               snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
+                           codec->chip_name, quirk->name);
+#endif
                add_verb(codec->spec, fix->verbs);
+       }
 }
 
 static int alc_read_coef_idx(struct hda_codec *codec,
@@ -4133,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
        SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
        SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
-       SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
+       SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
@@ -4808,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+static void alc880_auto_init_input_src(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int c;
+
+       for (c = 0; c < spec->num_adc_nids; c++) {
+               unsigned int mux_idx;
+               const struct hda_input_mux *imux;
+               mux_idx = c >= spec->num_mux_defs ? 0 : c;
+               imux = &spec->input_mux[mux_idx];
+               if (!imux->num_items && mux_idx > 0)
+                       imux = &spec->input_mux[0];
+               if (imux)
+                       snd_hda_codec_write(codec, spec->adc_nids[c], 0,
+                                           AC_VERB_SET_CONNECT_SEL,
+                                           imux->items[0].index);
+       }
+}
+
 /* parse the BIOS configuration and set up the alc_spec */
 /* return 1 if successful, 0 if the proper config is not found,
  * or a negative error code
@@ -4886,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec)
        alc880_auto_init_multi_out(codec);
        alc880_auto_init_extra_out(codec);
        alc880_auto_init_analog_input(codec);
+       alc880_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
 }
@@ -6397,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+#define alc260_auto_init_input_src     alc880_auto_init_input_src
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -6483,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        alc260_auto_init_multi_out(codec);
        alc260_auto_init_analog_input(codec);
+       alc260_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
 }
@@ -8455,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+static struct hda_verb alc883_medion_wim2160_verbs[] = {
+       /* Unmute front mixer */
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       /* Set speaker pin to front mixer */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+       /* Init headphone pin */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
+       { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_medion_wim2160_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x1a;
+       spec->autocfg.speaker_pins[0] = 0x15;
+}
+
 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -9164,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
        [ALC888_ACER_ASPIRE_7730G]      = "acer-aspire-7730g",
        [ALC883_MEDION]         = "medion",
        [ALC883_MEDION_MD2]     = "medion-md2",
+       [ALC883_MEDION_WIM2160] = "medion-wim2160",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
        [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
@@ -9280,6 +9350,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
 
        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
@@ -9818,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = {
                .setup = alc883_medion_md2_setup,
                .init_hook = alc_automute_amp,
        },
+       [ALC883_MEDION_WIM2160] = {
+               .mixers = { alc883_medion_wim2160_mixer },
+               .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc_automute_amp_unsol_event,
+               .setup = alc883_medion_wim2160_setup,
+               .init_hook = alc_automute_amp,
+       },
        [ALC883_LAPTOP_EAPD] = {
                .mixers = { alc883_base_mixer },
                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -10363,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec)
                board_config = ALC882_AUTO;
        }
 
-       alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
+       if (board_config == ALC882_AUTO)
+               alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
 
        if (board_config == ALC882_AUTO) {
                /* automatic parse from the BIOS config */
@@ -10436,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec)
        set_capture_mixer(codec);
        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
+       if (board_config == ALC882_AUTO)
+               alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
+
        spec->vmaster_nid = 0x0c;
 
        codec->patch_ops = alc_patch_ops;
@@ -12816,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
                dac = 0x02;
                break;
        case 0x15:
+       case 0x21: /* ALC269vb has this pin, too */
                dac = 0x03;
                break;
        default:
@@ -13735,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
        }
 }
 
-static void alc269_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_amic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        spec->autocfg.hp_pins[0] = 0x15;
        spec->autocfg.speaker_pins[0] = 0x14;
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
-       spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 5;
+       spec->int_mic.pin = 0x19;
+       spec->int_mic.mux_idx = 1;
        spec->auto_mic = 1;
 }
 
-static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_dmic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        spec->autocfg.hp_pins[0] = 0x15;
@@ -13755,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
        spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 6;
+       spec->int_mic.mux_idx = 5;
        spec->auto_mic = 1;
 }
 
-static void alc269_laptop_amic_setup(struct hda_codec *codec)
+static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.hp_pins[0] = 0x21;
        spec->autocfg.speaker_pins[0] = 0x14;
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
@@ -13771,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec)
        spec->auto_mic = 1;
 }
 
+static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       spec->autocfg.hp_pins[0] = 0x21;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->ext_mic.pin = 0x18;
+       spec->ext_mic.mux_idx = 0;
+       spec->int_mic.pin = 0x12;
+       spec->int_mic.mux_idx = 6;
+       spec->auto_mic = 1;
+}
+
 static void alc269_laptop_inithook(struct hda_codec *codec)
 {
        alc269_speaker_automute(codec);
@@ -13975,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec)
                alc_inithook(codec);
 }
 
+enum {
+       ALC269_FIXUP_SONY_VAIO,
+};
+
+const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
+       {}
+};
+
+static const struct alc_fixup alc269_fixups[] = {
+       [ALC269_FIXUP_SONY_VAIO] = {
+               .verbs = alc269_sony_vaio_fixup_verbs
+       },
+};
+
+static struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
+       {}
+};
+
+
 /*
  * configuration and preset
  */
@@ -14034,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
                      ALC269_DMIC),
        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
        SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
-       SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
+       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
        SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
        SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
@@ -14108,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc269_modes),
                .channel_mode = alc269_modes,
                .unsol_event = alc269_laptop_unsol_event,
-               .setup = alc269_laptop_amic_setup,
+               .setup = alc269vb_laptop_amic_setup,
                .init_hook = alc269_laptop_inithook,
        },
        [ALC269VB_DMIC] = {
@@ -14188,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec)
                board_config = ALC269_AUTO;
        }
 
+       if (board_config == ALC269_AUTO)
+               alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
+
        if (board_config == ALC269_AUTO) {
                /* automatic parse from the BIOS config */
                err = alc269_parse_auto_config(codec);
@@ -14240,6 +14367,9 @@ static int patch_alc269(struct hda_codec *codec)
                set_capture_mixer(codec);
        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
+       if (board_config == ALC269_AUTO)
+               alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
+
        spec->vmaster_nid = 0x02;
 
        codec->patch_ops = alc_patch_ops;
@@ -15328,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec)
                board_config = ALC861_AUTO;
        }
 
-       alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
+       if (board_config == ALC861_AUTO)
+               alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
 
        if (board_config == ALC861_AUTO) {
                /* automatic parse from the BIOS config */
@@ -15365,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec)
 
        spec->vmaster_nid = 0x03;
 
+       if (board_config == ALC861_AUTO)
+               alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC861_AUTO) {
                spec->init_hook = alc861_auto_init;
@@ -16299,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec)
                board_config = ALC861VD_AUTO;
        }
 
-       alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
+       if (board_config == ALC861VD_AUTO)
+               alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
 
        if (board_config == ALC861VD_AUTO) {
                /* automatic parse from the BIOS config */
@@ -16347,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec)
 
        spec->vmaster_nid = 0x02;
 
+       if (board_config == ALC861VD_AUTO)
+               alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
+
        codec->patch_ops = alc_patch_ops;
 
        if (board_config == ALC861VD_AUTO)
@@ -17733,7 +17871,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
                                        ALC662_3ST_6ch_DIG),
        SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
                           ALC663_ASUS_H13),
-       SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
        {}
 };
 
index c4be3fa..a0e06d8 100644 (file)
@@ -104,6 +104,7 @@ enum {
        STAC_DELL_M4_2,
        STAC_DELL_M4_3,
        STAC_HP_M4,
+       STAC_HP_DV4,
        STAC_HP_DV5,
        STAC_HP_HDX,
        STAC_HP_DV4_1222NR,
@@ -1544,11 +1545,9 @@ static unsigned int alienware_m17x_pin_configs[13] = {
        0x904601b0,
 };
 
-static unsigned int intel_dg45id_pin_configs[14] = {
+static unsigned int intel_dg45id_pin_configs[13] = {
        0x02214230, 0x02A19240, 0x01013214, 0x01014210,
-       0x01A19250, 0x01011212, 0x01016211, 0x40f000f0,
-       0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0,
-       0x074510B0, 0x40f000f0
+       0x01A19250, 0x01011212, 0x01016211
 };
 
 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
@@ -1607,6 +1606,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
                                "Dell Studio 1555", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
                                "Dell Studio 1557", STAC_DELL_M6_DMIC),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
+                               "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
+                               "Dell Studio 1558", STAC_DELL_M6_BOTH),
        {} /* terminator */
 };
 
@@ -1689,6 +1692,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
        [STAC_DELL_M4_2]        = dell_m4_2_pin_configs,
        [STAC_DELL_M4_3]        = dell_m4_3_pin_configs,
        [STAC_HP_M4]            = NULL,
+       [STAC_HP_DV4]           = NULL,
        [STAC_HP_DV5]           = NULL,
        [STAC_HP_HDX]           = NULL,
        [STAC_HP_DV4_1222NR]    = NULL,
@@ -1701,6 +1705,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
        [STAC_DELL_M4_2] = "dell-m4-2",
        [STAC_DELL_M4_3] = "dell-m4-3",
        [STAC_HP_M4] = "hp-m4",
+       [STAC_HP_DV4] = "hp-dv4",
        [STAC_HP_DV5] = "hp-dv5",
        [STAC_HP_HDX] = "hp-hdx",
        [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr",
@@ -1719,7 +1724,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080,
                      "HP", STAC_HP_DV5),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0,
-                     "HP dv4-7", STAC_HP_DV5),
+                     "HP dv4-7", STAC_HP_DV4),
        SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600,
                      "HP dv4-7", STAC_HP_DV5),
        SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610,
@@ -4764,6 +4769,9 @@ static void set_hp_led_gpio(struct hda_codec *codec)
        struct sigmatel_spec *spec = codec->spec;
        unsigned int gpio;
 
+       if (spec->gpio_led)
+               return;
+
        gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
        gpio &= AC_GPIO_IO_COUNT;
        if (gpio > 3)
@@ -5673,6 +5681,9 @@ again:
                spec->num_smuxes = 1;
                spec->num_dmuxes = 1;
                /* fallthrough */
+       case STAC_HP_DV4:
+               spec->gpio_led = 0x01;
+               /* fallthrough */
        case STAC_HP_DV5:
                snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
                stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
@@ -5686,6 +5697,7 @@ again:
                spec->num_dmics = 1;
                spec->num_dmuxes = 1;
                spec->num_smuxes = 1;
+               spec->gpio_led = 0x08;
                break;
        }
 
@@ -5742,7 +5754,8 @@ again:
        }
 
        /* enable bass on HP dv7 */
-       if (spec->board_config == STAC_HP_DV5) {
+       if (spec->board_config == STAC_HP_DV4 ||
+           spec->board_config == STAC_HP_DV5) {
                unsigned int cap;
                cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
                cap &= AC_GPIO_IO_COUNT;
index 9ddc373..7345381 100644 (file)
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
        knew->name = kstrdup(tmpl->name, GFP_KERNEL);
        if (!knew->name)
                return NULL;
-       return 0;
+       return knew;
 }
 
 static void via_free_kctls(struct hda_codec *codec)
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = {
        },
 };
 
-static int via_hp_build(struct via_spec *spec)
+static int via_hp_build(struct hda_codec *codec)
 {
+       struct via_spec *spec = codec->spec;
        struct snd_kcontrol_new *knew;
        hda_nid_t nid;
-
-       knew = via_clone_control(spec, &via_hp_mixer[0]);
-       if (knew == NULL)
-               return -ENOMEM;
+       int nums;
+       hda_nid_t conn[HDA_MAX_CONNECTIONS];
 
        switch (spec->codec_type) {
        case VT1718S:
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec)
                break;
        }
 
+       nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
+       if (nums <= 1)
+               return 0;
+
+       knew = via_clone_control(spec, &via_hp_mixer[0]);
+       if (knew == NULL)
+               return -ENOMEM;
+
        knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
        knew->private_value = nid;
 
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
 
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
 
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
 
        /* Line-Out: PortE */
        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
-                             "Master Front Playback Volume",
+                             "Front Playback Volume",
                              HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
        if (err < 0)
                return err;
        err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
-                             "Master Front Playback Switch",
+                             "Front Playback Switch",
                              HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
        if (err < 0)
                return err;
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
index 3e1c20a..726fd4b 100644 (file)
@@ -347,7 +347,7 @@ static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol,
 
 /* known working input slots (0-4) */
 #define MAYA_LINE_IN   1       /* in-2 */
-#define MAYA_MIC_IN    4       /* in-5 */
+#define MAYA_MIC_IN    3       /* in-4 */
 
 static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line)
 {
@@ -393,8 +393,8 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol,
        int changed;
 
        mutex_lock(&chip->mutex);
-       changed = maya_set_gpio_bits(chip->ice, GPIO_MIC_RELAY,
-                                    sel ? GPIO_MIC_RELAY : 0);
+       changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY,
+                                    sel ? (1 << GPIO_MIC_RELAY) : 0);
        wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN);
        mutex_unlock(&chip->mutex);
        return changed;
index b64e781..b56e336 100644 (file)
@@ -849,6 +849,7 @@ struct snd_m3 {
        struct snd_kcontrol *master_switch;
        struct snd_kcontrol *master_volume;
        struct tasklet_struct hwvol_tq;
+       unsigned int in_suspend;
 
 #ifdef CONFIG_PM
        u16 *suspend_mem;
@@ -884,6 +885,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
 MODULE_DEVICE_TABLE(pci, snd_m3_ids);
 
 static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
+       SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c),
        SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
        SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
        SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
@@ -1613,6 +1615,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
        outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
        outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
 
+       /* Ignore spurious HV interrupts during suspend / resume, this avoids
+          mistaking them for a mute button press. */
+       if (chip->in_suspend)
+               return;
+
        if (!chip->master_switch || !chip->master_volume)
                return;
 
@@ -2424,6 +2431,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
        if (chip->suspend_mem == NULL)
                return 0;
 
+       chip->in_suspend = 1;
        snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
        snd_pcm_suspend_all(chip->pcm);
        snd_ac97_suspend(chip->ac97);
@@ -2497,6 +2505,7 @@ static int m3_resume(struct pci_dev *pci)
        snd_m3_hv_init(chip);
 
        snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+       chip->in_suspend = 0;
        return 0;
 }
 #endif /* CONFIG_PM */
index 16c226b..7c4986b 100644 (file)
@@ -56,6 +56,7 @@
 #include <sound/pcm_params.h>
 #include <sound/tlv.h>
 #include "xonar.h"
+#include "cm9780.h"
 #include "cs4398.h"
 #include "cs4362a.h"
 
@@ -172,6 +173,8 @@ static void xonar_d1_init(struct oxygen *chip)
        oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
                            GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
 
+       oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
+
        xonar_init_cs53x1(chip);
        xonar_enable_output(chip);
 
index a34cbcf..002e289 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/firmware.h>
index 2e79d71..2b31ac6 100644 (file)
@@ -71,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data)
 
 static void snd_imx_dma_err_callback(int channel, void *data, int err)
 {
-       pr_err("DMA error callback called\n");
+       struct snd_pcm_substream *substream = data;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+       int ret;
 
        pr_err("DMA timeout on channel %d -%s%s%s%s\n",
                 channel,
@@ -79,6 +84,14 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
                 err & IMX_DMA_ERR_REQUEST ?  " request" : "",
                 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
                 err & IMX_DMA_ERR_BUFFER ?   " buffer" : "");
+
+       imx_dma_disable(iprtd->dma);
+       ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
+                       IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
+                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+                       DMA_MODE_WRITE : DMA_MODE_READ);
+       if (!ret)
+               imx_dma_enable(iprtd->dma);
 }
 
 static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
index f96a373..6b518e0 100644 (file)
@@ -39,23 +39,24 @@ struct imx_pcm_runtime_data {
        unsigned long offset;
        unsigned long last_offset;
        unsigned long size;
-       struct timer_list timer;
-       int poll_time;
+       struct hrtimer hrt;
+       int poll_time_ns;
+       struct snd_pcm_substream *substream;
+       atomic_t running;
 };
 
-static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)
+static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
 {
-       iprtd->timer.expires = jiffies + iprtd->poll_time;
-}
-
-static void imx_ssi_timer_callback(unsigned long data)
-{
-       struct snd_pcm_substream *substream = (void *)data;
+       struct imx_pcm_runtime_data *iprtd =
+               container_of(hrt, struct imx_pcm_runtime_data, hrt);
+       struct snd_pcm_substream *substream = iprtd->substream;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        struct pt_regs regs;
        unsigned long delta;
 
+       if (!atomic_read(&iprtd->running))
+               return HRTIMER_NORESTART;
+
        get_fiq_regs(&regs);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -72,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data)
 
        /* If we've transferred at least a period then report it and
         * reset our poll time */
-       if (delta >= runtime->period_size) {
+       if (delta >= iprtd->period) {
                snd_pcm_period_elapsed(substream);
                iprtd->last_offset = iprtd->offset;
-
-               imx_ssi_set_next_poll(iprtd);
        }
 
-       /* Restart the timer; if we didn't report we'll run on the next tick */
-       add_timer(&iprtd->timer);
+       hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
 
+       return HRTIMER_RESTART;
 }
 
 static struct fiq_handler fh = {
@@ -99,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
        iprtd->period = params_period_bytes(params) ;
        iprtd->offset = 0;
        iprtd->last_offset = 0;
-       iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));
-
+       iprtd->poll_time_ns = 1000000000 / params_rate(params) *
+                               params_period_size(params);
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
        return 0;
@@ -135,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               imx_ssi_set_next_poll(iprtd);
-               add_timer(&iprtd->timer);
+               atomic_set(&iprtd->running, 1);
+               hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
+                     HRTIMER_MODE_REL);
                if (++fiq_enable == 1)
                        enable_fiq(imx_pcm_fiq);
 
@@ -145,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               del_timer(&iprtd->timer);
+               atomic_set(&iprtd->running, 0);
+
                if (--fiq_enable == 0)
                        disable_fiq(imx_pcm_fiq);
 
-
                break;
        default:
                return -EINVAL;
@@ -180,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
        .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
        .period_bytes_min = 128,
        .period_bytes_max = 16 * 1024,
-       .periods_min = 2,
+       .periods_min = 4,
        .periods_max = 255,
        .fifo_size = 0,
 };
@@ -194,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
        iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
        runtime->private_data = iprtd;
 
-       init_timer(&iprtd->timer);
-       iprtd->timer.data = (unsigned long)substream;
-       iprtd->timer.function = imx_ssi_timer_callback;
+       iprtd->substream = substream;
+
+       atomic_set(&iprtd->running, 0);
+       hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       iprtd->hrt.function = snd_hrtimer_callback;
 
        ret = snd_pcm_hw_constraint_integer(substream->runtime,
                        SNDRV_PCM_HW_PARAM_PERIODS);
@@ -212,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
-       del_timer_sync(&iprtd->timer);
+       hrtimer_cancel(&iprtd->hrt);
+
        kfree(iprtd);
 
        return 0;
index 0bcc6d7..80b4fee 100644 (file)
@@ -656,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev)
        dai->private_data = ssi;
 
        if ((cpu_is_mx27() || cpu_is_mx21()) &&
-                       !(ssi->flags & IMX_SSI_USE_AC97)) {
+                       !(ssi->flags & IMX_SSI_USE_AC97) &&
+                       (ssi->flags & IMX_SSI_DMA)) {
                ssi->flags |= IMX_SSI_DMA;
                platform = imx_ssi_dma_mx2_init(pdev, ssi);
        } else
index 376e14a..78e6121 100644 (file)
@@ -23,6 +23,7 @@ config SND_PXA2XX_SOC_I2S
 
 config SND_PXA_SOC_SSP
        tristate
+       select PXA_SSP
 
 config SND_PXA2XX_SOC_CORGI
        tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
index 544fd95..a1fd23e 100644 (file)
@@ -32,9 +32,8 @@
 
 #include <mach/hardware.h>
 #include <mach/dma.h>
-#include <mach/regs-ssp.h>
 #include <mach/audio.h>
-#include <mach/ssp.h>
+#include <plat/ssp.h>
 
 #include "pxa2xx-pcm.h"
 #include "pxa-ssp.h"
@@ -57,15 +56,15 @@ struct ssp_priv {
 static void dump_registers(struct ssp_device *ssp)
 {
        dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
-                ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
-                ssp_read_reg(ssp, SSTO));
+                pxa_ssp_read_reg(ssp, SSCR0), pxa_ssp_read_reg(ssp, SSCR1),
+                pxa_ssp_read_reg(ssp, SSTO));
 
        dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
-                ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
-                ssp_read_reg(ssp, SSACD));
+                pxa_ssp_read_reg(ssp, SSPSP), pxa_ssp_read_reg(ssp, SSSR),
+                pxa_ssp_read_reg(ssp, SSACD));
 }
 
-static void ssp_enable(struct ssp_device *ssp)
+static void pxa_ssp_enable(struct ssp_device *ssp)
 {
        uint32_t sscr0;
 
@@ -73,7 +72,7 @@ static void ssp_enable(struct ssp_device *ssp)
        __raw_writel(sscr0, ssp->mmio_base + SSCR0);
 }
 
-static void ssp_disable(struct ssp_device *ssp)
+static void pxa_ssp_disable(struct ssp_device *ssp)
 {
        uint32_t sscr0;
 
@@ -87,7 +86,7 @@ struct pxa2xx_pcm_dma_data {
 };
 
 static struct pxa2xx_pcm_dma_params *
-ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
+pxa_ssp_get_dma_params(struct ssp_device *ssp, int width4, int out)
 {
        struct pxa2xx_pcm_dma_data *dma;
 
@@ -119,7 +118,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
 
        if (!cpu_dai->active) {
                clk_enable(ssp->clk);
-               ssp_disable(ssp);
+               pxa_ssp_disable(ssp);
        }
 
        kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
@@ -137,7 +136,7 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
        struct ssp_device *ssp = priv->ssp;
 
        if (!cpu_dai->active) {
-               ssp_disable(ssp);
+               pxa_ssp_disable(ssp);
                clk_disable(ssp->clk);
        }
 
@@ -160,7 +159,7 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
        priv->to  = __raw_readl(ssp->mmio_base + SSTO);
        priv->psp = __raw_readl(ssp->mmio_base + SSPSP);
 
-       ssp_disable(ssp);
+       pxa_ssp_disable(ssp);
        clk_disable(ssp->clk);
        return 0;
 }
@@ -180,7 +179,7 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
        __raw_writel(priv->psp, ssp->mmio_base + SSPSP);
 
        if (cpu_dai->active)
-               ssp_enable(ssp);
+               pxa_ssp_enable(ssp);
        else
                clk_disable(ssp->clk);
 
@@ -196,9 +195,9 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
  * ssp_set_clkdiv - set SSP clock divider
  * @div: serial clock rate divider
  */
-static void ssp_set_scr(struct ssp_device *ssp, u32 div)
+static void pxa_ssp_set_scr(struct ssp_device *ssp, u32 div)
 {
-       u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+       u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
 
        if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP) {
                sscr0 &= ~0x0000ff00;
@@ -207,15 +206,15 @@ static void ssp_set_scr(struct ssp_device *ssp, u32 div)
                sscr0 &= ~0x000fff00;
                sscr0 |= (div - 1) << 8;     /* 1..4096 */
        }
-       ssp_write_reg(ssp, SSCR0, sscr0);
+       pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 }
 
 /**
- * ssp_get_clkdiv - get SSP clock divider
+ * pxa_ssp_get_clkdiv - get SSP clock divider
  */
-static u32 ssp_get_scr(struct ssp_device *ssp)
+static u32 pxa_ssp_get_scr(struct ssp_device *ssp)
 {
-       u32 sscr0 = ssp_read_reg(ssp, SSCR0);
+       u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
        u32 div;
 
        if (cpu_is_pxa25x() && ssp->type == PXA25x_SSP)
@@ -235,7 +234,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
        struct ssp_device *ssp = priv->ssp;
        int val;
 
-       u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
+       u32 sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
                ~(SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
 
        dev_dbg(&ssp->pdev->dev,
@@ -263,7 +262,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
                break;
        case PXA_SSP_CLK_AUDIO:
                priv->sysclk = 0;
-               ssp_set_scr(ssp, 1);
+               pxa_ssp_set_scr(ssp, 1);
                sscr0 |= SSCR0_ACS;
                break;
        default:
@@ -274,8 +273,8 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
         * on PXA2xx.  On PXA3xx it must be enabled when doing so. */
        if (!cpu_is_pxa3xx())
                clk_disable(ssp->clk);
-       val = ssp_read_reg(ssp, SSCR0) | sscr0;
-       ssp_write_reg(ssp, SSCR0, val);
+       val = pxa_ssp_read_reg(ssp, SSCR0) | sscr0;
+       pxa_ssp_write_reg(ssp, SSCR0, val);
        if (!cpu_is_pxa3xx())
                clk_enable(ssp->clk);
 
@@ -294,11 +293,11 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
 
        switch (div_id) {
        case PXA_SSP_AUDIO_DIV_ACDS:
-               val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
-               ssp_write_reg(ssp, SSACD, val);
+               val = (pxa_ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+               pxa_ssp_write_reg(ssp, SSACD, val);
                break;
        case PXA_SSP_AUDIO_DIV_SCDB:
-               val = ssp_read_reg(ssp, SSACD);
+               val = pxa_ssp_read_reg(ssp, SSACD);
                val &= ~SSACD_SCDB;
 #if defined(CONFIG_PXA3xx)
                if (cpu_is_pxa3xx())
@@ -321,10 +320,10 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
                default:
                        return -EINVAL;
                }
-               ssp_write_reg(ssp, SSACD, val);
+               pxa_ssp_write_reg(ssp, SSACD, val);
                break;
        case PXA_SSP_DIV_SCR:
-               ssp_set_scr(ssp, div);
+               pxa_ssp_set_scr(ssp, div);
                break;
        default:
                return -ENODEV;
@@ -341,11 +340,11 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
 {
        struct ssp_priv *priv = cpu_dai->private_data;
        struct ssp_device *ssp = priv->ssp;
-       u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
+       u32 ssacd = pxa_ssp_read_reg(ssp, SSACD) & ~0x70;
 
 #if defined(CONFIG_PXA3xx)
        if (cpu_is_pxa3xx())
-               ssp_write_reg(ssp, SSACDD, 0);
+               pxa_ssp_write_reg(ssp, SSACDD, 0);
 #endif
 
        switch (freq_out) {
@@ -383,7 +382,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
                        val = tmp;
 
                        val = (val << 16) | 64;
-                       ssp_write_reg(ssp, SSACDD, val);
+                       pxa_ssp_write_reg(ssp, SSACDD, val);
 
                        ssacd |= (0x6 << 4);
 
@@ -397,7 +396,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
                return -EINVAL;
        }
 
-       ssp_write_reg(ssp, SSACD, ssacd);
+       pxa_ssp_write_reg(ssp, SSACD, ssacd);
 
        return 0;
 }
@@ -412,7 +411,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
        struct ssp_device *ssp = priv->ssp;
        u32 sscr0;
 
-       sscr0 = ssp_read_reg(ssp, SSCR0);
+       sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
        sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
 
        /* set slot width */
@@ -429,10 +428,10 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
                sscr0 |= SSCR0_SlotsPerFrm(slots);
 
                /* set active slot mask */
-               ssp_write_reg(ssp, SSTSA, tx_mask);
-               ssp_write_reg(ssp, SSRSA, rx_mask);
+               pxa_ssp_write_reg(ssp, SSTSA, tx_mask);
+               pxa_ssp_write_reg(ssp, SSRSA, rx_mask);
        }
-       ssp_write_reg(ssp, SSCR0, sscr0);
+       pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 
        return 0;
 }
@@ -447,12 +446,12 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
        struct ssp_device *ssp = priv->ssp;
        u32 sscr1;
 
-       sscr1 = ssp_read_reg(ssp, SSCR1);
+       sscr1 = pxa_ssp_read_reg(ssp, SSCR1);
        if (tristate)
                sscr1 &= ~SSCR1_TTE;
        else
                sscr1 |= SSCR1_TTE;
-       ssp_write_reg(ssp, SSCR1, sscr1);
+       pxa_ssp_write_reg(ssp, SSCR1, sscr1);
 
        return 0;
 }
@@ -476,14 +475,14 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                return 0;
 
        /* we can only change the settings if the port is not in use */
-       if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
+       if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) {
                dev_err(&ssp->pdev->dev,
                        "can't change hardware dai format: stream is in use");
                return -EINVAL;
        }
 
        /* reset port settings */
-       sscr0 = ssp_read_reg(ssp, SSCR0) &
+       sscr0 = pxa_ssp_read_reg(ssp, SSCR0) &
                (SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ACS);
        sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
        sspsp = 0;
@@ -535,9 +534,9 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                return -EINVAL;
        }
 
-       ssp_write_reg(ssp, SSCR0, sscr0);
-       ssp_write_reg(ssp, SSCR1, sscr1);
-       ssp_write_reg(ssp, SSPSP, sspsp);
+       pxa_ssp_write_reg(ssp, SSCR0, sscr0);
+       pxa_ssp_write_reg(ssp, SSCR1, sscr1);
+       pxa_ssp_write_reg(ssp, SSPSP, sspsp);
 
        dump_registers(ssp);
 
@@ -566,7 +565,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
        u32 sscr0;
        u32 sspsp;
        int width = snd_pcm_format_physical_width(params_format(params));
-       int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+       int ttsa = pxa_ssp_read_reg(ssp, SSTSA) & 0xf;
        struct pxa2xx_pcm_dma_params *dma_data;
 
        dma_data = snd_soc_dai_get_dma_data(dai, substream);
@@ -578,22 +577,22 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
         * to force 16-bit frame width on the wire (for S16_LE), even
         * with two channels. Use 16-bit DMA transfers for this case.
         */
-       dma_data = ssp_get_dma_params(ssp,
+       dma_data = pxa_ssp_get_dma_params(ssp,
                        ((chn == 2) && (ttsa != 1)) || (width == 32),
                        substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 
        snd_soc_dai_set_dma_data(dai, substream, dma_data);
 
        /* we can only change the settings if the port is not in use */
-       if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
+       if (pxa_ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
                return 0;
 
        /* clear selected SSP bits */
-       sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
-       ssp_write_reg(ssp, SSCR0, sscr0);
+       sscr0 = pxa_ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+       pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 
        /* bit size */
-       sscr0 = ssp_read_reg(ssp, SSCR0);
+       sscr0 = pxa_ssp_read_reg(ssp, SSCR0);
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
 #ifdef CONFIG_PXA3xx
@@ -609,13 +608,13 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
                sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
                break;
        }
-       ssp_write_reg(ssp, SSCR0, sscr0);
+       pxa_ssp_write_reg(ssp, SSCR0, sscr0);
 
        switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
-              sspsp = ssp_read_reg(ssp, SSPSP);
+              sspsp = pxa_ssp_read_reg(ssp, SSPSP);
 
-               if ((ssp_get_scr(ssp) == 4) && (width == 16)) {
+               if ((pxa_ssp_get_scr(ssp) == 4) && (width == 16)) {
                        /* This is a special case where the bitclk is 64fs
                        * and we're not dealing with 2*32 bits of audio
                        * samples.
@@ -649,7 +648,7 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
                        sspsp |= SSPSP_DMYSTRT(1);
                }
 
-               ssp_write_reg(ssp, SSPSP, sspsp);
+               pxa_ssp_write_reg(ssp, SSPSP, sspsp);
                break;
        default:
                break;
@@ -680,45 +679,45 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_RESUME:
-               ssp_enable(ssp);
+               pxa_ssp_enable(ssp);
                break;
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               val = ssp_read_reg(ssp, SSCR1);
+               val = pxa_ssp_read_reg(ssp, SSCR1);
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                        val |= SSCR1_TSRE;
                else
                        val |= SSCR1_RSRE;
-               ssp_write_reg(ssp, SSCR1, val);
-               val = ssp_read_reg(ssp, SSSR);
-               ssp_write_reg(ssp, SSSR, val);
+               pxa_ssp_write_reg(ssp, SSCR1, val);
+               val = pxa_ssp_read_reg(ssp, SSSR);
+               pxa_ssp_write_reg(ssp, SSSR, val);
                break;
        case SNDRV_PCM_TRIGGER_START:
-               val = ssp_read_reg(ssp, SSCR1);
+               val = pxa_ssp_read_reg(ssp, SSCR1);
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                        val |= SSCR1_TSRE;
                else
                        val |= SSCR1_RSRE;
-               ssp_write_reg(ssp, SSCR1, val);
-               ssp_enable(ssp);
+               pxa_ssp_write_reg(ssp, SSCR1, val);
+               pxa_ssp_enable(ssp);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
-               val = ssp_read_reg(ssp, SSCR1);
+               val = pxa_ssp_read_reg(ssp, SSCR1);
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                        val &= ~SSCR1_TSRE;
                else
                        val &= ~SSCR1_RSRE;
-               ssp_write_reg(ssp, SSCR1, val);
+               pxa_ssp_write_reg(ssp, SSCR1, val);
                break;
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               ssp_disable(ssp);
+               pxa_ssp_disable(ssp);
                break;
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               val = ssp_read_reg(ssp, SSCR1);
+               val = pxa_ssp_read_reg(ssp, SSCR1);
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                        val &= ~SSCR1_TSRE;
                else
                        val &= ~SSCR1_RSRE;
-               ssp_write_reg(ssp, SSCR1, val);
+               pxa_ssp_write_reg(ssp, SSCR1, val);
                break;
 
        default:
@@ -740,7 +739,7 @@ static int pxa_ssp_probe(struct platform_device *pdev,
        if (!priv)
                return -ENOMEM;
 
-       priv->ssp = ssp_request(dai->id + 1, "SoC audio");
+       priv->ssp = pxa_ssp_request(dai->id + 1, "SoC audio");
        if (priv->ssp == NULL) {
                ret = -ENODEV;
                goto err_priv;
@@ -760,7 +759,7 @@ static void pxa_ssp_remove(struct platform_device *pdev,
                              struct snd_soc_dai *dai)
 {
        struct ssp_priv *priv = dai->private_data;
-       ssp_free(priv->ssp);
+       pxa_ssp_free(priv->ssp);
 }
 
 #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
index 612e18b..0ec20b6 100644 (file)
@@ -254,3 +254,4 @@ module_exit(txx9aclc_ac97_exit);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("TXx9 ACLC AC97 driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:txx9aclc-ac97");
index 3175de9..95b17f7 100644 (file)
@@ -96,3 +96,4 @@ module_exit(txx9aclc_generic_exit);
 MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:txx9aclc-generic");
index 2c59afd..9e28b20 100644 (file)
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
        DEFINE_WAIT(wait);
        long timeout = msecs_to_jiffies(50);
 
+       if (ep->umidi->disconnected)
+               return;
        /*
         * The substream buffer is empty, but some data might still be in the
         * currently active URBs, so we have to wait for those to complete.
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
  * Frees an output endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
+static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
 {
        unsigned int i;
 
        for (i = 0; i < OUTPUT_URBS; ++i)
-               if (ep->urbs[i].urb)
+               if (ep->urbs[i].urb) {
                        free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
                                            ep->max_transfer);
+                       ep->urbs[i].urb = NULL;
+               }
+}
+
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
+{
+       snd_usbmidi_out_endpoint_clear(ep);
        kfree(ep);
 }
 
@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
                                usb_kill_urb(ep->out->urbs[j].urb);
                        if (umidi->usb_protocol_ops->finish_out_endpoint)
                                umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+                       ep->out->active_urbs = 0;
+                       if (ep->out->drain_urbs) {
+                               ep->out->drain_urbs = 0;
+                               wake_up(&ep->out->drain_wait);
+                       }
                }
                if (ep->in)
                        for (j = 0; j < INPUT_URBS; ++j)
                                usb_kill_urb(ep->in->urbs[j]);
                /* free endpoints here; later call can result in Oops */
-               if (ep->out) {
-                       snd_usbmidi_out_endpoint_delete(ep->out);
-                       ep->out = NULL;
-               }
+               if (ep->out)
+                       snd_usbmidi_out_endpoint_clear(ep->out);
                if (ep->in) {
                        snd_usbmidi_in_endpoint_delete(ep->in);
                        ep->in = NULL;
index ae525ac..a3dbadb 100644 (file)
@@ -1,5 +1,5 @@
 perf-bench(1)
-============
+=============
 
 NAME
 ----
@@ -19,12 +19,12 @@ COMMON OPTIONS
 -f::
 --format=::
 Specify format style.
-Current available format styles are,
+Current available format styles are:
 
 'default'::
 Default style. This is mainly for human reading.
 ---------------------
-% perf bench sched pipe                      # with no style specify
+% perf bench sched pipe                      # with no style specified
 (executing 1000000 pipe operations between two tasks)
         Total time:5.855 sec
                 5.855061 usecs/op
@@ -79,7 +79,7 @@ options (20 sender and receiver processes per group)
 
       Total time:0.308 sec
 
-% perf bench sched messaging -t -g 20        # be multi-thread,with 20 groups
+% perf bench sched messaging -t -g 20        # be multi-thread, with 20 groups
 (20 sender and receiver threads per group)
 (20 groups == 800 threads run)
 
index 88bc3b5..5d1a950 100644 (file)
@@ -8,7 +8,7 @@ perf-buildid-cache - Manage build-id cache.
 SYNOPSIS
 --------
 [verse]
-'perf buildid-list <options>'
+'perf buildid-cache <options>'
 
 DESCRIPTION
 -----------
@@ -30,4 +30,4 @@ OPTIONS
 
 SEE ALSO
 --------
-linkperf:perf-record[1], linkperf:perf-report[1]
+linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-buildid-list[1]
index 8974e20..20d97d8 100644 (file)
@@ -1,5 +1,5 @@
 perf-diff(1)
-==============
+============
 
 NAME
 ----
diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt
new file mode 100644 (file)
index 0000000..025630d
--- /dev/null
@@ -0,0 +1,35 @@
+perf-inject(1)
+==============
+
+NAME
+----
+perf-inject - Filter to augment the events stream with additional information
+
+SYNOPSIS
+--------
+[verse]
+'perf inject <options>'
+
+DESCRIPTION
+-----------
+perf-inject reads a perf-record event stream and repipes it to stdout.  At any
+point the processing code can inject other events into the event stream - in
+this case build-ids (-b option) are read and injected as needed into the event
+stream.
+
+Build-ids are just the first user of perf-inject - potentially anything that
+needs userspace processing to augment the events stream with additional
+information could make use of this facility.
+
+OPTIONS
+-------
+-b::
+--build-ids=::
+        Inject build-ids into the output stream
+-v::
+--verbose::
+       Be more verbose.
+
+SEE ALSO
+--------
+linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1]
index eac4d85..a52fcde 100644 (file)
@@ -1,5 +1,5 @@
 perf-kmem(1)
-==============
+============
 
 NAME
 ----
diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt
new file mode 100644 (file)
index 0000000..d004e19
--- /dev/null
@@ -0,0 +1,68 @@
+perf-kvm(1)
+===========
+
+NAME
+----
+perf-kvm - Tool to trace/measure kvm guest os
+
+SYNOPSIS
+--------
+[verse]
+'perf kvm' [--host] [--guest] [--guestmount=<path>
+       [--guestkallsyms=<path> --guestmodules=<path> | --guestvmlinux=<path>]]
+       {top|record|report|diff|buildid-list}
+'perf kvm' [--host] [--guest] [--guestkallsyms=<path> --guestmodules=<path>
+       | --guestvmlinux=<path>] {top|record|report|diff|buildid-list}
+
+DESCRIPTION
+-----------
+There are a couple of variants of perf kvm:
+
+  'perf kvm [options] top <command>' to generates and displays
+  a performance counter profile of guest os in realtime
+  of an arbitrary workload.
+
+  'perf kvm record <command>' to record the performance couinter profile
+  of an arbitrary workload and save it into a perf data file. If both
+  --host and --guest are input, the perf data file name is perf.data.kvm.
+  If there is  no --host but --guest, the file name is perf.data.guest.
+  If there is no --guest but --host, the file name is perf.data.host.
+
+  'perf kvm report' to display the performance counter profile information
+  recorded via perf kvm record.
+
+  'perf kvm diff' to displays the performance difference amongst two perf.data
+  files captured via perf record.
+
+  'perf kvm buildid-list' to  display the buildids found in a perf data file,
+  so that other tools can be used to fetch packages with matching symbol tables
+  for use by perf report.
+
+OPTIONS
+-------
+--host=::
+        Collect host side performance profile.
+--guest=::
+        Collect guest side performance profile.
+--guestmount=<path>::
+       Guest os root file system mount directory. Users mounts guest os
+        root directories under <path> by a specific filesystem access method,
+       typically, sshfs. For example, start 2 guest os. The one's pid is 8888
+       and the other's is 9999.
+        #mkdir ~/guestmount; cd ~/guestmount
+        #sshfs -o allow_other,direct_io -p 5551 localhost:/ 8888/
+        #sshfs -o allow_other,direct_io -p 5552 localhost:/ 9999/
+        #perf kvm --host --guest --guestmount=~/guestmount top
+--guestkallsyms=<path>::
+        Guest os /proc/kallsyms file copy. 'perf' kvm' reads it to get guest
+       kernel symbols. Users copy it out from guest os.
+--guestmodules=<path>::
+       Guest os /proc/modules file copy. 'perf' kvm' reads it to get guest
+       kernel module information. Users copy it out from guest os.
+--guestvmlinux=<path>::
+       Guest os kernel vmlinux.
+
+SEE ALSO
+--------
+linkperf:perf-top[1], linkperf:perf-record[1], linkperf:perf-report[1],
+linkperf:perf-diff[1], linkperf:perf-buildid-list[1]
index 8290b94..43e3dd2 100644 (file)
@@ -15,6 +15,35 @@ DESCRIPTION
 This command displays the symbolic event types which can be selected in the
 various perf commands with the -e option.
 
+RAW HARDWARE EVENT DESCRIPTOR
+-----------------------------
+Even when an event is not available in a symbolic form within perf right now,
+it can be encoded in a per processor specific way.
+
+For instance For x86 CPUs NNN represents the raw register encoding with the
+layout of IA32_PERFEVTSELx MSRs (see [Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide] Figure 30-1 Layout
+of IA32_PERFEVTSELx MSRs) or AMD's PerfEvtSeln (see [AMD64 Architecture Programmer’s Manual Volume 2: System Programming], Page 344,
+Figure 13-7 Performance Event-Select Register (PerfEvtSeln)).
+
+Example:
+
+If the Intel docs for a QM720 Core i7 describe an event as:
+
+  Event  Umask  Event Mask
+  Num.   Value  Mnemonic    Description                        Comment
+
+  A8H      01H  LSD.UOPS    Counts the number of micro-ops     Use cmask=1 and
+                            delivered by loop stream detector  invert to count
+                                                               cycles
+
+raw encoding of 0x1A8 can be used:
+
+ perf stat -e r1a8 -a sleep 1
+ perf record -e r1a8 ...
+
+You should refer to the processor specific documentation for getting these
+details. Some of them are referenced in the SEE ALSO section below.
+
 OPTIONS
 -------
 None
@@ -22,4 +51,6 @@ None
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-top[1],
-linkperf:perf-record[1]
+linkperf:perf-record[1],
+http://www.intel.com/Assets/PDF/manual/253669.pdf[Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide],
+http://support.amd.com/us/Processor_TechDocs/24593.pdf[AMD64 Architecture Programmer’s Manual Volume 2: System Programming]
index 34202b1..94a258c 100644 (file)
@@ -57,6 +57,14 @@ OPTIONS
 --force::
        Forcibly add events with existing name.
 
+-n::
+--dry-run::
+       Dry run. With this option, --add and --del doesn't execute actual
+       adding and removal operations.
+
+--max-probes::
+       Set the maximum number of probe points for an event. Default is 128.
+
 PROBE SYNTAX
 ------------
 Probe points are defined by following syntax.
@@ -74,13 +82,22 @@ Probe points are defined by following syntax.
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
 'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition.  In addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
-'ARG' specifies the arguments of this probe point. You can use the name of local variable, or kprobe-tracer argument format (e.g. $retval, %ax, etc).
+'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+
+PROBE ARGUMENT
+--------------
+Each probe argument follows below syntax.
+
+ [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
+
+'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
+'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo.
 
 LINE SYNTAX
 -----------
 Line range is descripted by following syntax.
 
- "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]"
+ "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]"
 
 FUNC specifies the function name of showing lines. 'RLN' is the start line
 number from function entry line, and 'RLN2' is the end line number. As same as
index fc46c0b..34e255f 100644 (file)
@@ -58,7 +58,7 @@ OPTIONS
 
 -f::
 --force::
-       Overwrite existing data file.
+       Overwrite existing data file. (deprecated)
 
 -c::
 --count=::
@@ -69,8 +69,8 @@ OPTIONS
        Output file name.
 
 -i::
---inherit::
-       Child tasks inherit counters.
+--no-inherit::
+       Child tasks do not inherit counters.
 -F::
 --freq=::
        Profile at this frequency.
@@ -101,7 +101,7 @@ OPTIONS
 
 -R::
 --raw-samples::
-Collect raw sample records from all opened counters (typically for tracepoint counters).
+Collect raw sample records from all opened counters (default for tracepoint counters).
 
 SEE ALSO
 --------
index 1ce7919..8417644 100644 (file)
@@ -12,7 +12,7 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-There's four variants of perf sched:
+There are four variants of perf sched:
 
   'perf sched record <command>' to record the scheduling events
   of an arbitrary workload.
@@ -27,7 +27,7 @@ There's four variants of perf sched:
   via perf sched record. (this is done by starting up mockup threads
   that mimic the workload based on the events in the trace. These
   threads can then replay the timings (CPU runtime and sleep patterns)
-  of the workload as it occured when it was recorded - and can repeat
+  of the workload as it occurred when it was recorded - and can repeat
   it a number of times, measuring its performance.)
 
 OPTIONS
index 484080d..2cab8e8 100644 (file)
@@ -31,8 +31,8 @@ OPTIONS
         hexadecimal event descriptor.
 
 -i::
---inherit::
-        child tasks inherit counters
+--no-inherit::
+        child tasks do not inherit counters
 -p::
 --pid=<pid>::
         stat events on existing pid
diff --git a/tools/perf/Documentation/perf-test.txt b/tools/perf/Documentation/perf-test.txt
new file mode 100644 (file)
index 0000000..1c4b5f5
--- /dev/null
@@ -0,0 +1,22 @@
+perf-test(1)
+============
+
+NAME
+----
+perf-test - Runs sanity tests.
+
+SYNOPSIS
+--------
+[verse]
+'perf test <options>'
+
+DESCRIPTION
+-----------
+This command does assorted sanity tests, initially thru linked routines but
+also will look for a directory with more tests in the form of scripts.
+
+OPTIONS
+-------
+-v::
+--verbose::
+       Be more verbose.
index d729cee..ee6525e 100644 (file)
@@ -49,12 +49,10 @@ available as calls back into the perf executable (see below).
 As an example, the following perf record command can be used to record
 all sched_wakeup events in the system:
 
- # perf record -c 1 -f -a -M -R -e sched:sched_wakeup
+ # perf record -a -e sched:sched_wakeup
 
 Traces meant to be processed using a script should be recorded with
-the above options: -c 1 says to sample every event, -a to enable
-system-wide collection, -M to multiplex the output, and -R to collect
-raw samples.
+the above option: -a to enable system-wide collection.
 
 The format file for the sched_wakep event defines the following fields
 (see /sys/kernel/debug/tracing/events/sched/sched_wakeup/format):
index a241aca..693be80 100644 (file)
@@ -1,5 +1,5 @@
 perf-trace-python(1)
-==================
+====================
 
 NAME
 ----
@@ -93,7 +93,7 @@ don't care how it exited, so we'll use 'perf record' to record only
 the sys_enter events:
 
 ----
-# perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+# perf record -a -e raw_syscalls:sys_enter
 
 ^C[ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 56.545 MB perf.data (~2470503 samples) ]
@@ -182,7 +182,7 @@ mean either that the record step recorded event types that it wasn't
 really interested in, or the script was run against a trace file that
 doesn't correspond to the script.
 
-The script generated by -g option option simply prints a line for each
+The script generated by -g option simply prints a line for each
 event found in the trace stream i.e. it basically just dumps the event
 and its parameter values to stdout.  The print_header() function is
 simply a utility function used for that purpose.  Let's rename the
@@ -359,7 +359,7 @@ your script:
 # cat kernel-source/tools/perf/scripts/python/bin/syscall-counts-record
 
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+perf record -a -e raw_syscalls:sys_enter
 ----
 
 The 'report' script is also a shell script with the same base name as
@@ -449,12 +449,10 @@ available as calls back into the perf executable (see below).
 As an example, the following perf record command can be used to record
 all sched_wakeup events in the system:
 
- # perf record -c 1 -f -a -M -R -e sched:sched_wakeup
+ # perf record -a -e sched:sched_wakeup
 
 Traces meant to be processed using a script should be recorded with
-the above options: -c 1 says to sample every event, -a to enable
-system-wide collection, -M to multiplex the output, and -R to collect
-raw samples.
+the above option: -a to enable system-wide collection.
 
 The format file for the sched_wakep event defines the following fields
 (see /sys/kernel/debug/tracing/events/sched/sched_wakeup/format):
@@ -584,7 +582,7 @@ files:
   flag_str(event_name, field_name, field_value) - returns the string represention corresponding to field_value for the flag field field_name of event event_name
   symbol_str(event_name, field_name, field_value) - returns the string represention corresponding to field_value for the symbolic field field_name of event event_name
 
-The *autodict* function returns a special special kind of Python
+The *autodict* function returns a special kind of Python
 dictionary that implements Perl's 'autovivifying' hashes in Python
 i.e. with autovivifying hashes, you can assign nested hash values
 without having to go to the trouble of creating intermediate levels if
index 8879299..122ec9d 100644 (file)
@@ -1,5 +1,5 @@
 perf-trace(1)
-==============
+=============
 
 NAME
 ----
index bc0f670..3d8f31e 100644 (file)
@@ -1,3 +1,7 @@
+ifeq ("$(origin O)", "command line")
+       OUTPUT := $(O)/
+endif
+
 # The default target of this Makefile is...
 all::
 
@@ -150,10 +154,17 @@ all::
 # Define LDFLAGS=-static to build a static binary.
 #
 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
+#
+# Define NO_DWARF if you do not want debug-info analysis feature at all.
 
-PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
-       @$(SHELL_PATH) util/PERF-VERSION-GEN
--include PERF-VERSION-FILE
+$(shell sh -c 'mkdir -p $(OUTPUT)scripts/python/Perf-Trace-Util/' 2> /dev/null)
+$(shell sh -c 'mkdir -p $(OUTPUT)scripts/perl/Perf-Trace-Util/' 2> /dev/null)
+$(shell sh -c 'mkdir -p $(OUTPUT)util/scripting-engines/' 2> /dev/null)
+$(shell sh -c 'mkdir $(OUTPUT)bench' 2> /dev/null)
+
+$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
+       @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
+-include $(OUTPUT)PERF-VERSION-FILE
 
 uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
 uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
@@ -162,6 +173,22 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
 uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
 uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
 
+ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+                                 -e s/arm.*/arm/ -e s/sa110/arm/ \
+                                 -e s/s390x/s390/ -e s/parisc64/parisc/ \
+                                 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
+                                 -e s/sh[234].*/sh/ )
+
+# Additional ARCH settings for x86
+ifeq ($(ARCH),i386)
+        ARCH := x86
+endif
+ifeq ($(ARCH),x86_64)
+        ARCH := x86
+endif
+
+$(shell sh -c 'mkdir -p $(OUTPUT)arch/$(ARCH)/util/' 2> /dev/null)
+
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
 #
@@ -274,7 +301,7 @@ endif
 # Those must not be GNU-specific; they are shared with perl/ which may
 # be built by a different compiler. (Note that this is an artifact now
 # but it still might be nice to keep that distinction.)
-BASIC_CFLAGS = -Iutil/include
+BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
 BASIC_LDFLAGS =
 
 # Guard against environment variables
@@ -308,7 +335,7 @@ PROGRAMS += $(EXTRA_PROGRAMS)
 #
 # Single 'perf' binary right now:
 #
-PROGRAMS += perf
+PROGRAMS += $(OUTPUT)perf
 
 # List built-in command $C whose implementation cmd_$C() is not in
 # builtin-$C.o but is linked in as part of some other command.
@@ -318,7 +345,7 @@ PROGRAMS += perf
 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
 
 # what 'all' will build but not install in perfexecdir
-OTHER_PROGRAMS = perf$X
+OTHER_PROGRAMS = $(OUTPUT)perf$X
 
 # Set paths to tools early so that they can be used for version tests.
 ifndef SHELL_PATH
@@ -330,7 +357,7 @@ endif
 
 export PERL_PATH
 
-LIB_FILE=libperf.a
+LIB_FILE=$(OUTPUT)libperf.a
 
 LIB_H += ../../include/linux/perf_event.h
 LIB_H += ../../include/linux/rbtree.h
@@ -350,12 +377,13 @@ LIB_H += util/include/linux/rbtree.h
 LIB_H += util/include/linux/string.h
 LIB_H += util/include/linux/types.h
 LIB_H += util/include/asm/asm-offsets.h
-LIB_H += util/include/asm/bitops.h
 LIB_H += util/include/asm/bug.h
 LIB_H += util/include/asm/byteorder.h
+LIB_H += util/include/asm/hweight.h
 LIB_H += util/include/asm/swab.h
 LIB_H += util/include/asm/system.h
 LIB_H += util/include/asm/uaccess.h
+LIB_H += util/include/dwarf-regs.h
 LIB_H += perf.h
 LIB_H += util/cache.h
 LIB_H += util/callchain.h
@@ -375,7 +403,6 @@ LIB_H += util/header.h
 LIB_H += util/help.h
 LIB_H += util/session.h
 LIB_H += util/strbuf.h
-LIB_H += util/string.h
 LIB_H += util/strlist.h
 LIB_H += util/svghelper.h
 LIB_H += util/run-command.h
@@ -389,79 +416,83 @@ LIB_H += util/thread.h
 LIB_H += util/trace-event.h
 LIB_H += util/probe-finder.h
 LIB_H += util/probe-event.h
+LIB_H += util/pstack.h
 LIB_H += util/cpumap.h
 
-LIB_OBJS += util/abspath.o
-LIB_OBJS += util/alias.o
-LIB_OBJS += util/build-id.o
-LIB_OBJS += util/config.o
-LIB_OBJS += util/ctype.o
-LIB_OBJS += util/debugfs.o
-LIB_OBJS += util/environment.o
-LIB_OBJS += util/event.o
-LIB_OBJS += util/exec_cmd.o
-LIB_OBJS += util/help.o
-LIB_OBJS += util/levenshtein.o
-LIB_OBJS += util/parse-options.o
-LIB_OBJS += util/parse-events.o
-LIB_OBJS += util/path.o
-LIB_OBJS += util/rbtree.o
-LIB_OBJS += util/bitmap.o
-LIB_OBJS += util/hweight.o
-LIB_OBJS += util/find_next_bit.o
-LIB_OBJS += util/run-command.o
-LIB_OBJS += util/quote.o
-LIB_OBJS += util/strbuf.o
-LIB_OBJS += util/string.o
-LIB_OBJS += util/strlist.o
-LIB_OBJS += util/usage.o
-LIB_OBJS += util/wrapper.o
-LIB_OBJS += util/sigchain.o
-LIB_OBJS += util/symbol.o
-LIB_OBJS += util/color.o
-LIB_OBJS += util/pager.o
-LIB_OBJS += util/header.o
-LIB_OBJS += util/callchain.o
-LIB_OBJS += util/values.o
-LIB_OBJS += util/debug.o
-LIB_OBJS += util/map.o
-LIB_OBJS += util/session.o
-LIB_OBJS += util/thread.o
-LIB_OBJS += util/trace-event-parse.o
-LIB_OBJS += util/trace-event-read.o
-LIB_OBJS += util/trace-event-info.o
-LIB_OBJS += util/trace-event-scripting.o
-LIB_OBJS += util/svghelper.o
-LIB_OBJS += util/sort.o
-LIB_OBJS += util/hist.o
-LIB_OBJS += util/probe-event.o
-LIB_OBJS += util/util.o
-LIB_OBJS += util/cpumap.o
-
-BUILTIN_OBJS += builtin-annotate.o
-
-BUILTIN_OBJS += builtin-bench.o
+LIB_OBJS += $(OUTPUT)util/abspath.o
+LIB_OBJS += $(OUTPUT)util/alias.o
+LIB_OBJS += $(OUTPUT)util/build-id.o
+LIB_OBJS += $(OUTPUT)util/config.o
+LIB_OBJS += $(OUTPUT)util/ctype.o
+LIB_OBJS += $(OUTPUT)util/debugfs.o
+LIB_OBJS += $(OUTPUT)util/environment.o
+LIB_OBJS += $(OUTPUT)util/event.o
+LIB_OBJS += $(OUTPUT)util/exec_cmd.o
+LIB_OBJS += $(OUTPUT)util/help.o
+LIB_OBJS += $(OUTPUT)util/levenshtein.o
+LIB_OBJS += $(OUTPUT)util/parse-options.o
+LIB_OBJS += $(OUTPUT)util/parse-events.o
+LIB_OBJS += $(OUTPUT)util/path.o
+LIB_OBJS += $(OUTPUT)util/rbtree.o
+LIB_OBJS += $(OUTPUT)util/bitmap.o
+LIB_OBJS += $(OUTPUT)util/hweight.o
+LIB_OBJS += $(OUTPUT)util/run-command.o
+LIB_OBJS += $(OUTPUT)util/quote.o
+LIB_OBJS += $(OUTPUT)util/strbuf.o
+LIB_OBJS += $(OUTPUT)util/string.o
+LIB_OBJS += $(OUTPUT)util/strlist.o
+LIB_OBJS += $(OUTPUT)util/usage.o
+LIB_OBJS += $(OUTPUT)util/wrapper.o
+LIB_OBJS += $(OUTPUT)util/sigchain.o
+LIB_OBJS += $(OUTPUT)util/symbol.o
+LIB_OBJS += $(OUTPUT)util/color.o
+LIB_OBJS += $(OUTPUT)util/pager.o
+LIB_OBJS += $(OUTPUT)util/header.o
+LIB_OBJS += $(OUTPUT)util/callchain.o
+LIB_OBJS += $(OUTPUT)util/values.o
+LIB_OBJS += $(OUTPUT)util/debug.o
+LIB_OBJS += $(OUTPUT)util/map.o
+LIB_OBJS += $(OUTPUT)util/pstack.o
+LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/thread.o
+LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
+LIB_OBJS += $(OUTPUT)util/trace-event-read.o
+LIB_OBJS += $(OUTPUT)util/trace-event-info.o
+LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
+LIB_OBJS += $(OUTPUT)util/svghelper.o
+LIB_OBJS += $(OUTPUT)util/sort.o
+LIB_OBJS += $(OUTPUT)util/hist.o
+LIB_OBJS += $(OUTPUT)util/probe-event.o
+LIB_OBJS += $(OUTPUT)util/util.o
+LIB_OBJS += $(OUTPUT)util/cpumap.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
 
 # Benchmark modules
-BUILTIN_OBJS += bench/sched-messaging.o
-BUILTIN_OBJS += bench/sched-pipe.o
-BUILTIN_OBJS += bench/mem-memcpy.o
-
-BUILTIN_OBJS += builtin-diff.o
-BUILTIN_OBJS += builtin-help.o
-BUILTIN_OBJS += builtin-sched.o
-BUILTIN_OBJS += builtin-buildid-list.o
-BUILTIN_OBJS += builtin-buildid-cache.o
-BUILTIN_OBJS += builtin-list.o
-BUILTIN_OBJS += builtin-record.o
-BUILTIN_OBJS += builtin-report.o
-BUILTIN_OBJS += builtin-stat.o
-BUILTIN_OBJS += builtin-timechart.o
-BUILTIN_OBJS += builtin-top.o
-BUILTIN_OBJS += builtin-trace.o
-BUILTIN_OBJS += builtin-probe.o
-BUILTIN_OBJS += builtin-kmem.o
-BUILTIN_OBJS += builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
+BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
+BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
+
+BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
+BUILTIN_OBJS += $(OUTPUT)builtin-help.o
+BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
+BUILTIN_OBJS += $(OUTPUT)builtin-list.o
+BUILTIN_OBJS += $(OUTPUT)builtin-record.o
+BUILTIN_OBJS += $(OUTPUT)builtin-report.o
+BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
+BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
+BUILTIN_OBJS += $(OUTPUT)builtin-top.o
+BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
+BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
+BUILTIN_OBJS += $(OUTPUT)builtin-test.o
+BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
 
 PERFLIBS = $(LIB_FILE)
 
@@ -476,6 +507,15 @@ PERFLIBS = $(LIB_FILE)
 -include config.mak.autogen
 -include config.mak
 
+ifndef NO_DWARF
+ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo '\#include <version.h>'; echo '\#ifndef _ELFUTILS_PREREQ'; echo '\#error'; echo '\#endif'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+       msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
+       NO_DWARF := 1
+endif # Dwarf support
+endif # NO_DWARF
+
+-include arch/$(ARCH)/Makefile
+
 ifeq ($(uname_S),Darwin)
        ifndef NO_FINK
                ifeq ($(shell test -d /sw/lib && echo y),y)
@@ -492,6 +532,10 @@ ifeq ($(uname_S),Darwin)
        PTHREAD_LIBS =
 endif
 
+ifneq ($(OUTPUT),)
+       BASIC_CFLAGS += -I$(OUTPUT)
+endif
+
 ifeq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
 ifneq ($(shell sh -c "(echo '\#include <gnu/libc-version.h>'; echo 'int main(void) { const char * version = gnu_get_libc_version(); return (long)version; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
        msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
@@ -504,14 +548,29 @@ else
        msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
 endif
 
-ifneq ($(shell sh -c "(echo '\#include <dwarf.h>'; echo '\#include <libdw.h>'; echo 'int main(void) { Dwarf *dbg; dbg = dwarf_begin(0, DWARF_C_READ); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -I/usr/include/elfutils -ldw -lelf -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
-       msg := $(warning No libdw.h found or old libdw.h found, disables dwarf support. Please install elfutils-devel/elfutils-dev);
-       BASIC_CFLAGS += -DNO_DWARF_SUPPORT
+ifndef NO_DWARF
+ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
+       msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
 else
-       BASIC_CFLAGS += -I/usr/include/elfutils
+       BASIC_CFLAGS += -I/usr/include/elfutils -DDWARF_SUPPORT
        EXTLIBS += -lelf -ldw
-       LIB_OBJS += util/probe-finder.o
+       LIB_OBJS += $(OUTPUT)util/probe-finder.o
+endif # PERF_HAVE_DWARF_REGS
+endif # NO_DWARF
+
+ifdef NO_NEWT
+       BASIC_CFLAGS += -DNO_NEWT_SUPPORT
+else
+ifneq ($(shell sh -c "(echo '\#include <newt.h>'; echo 'int main(void) { newtInit(); newtCls(); return newtFinished(); }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lnewt -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+       msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
+       BASIC_CFLAGS += -DNO_NEWT_SUPPORT
+else
+       # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
+       BASIC_CFLAGS += -I/usr/include/slang
+       EXTLIBS += -lnewt -lslang
+       LIB_OBJS += $(OUTPUT)util/newt.o
 endif
+endif # NO_NEWT
 
 ifndef NO_LIBPERL
 PERL_EMBED_LDOPTS = `perl -MExtUtils::Embed -e ldopts 2>/dev/null`
@@ -522,8 +581,8 @@ ifneq ($(shell sh -c "(echo '\#include <EXTERN.h>'; echo '\#include <perl.h>'; e
        BASIC_CFLAGS += -DNO_LIBPERL
 else
        ALL_LDFLAGS += $(PERL_EMBED_LDOPTS)
-       LIB_OBJS += util/scripting-engines/trace-event-perl.o
-       LIB_OBJS += scripts/perl/Perf-Trace-Util/Context.o
+       LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
+       LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
 endif
 
 ifndef NO_LIBPYTHON
@@ -531,16 +590,19 @@ PYTHON_EMBED_LDOPTS = `python-config --ldflags 2>/dev/null`
 PYTHON_EMBED_CCOPTS = `python-config --cflags 2>/dev/null`
 endif
 
-ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o /dev/null $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
+ifneq ($(shell sh -c "(echo '\#include <Python.h>'; echo 'int main(void) { Py_Initialize(); return 0; }') | $(CC) -x c - $(PYTHON_EMBED_CCOPTS) -o $(BITBUCKET) $(PYTHON_EMBED_LDOPTS) > /dev/null 2>&1 && echo y"), y)
        BASIC_CFLAGS += -DNO_LIBPYTHON
 else
        ALL_LDFLAGS += $(PYTHON_EMBED_LDOPTS)
-       LIB_OBJS += util/scripting-engines/trace-event-python.o
-       LIB_OBJS += scripts/python/Perf-Trace-Util/Context.o
+       LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
+       LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
 endif
 
 ifdef NO_DEMANGLE
        BASIC_CFLAGS += -DNO_DEMANGLE
+else ifdef HAVE_CPLUS_DEMANGLE
+       EXTLIBS += -liberty
+       BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
 else
        has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o $(BITBUCKET) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd "$(QUIET_STDERR)" && echo y")
 
@@ -607,53 +669,53 @@ ifdef NO_C99_FORMAT
 endif
 ifdef SNPRINTF_RETURNS_BOGUS
        COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS
-       COMPAT_OBJS += compat/snprintf.o
+       COMPAT_OBJS += $(OUTPUT)compat/snprintf.o
 endif
 ifdef FREAD_READS_DIRECTORIES
        COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES
-       COMPAT_OBJS += compat/fopen.o
+       COMPAT_OBJS += $(OUTPUT)compat/fopen.o
 endif
 ifdef NO_SYMLINK_HEAD
        BASIC_CFLAGS += -DNO_SYMLINK_HEAD
 endif
 ifdef NO_STRCASESTR
        COMPAT_CFLAGS += -DNO_STRCASESTR
-       COMPAT_OBJS += compat/strcasestr.o
+       COMPAT_OBJS += $(OUTPUT)compat/strcasestr.o
 endif
 ifdef NO_STRTOUMAX
        COMPAT_CFLAGS += -DNO_STRTOUMAX
-       COMPAT_OBJS += compat/strtoumax.o
+       COMPAT_OBJS += $(OUTPUT)compat/strtoumax.o
 endif
 ifdef NO_STRTOULL
        COMPAT_CFLAGS += -DNO_STRTOULL
 endif
 ifdef NO_SETENV
        COMPAT_CFLAGS += -DNO_SETENV
-       COMPAT_OBJS += compat/setenv.o
+       COMPAT_OBJS += $(OUTPUT)compat/setenv.o
 endif
 ifdef NO_MKDTEMP
        COMPAT_CFLAGS += -DNO_MKDTEMP
-       COMPAT_OBJS += compat/mkdtemp.o
+       COMPAT_OBJS += $(OUTPUT)compat/mkdtemp.o
 endif
 ifdef NO_UNSETENV
        COMPAT_CFLAGS += -DNO_UNSETENV
-       COMPAT_OBJS += compat/unsetenv.o
+       COMPAT_OBJS += $(OUTPUT)compat/unsetenv.o
 endif
 ifdef NO_SYS_SELECT_H
        BASIC_CFLAGS += -DNO_SYS_SELECT_H
 endif
 ifdef NO_MMAP
        COMPAT_CFLAGS += -DNO_MMAP
-       COMPAT_OBJS += compat/mmap.o
+       COMPAT_OBJS += $(OUTPUT)compat/mmap.o
 else
        ifdef USE_WIN32_MMAP
                COMPAT_CFLAGS += -DUSE_WIN32_MMAP
-               COMPAT_OBJS += compat/win32mmap.o
+               COMPAT_OBJS += $(OUTPUT)compat/win32mmap.o
        endif
 endif
 ifdef NO_PREAD
        COMPAT_CFLAGS += -DNO_PREAD
-       COMPAT_OBJS += compat/pread.o
+       COMPAT_OBJS += $(OUTPUT)compat/pread.o
 endif
 ifdef NO_FAST_WORKING_DIRECTORY
        BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
@@ -675,10 +737,10 @@ else
 endif
 endif
 ifdef NO_INET_NTOP
-       LIB_OBJS += compat/inet_ntop.o
+       LIB_OBJS += $(OUTPUT)compat/inet_ntop.o
 endif
 ifdef NO_INET_PTON
-       LIB_OBJS += compat/inet_pton.o
+       LIB_OBJS += $(OUTPUT)compat/inet_pton.o
 endif
 
 ifdef NO_ICONV
@@ -695,15 +757,15 @@ endif
 
 ifdef PPC_SHA1
        SHA1_HEADER = "ppc/sha1.h"
-       LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o
+       LIB_OBJS += $(OUTPUT)ppc/sha1.o ppc/sha1ppc.o
 else
 ifdef ARM_SHA1
        SHA1_HEADER = "arm/sha1.h"
-       LIB_OBJS += arm/sha1.o arm/sha1_arm.o
+       LIB_OBJS += $(OUTPUT)arm/sha1.o $(OUTPUT)arm/sha1_arm.o
 else
 ifdef MOZILLA_SHA1
        SHA1_HEADER = "mozilla-sha1/sha1.h"
-       LIB_OBJS += mozilla-sha1/sha1.o
+       LIB_OBJS += $(OUTPUT)mozilla-sha1/sha1.o
 else
        SHA1_HEADER = <openssl/sha.h>
        EXTLIBS += $(LIB_4_CRYPTO)
@@ -715,15 +777,15 @@ ifdef NO_PERL_MAKEMAKER
 endif
 ifdef NO_HSTRERROR
        COMPAT_CFLAGS += -DNO_HSTRERROR
-       COMPAT_OBJS += compat/hstrerror.o
+       COMPAT_OBJS += $(OUTPUT)compat/hstrerror.o
 endif
 ifdef NO_MEMMEM
        COMPAT_CFLAGS += -DNO_MEMMEM
-       COMPAT_OBJS += compat/memmem.o
+       COMPAT_OBJS += $(OUTPUT)compat/memmem.o
 endif
 ifdef INTERNAL_QSORT
        COMPAT_CFLAGS += -DINTERNAL_QSORT
-       COMPAT_OBJS += compat/qsort.o
+       COMPAT_OBJS += $(OUTPUT)compat/qsort.o
 endif
 ifdef RUNTIME_PREFIX
        COMPAT_CFLAGS += -DRUNTIME_PREFIX
@@ -803,7 +865,7 @@ export TAR INSTALL DESTDIR SHELL_PATH
 
 SHELL = $(SHELL_PATH)
 
-all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS
+all:: .perf.dev.null shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) $(OUTPUT)PERF-BUILD-OPTIONS
 ifneq (,$X)
        $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';)
 endif
@@ -815,39 +877,39 @@ please_set_SHELL_PATH_to_a_more_modern_shell:
 
 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
 
-strip: $(PROGRAMS) perf$X
-       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X
+strip: $(PROGRAMS) $(OUTPUT)perf$X
+       $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf$X
 
-perf.o: perf.c common-cmds.h PERF-CFLAGS
+$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
-               $(ALL_CFLAGS) -c $(filter %.c,$^)
+               $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
 
-perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS)
-       $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \
+$(OUTPUT)perf$X: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
+       $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(OUTPUT)perf.o \
                $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
 
-builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
                '-DPERF_MAN_PATH="$(mandir_SQ)"' \
                '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
 
-builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
                '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
                '-DPERF_MAN_PATH="$(mandir_SQ)"' \
                '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
 
-$(BUILT_INS): perf$X
+$(BUILT_INS): $(OUTPUT)perf$X
        $(QUIET_BUILT_IN)$(RM) $@ && \
        ln perf$X $@ 2>/dev/null || \
        ln -s perf$X $@ 2>/dev/null || \
        cp perf$X $@
 
-common-cmds.h: util/generate-cmdlist.sh command-list.txt
+$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
 
-common-cmds.h: $(wildcard Documentation/perf-*.txt)
+$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
        $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
 
 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
@@ -859,7 +921,7 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
            -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
            $@.sh >$@+ && \
        chmod +x $@+ && \
-       mv $@+ $@
+       mv $@+ $(OUTPUT)$@
 
 configure: configure.ac
        $(QUIET_GEN)$(RM) $@ $<+ && \
@@ -869,60 +931,50 @@ configure: configure.ac
        $(RM) $<+
 
 # These can record PERF_VERSION
-perf.o perf.spec \
+$(OUTPUT)perf.o perf.spec \
        $(patsubst %.sh,%,$(SCRIPT_SH)) \
        $(patsubst %.perl,%,$(SCRIPT_PERL)) \
-       : PERF-VERSION-FILE
+       : $(OUTPUT)PERF-VERSION-FILE
 
-%.o: %.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
-%.s: %.c PERF-CFLAGS
+$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
+$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
-%.o: %.S
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $<
+$(OUTPUT)%.o: %.S
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
 
-util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
                '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
                '-DBINDIR="$(bindir_relative_SQ)"' \
                '-DPREFIX="$(prefix_SQ)"' \
                $<
 
-builtin-init-db.o: builtin-init-db.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
-
-util/config.o: util/config.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-
-util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
-
-# some perf warning policies can't fit to lib/bitmap.c, eg: it warns about variable shadowing
-# from <string.h> that comes from kernel headers wrapping.
-KBITMAP_FLAGS=`echo $(ALL_CFLAGS) | sed s/-Wshadow// | sed s/-Wswitch-default// | sed s/-Wextra//`
+$(OUTPUT)builtin-init-db.o: builtin-init-db.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
 
-util/bitmap.o: ../../lib/bitmap.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/bitmap.o -c $(KBITMAP_FLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
 
-util/hweight.o: ../../lib/hweight.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/hweight.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/newt.o: util/newt.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
 
-util/find_next_bit.o: ../../lib/find_next_bit.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/find_next_bit.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
+$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
 
-util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-perl.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
 
-scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o scripts/perl/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
 
-util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o util/scripting-engines/trace-event-python.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
+$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
 
-scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c PERF-CFLAGS
-       $(QUIET_CC)$(CC) -o scripts/python/Perf-Trace-Util/Context.o -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
+$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
+       $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
 
-perf-%$X: %.o $(PERFLIBS)
+$(OUTPUT)perf-%$X: %.o $(PERFLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
 
 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
@@ -963,17 +1015,17 @@ cscope:
 TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
              $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
 
-PERF-CFLAGS: .FORCE-PERF-CFLAGS
+$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
        @FLAGS='$(TRACK_CFLAGS)'; \
-           if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \
+           if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
                echo 1>&2 "    * new build flags or prefix"; \
-               echo "$$FLAGS" >PERF-CFLAGS; \
+               echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
             fi
 
 # We need to apply sq twice, once to protect from the shell
-# that runs PERF-BUILD-OPTIONS, and then again to protect it
+# that runs $(OUTPUT)PERF-BUILD-OPTIONS, and then again to protect it
 # and the first level quoting from the shell that runs "echo".
-PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
+$(OUTPUT)PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS
        @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@
        @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@
        @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@
@@ -994,7 +1046,7 @@ all:: $(TEST_PROGRAMS)
 
 export NO_SVN_TESTS
 
-check: common-cmds.h
+check: $(OUTPUT)common-cmds.h
        if sparse; \
        then \
                for i in *.c */*.c; \
@@ -1028,10 +1080,10 @@ export perfexec_instdir
 
 install: all
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
-       $(INSTALL) perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
+       $(INSTALL) $(OUTPUT)perf$X '$(DESTDIR_SQ)$(bindir_SQ)'
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
-       $(INSTALL) perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+       $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
        $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
        $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
        $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
@@ -1045,7 +1097,7 @@ ifdef BUILT_INS
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
        $(INSTALL) $(BUILT_INS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
 ifneq (,$X)
-       $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
+       $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) $(OUTPUT)perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';)
 endif
 endif
 
@@ -1129,14 +1181,14 @@ clean:
        $(RM) *.o */*.o */*/*.o */*/*/*.o $(LIB_FILE)
        $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X
        $(RM) $(TEST_PROGRAMS)
-       $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope*
+       $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
        $(RM) -r autom4te.cache
        $(RM) config.log config.mak.autogen config.mak.append config.status config.cache
        $(RM) -r $(PERF_TARNAME) .doc-tmp-dir
        $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz
        $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
        $(MAKE) -C Documentation/ clean
-       $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS
+       $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)PERF-BUILD-OPTIONS
 
 .PHONY: all install clean strip
 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile
new file mode 100644 (file)
index 0000000..15130b5
--- /dev/null
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..48ae0c5
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Ian Munsie, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+
+struct pt_regs_dwarfnum {
+       const char *name;
+       unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+       {.name = STR(%gpr##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+       GPR_DWARFNUM_NAME(0),
+       GPR_DWARFNUM_NAME(1),
+       GPR_DWARFNUM_NAME(2),
+       GPR_DWARFNUM_NAME(3),
+       GPR_DWARFNUM_NAME(4),
+       GPR_DWARFNUM_NAME(5),
+       GPR_DWARFNUM_NAME(6),
+       GPR_DWARFNUM_NAME(7),
+       GPR_DWARFNUM_NAME(8),
+       GPR_DWARFNUM_NAME(9),
+       GPR_DWARFNUM_NAME(10),
+       GPR_DWARFNUM_NAME(11),
+       GPR_DWARFNUM_NAME(12),
+       GPR_DWARFNUM_NAME(13),
+       GPR_DWARFNUM_NAME(14),
+       GPR_DWARFNUM_NAME(15),
+       GPR_DWARFNUM_NAME(16),
+       GPR_DWARFNUM_NAME(17),
+       GPR_DWARFNUM_NAME(18),
+       GPR_DWARFNUM_NAME(19),
+       GPR_DWARFNUM_NAME(20),
+       GPR_DWARFNUM_NAME(21),
+       GPR_DWARFNUM_NAME(22),
+       GPR_DWARFNUM_NAME(23),
+       GPR_DWARFNUM_NAME(24),
+       GPR_DWARFNUM_NAME(25),
+       GPR_DWARFNUM_NAME(26),
+       GPR_DWARFNUM_NAME(27),
+       GPR_DWARFNUM_NAME(28),
+       GPR_DWARFNUM_NAME(29),
+       GPR_DWARFNUM_NAME(30),
+       GPR_DWARFNUM_NAME(31),
+       REG_DWARFNUM_NAME("%msr",   66),
+       REG_DWARFNUM_NAME("%ctr",   109),
+       REG_DWARFNUM_NAME("%link",  108),
+       REG_DWARFNUM_NAME("%xer",   101),
+       REG_DWARFNUM_NAME("%dar",   119),
+       REG_DWARFNUM_NAME("%dsisr", 118),
+       REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n: the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+       const struct pt_regs_dwarfnum *roff;
+       for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+               if (roff->dwarfnum == n)
+                       return roff->name;
+       return NULL;
+}
diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile
new file mode 100644 (file)
index 0000000..15130b5
--- /dev/null
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..a794d30
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ * Extracted from probe-finder.c
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.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 <libio.h>
+#include <dwarf-regs.h>
+
+/*
+ * Generic dwarf analysis helpers
+ */
+
+#define X86_32_MAX_REGS 8
+const char *x86_32_regs_table[X86_32_MAX_REGS] = {
+       "%ax",
+       "%cx",
+       "%dx",
+       "%bx",
+       "$stack",       /* Stack address instead of %sp */
+       "%bp",
+       "%si",
+       "%di",
+};
+
+#define X86_64_MAX_REGS 16
+const char *x86_64_regs_table[X86_64_MAX_REGS] = {
+       "%ax",
+       "%dx",
+       "%cx",
+       "%bx",
+       "%si",
+       "%di",
+       "%bp",
+       "%sp",
+       "%r8",
+       "%r9",
+       "%r10",
+       "%r11",
+       "%r12",
+       "%r13",
+       "%r14",
+       "%r15",
+};
+
+/* TODO: switching by dwarf address size */
+#ifdef __x86_64__
+#define ARCH_MAX_REGS X86_64_MAX_REGS
+#define arch_regs_table x86_64_regs_table
+#else
+#define ARCH_MAX_REGS X86_32_MAX_REGS
+#define arch_regs_table x86_32_regs_table
+#endif
+
+/* Return architecture dependent register string (for kprobe-tracer) */
+const char *get_arch_regstr(unsigned int n)
+{
+       return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
+}
index 8977317..38dae74 100644 (file)
@@ -10,7 +10,6 @@
 #include "../perf.h"
 #include "../util/util.h"
 #include "../util/parse-options.h"
-#include "../util/string.h"
 #include "../util/header.h"
 #include "bench.h"
 
@@ -24,7 +23,7 @@
 
 static const char      *length_str     = "1MB";
 static const char      *routine        = "default";
-static int             use_clock       = 0;
+static bool            use_clock       = false;
 static int             clock_fd;
 
 static const struct option options[] = {
index 81cee78..d1d1b30 100644 (file)
@@ -31,9 +31,9 @@
 
 #define DATASIZE 100
 
-static int use_pipes = 0;
+static bool use_pipes = false;
 static unsigned int loops = 100;
-static unsigned int thread_mode = 0;
+static bool thread_mode = false;
 static unsigned int num_groups = 10;
 
 struct sender_context {
@@ -256,10 +256,8 @@ static const struct option options[] = {
                    "Use pipe() instead of socketpair()"),
        OPT_BOOLEAN('t', "thread", &thread_mode,
                    "Be multi thread instead of multi process"),
-       OPT_INTEGER('g', "group", &num_groups,
-                   "Specify number of groups"),
-       OPT_INTEGER('l', "loop", &loops,
-                   "Specify number of loops"),
+       OPT_UINTEGER('g', "group", &num_groups, "Specify number of groups"),
+       OPT_UINTEGER('l', "loop", &loops, "Specify number of loops"),
        OPT_END()
 };
 
index 4f77c7c..d9ab3ce 100644 (file)
@@ -93,7 +93,7 @@ int bench_sched_pipe(int argc, const char **argv,
 
        switch (bench_format) {
        case BENCH_FORMAT_DEFAULT:
-               printf("# Extecuted %d pipe operations between two tasks\n\n",
+               printf("# Executed %d pipe operations between two tasks\n\n",
                        loops);
 
                result_usec = diff.tv_sec * 1000000;
index 6ad7148..77bcc9b 100644 (file)
@@ -14,7 +14,6 @@
 #include "util/cache.h"
 #include <linux/rbtree.h>
 #include "util/symbol.h"
-#include "util/string.h"
 
 #include "perf.h"
 #include "util/debug.h"
 
 static char            const *input_name = "perf.data";
 
-static int             force;
+static bool            force;
 
-static int             full_paths;
+static bool            full_paths;
 
-static int             print_line;
-
-struct sym_hist {
-       u64             sum;
-       u64             ip[0];
-};
-
-struct sym_ext {
-       struct rb_node  node;
-       double          percent;
-       char            *path;
-};
-
-struct sym_priv {
-       struct sym_hist *hist;
-       struct sym_ext  *ext;
-};
+static bool            print_line;
 
 static const char *sym_hist_filter;
 
-static int sym__alloc_hist(struct symbol *self)
-{
-       struct sym_priv *priv = symbol__priv(self);
-       const int size = (sizeof(*priv->hist) +
-                         (self->end - self->start) * sizeof(u64));
-
-       priv->hist = zalloc(size);
-       return priv->hist == NULL ? -1 : 0;
-}
-
-/*
- * collect histogram counts
- */
-static int annotate__hist_hit(struct hist_entry *he, u64 ip)
-{
-       unsigned int sym_size, offset;
-       struct symbol *sym = he->sym;
-       struct sym_priv *priv;
-       struct sym_hist *h;
-
-       he->count++;
-
-       if (!sym || !he->map)
-               return 0;
-
-       priv = symbol__priv(sym);
-       if (priv->hist == NULL && sym__alloc_hist(sym) < 0)
-               return -ENOMEM;
-
-       sym_size = sym->end - sym->start;
-       offset = ip - sym->start;
-
-       pr_debug3("%s: ip=%#Lx\n", __func__, he->map->unmap_ip(he->map, ip));
-
-       if (offset >= sym_size)
-               return 0;
-
-       h = priv->hist;
-       h->sum++;
-       h->ip[offset]++;
-
-       pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", he->sym->start,
-                 he->sym->name, ip, ip - he->sym->start, h->ip[offset]);
-       return 0;
-}
-
-static int perf_session__add_hist_entry(struct perf_session *self,
-                                       struct addr_location *al, u64 count)
+static int hists__add_entry(struct hists *self, struct addr_location *al)
 {
-       bool hit;
        struct hist_entry *he;
 
        if (sym_hist_filter != NULL &&
@@ -116,11 +51,11 @@ static int perf_session__add_hist_entry(struct perf_session *self,
                return 0;
        }
 
-       he = __perf_session__add_hist_entry(&self->hists, al, NULL, count, &hit);
+       he = __hists__add_entry(self, al, NULL, 1);
        if (he == NULL)
                return -ENOMEM;
 
-       return annotate__hist_hit(he, al->addr);
+       return hist_entry__inc_addr_samples(he, al->addr);
 }
 
 static int process_sample_event(event_t *event, struct perf_session *session)
@@ -136,7 +71,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                return -1;
        }
 
-       if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) {
+       if (!al.filtered && hists__add_entry(&session->hists, &al)) {
                pr_warning("problem incrementing symbol count, "
                           "skipping event\n");
                return -1;
@@ -145,106 +80,11 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        return 0;
 }
 
-struct objdump_line {
-       struct list_head node;
-       s64              offset;
-       char             *line;
-};
-
-static struct objdump_line *objdump_line__new(s64 offset, char *line)
-{
-       struct objdump_line *self = malloc(sizeof(*self));
-
-       if (self != NULL) {
-               self->offset = offset;
-               self->line = line;
-       }
-
-       return self;
-}
-
-static void objdump_line__free(struct objdump_line *self)
-{
-       free(self->line);
-       free(self);
-}
-
-static void objdump__add_line(struct list_head *head, struct objdump_line *line)
-{
-       list_add_tail(&line->node, head);
-}
-
-static struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
-                                                     struct objdump_line *pos)
-{
-       list_for_each_entry_continue(pos, head, node)
-               if (pos->offset >= 0)
-                       return pos;
-
-       return NULL;
-}
-
-static int parse_line(FILE *file, struct hist_entry *he,
-                     struct list_head *head)
-{
-       struct symbol *sym = he->sym;
-       struct objdump_line *objdump_line;
-       char *line = NULL, *tmp, *tmp2;
-       size_t line_len;
-       s64 line_ip, offset = -1;
-       char *c;
-
-       if (getline(&line, &line_len, file) < 0)
-               return -1;
-
-       if (!line)
-               return -1;
-
-       c = strchr(line, '\n');
-       if (c)
-               *c = 0;
-
-       line_ip = -1;
-
-       /*
-        * Strip leading spaces:
-        */
-       tmp = line;
-       while (*tmp) {
-               if (*tmp != ' ')
-                       break;
-               tmp++;
-       }
-
-       if (*tmp) {
-               /*
-                * Parse hexa addresses followed by ':'
-                */
-               line_ip = strtoull(tmp, &tmp2, 16);
-               if (*tmp2 != ':')
-                       line_ip = -1;
-       }
-
-       if (line_ip != -1) {
-               u64 start = map__rip_2objdump(he->map, sym->start);
-               offset = line_ip - start;
-       }
-
-       objdump_line = objdump_line__new(offset, line);
-       if (objdump_line == NULL) {
-               free(line);
-               return -1;
-       }
-       objdump__add_line(head, objdump_line);
-
-       return 0;
-}
-
 static int objdump_line__print(struct objdump_line *self,
                               struct list_head *head,
                               struct hist_entry *he, u64 len)
 {
-       struct symbol *sym = he->sym;
+       struct symbol *sym = he->ms.sym;
        static const char *prev_line;
        static const char *prev_color;
 
@@ -327,7 +167,7 @@ static void insert_source_line(struct sym_ext *sym_ext)
 
 static void free_source_line(struct hist_entry *he, int len)
 {
-       struct sym_priv *priv = symbol__priv(he->sym);
+       struct sym_priv *priv = symbol__priv(he->ms.sym);
        struct sym_ext *sym_ext = priv->ext;
        int i;
 
@@ -346,7 +186,7 @@ static void free_source_line(struct hist_entry *he, int len)
 static void
 get_source_line(struct hist_entry *he, int len, const char *filename)
 {
-       struct symbol *sym = he->sym;
+       struct symbol *sym = he->ms.sym;
        u64 start;
        int i;
        char cmd[PATH_MAX * 2];
@@ -361,7 +201,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename)
        if (!priv->ext)
                return;
 
-       start = he->map->unmap_ip(he->map, sym->start);
+       start = he->ms.map->unmap_ip(he->ms.map, sym->start);
 
        for (i = 0; i < len; i++) {
                char *path = NULL;
@@ -425,7 +265,7 @@ static void print_summary(const char *filename)
 
 static void hist_entry__print_hits(struct hist_entry *self)
 {
-       struct symbol *sym = self->sym;
+       struct symbol *sym = self->ms.sym;
        struct sym_priv *priv = symbol__priv(sym);
        struct sym_hist *h = priv->hist;
        u64 len = sym->end - sym->start, offset;
@@ -439,23 +279,17 @@ static void hist_entry__print_hits(struct hist_entry *self)
 
 static void annotate_sym(struct hist_entry *he)
 {
-       struct map *map = he->map;
+       struct map *map = he->ms.map;
        struct dso *dso = map->dso;
-       struct symbol *sym = he->sym;
+       struct symbol *sym = he->ms.sym;
        const char *filename = dso->long_name, *d_filename;
        u64 len;
-       char command[PATH_MAX*2];
-       FILE *file;
        LIST_HEAD(head);
        struct objdump_line *pos, *n;
 
-       if (!filename)
+       if (hist_entry__annotate(he, &head) < 0)
                return;
 
-       pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__,
-                filename, sym->name, map->unmap_ip(map, sym->start),
-                map->unmap_ip(map, sym->end));
-
        if (full_paths)
                d_filename = filename;
        else
@@ -472,29 +306,6 @@ static void annotate_sym(struct hist_entry *he)
        printf(" Percent |      Source code & Disassembly of %s\n", d_filename);
        printf("------------------------------------------------\n");
 
-       if (verbose >= 2)
-               printf("annotating [%p] %30s : [%p] %30s\n",
-                      dso, dso->long_name, sym, sym->name);
-
-       sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s",
-               map__rip_2objdump(map, sym->start),
-               map__rip_2objdump(map, sym->end),
-               filename, filename);
-
-       if (verbose >= 3)
-               printf("doing: %s\n", command);
-
-       file = popen(command, "r");
-       if (!file)
-               return;
-
-       while (!feof(file)) {
-               if (parse_line(file, he, &head) < 0)
-                       break;
-       }
-
-       pclose(file);
-
        if (verbose)
                hist_entry__print_hits(he);
 
@@ -508,25 +319,25 @@ static void annotate_sym(struct hist_entry *he)
                free_source_line(he, len);
 }
 
-static void perf_session__find_annotations(struct perf_session *self)
+static void hists__find_annotations(struct hists *self)
 {
        struct rb_node *nd;
 
-       for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
                struct sym_priv *priv;
 
-               if (he->sym == NULL)
+               if (he->ms.sym == NULL)
                        continue;
 
-               priv = symbol__priv(he->sym);
+               priv = symbol__priv(he->ms.sym);
                if (priv->hist == NULL)
                        continue;
 
                annotate_sym(he);
                /*
                 * Since we have a hist_entry per IP for the same symbol, free
-                * he->sym->hist to signal we already processed this symbol.
+                * he->ms.sym->hist to signal we already processed this symbol.
                 */
                free(priv->hist);
                priv->hist = NULL;
@@ -545,7 +356,7 @@ static int __cmd_annotate(void)
        int ret;
        struct perf_session *session;
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, false);
        if (session == NULL)
                return -ENOMEM;
 
@@ -554,7 +365,7 @@ static int __cmd_annotate(void)
                goto out_delete;
 
        if (dump_trace) {
-               event__print_totals();
+               perf_session__fprintf_nr_events(session, stdout);
                goto out_delete;
        }
 
@@ -562,11 +373,11 @@ static int __cmd_annotate(void)
                perf_session__fprintf(session, stdout);
 
        if (verbose > 2)
-               dsos__fprintf(stdout);
+               perf_session__fprintf_dsos(session, stdout);
 
-       perf_session__collapse_resort(&session->hists);
-       perf_session__output_resort(&session->hists, session->event_total[0]);
-       perf_session__find_annotations(session);
+       hists__collapse_resort(&session->hists);
+       hists__output_resort(&session->hists);
+       hists__find_annotations(&session->hists);
 out_delete:
        perf_session__delete(session);
 
@@ -581,10 +392,12 @@ static const char * const annotate_usage[] = {
 static const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
+       OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
+                  "only consider symbols in these dsos"),
        OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
                    "symbol to annotate"),
        OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
index 4699677..fcb9626 100644 (file)
@@ -95,7 +95,7 @@ static void dump_suites(int subsys_index)
        return;
 }
 
-static char *bench_format_str;
+static const char *bench_format_str;
 int bench_format = BENCH_FORMAT_DEFAULT;
 
 static const struct option bench_options[] = {
@@ -126,7 +126,7 @@ static void print_usage(void)
        printf("\n");
 }
 
-static int bench_str2int(char *str)
+static int bench_str2int(const char *str)
 {
        if (!str)
                return BENCH_FORMAT_DEFAULT;
index 30a05f5..f8e3d18 100644 (file)
@@ -27,7 +27,7 @@ static const struct option buildid_cache_options[] = {
                   "file list", "file(s) to add"),
        OPT_STRING('r', "remove", &remove_name_list_str, "file list",
                    "file(s) to remove"),
-       OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose"),
+       OPT_INCR('v', "verbose", &verbose, "be more verbose"),
        OPT_END()
 };
 
index d0675c0..44a47e1 100644 (file)
@@ -16,7 +16,7 @@
 #include "util/symbol.h"
 
 static char const *input_name = "perf.data";
-static int force;
+static bool force;
 static bool with_hits;
 
 static const char * const buildid_list_usage[] = {
@@ -29,7 +29,7 @@ static const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
        OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose"),
        OPT_END()
 };
@@ -39,14 +39,14 @@ static int __cmd_buildid_list(void)
        int err = -1;
        struct perf_session *session;
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, false);
        if (session == NULL)
                return -1;
 
        if (with_hits)
                perf_session__process_events(session, &build_id__mark_dso_hit_ops);
 
-       dsos__fprintf_buildid(stdout, with_hits);
+       perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
 
        perf_session__delete(session);
        return err;
index 1ea15d8..a6e2fdc 100644 (file)
 static char const *input_old = "perf.data.old",
                  *input_new = "perf.data";
 static char      diff__default_sort_order[] = "dso,symbol";
-static int  force;
+static bool  force;
 static bool show_displacement;
 
-static int perf_session__add_hist_entry(struct perf_session *self,
-                                       struct addr_location *al, u64 count)
+static int hists__add_entry(struct hists *self,
+                           struct addr_location *al, u64 period)
 {
-       bool hit;
-       struct hist_entry *he = __perf_session__add_hist_entry(&self->hists,
-                                                              al, NULL,
-                                                              count, &hit);
-       if (he == NULL)
-               return -ENOMEM;
-
-       if (hit)
-               he->count += count;
-
-       return 0;
+       if (__hists__add_entry(self, al, NULL, period) != NULL)
+               return 0;
+       return -ENOMEM;
 }
 
 static int diff__process_sample_event(event_t *event, struct perf_session *session)
@@ -57,12 +49,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
 
        event__parse_sample(event, session->sample_type, &data);
 
-       if (perf_session__add_hist_entry(session, &al, data.period)) {
-               pr_warning("problem incrementing symbol count, skipping event\n");
+       if (hists__add_entry(&session->hists, &al, data.period)) {
+               pr_warning("problem incrementing symbol period, skipping event\n");
                return -1;
        }
 
-       session->events_stats.total += data.period;
+       session->hists.stats.total_period += data.period;
        return 0;
 }
 
@@ -95,35 +87,34 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
        rb_insert_color(&he->rb_node, root);
 }
 
-static void perf_session__resort_hist_entries(struct perf_session *self)
+static void hists__resort_entries(struct hists *self)
 {
        unsigned long position = 1;
        struct rb_root tmp = RB_ROOT;
-       struct rb_node *next = rb_first(&self->hists);
+       struct rb_node *next = rb_first(&self->entries);
 
        while (next != NULL) {
                struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node);
 
                next = rb_next(&n->rb_node);
-               rb_erase(&n->rb_node, &self->hists);
+               rb_erase(&n->rb_node, &self->entries);
                n->position = position++;
                perf_session__insert_hist_entry_by_name(&tmp, n);
        }
 
-       self->hists = tmp;
+       self->entries = tmp;
 }
 
-static void perf_session__set_hist_entries_positions(struct perf_session *self)
+static void hists__set_positions(struct hists *self)
 {
-       perf_session__output_resort(&self->hists, self->events_stats.total);
-       perf_session__resort_hist_entries(self);
+       hists__output_resort(self);
+       hists__resort_entries(self);
 }
 
-static struct hist_entry *
-perf_session__find_hist_entry(struct perf_session *self,
-                             struct hist_entry *he)
+static struct hist_entry *hists__find_entry(struct hists *self,
+                                           struct hist_entry *he)
 {
-       struct rb_node *n = self->hists.rb_node;
+       struct rb_node *n = self->entries.rb_node;
 
        while (n) {
                struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node);
@@ -140,14 +131,13 @@ perf_session__find_hist_entry(struct perf_session *self,
        return NULL;
 }
 
-static void perf_session__match_hists(struct perf_session *old_session,
-                                     struct perf_session *new_session)
+static void hists__match(struct hists *older, struct hists *newer)
 {
        struct rb_node *nd;
 
-       for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) {
+       for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node);
-               pos->pair = perf_session__find_hist_entry(old_session, pos);
+               pos->pair = hists__find_entry(older, pos);
        }
 }
 
@@ -156,8 +146,8 @@ static int __cmd_diff(void)
        int ret, i;
        struct perf_session *session[2];
 
-       session[0] = perf_session__new(input_old, O_RDONLY, force);
-       session[1] = perf_session__new(input_new, O_RDONLY, force);
+       session[0] = perf_session__new(input_old, O_RDONLY, force, false);
+       session[1] = perf_session__new(input_new, O_RDONLY, force, false);
        if (session[0] == NULL || session[1] == NULL)
                return -ENOMEM;
 
@@ -167,15 +157,13 @@ static int __cmd_diff(void)
                        goto out_delete;
        }
 
-       perf_session__output_resort(&session[1]->hists,
-                                   session[1]->events_stats.total);
+       hists__output_resort(&session[1]->hists);
        if (show_displacement)
-               perf_session__set_hist_entries_positions(session[0]);
+               hists__set_positions(&session[0]->hists);
 
-       perf_session__match_hists(session[0], session[1]);
-       perf_session__fprintf_hists(&session[1]->hists, session[0],
-                                   show_displacement, stdout,
-                                   session[1]->events_stats.total);
+       hists__match(&session[0]->hists, &session[1]->hists);
+       hists__fprintf(&session[1]->hists, &session[0]->hists,
+                      show_displacement, stdout);
 out_delete:
        for (i = 0; i < 2; ++i)
                perf_session__delete(session[i]);
@@ -188,7 +176,7 @@ static const char * const diff_usage[] = {
 };
 
 static const struct option options[] = {
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('m', "displacement", &show_displacement,
                    "Show position displacement relative to baseline"),
@@ -225,6 +213,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix __used)
                        input_new = argv[1];
                } else
                        input_new = argv[0];
+       } else if (symbol_conf.default_guest_vmlinux_name ||
+                  symbol_conf.default_guest_kallsyms) {
+               input_old = "perf.data.host";
+               input_new = "perf.data.guest";
        }
 
        symbol_conf.exclude_other = false;
index 215b584..6d5a8a7 100644 (file)
@@ -29,14 +29,14 @@ enum help_format {
        HELP_FORMAT_WEB,
 };
 
-static int show_all = 0;
+static bool show_all = false;
 static enum help_format help_format = HELP_FORMAT_MAN;
 static struct option builtin_help_options[] = {
        OPT_BOOLEAN('a', "all", &show_all, "print all available commands"),
-       OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
-       OPT_SET_INT('w', "web", &help_format, "show manual in web browser",
+       OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN),
+       OPT_SET_UINT('w', "web", &help_format, "show manual in web browser",
                        HELP_FORMAT_WEB),
-       OPT_SET_INT('i', "info", &help_format, "show info page",
+       OPT_SET_UINT('i', "info", &help_format, "show info page",
                        HELP_FORMAT_INFO),
        OPT_END(),
 };
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
new file mode 100644 (file)
index 0000000..8e3e47b
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * builtin-inject.c
+ *
+ * Builtin inject command: Examine the live mode (stdin) event stream
+ * and repipe it to stdout while optionally injecting additional
+ * events into it.
+ */
+#include "builtin.h"
+
+#include "perf.h"
+#include "util/session.h"
+#include "util/debug.h"
+
+#include "util/parse-options.h"
+
+static char            const *input_name = "-";
+static bool            inject_build_ids;
+
+static int event__repipe(event_t *event __used,
+                        struct perf_session *session __used)
+{
+       uint32_t size;
+       void *buf = event;
+
+       size = event->header.size;
+
+       while (size) {
+               int ret = write(STDOUT_FILENO, buf, size);
+               if (ret < 0)
+                       return -errno;
+
+               size -= ret;
+               buf += ret;
+       }
+
+       return 0;
+}
+
+static int event__repipe_mmap(event_t *self, struct perf_session *session)
+{
+       int err;
+
+       err = event__process_mmap(self, session);
+       event__repipe(self, session);
+
+       return err;
+}
+
+static int event__repipe_task(event_t *self, struct perf_session *session)
+{
+       int err;
+
+       err = event__process_task(self, session);
+       event__repipe(self, session);
+
+       return err;
+}
+
+static int event__repipe_tracing_data(event_t *self,
+                                     struct perf_session *session)
+{
+       int err;
+
+       event__repipe(self, session);
+       err = event__process_tracing_data(self, session);
+
+       return err;
+}
+
+static int dso__read_build_id(struct dso *self)
+{
+       if (self->has_build_id)
+               return 0;
+
+       if (filename__read_build_id(self->long_name, self->build_id,
+                                   sizeof(self->build_id)) > 0) {
+               self->has_build_id = true;
+               return 0;
+       }
+
+       return -1;
+}
+
+static int dso__inject_build_id(struct dso *self, struct perf_session *session)
+{
+       u16 misc = PERF_RECORD_MISC_USER;
+       struct machine *machine;
+       int err;
+
+       if (dso__read_build_id(self) < 0) {
+               pr_debug("no build_id found for %s\n", self->long_name);
+               return -1;
+       }
+
+       machine = perf_session__find_host_machine(session);
+       if (machine == NULL) {
+               pr_err("Can't find machine for session\n");
+               return -1;
+       }
+
+       if (self->kernel)
+               misc = PERF_RECORD_MISC_KERNEL;
+
+       err = event__synthesize_build_id(self, misc, event__repipe,
+                                        machine, session);
+       if (err) {
+               pr_err("Can't synthesize build_id event for %s\n", self->long_name);
+               return -1;
+       }
+
+       return 0;
+}
+
+static int event__inject_buildid(event_t *event, struct perf_session *session)
+{
+       struct addr_location al;
+       struct thread *thread;
+       u8 cpumode;
+
+       cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+       thread = perf_session__findnew(session, event->ip.pid);
+       if (thread == NULL) {
+               pr_err("problem processing %d event, skipping it.\n",
+                      event->header.type);
+               goto repipe;
+       }
+
+       thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+                             event->ip.pid, event->ip.ip, &al);
+
+       if (al.map != NULL) {
+               if (!al.map->dso->hit) {
+                       al.map->dso->hit = 1;
+                       if (map__load(al.map, NULL) >= 0) {
+                               dso__inject_build_id(al.map->dso, session);
+                               /*
+                                * If this fails, too bad, let the other side
+                                * account this as unresolved.
+                                */
+                       } else
+                               pr_warning("no symbols found in %s, maybe "
+                                          "install a debug package?\n",
+                                          al.map->dso->long_name);
+               }
+       }
+
+repipe:
+       event__repipe(event, session);
+       return 0;
+}
+
+struct perf_event_ops inject_ops = {
+       .sample         = event__repipe,
+       .mmap           = event__repipe,
+       .comm           = event__repipe,
+       .fork           = event__repipe,
+       .exit           = event__repipe,
+       .lost           = event__repipe,
+       .read           = event__repipe,
+       .throttle       = event__repipe,
+       .unthrottle     = event__repipe,
+       .attr           = event__repipe,
+       .event_type     = event__repipe,
+       .tracing_data   = event__repipe,
+       .build_id       = event__repipe,
+};
+
+extern volatile int session_done;
+
+static void sig_handler(int sig __attribute__((__unused__)))
+{
+       session_done = 1;
+}
+
+static int __cmd_inject(void)
+{
+       struct perf_session *session;
+       int ret = -EINVAL;
+
+       signal(SIGINT, sig_handler);
+
+       if (inject_build_ids) {
+               inject_ops.sample       = event__inject_buildid;
+               inject_ops.mmap         = event__repipe_mmap;
+               inject_ops.fork         = event__repipe_task;
+               inject_ops.tracing_data = event__repipe_tracing_data;
+       }
+
+       session = perf_session__new(input_name, O_RDONLY, false, true);
+       if (session == NULL)
+               return -ENOMEM;
+
+       ret = perf_session__process_events(session, &inject_ops);
+
+       perf_session__delete(session);
+
+       return ret;
+}
+
+static const char * const report_usage[] = {
+       "perf inject [<options>]",
+       NULL
+};
+
+static const struct option options[] = {
+       OPT_BOOLEAN('b', "build-ids", &inject_build_ids,
+                   "Inject build-ids into the output stream"),
+       OPT_INCR('v', "verbose", &verbose,
+                "be more verbose (show build ids, etc)"),
+       OPT_END()
+};
+
+int cmd_inject(int argc, const char **argv, const char *prefix __used)
+{
+       argc = parse_options(argc, argv, options, report_usage, 0);
+
+       /*
+        * Any (unrecognized) arguments left?
+        */
+       if (argc)
+               usage_with_options(report_usage, options);
+
+       if (symbol__init() < 0)
+               return -1;
+
+       return __cmd_inject();
+}
index 924a951..31f60a2 100644 (file)
@@ -335,8 +335,9 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 }
 
 static struct perf_event_ops event_ops = {
-       .sample = process_sample_event,
-       .comm   = event__process_comm,
+       .sample                 = process_sample_event,
+       .comm                   = event__process_comm,
+       .ordered_samples        = true,
 };
 
 static double fragmentation(unsigned long n_req, unsigned long n_alloc)
@@ -351,6 +352,7 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
                           int n_lines, int is_caller)
 {
        struct rb_node *next;
+       struct machine *machine;
 
        printf("%.102s\n", graph_dotted_line);
        printf(" %-34s |",  is_caller ? "Callsite": "Alloc Ptr");
@@ -359,23 +361,29 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
 
        next = rb_first(root);
 
+       machine = perf_session__find_host_machine(session);
+       if (!machine) {
+               pr_err("__print_result: couldn't find kernel information\n");
+               return;
+       }
        while (next && n_lines--) {
                struct alloc_stat *data = rb_entry(next, struct alloc_stat,
                                                   node);
                struct symbol *sym = NULL;
+               struct map *map;
                char buf[BUFSIZ];
                u64 addr;
 
                if (is_caller) {
                        addr = data->call_site;
                        if (!raw_ip)
-                               sym = map_groups__find_function(&session->kmaps, addr, NULL);
+                               sym = machine__find_kernel_function(machine, addr, &map, NULL);
                } else
                        addr = data->ptr;
 
                if (sym != NULL)
                        snprintf(buf, sizeof(buf), "%s+%Lx", sym->name,
-                                addr - sym->start);
+                                addr - map->unmap_ip(map, sym->start));
                else
                        snprintf(buf, sizeof(buf), "%#Lx", addr);
                printf(" %-34s |", buf);
@@ -484,10 +492,13 @@ static void sort_result(void)
 static int __cmd_kmem(void)
 {
        int err = -EINVAL;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (session == NULL)
                return -ENOMEM;
 
+       if (perf_session__create_kernel_maps(session) < 0)
+               goto out_delete;
+
        if (!perf_session__has_traces(session, "kmem record"))
                goto out_delete;
 
@@ -718,7 +729,6 @@ static const char *record_args[] = {
        "record",
        "-a",
        "-R",
-       "-M",
        "-f",
        "-c", "1",
        "-e", "kmem:kmalloc",
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
new file mode 100644 (file)
index 0000000..34d1e85
--- /dev/null
@@ -0,0 +1,144 @@
+#include "builtin.h"
+#include "perf.h"
+
+#include "util/util.h"
+#include "util/cache.h"
+#include "util/symbol.h"
+#include "util/thread.h"
+#include "util/header.h"
+#include "util/session.h"
+
+#include "util/parse-options.h"
+#include "util/trace-event.h"
+
+#include "util/debug.h"
+
+#include <sys/prctl.h>
+
+#include <semaphore.h>
+#include <pthread.h>
+#include <math.h>
+
+static const char              *file_name;
+static char                    name_buffer[256];
+
+bool                           perf_host = 1;
+bool                           perf_guest;
+
+static const char * const kvm_usage[] = {
+       "perf kvm [<options>] {top|record|report|diff|buildid-list}",
+       NULL
+};
+
+static const struct option kvm_options[] = {
+       OPT_STRING('i', "input", &file_name, "file",
+                  "Input file name"),
+       OPT_STRING('o', "output", &file_name, "file",
+                  "Output file name"),
+       OPT_BOOLEAN(0, "guest", &perf_guest,
+                   "Collect guest os data"),
+       OPT_BOOLEAN(0, "host", &perf_host,
+                   "Collect guest os data"),
+       OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory",
+                  "guest mount directory under which every guest os"
+                  " instance has a subdir"),
+       OPT_STRING(0, "guestvmlinux", &symbol_conf.default_guest_vmlinux_name,
+                  "file", "file saving guest os vmlinux"),
+       OPT_STRING(0, "guestkallsyms", &symbol_conf.default_guest_kallsyms,
+                  "file", "file saving guest os /proc/kallsyms"),
+       OPT_STRING(0, "guestmodules", &symbol_conf.default_guest_modules,
+                  "file", "file saving guest os /proc/modules"),
+       OPT_END()
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+       int rec_argc, i = 0, j;
+       const char **rec_argv;
+
+       rec_argc = argc + 2;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+       rec_argv[i++] = strdup("record");
+       rec_argv[i++] = strdup("-o");
+       rec_argv[i++] = strdup(file_name);
+       for (j = 1; j < argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       BUG_ON(i != rec_argc);
+
+       return cmd_record(i, rec_argv, NULL);
+}
+
+static int __cmd_report(int argc, const char **argv)
+{
+       int rec_argc, i = 0, j;
+       const char **rec_argv;
+
+       rec_argc = argc + 2;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+       rec_argv[i++] = strdup("report");
+       rec_argv[i++] = strdup("-i");
+       rec_argv[i++] = strdup(file_name);
+       for (j = 1; j < argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       BUG_ON(i != rec_argc);
+
+       return cmd_report(i, rec_argv, NULL);
+}
+
+static int __cmd_buildid_list(int argc, const char **argv)
+{
+       int rec_argc, i = 0, j;
+       const char **rec_argv;
+
+       rec_argc = argc + 2;
+       rec_argv = calloc(rec_argc + 1, sizeof(char *));
+       rec_argv[i++] = strdup("buildid-list");
+       rec_argv[i++] = strdup("-i");
+       rec_argv[i++] = strdup(file_name);
+       for (j = 1; j < argc; j++, i++)
+               rec_argv[i] = argv[j];
+
+       BUG_ON(i != rec_argc);
+
+       return cmd_buildid_list(i, rec_argv, NULL);
+}
+
+int cmd_kvm(int argc, const char **argv, const char *prefix __used)
+{
+       perf_host = perf_guest = 0;
+
+       argc = parse_options(argc, argv, kvm_options, kvm_usage,
+                       PARSE_OPT_STOP_AT_NON_OPTION);
+       if (!argc)
+               usage_with_options(kvm_usage, kvm_options);
+
+       if (!perf_host)
+               perf_guest = 1;
+
+       if (!file_name) {
+               if (perf_host && !perf_guest)
+                       sprintf(name_buffer, "perf.data.host");
+               else if (!perf_host && perf_guest)
+                       sprintf(name_buffer, "perf.data.guest");
+               else
+                       sprintf(name_buffer, "perf.data.kvm");
+               file_name = name_buffer;
+       }
+
+       if (!strncmp(argv[0], "rec", 3))
+               return __cmd_record(argc, argv);
+       else if (!strncmp(argv[0], "rep", 3))
+               return __cmd_report(argc, argv);
+       else if (!strncmp(argv[0], "diff", 4))
+               return cmd_diff(argc, argv, NULL);
+       else if (!strncmp(argv[0], "top", 3))
+               return cmd_top(argc, argv, NULL);
+       else if (!strncmp(argv[0], "buildid-list", 12))
+               return __cmd_buildid_list(argc, argv);
+       else
+               usage_with_options(kvm_usage, kvm_options);
+
+       return 0;
+}
index e12c844..821c158 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/list.h>
 #include <linux/hash.h>
 
+static struct perf_session *session;
+
 /* based on kernel/lockdep.c */
 #define LOCKHASH_BITS          12
 #define LOCKHASH_SIZE          (1UL << LOCKHASH_BITS)
@@ -32,9 +34,6 @@ static struct list_head lockhash_table[LOCKHASH_SIZE];
 #define __lockhashfn(key)      hash_long((unsigned long)key, LOCKHASH_BITS)
 #define lockhashentry(key)     (lockhash_table + __lockhashfn((key)))
 
-#define LOCK_STATE_UNLOCKED    0              /* initial state */
-#define LOCK_STATE_LOCKED      1
-
 struct lock_stat {
        struct list_head        hash_entry;
        struct rb_node          rb;             /* used for sorting */
@@ -47,20 +46,151 @@ struct lock_stat {
        void                    *addr;          /* address of lockdep_map, used as ID */
        char                    *name;          /* for strcpy(), we cannot use const */
 
-       int                     state;
-       u64                     prev_event_time; /* timestamp of previous event */
-
-       unsigned int            nr_acquired;
        unsigned int            nr_acquire;
+       unsigned int            nr_acquired;
        unsigned int            nr_contended;
        unsigned int            nr_release;
 
+       unsigned int            nr_readlock;
+       unsigned int            nr_trylock;
        /* these times are in nano sec. */
        u64                     wait_time_total;
        u64                     wait_time_min;
        u64                     wait_time_max;
+
+       int                     discard; /* flag of blacklist */
 };
 
+/*
+ * States of lock_seq_stat
+ *
+ * UNINITIALIZED is required for detecting first event of acquire.
+ * As the nature of lock events, there is no guarantee
+ * that the first event for the locks are acquire,
+ * it can be acquired, contended or release.
+ */
+#define SEQ_STATE_UNINITIALIZED      0        /* initial state */
+#define SEQ_STATE_RELEASED     1
+#define SEQ_STATE_ACQUIRING    2
+#define SEQ_STATE_ACQUIRED     3
+#define SEQ_STATE_READ_ACQUIRED        4
+#define SEQ_STATE_CONTENDED    5
+
+/*
+ * MAX_LOCK_DEPTH
+ * Imported from include/linux/sched.h.
+ * Should this be synchronized?
+ */
+#define MAX_LOCK_DEPTH 48
+
+/*
+ * struct lock_seq_stat:
+ * Place to put on state of one lock sequence
+ * 1) acquire -> acquired -> release
+ * 2) acquire -> contended -> acquired -> release
+ * 3) acquire (with read or try) -> release
+ * 4) Are there other patterns?
+ */
+struct lock_seq_stat {
+       struct list_head        list;
+       int                     state;
+       u64                     prev_event_time;
+       void                    *addr;
+
+       int                     read_count;
+};
+
+struct thread_stat {
+       struct rb_node          rb;
+
+       u32                     tid;
+       struct list_head        seq_list;
+};
+
+static struct rb_root          thread_stats;
+
+static struct thread_stat *thread_stat_find(u32 tid)
+{
+       struct rb_node *node;
+       struct thread_stat *st;
+
+       node = thread_stats.rb_node;
+       while (node) {
+               st = container_of(node, struct thread_stat, rb);
+               if (st->tid == tid)
+                       return st;
+               else if (tid < st->tid)
+                       node = node->rb_left;
+               else
+                       node = node->rb_right;
+       }
+
+       return NULL;
+}
+
+static void thread_stat_insert(struct thread_stat *new)
+{
+       struct rb_node **rb = &thread_stats.rb_node;
+       struct rb_node *parent = NULL;
+       struct thread_stat *p;
+
+       while (*rb) {
+               p = container_of(*rb, struct thread_stat, rb);
+               parent = *rb;
+
+               if (new->tid < p->tid)
+                       rb = &(*rb)->rb_left;
+               else if (new->tid > p->tid)
+                       rb = &(*rb)->rb_right;
+               else
+                       BUG_ON("inserting invalid thread_stat\n");
+       }
+
+       rb_link_node(&new->rb, parent, rb);
+       rb_insert_color(&new->rb, &thread_stats);
+}
+
+static struct thread_stat *thread_stat_findnew_after_first(u32 tid)
+{
+       struct thread_stat *st;
+
+       st = thread_stat_find(tid);
+       if (st)
+               return st;
+
+       st = zalloc(sizeof(struct thread_stat));
+       if (!st)
+               die("memory allocation failed\n");
+
+       st->tid = tid;
+       INIT_LIST_HEAD(&st->seq_list);
+
+       thread_stat_insert(st);
+
+       return st;
+}
+
+static struct thread_stat *thread_stat_findnew_first(u32 tid);
+static struct thread_stat *(*thread_stat_findnew)(u32 tid) =
+       thread_stat_findnew_first;
+
+static struct thread_stat *thread_stat_findnew_first(u32 tid)
+{
+       struct thread_stat *st;
+
+       st = zalloc(sizeof(struct thread_stat));
+       if (!st)
+               die("memory allocation failed\n");
+       st->tid = tid;
+       INIT_LIST_HEAD(&st->seq_list);
+
+       rb_link_node(&st->rb, NULL, &thread_stats.rb_node);
+       rb_insert_color(&st->rb, &thread_stats);
+
+       thread_stat_findnew = thread_stat_findnew_after_first;
+       return st;
+}
+
 /* build simple key function one is bigger than two */
 #define SINGLE_KEY(member)                                             \
        static int lock_stat_key_ ## member(struct lock_stat *one,      \
@@ -175,8 +305,6 @@ static struct lock_stat *lock_stat_findnew(void *addr, const char *name)
                goto alloc_failed;
        strcpy(new->name, name);
 
-       /* LOCK_STATE_UNLOCKED == 0 isn't guaranteed forever */
-       new->state = LOCK_STATE_UNLOCKED;
        new->wait_time_min = ULLONG_MAX;
 
        list_add(&new->hash_entry, entry);
@@ -188,8 +316,6 @@ alloc_failed:
 
 static char                    const *input_name = "perf.data";
 
-static int                     profile_cpu = -1;
-
 struct raw_event_sample {
        u32                     size;
        char                    data[0];
@@ -198,6 +324,7 @@ struct raw_event_sample {
 struct trace_acquire_event {
        void                    *addr;
        const char              *name;
+       int                     flag;
 };
 
 struct trace_acquired_event {
@@ -241,120 +368,258 @@ struct trace_lock_handler {
                              struct thread *thread);
 };
 
+static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr)
+{
+       struct lock_seq_stat *seq;
+
+       list_for_each_entry(seq, &ts->seq_list, list) {
+               if (seq->addr == addr)
+                       return seq;
+       }
+
+       seq = zalloc(sizeof(struct lock_seq_stat));
+       if (!seq)
+               die("Not enough memory\n");
+       seq->state = SEQ_STATE_UNINITIALIZED;
+       seq->addr = addr;
+
+       list_add(&seq->list, &ts->seq_list);
+       return seq;
+}
+
+enum broken_state {
+       BROKEN_ACQUIRE,
+       BROKEN_ACQUIRED,
+       BROKEN_CONTENDED,
+       BROKEN_RELEASE,
+       BROKEN_MAX,
+};
+
+static int bad_hist[BROKEN_MAX];
+
+enum acquire_flags {
+       TRY_LOCK = 1,
+       READ_LOCK = 2,
+};
+
 static void
 report_lock_acquire_event(struct trace_acquire_event *acquire_event,
                        struct event *__event __used,
                        int cpu __used,
-                       u64 timestamp,
+                       u64 timestamp __used,
                        struct thread *thread __used)
 {
-       struct lock_stat *st;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
+
+       ls = lock_stat_findnew(acquire_event->addr, acquire_event->name);
+       if (ls->discard)
+               return;
 
-       st = lock_stat_findnew(acquire_event->addr, acquire_event->name);
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, acquire_event->addr);
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+       case SEQ_STATE_RELEASED:
+               if (!acquire_event->flag) {
+                       seq->state = SEQ_STATE_ACQUIRING;
+               } else {
+                       if (acquire_event->flag & TRY_LOCK)
+                               ls->nr_trylock++;
+                       if (acquire_event->flag & READ_LOCK)
+                               ls->nr_readlock++;
+                       seq->state = SEQ_STATE_READ_ACQUIRED;
+                       seq->read_count = 1;
+                       ls->nr_acquired++;
+               }
+               break;
+       case SEQ_STATE_READ_ACQUIRED:
+               if (acquire_event->flag & READ_LOCK) {
+                       seq->read_count++;
+                       ls->nr_acquired++;
+                       goto end;
+               } else {
+                       goto broken;
+               }
                break;
-       case LOCK_STATE_LOCKED:
+       case SEQ_STATE_ACQUIRED:
+       case SEQ_STATE_ACQUIRING:
+       case SEQ_STATE_CONTENDED:
+broken:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_ACQUIRE]++;
+               list_del(&seq->list);
+               free(seq);
+               goto end;
                break;
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
-       st->prev_event_time = timestamp;
+       ls->nr_acquire++;
+       seq->prev_event_time = timestamp;
+end:
+       return;
 }
 
 static void
 report_lock_acquired_event(struct trace_acquired_event *acquired_event,
                         struct event *__event __used,
                         int cpu __used,
-                        u64 timestamp,
+                        u64 timestamp __used,
                         struct thread *thread __used)
 {
-       struct lock_stat *st;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
+       u64 contended_term;
+
+       ls = lock_stat_findnew(acquired_event->addr, acquired_event->name);
+       if (ls->discard)
+               return;
 
-       st = lock_stat_findnew(acquired_event->addr, acquired_event->name);
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, acquired_event->addr);
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
-               st->state = LOCK_STATE_LOCKED;
-               st->nr_acquired++;
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+               /* orphan event, do nothing */
+               return;
+       case SEQ_STATE_ACQUIRING:
+               break;
+       case SEQ_STATE_CONTENDED:
+               contended_term = timestamp - seq->prev_event_time;
+               ls->wait_time_total += contended_term;
+               if (contended_term < ls->wait_time_min)
+                       ls->wait_time_min = contended_term;
+               if (ls->wait_time_max < contended_term)
+                       ls->wait_time_max = contended_term;
                break;
-       case LOCK_STATE_LOCKED:
+       case SEQ_STATE_RELEASED:
+       case SEQ_STATE_ACQUIRED:
+       case SEQ_STATE_READ_ACQUIRED:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_ACQUIRED]++;
+               list_del(&seq->list);
+               free(seq);
+               goto end;
                break;
+
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
-       st->prev_event_time = timestamp;
+       seq->state = SEQ_STATE_ACQUIRED;
+       ls->nr_acquired++;
+       seq->prev_event_time = timestamp;
+end:
+       return;
 }
 
 static void
 report_lock_contended_event(struct trace_contended_event *contended_event,
                          struct event *__event __used,
                          int cpu __used,
-                         u64 timestamp,
+                         u64 timestamp __used,
                          struct thread *thread __used)
 {
-       struct lock_stat *st;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
 
-       st = lock_stat_findnew(contended_event->addr, contended_event->name);
+       ls = lock_stat_findnew(contended_event->addr, contended_event->name);
+       if (ls->discard)
+               return;
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, contended_event->addr);
+
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+               /* orphan event, do nothing */
+               return;
+       case SEQ_STATE_ACQUIRING:
                break;
-       case LOCK_STATE_LOCKED:
-               st->nr_contended++;
+       case SEQ_STATE_RELEASED:
+       case SEQ_STATE_ACQUIRED:
+       case SEQ_STATE_READ_ACQUIRED:
+       case SEQ_STATE_CONTENDED:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_CONTENDED]++;
+               list_del(&seq->list);
+               free(seq);
+               goto end;
                break;
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
-       st->prev_event_time = timestamp;
+       seq->state = SEQ_STATE_CONTENDED;
+       ls->nr_contended++;
+       seq->prev_event_time = timestamp;
+end:
+       return;
 }
 
 static void
 report_lock_release_event(struct trace_release_event *release_event,
                        struct event *__event __used,
                        int cpu __used,
-                       u64 timestamp,
+                       u64 timestamp __used,
                        struct thread *thread __used)
 {
-       struct lock_stat *st;
-       u64 hold_time;
+       struct lock_stat *ls;
+       struct thread_stat *ts;
+       struct lock_seq_stat *seq;
 
-       st = lock_stat_findnew(release_event->addr, release_event->name);
+       ls = lock_stat_findnew(release_event->addr, release_event->name);
+       if (ls->discard)
+               return;
 
-       switch (st->state) {
-       case LOCK_STATE_UNLOCKED:
-               break;
-       case LOCK_STATE_LOCKED:
-               st->state = LOCK_STATE_UNLOCKED;
-               hold_time = timestamp - st->prev_event_time;
+       ts = thread_stat_findnew(thread->pid);
+       seq = get_seq(ts, release_event->addr);
 
-               if (timestamp < st->prev_event_time) {
-                       /* terribly, this can happen... */
+       switch (seq->state) {
+       case SEQ_STATE_UNINITIALIZED:
+               goto end;
+               break;
+       case SEQ_STATE_ACQUIRED:
+               break;
+       case SEQ_STATE_READ_ACQUIRED:
+               seq->read_count--;
+               BUG_ON(seq->read_count < 0);
+               if (!seq->read_count) {
+                       ls->nr_release++;
                        goto end;
                }
-
-               if (st->wait_time_min > hold_time)
-                       st->wait_time_min = hold_time;
-               if (st->wait_time_max < hold_time)
-                       st->wait_time_max = hold_time;
-               st->wait_time_total += hold_time;
-
-               st->nr_release++;
+               break;
+       case SEQ_STATE_ACQUIRING:
+       case SEQ_STATE_CONTENDED:
+       case SEQ_STATE_RELEASED:
+               /* broken lock sequence, discard it */
+               ls->discard = 1;
+               bad_hist[BROKEN_RELEASE]++;
+               goto free_seq;
                break;
        default:
-               BUG_ON(1);
+               BUG_ON("Unknown state of lock sequence found!\n");
                break;
        }
 
+       ls->nr_release++;
+free_seq:
+       list_del(&seq->list);
+       free(seq);
 end:
-       st->prev_event_time = timestamp;
+       return;
 }
 
 /* lock oriented handlers */
@@ -381,6 +646,7 @@ process_lock_acquire_event(void *data,
        tmp = raw_field_value(event, "lockdep_addr", data);
        memcpy(&acquire_event.addr, &tmp, sizeof(void *));
        acquire_event.name = (char *)raw_field_ptr(event, "name", data);
+       acquire_event.flag = (int)raw_field_value(event, "flag", data);
 
        if (trace_handler->acquire_event)
                trace_handler->acquire_event(&acquire_event, event, cpu, timestamp, thread);
@@ -441,8 +707,7 @@ process_lock_release_event(void *data,
 }
 
 static void
-process_raw_event(void *data, int cpu,
-                 u64 timestamp, struct thread *thread)
+process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread)
 {
        struct event *event;
        int type;
@@ -460,173 +725,19 @@ process_raw_event(void *data, int cpu,
                process_lock_release_event(data, event, cpu, timestamp, thread);
 }
 
-struct raw_event_queue {
-       u64                     timestamp;
-       int                     cpu;
-       void                    *data;
-       struct thread           *thread;
-       struct list_head        list;
-};
-
-static LIST_HEAD(raw_event_head);
-
-#define FLUSH_PERIOD   (5 * NSEC_PER_SEC)
-
-static u64 flush_limit = ULLONG_MAX;
-static u64 last_flush = 0;
-struct raw_event_queue *last_inserted;
-
-static void flush_raw_event_queue(u64 limit)
-{
-       struct raw_event_queue *tmp, *iter;
-
-       list_for_each_entry_safe(iter, tmp, &raw_event_head, list) {
-               if (iter->timestamp > limit)
-                       return;
-
-               if (iter == last_inserted)
-                       last_inserted = NULL;
-
-               process_raw_event(iter->data, iter->cpu, iter->timestamp,
-                                 iter->thread);
-
-               last_flush = iter->timestamp;
-               list_del(&iter->list);
-               free(iter->data);
-               free(iter);
-       }
-}
-
-static void __queue_raw_event_end(struct raw_event_queue *new)
-{
-       struct raw_event_queue *iter;
-
-       list_for_each_entry_reverse(iter, &raw_event_head, list) {
-               if (iter->timestamp < new->timestamp) {
-                       list_add(&new->list, &iter->list);
-                       return;
-               }
-       }
-
-       list_add(&new->list, &raw_event_head);
-}
-
-static void __queue_raw_event_before(struct raw_event_queue *new,
-                                    struct raw_event_queue *iter)
+static void print_bad_events(int bad, int total)
 {
-       list_for_each_entry_continue_reverse(iter, &raw_event_head, list) {
-               if (iter->timestamp < new->timestamp) {
-                       list_add(&new->list, &iter->list);
-                       return;
-               }
-       }
-
-       list_add(&new->list, &raw_event_head);
-}
-
-static void __queue_raw_event_after(struct raw_event_queue *new,
-                                    struct raw_event_queue *iter)
-{
-       list_for_each_entry_continue(iter, &raw_event_head, list) {
-               if (iter->timestamp > new->timestamp) {
-                       list_add_tail(&new->list, &iter->list);
-                       return;
-               }
-       }
-       list_add_tail(&new->list, &raw_event_head);
-}
-
-/* The queue is ordered by time */
-static void __queue_raw_event(struct raw_event_queue *new)
-{
-       if (!last_inserted) {
-               __queue_raw_event_end(new);
-               return;
-       }
-
-       /*
-        * Most of the time the current event has a timestamp
-        * very close to the last event inserted, unless we just switched
-        * to another event buffer. Having a sorting based on a list and
-        * on the last inserted event that is close to the current one is
-        * probably more efficient than an rbtree based sorting.
-        */
-       if (last_inserted->timestamp >= new->timestamp)
-               __queue_raw_event_before(new, last_inserted);
-       else
-               __queue_raw_event_after(new, last_inserted);
-}
-
-static void queue_raw_event(void *data, int raw_size, int cpu,
-                           u64 timestamp, struct thread *thread)
-{
-       struct raw_event_queue *new;
-
-       if (flush_limit == ULLONG_MAX)
-               flush_limit = timestamp + FLUSH_PERIOD;
-
-       if (timestamp < last_flush) {
-               printf("Warning: Timestamp below last timeslice flush\n");
-               return;
-       }
-
-       new = malloc(sizeof(*new));
-       if (!new)
-               die("Not enough memory\n");
-
-       new->timestamp = timestamp;
-       new->cpu = cpu;
-       new->thread = thread;
-
-       new->data = malloc(raw_size);
-       if (!new->data)
-               die("Not enough memory\n");
-
-       memcpy(new->data, data, raw_size);
-
-       __queue_raw_event(new);
-       last_inserted = new;
-
-       /*
-        * We want to have a slice of events covering 2 * FLUSH_PERIOD
-        * If FLUSH_PERIOD is big enough, it ensures every events that occured
-        * in the first half of the timeslice have all been buffered and there
-        * are none remaining (we need that because of the weakly ordered
-        * event recording we have). Then once we reach the 2 * FLUSH_PERIOD
-        * timeslice, we flush the first half to be gentle with the memory
-        * (the second half can still get new events in the middle, so wait
-        * another period to flush it)
-        */
-       if (new->timestamp > flush_limit &&
-               new->timestamp - flush_limit > FLUSH_PERIOD) {
-               flush_limit += FLUSH_PERIOD;
-               flush_raw_event_queue(flush_limit);
-       }
-}
-
-static int process_sample_event(event_t *event, struct perf_session *session)
-{
-       struct thread *thread;
-       struct sample_data data;
-
-       bzero(&data, sizeof(struct sample_data));
-       event__parse_sample(event, session->sample_type, &data);
-       thread = perf_session__findnew(session, data.pid);
-
-       if (thread == NULL) {
-               pr_debug("problem processing %d event, skipping it.\n",
-                        event->header.type);
-               return -1;
-       }
-
-       dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
-       if (profile_cpu != -1 && profile_cpu != (int) data.cpu)
-               return 0;
-
-       queue_raw_event(data.raw_data, data.raw_size, data.cpu, data.time, thread);
-
-       return 0;
+       /* Output for debug, this have to be removed */
+       int i;
+       const char *name[4] =
+               { "acquire", "acquired", "contended", "release" };
+
+       pr_info("\n=== output for debug===\n\n");
+       pr_info("bad: %d, total: %d\n", bad, total);
+       pr_info("bad rate: %f %%\n", (double)bad / (double)total * 100);
+       pr_info("histogram of events caused bad sequence\n");
+       for (i = 0; i < BROKEN_MAX; i++)
+               pr_info(" %10s: %d\n", name[i], bad_hist[i]);
 }
 
 /* TODO: various way to print, coloring, nano or milli sec */
@@ -634,26 +745,30 @@ static void print_result(void)
 {
        struct lock_stat *st;
        char cut_name[20];
+       int bad, total;
 
-       printf("%18s ", "ID");
-       printf("%20s ", "Name");
-       printf("%10s ", "acquired");
-       printf("%10s ", "contended");
+       pr_info("%20s ", "Name");
+       pr_info("%10s ", "acquired");
+       pr_info("%10s ", "contended");
 
-       printf("%15s ", "total wait (ns)");
-       printf("%15s ", "max wait (ns)");
-       printf("%15s ", "min wait (ns)");
+       pr_info("%15s ", "total wait (ns)");
+       pr_info("%15s ", "max wait (ns)");
+       pr_info("%15s ", "min wait (ns)");
 
-       printf("\n\n");
+       pr_info("\n\n");
 
+       bad = total = 0;
        while ((st = pop_from_result())) {
+               total++;
+               if (st->discard) {
+                       bad++;
+                       continue;
+               }
                bzero(cut_name, 20);
 
-               printf("%p ", st->addr);
-
                if (strlen(st->name) < 16) {
                        /* output raw name */
-                       printf("%20s ", st->name);
+                       pr_info("%20s ", st->name);
                } else {
                        strncpy(cut_name, st->name, 16);
                        cut_name[16] = '.';
@@ -661,18 +776,39 @@ static void print_result(void)
                        cut_name[18] = '.';
                        cut_name[19] = '\0';
                        /* cut off name for saving output style */
-                       printf("%20s ", cut_name);
+                       pr_info("%20s ", cut_name);
                }
 
-               printf("%10u ", st->nr_acquired);
-               printf("%10u ", st->nr_contended);
+               pr_info("%10u ", st->nr_acquired);
+               pr_info("%10u ", st->nr_contended);
 
-               printf("%15llu ", st->wait_time_total);
-               printf("%15llu ", st->wait_time_max);
-               printf("%15llu ", st->wait_time_min == ULLONG_MAX ?
+               pr_info("%15llu ", st->wait_time_total);
+               pr_info("%15llu ", st->wait_time_max);
+               pr_info("%15llu ", st->wait_time_min == ULLONG_MAX ?
                       0 : st->wait_time_min);
-               printf("\n");
+               pr_info("\n");
        }
+
+       print_bad_events(bad, total);
+}
+
+static bool info_threads, info_map;
+
+static void dump_threads(void)
+{
+       struct thread_stat *st;
+       struct rb_node *node;
+       struct thread *t;
+
+       pr_info("%10s: comm\n", "Thread ID");
+
+       node = rb_first(&thread_stats);
+       while (node) {
+               st = container_of(node, struct thread_stat, rb);
+               t = perf_session__findnew(session, st->tid);
+               pr_info("%10d: %s\n", st->tid, t->comm);
+               node = rb_next(node);
+       };
 }
 
 static void dump_map(void)
@@ -680,23 +816,53 @@ static void dump_map(void)
        unsigned int i;
        struct lock_stat *st;
 
+       pr_info("Address of instance: name of class\n");
        for (i = 0; i < LOCKHASH_SIZE; i++) {
                list_for_each_entry(st, &lockhash_table[i], hash_entry) {
-                       printf("%p: %s\n", st->addr, st->name);
+                       pr_info(" %p: %s\n", st->addr, st->name);
                }
        }
 }
 
+static void dump_info(void)
+{
+       if (info_threads)
+               dump_threads();
+       else if (info_map)
+               dump_map();
+       else
+               die("Unknown type of information\n");
+}
+
+static int process_sample_event(event_t *self, struct perf_session *s)
+{
+       struct sample_data data;
+       struct thread *thread;
+
+       bzero(&data, sizeof(data));
+       event__parse_sample(self, s->sample_type, &data);
+
+       thread = perf_session__findnew(s, data.tid);
+       if (thread == NULL) {
+               pr_debug("problem processing %d event, skipping it.\n",
+                       self->header.type);
+               return -1;
+       }
+
+       process_raw_event(data.raw_data, data.cpu, data.time, thread);
+
+       return 0;
+}
+
 static struct perf_event_ops eops = {
        .sample                 = process_sample_event,
        .comm                   = event__process_comm,
+       .ordered_samples        = true,
 };
 
-static struct perf_session *session;
-
 static int read_events(void)
 {
-       session = perf_session__new(input_name, O_RDONLY, 0);
+       session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (!session)
                die("Initializing perf session failed\n");
 
@@ -720,7 +886,6 @@ static void __cmd_report(void)
        setup_pager();
        select_key();
        read_events();
-       flush_raw_event_queue(ULLONG_MAX);
        sort_result();
        print_result();
 }
@@ -737,6 +902,19 @@ static const struct option report_options[] = {
        OPT_END()
 };
 
+static const char * const info_usage[] = {
+       "perf lock info [<options>]",
+       NULL
+};
+
+static const struct option info_options[] = {
+       OPT_BOOLEAN('t', "threads", &info_threads,
+                   "dump thread list in perf.data"),
+       OPT_BOOLEAN('m', "map", &info_map,
+                   "map of lock instances (name:address table)"),
+       OPT_END()
+};
+
 static const char * const lock_usage[] = {
        "perf lock [<options>] {record|trace|report}",
        NULL
@@ -744,14 +922,13 @@ static const char * const lock_usage[] = {
 
 static const struct option lock_options[] = {
        OPT_STRING('i', "input", &input_name, "file", "input file name"),
-       OPT_BOOLEAN('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
+       OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
        OPT_END()
 };
 
 static const char *record_args[] = {
        "record",
-       "-a",
        "-R",
        "-f",
        "-m", "1024",
@@ -808,12 +985,18 @@ int cmd_lock(int argc, const char **argv, const char *prefix __used)
        } else if (!strcmp(argv[0], "trace")) {
                /* Aliased to 'perf trace' */
                return cmd_trace(argc, argv, prefix);
-       } else if (!strcmp(argv[0], "map")) {
+       } else if (!strcmp(argv[0], "info")) {
+               if (argc) {
+                       argc = parse_options(argc, argv,
+                                            info_options, info_usage, 0);
+                       if (argc)
+                               usage_with_options(info_usage, info_options);
+               }
                /* recycling report_lock_ops */
                trace_handler = &report_lock_ops;
                setup_pager();
                read_events();
-               dump_map();
+               dump_info();
        } else {
                usage_with_options(lock_usage, lock_options);
        }
index 152d6c9..61c6d70 100644 (file)
 #include "builtin.h"
 #include "util/util.h"
 #include "util/strlist.h"
-#include "util/event.h"
+#include "util/symbol.h"
 #include "util/debug.h"
 #include "util/debugfs.h"
-#include "util/symbol.h"
-#include "util/thread.h"
 #include "util/parse-options.h"
-#include "util/parse-events.h" /* For debugfs_path */
 #include "util/probe-finder.h"
 #include "util/probe-event.h"
 
 
 /* Session management structure */
 static struct {
-       bool need_dwarf;
        bool list_events;
        bool force_add;
        bool show_lines;
-       int nr_probe;
-       struct probe_point probes[MAX_PROBES];
+       int nevents;
+       struct perf_probe_event events[MAX_PROBES];
        struct strlist *dellist;
-       struct map_groups kmap_groups;
-       struct map *kmaps[MAP__NR_TYPES];
        struct line_range line_range;
-} session;
+       int max_probe_points;
+} params;
 
 
 /* Parse an event definition. Note that any error must die. */
-static void parse_probe_event(const char *str)
+static int parse_probe_event(const char *str)
 {
-       struct probe_point *pp = &session.probes[session.nr_probe];
+       struct perf_probe_event *pev = &params.events[params.nevents];
+       int ret;
 
-       pr_debug("probe-definition(%d): %s\n", session.nr_probe, str);
-       if (++session.nr_probe == MAX_PROBES)
+       pr_debug("probe-definition(%d): %s\n", params.nevents, str);
+       if (++params.nevents == MAX_PROBES)
                die("Too many probes (> %d) are specified.", MAX_PROBES);
 
-       /* Parse perf-probe event into probe_point */
-       parse_perf_probe_event(str, pp, &session.need_dwarf);
+       /* Parse a perf-probe command into event */
+       ret = parse_perf_probe_command(str, pev);
+       pr_debug("%d arguments\n", pev->nargs);
 
-       pr_debug("%d arguments\n", pp->nr_args);
+       return ret;
 }
 
-static void parse_probe_event_argv(int argc, const char **argv)
+static int parse_probe_event_argv(int argc, const char **argv)
 {
-       int i, len;
+       int i, len, ret;
        char *buf;
 
        /* Bind up rest arguments */
        len = 0;
        for (i = 0; i < argc; i++)
                len += strlen(argv[i]) + 1;
-       buf = zalloc(len + 1);
-       if (!buf)
-               die("Failed to allocate memory for binding arguments.");
+       buf = xzalloc(len + 1);
        len = 0;
        for (i = 0; i < argc; i++)
                len += sprintf(&buf[len], "%s ", argv[i]);
-       parse_probe_event(buf);
+       ret = parse_probe_event(buf);
        free(buf);
+       return ret;
 }
 
 static int opt_add_probe_event(const struct option *opt __used,
                              const char *str, int unset __used)
 {
        if (str)
-               parse_probe_event(str);
-       return 0;
+               return parse_probe_event(str);
+       else
+               return 0;
 }
 
 static int opt_del_probe_event(const struct option *opt __used,
                               const char *str, int unset __used)
 {
        if (str) {
-               if (!session.dellist)
-                       session.dellist = strlist__new(true, NULL);
-               strlist__add(session.dellist, str);
+               if (!params.dellist)
+                       params.dellist = strlist__new(true, NULL);
+               strlist__add(params.dellist, str);
        }
        return 0;
 }
 
-/* Currently just checking function name from symbol map */
-static void evaluate_probe_point(struct probe_point *pp)
-{
-       struct symbol *sym;
-       sym = map__find_symbol_by_name(session.kmaps[MAP__FUNCTION],
-                                      pp->function, NULL);
-       if (!sym)
-               die("Kernel symbol \'%s\' not found - probe not added.",
-                   pp->function);
-}
-
-#ifndef NO_DWARF_SUPPORT
-static int open_vmlinux(void)
-{
-       if (map__load(session.kmaps[MAP__FUNCTION], NULL) < 0) {
-               pr_debug("Failed to load kernel map.\n");
-               return -EINVAL;
-       }
-       pr_debug("Try to open %s\n",
-                session.kmaps[MAP__FUNCTION]->dso->long_name);
-       return open(session.kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
-}
-
+#ifdef DWARF_SUPPORT
 static int opt_show_lines(const struct option *opt __used,
                          const char *str, int unset __used)
 {
+       int ret = 0;
+
        if (str)
-               parse_line_range_desc(str, &session.line_range);
-       INIT_LIST_HEAD(&session.line_range.line_list);
-       session.show_lines = true;
-       return 0;
+               ret = parse_line_range_desc(str, &params.line_range);
+       INIT_LIST_HEAD(&params.line_range.line_list);
+       params.show_lines = true;
+
+       return ret;
 }
 #endif
 
@@ -155,29 +133,25 @@ static const char * const probe_usage[] = {
        "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
        "perf probe [<options>] --del '[GROUP:]EVENT' ...",
        "perf probe --list",
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
        "perf probe --line 'LINEDESC'",
 #endif
        NULL
 };
 
 static const struct option options[] = {
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show parsed arguments, etc)"),
-#ifndef NO_DWARF_SUPPORT
-       OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
-                  "file", "vmlinux pathname"),
-#endif
-       OPT_BOOLEAN('l', "list", &session.list_events,
+       OPT_BOOLEAN('l', "list", &params.list_events,
                    "list up current probe events"),
        OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
                opt_del_probe_event),
        OPT_CALLBACK('a', "add", NULL,
-#ifdef NO_DWARF_SUPPORT
-               "[EVENT=]FUNC[+OFF|%return] [ARG ...]",
-#else
+#ifdef DWARF_SUPPORT
                "[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
-               " [ARG ...]",
+               " [[NAME=]ARG ...]",
+#else
+               "[EVENT=]FUNC[+OFF|%return] [[NAME=]ARG ...]",
 #endif
                "probe point definition, where\n"
                "\t\tGROUP:\tGroup name (optional)\n"
@@ -185,51 +159,35 @@ static const struct option options[] = {
                "\t\tFUNC:\tFunction name\n"
                "\t\tOFF:\tOffset from function entry (in byte)\n"
                "\t\t%return:\tPut the probe at function return\n"
-#ifdef NO_DWARF_SUPPORT
-               "\t\tARG:\tProbe argument (only \n"
-#else
+#ifdef DWARF_SUPPORT
                "\t\tSRC:\tSource code path\n"
                "\t\tRL:\tRelative line number from function entry.\n"
                "\t\tAL:\tAbsolute line number in file.\n"
                "\t\tPT:\tLazy expression of line code.\n"
                "\t\tARG:\tProbe argument (local variable name or\n"
-#endif
                "\t\t\tkprobe-tracer argument format.)\n",
+#else
+               "\t\tARG:\tProbe argument (kprobe-tracer argument format.)\n",
+#endif
                opt_add_probe_event),
-       OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events"
+       OPT_BOOLEAN('f', "force", &params.force_add, "forcibly add events"
                    " with existing name"),
-#ifndef NO_DWARF_SUPPORT
+#ifdef DWARF_SUPPORT
        OPT_CALLBACK('L', "line", NULL,
-                    "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
+                    "FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
                     "Show source code lines.", opt_show_lines),
+       OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+                  "file", "vmlinux pathname"),
 #endif
+       OPT__DRY_RUN(&probe_event_dry_run),
+       OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
+                "Set how many probe points can be found for a probe."),
        OPT_END()
 };
 
-/* Initialize symbol maps for vmlinux */
-static void init_vmlinux(void)
-{
-       symbol_conf.sort_by_name = true;
-       if (symbol_conf.vmlinux_name == NULL)
-               symbol_conf.try_vmlinux_path = true;
-       else
-               pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
-       if (symbol__init() < 0)
-               die("Failed to init symbol map.");
-
-       map_groups__init(&session.kmap_groups);
-       if (map_groups__create_kernel_maps(&session.kmap_groups,
-                                          session.kmaps) < 0)
-               die("Failed to create kernel maps.");
-}
-
 int cmd_probe(int argc, const char **argv, const char *prefix __used)
 {
-       int i, ret;
-#ifndef NO_DWARF_SUPPORT
-       int fd;
-#endif
-       struct probe_point *pp;
+       int ret;
 
        argc = parse_options(argc, argv, options, probe_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
@@ -238,123 +196,69 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
                        pr_warning("  Error: '-' is not supported.\n");
                        usage_with_options(probe_usage, options);
                }
-               parse_probe_event_argv(argc, argv);
+               ret = parse_probe_event_argv(argc, argv);
+               if (ret < 0) {
+                       pr_err("  Error: Parse Error.  (%d)\n", ret);
+                       return ret;
+               }
        }
 
-       if ((!session.nr_probe && !session.dellist && !session.list_events &&
-            !session.show_lines))
-               usage_with_options(probe_usage, options);
+       if (params.max_probe_points == 0)
+               params.max_probe_points = MAX_PROBES;
 
-       if (debugfs_valid_mountpoint(debugfs_path) < 0)
-               die("Failed to find debugfs path.");
+       if ((!params.nevents && !params.dellist && !params.list_events &&
+            !params.show_lines))
+               usage_with_options(probe_usage, options);
 
-       if (session.list_events) {
-               if (session.nr_probe != 0 || session.dellist) {
-                       pr_warning("  Error: Don't use --list with"
-                                  " --add/--del.\n");
+       if (params.list_events) {
+               if (params.nevents != 0 || params.dellist) {
+                       pr_err("  Error: Don't use --list with --add/--del.\n");
                        usage_with_options(probe_usage, options);
                }
-               if (session.show_lines) {
-                       pr_warning("  Error: Don't use --list with --line.\n");
+               if (params.show_lines) {
+                       pr_err("  Error: Don't use --list with --line.\n");
                        usage_with_options(probe_usage, options);
                }
-               show_perf_probe_events();
-               return 0;
+               ret = show_perf_probe_events();
+               if (ret < 0)
+                       pr_err("  Error: Failed to show event list. (%d)\n",
+                              ret);
+               return ret;
        }
 
-#ifndef NO_DWARF_SUPPORT
-       if (session.show_lines) {
-               if (session.nr_probe != 0 || session.dellist) {
+#ifdef DWARF_SUPPORT
+       if (params.show_lines) {
+               if (params.nevents != 0 || params.dellist) {
                        pr_warning("  Error: Don't use --line with"
                                   " --add/--del.\n");
                        usage_with_options(probe_usage, options);
                }
-               init_vmlinux();
-               fd = open_vmlinux();
-               if (fd < 0)
-                       die("Could not open debuginfo file.");
-               ret = find_line_range(fd, &session.line_range);
-               if (ret <= 0)
-                       die("Source line is not found.\n");
-               close(fd);
-               show_line_range(&session.line_range);
-               return 0;
-       }
-#endif
 
-       if (session.dellist) {
-               del_trace_kprobe_events(session.dellist);
-               strlist__delete(session.dellist);
-               if (session.nr_probe == 0)
-                       return 0;
+               ret = show_line_range(&params.line_range);
+               if (ret < 0)
+                       pr_err("  Error: Failed to show lines. (%d)\n", ret);
+               return ret;
        }
+#endif
 
-       /* Add probes */
-       init_vmlinux();
-
-       if (session.need_dwarf)
-#ifdef NO_DWARF_SUPPORT
-               die("Debuginfo-analysis is not supported");
-#else  /* !NO_DWARF_SUPPORT */
-               pr_debug("Some probes require debuginfo.\n");
-
-       fd = open_vmlinux();
-       if (fd < 0) {
-               if (session.need_dwarf)
-                       die("Could not open debuginfo file.");
-
-               pr_debug("Could not open vmlinux/module file."
-                        " Try to use symbols.\n");
-               goto end_dwarf;
-       }
-
-       /* Searching probe points */
-       for (i = 0; i < session.nr_probe; i++) {
-               pp = &session.probes[i];
-               if (pp->found)
-                       continue;
-
-               lseek(fd, SEEK_SET, 0);
-               ret = find_probe_point(fd, pp);
-               if (ret > 0)
-                       continue;
-               if (ret == 0) { /* No error but failed to find probe point. */
-                       synthesize_perf_probe_point(pp);
-                       die("Probe point '%s' not found. - probe not added.",
-                           pp->probes[0]);
-               }
-               /* Error path */
-               if (session.need_dwarf) {
-                       if (ret == -ENOENT)
-                               pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
-                       die("Could not analyze debuginfo.");
+       if (params.dellist) {
+               ret = del_perf_probe_events(params.dellist);
+               strlist__delete(params.dellist);
+               if (ret < 0) {
+                       pr_err("  Error: Failed to delete events. (%d)\n", ret);
+                       return ret;
                }
-               pr_debug("An error occurred in debuginfo analysis."
-                        " Try to use symbols.\n");
-               break;
        }
-       close(fd);
-
-end_dwarf:
-#endif /* !NO_DWARF_SUPPORT */
 
-       /* Synthesize probes without dwarf */
-       for (i = 0; i < session.nr_probe; i++) {
-               pp = &session.probes[i];
-               if (pp->found)  /* This probe is already found. */
-                       continue;
-
-               evaluate_probe_point(pp);
-               ret = synthesize_trace_kprobe_event(pp);
-               if (ret == -E2BIG)
-                       die("probe point definition becomes too long.");
-               else if (ret < 0)
-                       die("Failed to synthesize a probe point.");
+       if (params.nevents) {
+               ret = add_perf_probe_events(params.events, params.nevents,
+                                           params.force_add,
+                                           params.max_probe_points);
+               if (ret < 0) {
+                       pr_err("  Error: Failed to add events. (%d)\n", ret);
+                       return ret;
+               }
        }
-
-       /* Settng up probe points */
-       add_trace_kprobe_events(session.probes, session.nr_probe,
-                               session.force_add);
        return 0;
 }
 
index 3b8b638..cb46c7d 100644 (file)
@@ -15,7 +15,6 @@
 #include "util/util.h"
 #include "util/parse-options.h"
 #include "util/parse-events.h"
-#include "util/string.h"
 
 #include "util/header.h"
 #include "util/event.h"
 #include <unistd.h>
 #include <sched.h>
 
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
+enum write_mode_t {
+       WRITE_FORCE,
+       WRITE_APPEND
+};
+
+static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
 
-static long                    default_interval                =      0;
+static u64                     user_interval                   = ULLONG_MAX;
+static u64                     default_interval                =      0;
 
 static int                     nr_cpus                         =      0;
 static unsigned int            page_size;
 static unsigned int            mmap_pages                      =    128;
+static unsigned int            user_freq                       = UINT_MAX;
 static int                     freq                            =   1000;
 static int                     output;
+static int                     pipe_output                     =      0;
 static const char              *output_name                    = "perf.data";
 static int                     group                           =      0;
-static unsigned int            realtime_prio                   =      0;
-static int                     raw_samples                     =      0;
-static int                     system_wide                     =      0;
+static int                     realtime_prio                   =      0;
+static bool                    raw_samples                     =  false;
+static bool                    system_wide                     =  false;
 static int                     profile_cpu                     =     -1;
 static pid_t                   target_pid                      =     -1;
+static pid_t                   target_tid                      =     -1;
+static pid_t                   *all_tids                       =      NULL;
+static int                     thread_num                      =      0;
 static pid_t                   child_pid                       =     -1;
-static int                     inherit                         =      1;
-static int                     force                           =      0;
-static int                     append_file                     =      0;
-static int                     call_graph                      =      0;
-static int                     inherit_stat                    =      0;
-static int                     no_samples                      =      0;
-static int                     sample_address                  =      0;
-static int                     multiplex                       =      0;
+static bool                    no_inherit                      =  false;
+static enum write_mode_t       write_mode                      = WRITE_FORCE;
+static bool                    call_graph                      =  false;
+static bool                    inherit_stat                    =  false;
+static bool                    no_samples                      =  false;
+static bool                    sample_address                  =  false;
+static bool                    multiplex                       =  false;
 static int                     multiplex_fd                    =     -1;
 
 static long                    samples                         =      0;
@@ -60,7 +69,7 @@ static struct timeval         this_read;
 
 static u64                     bytes_written                   =      0;
 
-static struct pollfd           event_array[MAX_NR_CPUS * MAX_COUNTERS];
+static struct pollfd           *event_array;
 
 static int                     nr_poll                         =      0;
 static int                     nr_cpu                          =      0;
@@ -77,7 +86,7 @@ struct mmap_data {
        unsigned int            prev;
 };
 
-static struct mmap_data                mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
+static struct mmap_data                *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
 
 static unsigned long mmap_read_head(struct mmap_data *md)
 {
@@ -101,6 +110,11 @@ static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
        pc->data_tail = tail;
 }
 
+static void advance_output(size_t size)
+{
+       bytes_written += size;
+}
+
 static void write_output(void *buf, size_t size)
 {
        while (size) {
@@ -225,12 +239,13 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
        return h_attr;
 }
 
-static void create_counter(int counter, int cpu, pid_t pid)
+static void create_counter(int counter, int cpu)
 {
        char *filter = filters[counter];
        struct perf_event_attr *attr = attrs + counter;
        struct perf_header_attr *h_attr;
        int track = !counter; /* only the first counter needs these */
+       int thread_index;
        int ret;
        struct {
                u64 count;
@@ -248,10 +263,19 @@ static void create_counter(int counter, int cpu, pid_t pid)
        if (nr_counters > 1)
                attr->sample_type |= PERF_SAMPLE_ID;
 
-       if (freq) {
-               attr->sample_type       |= PERF_SAMPLE_PERIOD;
-               attr->freq              = 1;
-               attr->sample_freq       = freq;
+       /*
+        * We default some events to a 1 default interval. But keep
+        * it a weak assumption overridable by the user.
+        */
+       if (!attr->sample_period || (user_freq != UINT_MAX &&
+                                    user_interval != ULLONG_MAX)) {
+               if (freq) {
+                       attr->sample_type       |= PERF_SAMPLE_PERIOD;
+                       attr->freq              = 1;
+                       attr->sample_freq       = freq;
+               } else {
+                       attr->sample_period = default_interval;
+               }
        }
 
        if (no_samples)
@@ -274,119 +298,130 @@ static void create_counter(int counter, int cpu, pid_t pid)
 
        attr->mmap              = track;
        attr->comm              = track;
-       attr->inherit           = inherit;
-       attr->disabled          = 1;
+       attr->inherit           = !no_inherit;
+       if (target_pid == -1 && target_tid == -1 && !system_wide) {
+               attr->disabled = 1;
+               attr->enable_on_exec = 1;
+       }
 
+       for (thread_index = 0; thread_index < thread_num; thread_index++) {
 try_again:
-       fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0);
-
-       if (fd[nr_cpu][counter] < 0) {
-               int err = errno;
-
-               if (err == EPERM || err == EACCES)
-                       die("Permission error - are you root?\n");
-               else if (err ==  ENODEV && profile_cpu != -1)
-                       die("No such device - did you specify an out-of-range profile CPU?\n");
+               fd[nr_cpu][counter][thread_index] = sys_perf_event_open(attr,
+                               all_tids[thread_index], cpu, group_fd, 0);
+
+               if (fd[nr_cpu][counter][thread_index] < 0) {
+                       int err = errno;
+
+                       if (err == EPERM || err == EACCES)
+                               die("Permission error - are you root?\n"
+                                       "\t Consider tweaking"
+                                       " /proc/sys/kernel/perf_event_paranoid.\n");
+                       else if (err ==  ENODEV && profile_cpu != -1) {
+                               die("No such device - did you specify"
+                                       " an out-of-range profile CPU?\n");
+                       }
 
-               /*
-                * If it's cycles then fall back to hrtimer
-                * based cpu-clock-tick sw counter, which
-                * is always available even if no PMU support:
-                */
-               if (attr->type == PERF_TYPE_HARDWARE
-                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
-                       if (verbose)
-                               warning(" ... trying to fall back to cpu-clock-ticks\n");
-                       attr->type = PERF_TYPE_SOFTWARE;
-                       attr->config = PERF_COUNT_SW_CPU_CLOCK;
-                       goto try_again;
-               }
-               printf("\n");
-               error("perfcounter syscall returned with %d (%s)\n",
-                       fd[nr_cpu][counter], strerror(err));
+                       /*
+                        * If it's cycles then fall back to hrtimer
+                        * based cpu-clock-tick sw counter, which
+                        * is always available even if no PMU support:
+                        */
+                       if (attr->type == PERF_TYPE_HARDWARE
+                                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
+
+                               if (verbose)
+                                       warning(" ... trying to fall back to cpu-clock-ticks\n");
+                               attr->type = PERF_TYPE_SOFTWARE;
+                               attr->config = PERF_COUNT_SW_CPU_CLOCK;
+                               goto try_again;
+                       }
+                       printf("\n");
+                       error("perfcounter syscall returned with %d (%s)\n",
+                                       fd[nr_cpu][counter][thread_index], strerror(err));
 
 #if defined(__i386__) || defined(__x86_64__)
-               if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
-                       die("No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.\n");
+                       if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
+                               die("No hardware sampling interrupt available."
+                                   " No APIC? If so then you can boot the kernel"
+                                   " with the \"lapic\" boot parameter to"
+                                   " force-enable it.\n");
 #endif
 
-               die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
-               exit(-1);
-       }
+                       die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
+                       exit(-1);
+               }
 
-       h_attr = get_header_attr(attr, counter);
-       if (h_attr == NULL)
-               die("nomem\n");
+               h_attr = get_header_attr(attr, counter);
+               if (h_attr == NULL)
+                       die("nomem\n");
 
-       if (!file_new) {
-               if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
-                       fprintf(stderr, "incompatible append\n");
-                       exit(-1);
+               if (!file_new) {
+                       if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
+                               fprintf(stderr, "incompatible append\n");
+                               exit(-1);
+                       }
                }
-       }
 
-       if (read(fd[nr_cpu][counter], &read_data, sizeof(read_data)) == -1) {
-               perror("Unable to read perf file descriptor\n");
-               exit(-1);
-       }
+               if (read(fd[nr_cpu][counter][thread_index], &read_data, sizeof(read_data)) == -1) {
+                       perror("Unable to read perf file descriptor\n");
+                       exit(-1);
+               }
 
-       if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
-               pr_warning("Not enough memory to add id\n");
-               exit(-1);
-       }
+               if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
+                       pr_warning("Not enough memory to add id\n");
+                       exit(-1);
+               }
 
-       assert(fd[nr_cpu][counter] >= 0);
-       fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK);
+               assert(fd[nr_cpu][counter][thread_index] >= 0);
+               fcntl(fd[nr_cpu][counter][thread_index], F_SETFL, O_NONBLOCK);
 
-       /*
-        * First counter acts as the group leader:
-        */
-       if (group && group_fd == -1)
-               group_fd = fd[nr_cpu][counter];
-       if (multiplex && multiplex_fd == -1)
-               multiplex_fd = fd[nr_cpu][counter];
+               /*
+                * First counter acts as the group leader:
+                */
+               if (group && group_fd == -1)
+                       group_fd = fd[nr_cpu][counter][thread_index];
+               if (multiplex && multiplex_fd == -1)
+                       multiplex_fd = fd[nr_cpu][counter][thread_index];
 
-       if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
+               if (multiplex && fd[nr_cpu][counter][thread_index] != multiplex_fd) {
 
-               ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
-               assert(ret != -1);
-       } else {
-               event_array[nr_poll].fd = fd[nr_cpu][counter];
-               event_array[nr_poll].events = POLLIN;
-               nr_poll++;
-
-               mmap_array[nr_cpu][counter].counter = counter;
-               mmap_array[nr_cpu][counter].prev = 0;
-               mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
-               mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-                               PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
-               if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
-                       error("failed to mmap with %d (%s)\n", errno, strerror(errno));
-                       exit(-1);
+                       ret = ioctl(fd[nr_cpu][counter][thread_index], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
+                       assert(ret != -1);
+               } else {
+                       event_array[nr_poll].fd = fd[nr_cpu][counter][thread_index];
+                       event_array[nr_poll].events = POLLIN;
+                       nr_poll++;
+
+                       mmap_array[nr_cpu][counter][thread_index].counter = counter;
+                       mmap_array[nr_cpu][counter][thread_index].prev = 0;
+                       mmap_array[nr_cpu][counter][thread_index].mask = mmap_pages*page_size - 1;
+                       mmap_array[nr_cpu][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
+                               PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter][thread_index], 0);
+                       if (mmap_array[nr_cpu][counter][thread_index].base == MAP_FAILED) {
+                               error("failed to mmap with %d (%s)\n", errno, strerror(errno));
+                               exit(-1);
+                       }
                }
-       }
 
-       if (filter != NULL) {
-               ret = ioctl(fd[nr_cpu][counter],
-                           PERF_EVENT_IOC_SET_FILTER, filter);
-               if (ret) {
-                       error("failed to set filter with %d (%s)\n", errno,
-                             strerror(errno));
-                       exit(-1);
+               if (filter != NULL) {
+                       ret = ioctl(fd[nr_cpu][counter][thread_index],
+                                       PERF_EVENT_IOC_SET_FILTER, filter);
+                       if (ret) {
+                               error("failed to set filter with %d (%s)\n", errno,
+                                               strerror(errno));
+                               exit(-1);
+                       }
                }
        }
-
-       ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
 }
 
-static void open_counters(int cpu, pid_t pid)
+static void open_counters(int cpu)
 {
        int counter;
 
        group_fd = -1;
        for (counter = 0; counter < nr_counters; counter++)
-               create_counter(counter, cpu, pid);
+               create_counter(counter, cpu);
 
        nr_cpu++;
 }
@@ -406,10 +441,80 @@ static int process_buildids(void)
 
 static void atexit_header(void)
 {
-       session->header.data_size += bytes_written;
+       if (!pipe_output) {
+               session->header.data_size += bytes_written;
+
+               process_buildids();
+               perf_header__write(&session->header, output, true);
+       }
+}
+
+static void event__synthesize_guest_os(struct machine *machine, void *data)
+{
+       int err;
+       char *guest_kallsyms;
+       char path[PATH_MAX];
+       struct perf_session *psession = data;
+
+       if (machine__is_host(machine))
+               return;
+
+       /*
+        *As for guest kernel when processing subcommand record&report,
+        *we arrange module mmap prior to guest kernel mmap and trigger
+        *a preload dso because default guest module symbols are loaded
+        *from guest kallsyms instead of /lib/modules/XXX/XXX. This
+        *method is used to avoid symbol missing when the first addr is
+        *in module instead of in guest kernel.
+        */
+       err = event__synthesize_modules(process_synthesized_event,
+                                       psession, machine);
+       if (err < 0)
+               pr_err("Couldn't record guest kernel [%d]'s reference"
+                      " relocation symbol.\n", machine->pid);
+
+       if (machine__is_default_guest(machine))
+               guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms;
+       else {
+               sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+               guest_kallsyms = path;
+       }
+
+       /*
+        * We use _stext for guest kernel because guest kernel's /proc/kallsyms
+        * have no _text sometimes.
+        */
+       err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                           psession, machine, "_text");
+       if (err < 0)
+               err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                                   psession, machine, "_stext");
+       if (err < 0)
+               pr_err("Couldn't record guest kernel [%d]'s reference"
+                      " relocation symbol.\n", machine->pid);
+}
+
+static struct perf_event_header finished_round_event = {
+       .size = sizeof(struct perf_event_header),
+       .type = PERF_RECORD_FINISHED_ROUND,
+};
+
+static void mmap_read_all(void)
+{
+       int i, counter, thread;
 
-       process_buildids();
-       perf_header__write(&session->header, output, true);
+       for (i = 0; i < nr_cpu; i++) {
+               for (counter = 0; counter < nr_counters; counter++) {
+                       for (thread = 0; thread < thread_num; thread++) {
+                               if (mmap_array[i][counter][thread].base)
+                                       mmap_read(&mmap_array[i][counter][thread]);
+                       }
+
+               }
+       }
+
+       if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
+               write_output(&finished_round_event, sizeof(finished_round_event));
 }
 
 static int __cmd_record(int argc, const char **argv)
@@ -421,8 +526,9 @@ static int __cmd_record(int argc, const char **argv)
        int err;
        unsigned long waking = 0;
        int child_ready_pipe[2], go_pipe[2];
-       const bool forks = target_pid == -1 && argc > 0;
+       const bool forks = argc > 0;
        char buf;
+       struct machine *machine;
 
        page_size = sysconf(_SC_PAGE_SIZE);
 
@@ -435,70 +541,63 @@ static int __cmd_record(int argc, const char **argv)
                exit(-1);
        }
 
-       if (!stat(output_name, &st) && st.st_size) {
-               if (!force) {
-                       if (!append_file) {
-                               pr_err("Error, output file %s exists, use -A "
-                                      "to append or -f to overwrite.\n",
-                                      output_name);
-                               exit(-1);
-                       }
-               } else {
+       if (!strcmp(output_name, "-"))
+               pipe_output = 1;
+       else if (!stat(output_name, &st) && st.st_size) {
+               if (write_mode == WRITE_FORCE) {
                        char oldname[PATH_MAX];
                        snprintf(oldname, sizeof(oldname), "%s.old",
                                 output_name);
                        unlink(oldname);
                        rename(output_name, oldname);
                }
-       } else {
-               append_file = 0;
+       } else if (write_mode == WRITE_APPEND) {
+               write_mode = WRITE_FORCE;
        }
 
        flags = O_CREAT|O_RDWR;
-       if (append_file)
+       if (write_mode == WRITE_APPEND)
                file_new = 0;
        else
                flags |= O_TRUNC;
 
-       output = open(output_name, flags, S_IRUSR|S_IWUSR);
+       if (pipe_output)
+               output = STDOUT_FILENO;
+       else
+               output = open(output_name, flags, S_IRUSR | S_IWUSR);
        if (output < 0) {
                perror("failed to create output file");
                exit(-1);
        }
 
-       session = perf_session__new(output_name, O_WRONLY, force);
+       session = perf_session__new(output_name, O_WRONLY,
+                                   write_mode == WRITE_FORCE, false);
        if (session == NULL) {
                pr_err("Not enough memory for reading perf file header\n");
                return -1;
        }
 
        if (!file_new) {
-               err = perf_header__read(&session->header, output);
+               err = perf_header__read(session, output);
                if (err < 0)
                        return err;
        }
 
-       if (raw_samples) {
+       if (have_tracepoints(attrs, nr_counters))
                perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
-       } else {
-               for (i = 0; i < nr_counters; i++) {
-                       if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
-                               perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
-                               break;
-                       }
-               }
-       }
 
        atexit(atexit_header);
 
        if (forks) {
-               pid = fork();
+               child_pid = fork();
                if (pid < 0) {
                        perror("failed to fork");
                        exit(-1);
                }
 
-               if (!pid) {
+               if (!child_pid) {
+                       if (pipe_output)
+                               dup2(2, 1);
                        close(child_ready_pipe[0]);
                        close(go_pipe[1]);
                        fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -527,10 +626,8 @@ static int __cmd_record(int argc, const char **argv)
                        exit(-1);
                }
 
-               child_pid = pid;
-
-               if (!system_wide)
-                       target_pid = pid;
+               if (!system_wide && target_tid == -1 && target_pid == -1)
+                       all_tids[0] = child_pid;
 
                close(child_ready_pipe[1]);
                close(go_pipe[0]);
@@ -544,16 +641,19 @@ static int __cmd_record(int argc, const char **argv)
                close(child_ready_pipe[0]);
        }
 
-
-       if ((!system_wide && !inherit) || profile_cpu != -1) {
-               open_counters(profile_cpu, target_pid);
+       if ((!system_wide && no_inherit) || profile_cpu != -1) {
+               open_counters(profile_cpu);
        } else {
                nr_cpus = read_cpu_map();
                for (i = 0; i < nr_cpus; i++)
-                       open_counters(cpumap[i], target_pid);
+                       open_counters(cpumap[i]);
        }
 
-       if (file_new) {
+       if (pipe_output) {
+               err = perf_header__write_pipe(output);
+               if (err < 0)
+                       return err;
+       } else if (file_new) {
                err = perf_header__write(&session->header, output, false);
                if (err < 0)
                        return err;
@@ -561,21 +661,70 @@ static int __cmd_record(int argc, const char **argv)
 
        post_processing_offset = lseek(output, 0, SEEK_CUR);
 
+       if (pipe_output) {
+               err = event__synthesize_attrs(&session->header,
+                                             process_synthesized_event,
+                                             session);
+               if (err < 0) {
+                       pr_err("Couldn't synthesize attrs.\n");
+                       return err;
+               }
+
+               err = event__synthesize_event_types(process_synthesized_event,
+                                                   session);
+               if (err < 0) {
+                       pr_err("Couldn't synthesize event_types.\n");
+                       return err;
+               }
+
+               if (have_tracepoints(attrs, nr_counters)) {
+                       /*
+                        * FIXME err <= 0 here actually means that
+                        * there were no tracepoints so its not really
+                        * an error, just that we don't need to
+                        * synthesize anything.  We really have to
+                        * return this more properly and also
+                        * propagate errors that now are calling die()
+                        */
+                       err = event__synthesize_tracing_data(output, attrs,
+                                                            nr_counters,
+                                                            process_synthesized_event,
+                                                            session);
+                       if (err <= 0) {
+                               pr_err("Couldn't record tracing data.\n");
+                               return err;
+                       }
+                       advance_output(err);
+               }
+       }
+
+       machine = perf_session__find_host_machine(session);
+       if (!machine) {
+               pr_err("Couldn't find native kernel information.\n");
+               return -1;
+       }
+
        err = event__synthesize_kernel_mmap(process_synthesized_event,
-                                           session, "_text");
+                                           session, machine, "_text");
+       if (err < 0)
+               err = event__synthesize_kernel_mmap(process_synthesized_event,
+                                                   session, machine, "_stext");
        if (err < 0) {
                pr_err("Couldn't record kernel reference relocation symbol.\n");
                return err;
        }
 
-       err = event__synthesize_modules(process_synthesized_event, session);
+       err = event__synthesize_modules(process_synthesized_event,
+                                       session, machine);
        if (err < 0) {
                pr_err("Couldn't record kernel reference relocation symbol.\n");
                return err;
        }
+       if (perf_guest)
+               perf_session__process_machines(session, event__synthesize_guest_os);
 
        if (!system_wide && profile_cpu == -1)
-               event__synthesize_thread(target_pid, process_synthesized_event,
+               event__synthesize_thread(target_tid, process_synthesized_event,
                                         session);
        else
                event__synthesize_threads(process_synthesized_event, session);
@@ -598,13 +747,9 @@ static int __cmd_record(int argc, const char **argv)
 
        for (;;) {
                int hits = samples;
+               int thread;
 
-               for (i = 0; i < nr_cpu; i++) {
-                       for (counter = 0; counter < nr_counters; counter++) {
-                               if (mmap_array[i][counter].base)
-                                       mmap_read(&mmap_array[i][counter]);
-                       }
-               }
+               mmap_read_all();
 
                if (hits == samples) {
                        if (done)
@@ -615,8 +760,15 @@ static int __cmd_record(int argc, const char **argv)
 
                if (done) {
                        for (i = 0; i < nr_cpu; i++) {
-                               for (counter = 0; counter < nr_counters; counter++)
-                                       ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE);
+                               for (counter = 0;
+                                       counter < nr_counters;
+                                       counter++) {
+                                       for (thread = 0;
+                                               thread < thread_num;
+                                               thread++)
+                                               ioctl(fd[i][counter][thread],
+                                                       PERF_EVENT_IOC_DISABLE);
+                               }
                        }
                }
        }
@@ -641,6 +793,8 @@ static const char * const record_usage[] = {
        NULL
 };
 
+static bool force, append_file;
+
 static const struct option options[] = {
        OPT_CALLBACK('e', "event", NULL, "event",
                     "event selector. use 'perf list' to list available events",
@@ -648,7 +802,9 @@ static const struct option options[] = {
        OPT_CALLBACK(0, "filter", NULL, "filter",
                     "event filter", parse_filter),
        OPT_INTEGER('p', "pid", &target_pid,
-                   "record events on existing pid"),
+                   "record events on existing process id"),
+       OPT_INTEGER('t', "tid", &target_tid,
+                   "record events on existing thread id"),
        OPT_INTEGER('r', "realtime", &realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
        OPT_BOOLEAN('R', "raw-samples", &raw_samples,
@@ -660,20 +816,17 @@ static const struct option options[] = {
        OPT_INTEGER('C', "profile_cpu", &profile_cpu,
                            "CPU to profile on"),
        OPT_BOOLEAN('f', "force", &force,
-                       "overwrite existing data file"),
-       OPT_LONG('c', "count", &default_interval,
-                   "event period to sample"),
+                       "overwrite existing data file (deprecated)"),
+       OPT_U64('c', "count", &user_interval, "event period to sample"),
        OPT_STRING('o', "output", &output_name, "file",
                    "output file name"),
-       OPT_BOOLEAN('i', "inherit", &inherit,
-                   "child tasks inherit counters"),
-       OPT_INTEGER('F', "freq", &freq,
-                   "profile at this frequency"),
-       OPT_INTEGER('m', "mmap-pages", &mmap_pages,
-                   "number of mmap data pages"),
+       OPT_BOOLEAN('i', "no-inherit", &no_inherit,
+                   "child tasks do not inherit counters"),
+       OPT_UINTEGER('F', "freq", &user_freq, "profile at this frequency"),
+       OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
        OPT_BOOLEAN('g', "call-graph", &call_graph,
                    "do call-graph (stack chain/backtrace) recording"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_BOOLEAN('s', "stat", &inherit_stat,
                    "per thread counts"),
@@ -688,13 +841,24 @@ static const struct option options[] = {
 
 int cmd_record(int argc, const char **argv, const char *prefix __used)
 {
-       int counter;
+       int i,j;
 
        argc = parse_options(argc, argv, options, record_usage,
                            PARSE_OPT_STOP_AT_NON_OPTION);
-       if (!argc && target_pid == -1 && !system_wide && profile_cpu == -1)
+       if (!argc && target_pid == -1 && target_tid == -1 &&
+               !system_wide && profile_cpu == -1)
                usage_with_options(record_usage, options);
 
+       if (force && append_file) {
+               fprintf(stderr, "Can't overwrite and append at the same time."
+                               " You need to choose between -f and -A");
+               usage_with_options(record_usage, options);
+       } else if (append_file) {
+               write_mode = WRITE_APPEND;
+       } else {
+               write_mode = WRITE_FORCE;
+       }
+
        symbol__init();
 
        if (!nr_counters) {
@@ -703,6 +867,42 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
        }
 
+       if (target_pid != -1) {
+               target_tid = target_pid;
+               thread_num = find_all_tid(target_pid, &all_tids);
+               if (thread_num <= 0) {
+                       fprintf(stderr, "Can't find all threads of pid %d\n",
+                                       target_pid);
+                       usage_with_options(record_usage, options);
+               }
+       } else {
+               all_tids=malloc(sizeof(pid_t));
+               if (!all_tids)
+                       return -ENOMEM;
+
+               all_tids[0] = target_tid;
+               thread_num = 1;
+       }
+
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++) {
+                       fd[i][j] = malloc(sizeof(int)*thread_num);
+                       mmap_array[i][j] = zalloc(
+                               sizeof(struct mmap_data)*thread_num);
+                       if (!fd[i][j] || !mmap_array[i][j])
+                               return -ENOMEM;
+               }
+       }
+       event_array = malloc(
+               sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
+       if (!event_array)
+               return -ENOMEM;
+
+       if (user_interval != ULLONG_MAX)
+               default_interval = user_interval;
+       if (user_freq != UINT_MAX)
+               freq = user_freq;
+
        /*
         * User specified count overrides default frequency.
         */
@@ -715,12 +915,5 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
                exit(EXIT_FAILURE);
        }
 
-       for (counter = 0; counter < nr_counters; counter++) {
-               if (attrs[counter].sample_period)
-                       continue;
-
-               attrs[counter].sample_period = default_interval;
-       }
-
        return __cmd_record(argc, argv);
 }
index f815de2..1d3c100 100644 (file)
@@ -14,7 +14,6 @@
 #include "util/cache.h"
 #include <linux/rbtree.h>
 #include "util/symbol.h"
-#include "util/string.h"
 #include "util/callchain.h"
 #include "util/strlist.h"
 #include "util/values.h"
 
 static char            const *input_name = "perf.data";
 
-static int             force;
+static bool            force;
 static bool            hide_unresolved;
 static bool            dont_use_callchains;
 
-static int             show_threads;
+static bool            show_threads;
 static struct perf_read_values show_threads_values;
 
-static char            default_pretty_printing_style[] = "normal";
-static char            *pretty_printing_style = default_pretty_printing_style;
+static const char      default_pretty_printing_style[] = "normal";
+static const char      *pretty_printing_style = default_pretty_printing_style;
 
 static char            callchain_default_opt[] = "fractal,0.5";
 
-static struct event_stat_id *get_stats(struct perf_session *self,
-                                      u64 event_stream, u32 type, u64 config)
+static struct hists *perf_session__hists_findnew(struct perf_session *self,
+                                                u64 event_stream, u32 type,
+                                                u64 config)
 {
-       struct rb_node **p = &self->stats_by_id.rb_node;
+       struct rb_node **p = &self->hists_tree.rb_node;
        struct rb_node *parent = NULL;
-       struct event_stat_id *iter, *new;
+       struct hists *iter, *new;
 
        while (*p != NULL) {
                parent = *p;
-               iter = rb_entry(parent, struct event_stat_id, rb_node);
+               iter = rb_entry(parent, struct hists, rb_node);
                if (iter->config == config)
                        return iter;
 
@@ -65,15 +65,15 @@ static struct event_stat_id *get_stats(struct perf_session *self,
                        p = &(*p)->rb_left;
        }
 
-       new = malloc(sizeof(struct event_stat_id));
+       new = malloc(sizeof(struct hists));
        if (new == NULL)
                return NULL;
-       memset(new, 0, sizeof(struct event_stat_id));
+       memset(new, 0, sizeof(struct hists));
        new->event_stream = event_stream;
        new->config = config;
        new->type = type;
        rb_link_node(&new->rb_node, parent, p);
-       rb_insert_color(&new->rb_node, &self->stats_by_id);
+       rb_insert_color(&new->rb_node, &self->hists_tree);
        return new;
 }
 
@@ -81,70 +81,71 @@ static int perf_session__add_hist_entry(struct perf_session *self,
                                        struct addr_location *al,
                                        struct sample_data *data)
 {
-       struct symbol **syms = NULL, *parent = NULL;
-       bool hit;
+       struct map_symbol *syms = NULL;
+       struct symbol *parent = NULL;
+       int err = -ENOMEM;
        struct hist_entry *he;
-       struct event_stat_id *stats;
+       struct hists *hists;
        struct perf_event_attr *attr;
 
-       if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain)
+       if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) {
                syms = perf_session__resolve_callchain(self, al->thread,
                                                       data->callchain, &parent);
+               if (syms == NULL)
+                       return -ENOMEM;
+       }
 
        attr = perf_header__find_attr(data->id, &self->header);
        if (attr)
-               stats = get_stats(self, data->id, attr->type, attr->config);
+               hists = perf_session__hists_findnew(self, data->id, attr->type, attr->config);
        else
-               stats = get_stats(self, data->id, 0, 0);
-       if (stats == NULL)
-               return -ENOMEM;
-       he = __perf_session__add_hist_entry(&stats->hists, al, parent,
-                                           data->period, &hit);
+               hists = perf_session__hists_findnew(self, data->id, 0, 0);
+       if (hists == NULL)
+               goto out_free_syms;
+       he = __hists__add_entry(hists, al, parent, data->period);
        if (he == NULL)
-               return -ENOMEM;
-
-       if (hit)
-               he->count += data->period;
-
+               goto out_free_syms;
+       err = 0;
        if (symbol_conf.use_callchain) {
-               if (!hit)
-                       callchain_init(&he->callchain);
-               append_chain(&he->callchain, data->callchain, syms);
-               free(syms);
+               err = append_chain(he->callchain, data->callchain, syms);
+               if (err)
+                       goto out_free_syms;
        }
-
-       return 0;
-}
-
-static int validate_chain(struct ip_callchain *chain, event_t *event)
-{
-       unsigned int chain_size;
-
-       chain_size = event->header.size;
-       chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
-
-       if (chain->nr*sizeof(u64) > chain_size)
-               return -1;
-
-       return 0;
+       /*
+        * Only in the newt browser we are doing integrated annotation,
+        * so we don't allocated the extra space needed because the stdio
+        * code will not use it.
+        */
+       if (use_browser)
+               err = hist_entry__inc_addr_samples(he, al->addr);
+out_free_syms:
+       free(syms);
+       return err;
 }
 
 static int add_event_total(struct perf_session *session,
                           struct sample_data *data,
                           struct perf_event_attr *attr)
 {
-       struct event_stat_id *stats;
+       struct hists *hists;
 
        if (attr)
-               stats = get_stats(session, data->id, attr->type, attr->config);
+               hists = perf_session__hists_findnew(session, data->id,
+                                                   attr->type, attr->config);
        else
-               stats = get_stats(session, data->id, 0, 0);
+               hists = perf_session__hists_findnew(session, data->id, 0, 0);
 
-       if (!stats)
+       if (!hists)
                return -ENOMEM;
 
-       stats->stats.total += data->period;
-       session->events_stats.total += data->period;
+       hists->stats.total_period += data->period;
+       /*
+        * FIXME: add_event_total should be moved from here to
+        * perf_session__process_event so that the proper hist is passed to
+        * the event_op methods.
+        */
+       hists__inc_nr_events(hists, PERF_RECORD_SAMPLE);
+       session->hists.stats.total_period += data->period;
        return 0;
 }
 
@@ -164,7 +165,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
 
                dump_printf("... chain: nr:%Lu\n", data.callchain->nr);
 
-               if (validate_chain(data.callchain, event) < 0) {
+               if (!ip_callchain__valid(data.callchain, event)) {
                        pr_debug("call-chain problem with event, "
                                 "skipping it.\n");
                        return 0;
@@ -187,14 +188,14 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                return 0;
 
        if (perf_session__add_hist_entry(session, &al, &data)) {
-               pr_debug("problem incrementing symbol count, skipping event\n");
+               pr_debug("problem incrementing symbol period, skipping event\n");
                return -1;
        }
 
        attr = perf_header__find_attr(data.id, &session->header);
 
        if (add_event_total(session, &data, attr)) {
-               pr_debug("problem adding event count\n");
+               pr_debug("problem adding event period\n");
                return -1;
        }
 
@@ -260,15 +261,43 @@ static struct perf_event_ops event_ops = {
        .fork   = event__process_task,
        .lost   = event__process_lost,
        .read   = process_read_event,
+       .attr   = event__process_attr,
+       .event_type = event__process_event_type,
+       .tracing_data = event__process_tracing_data,
+       .build_id = event__process_build_id,
 };
 
+extern volatile int session_done;
+
+static void sig_handler(int sig __used)
+{
+       session_done = 1;
+}
+
+static size_t hists__fprintf_nr_sample_events(struct hists *self,
+                                             const char *evname, FILE *fp)
+{
+       size_t ret;
+       char unit;
+       unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
+
+       nr_events = convert_unit(nr_events, &unit);
+       ret = fprintf(fp, "# Events: %lu%c", nr_events, unit);
+       if (evname != NULL)
+               ret += fprintf(fp, " %s", evname);
+       return ret + fprintf(fp, "\n#\n");
+}
+
 static int __cmd_report(void)
 {
        int ret = -EINVAL;
        struct perf_session *session;
        struct rb_node *next;
+       const char *help = "For a higher level overview, try: perf report --sort comm,dso";
+
+       signal(SIGINT, sig_handler);
 
-       session = perf_session__new(input_name, O_RDONLY, force);
+       session = perf_session__new(input_name, O_RDONLY, force, false);
        if (session == NULL)
                return -ENOMEM;
 
@@ -284,7 +313,7 @@ static int __cmd_report(void)
                goto out_delete;
 
        if (dump_trace) {
-               event__print_totals();
+               perf_session__fprintf_nr_events(session, stdout);
                goto out_delete;
        }
 
@@ -292,39 +321,42 @@ static int __cmd_report(void)
                perf_session__fprintf(session, stdout);
 
        if (verbose > 2)
-               dsos__fprintf(stdout);
+               perf_session__fprintf_dsos(session, stdout);
 
-       next = rb_first(&session->stats_by_id);
+       next = rb_first(&session->hists_tree);
        while (next) {
-               struct event_stat_id *stats;
-
-               stats = rb_entry(next, struct event_stat_id, rb_node);
-               perf_session__collapse_resort(&stats->hists);
-               perf_session__output_resort(&stats->hists, stats->stats.total);
-               if (rb_first(&session->stats_by_id) ==
-                   rb_last(&session->stats_by_id))
-                       fprintf(stdout, "# Samples: %Ld\n#\n",
-                               stats->stats.total);
-               else
-                       fprintf(stdout, "# Samples: %Ld %s\n#\n",
-                               stats->stats.total,
-                               __event_name(stats->type, stats->config));
-
-               perf_session__fprintf_hists(&stats->hists, NULL, false, stdout,
-                                           stats->stats.total);
-               fprintf(stdout, "\n\n");
-               next = rb_next(&stats->rb_node);
+               struct hists *hists;
+
+               hists = rb_entry(next, struct hists, rb_node);
+               hists__collapse_resort(hists);
+               hists__output_resort(hists);
+               if (use_browser)
+                       hists__browse(hists, help, input_name);
+               else {
+                       const char *evname = NULL;
+                       if (rb_first(&session->hists.entries) !=
+                           rb_last(&session->hists.entries))
+                               evname = __event_name(hists->type, hists->config);
+
+                       hists__fprintf_nr_sample_events(hists, evname, stdout);
+
+                       hists__fprintf(hists, NULL, false, stdout);
+                       fprintf(stdout, "\n\n");
+               }
+
+               next = rb_next(&hists->rb_node);
        }
 
-       if (sort_order == default_sort_order &&
-           parent_pattern == default_parent_pattern)
-               fprintf(stdout, "#\n# (For a higher level overview, try: perf report --sort comm,dso)\n#\n");
+       if (!use_browser && sort_order == default_sort_order &&
+           parent_pattern == default_parent_pattern) {
+               fprintf(stdout, "#\n# (%s)\n#\n", help);
 
-       if (show_threads) {
-               bool raw_printing_style = !strcmp(pretty_printing_style, "raw");
-               perf_read_values_display(stdout, &show_threads_values,
-                                        raw_printing_style);
-               perf_read_values_destroy(&show_threads_values);
+               if (show_threads) {
+                       bool style = !strcmp(pretty_printing_style, "raw");
+                       perf_read_values_display(stdout, &show_threads_values,
+                                                style);
+                       perf_read_values_destroy(&show_threads_values);
+               }
        }
 out_delete:
        perf_session__delete(session);
@@ -335,7 +367,7 @@ static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
                    int unset)
 {
-       char *tok;
+       char *tok, *tok2;
        char *endptr;
 
        /*
@@ -380,10 +412,13 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
        if (!tok)
                goto setup;
 
+       tok2 = strtok(NULL, ",");
        callchain_param.min_percent = strtod(tok, &endptr);
        if (tok == endptr)
                return -1;
 
+       if (tok2)
+               callchain_param.print_limit = strtod(tok2, &endptr);
 setup:
        if (register_callchain_param(&callchain_param) < 0) {
                fprintf(stderr, "Can't register callchain params\n");
@@ -400,7 +435,7 @@ static const char * const report_usage[] = {
 static const struct option options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -419,12 +454,14 @@ static const struct option options[] = {
                   "sort by key(s): pid, comm, dso, symbol, parent"),
        OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
                    "Don't shorten the pathnames taking into account the cwd"),
+       OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
+                   "Show sample percentage for different cpu modes"),
        OPT_STRING('p', "parent", &parent_pattern, "regex",
                   "regex filter to identify parent, see: '--sort parent'"),
        OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
                    "Only display entries with parent-match"),
        OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
-                    "Display callchains using output_type and min percent threshold. "
+                    "Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. "
                     "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
        OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
                   "only consider symbols in these dsos"),
@@ -447,7 +484,15 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
 {
        argc = parse_options(argc, argv, options, report_usage, 0);
 
-       setup_pager();
+       if (strcmp(input_name, "-") != 0)
+               setup_browser();
+       /*
+        * Only in the newt browser we are doing integrated annotation,
+        * so don't allocate extra space that won't be used in the stdio
+        * implementation.
+        */
+       if (use_browser)
+               symbol_conf.priv_size = sizeof(struct sym_priv);
 
        if (symbol__init() < 0)
                return -1;
@@ -455,7 +500,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
        setup_sorting(report_usage, options);
 
        if (parent_pattern != default_parent_pattern) {
-               sort_dimension__add("parent");
+               if (sort_dimension__add("parent") < 0)
+                       return -1;
                sort_parent.elide = 1;
        } else
                symbol_conf.exclude_other = false;
index 4f5a03e..f67bce2 100644 (file)
@@ -22,7 +22,7 @@
 static char                    const *input_name = "perf.data";
 
 static char                    default_sort_order[] = "avg, max, switch, runtime";
-static char                    *sort_order = default_sort_order;
+static const char              *sort_order = default_sort_order;
 
 static int                     profile_cpu = -1;
 
@@ -68,10 +68,10 @@ enum sched_event_type {
 
 struct sched_atom {
        enum sched_event_type   type;
+       int                     specific_wait;
        u64                     timestamp;
        u64                     duration;
        unsigned long           nr;
-       int                     specific_wait;
        sem_t                   *wait_sem;
        struct task_desc        *wakee;
 };
@@ -105,7 +105,7 @@ static u64                  sum_runtime;
 static u64                     sum_fluct;
 static u64                     run_avg;
 
-static unsigned long           replay_repeat = 10;
+static unsigned int            replay_repeat = 10;
 static unsigned long           nr_timestamps;
 static unsigned long           nr_unordered_timestamps;
 static unsigned long           nr_state_machine_bugs;
@@ -1641,30 +1641,26 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        return 0;
 }
 
-static int process_lost_event(event_t *event __used,
-                             struct perf_session *session __used)
-{
-       nr_lost_chunks++;
-       nr_lost_events += event->lost.lost;
-
-       return 0;
-}
-
 static struct perf_event_ops event_ops = {
-       .sample = process_sample_event,
-       .comm   = event__process_comm,
-       .lost   = process_lost_event,
+       .sample                 = process_sample_event,
+       .comm                   = event__process_comm,
+       .lost                   = event__process_lost,
+       .ordered_samples        = true,
 };
 
 static int read_events(void)
 {
        int err = -EINVAL;
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (session == NULL)
                return -ENOMEM;
 
-       if (perf_session__has_traces(session, "record -R"))
+       if (perf_session__has_traces(session, "record -R")) {
                err = perf_session__process_events(session, &event_ops);
+               nr_events      = session->hists.stats.nr_events[0];
+               nr_lost_events = session->hists.stats.total_lost;
+               nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST];
+       }
 
        perf_session__delete(session);
        return err;
@@ -1790,7 +1786,7 @@ static const char * const sched_usage[] = {
 static const struct option sched_options[] = {
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -1805,7 +1801,7 @@ static const char * const latency_usage[] = {
 static const struct option latency_options[] = {
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
                   "sort by key(s): runtime, switch, avg, max"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_INTEGER('C', "CPU", &profile_cpu,
                    "CPU to profile on"),
@@ -1820,9 +1816,9 @@ static const char * const replay_usage[] = {
 };
 
 static const struct option replay_options[] = {
-       OPT_INTEGER('r', "repeat", &replay_repeat,
-                   "repeat the workload replay N times (-1: infinite)"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_UINTEGER('r', "repeat", &replay_repeat,
+                    "repeat the workload replay N times (-1: infinite)"),
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
@@ -1850,7 +1846,6 @@ static const char *record_args[] = {
        "record",
        "-a",
        "-R",
-       "-M",
        "-f",
        "-m", "1024",
        "-c", "1",
index 95db31c..ff8c413 100644 (file)
@@ -46,6 +46,7 @@
 #include "util/debug.h"
 #include "util/header.h"
 #include "util/cpumap.h"
+#include "util/thread.h"
 
 #include <sys/prctl.h>
 #include <math.h>
@@ -66,18 +67,21 @@ static struct perf_event_attr default_attrs[] = {
 
 };
 
-static int                     system_wide                     =  0;
+static bool                    system_wide                     =  false;
 static unsigned int            nr_cpus                         =  0;
 static int                     run_idx                         =  0;
 
 static int                     run_count                       =  1;
-static int                     inherit                         =  1;
-static int                     scale                           =  1;
+static bool                    no_inherit                      = false;
+static bool                    scale                           =  true;
 static pid_t                   target_pid                      = -1;
+static pid_t                   target_tid                      = -1;
+static pid_t                   *all_tids                       =  NULL;
+static int                     thread_num                      =  0;
 static pid_t                   child_pid                       = -1;
-static int                     null_run                        =  0;
+static bool                    null_run                        =  false;
 
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
+static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
 
 static int                     event_scaled[MAX_COUNTERS];
 
@@ -140,9 +144,11 @@ struct stats                       runtime_branches_stats;
 #define ERR_PERF_OPEN \
 "Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n"
 
-static void create_perf_stat_counter(int counter, int pid)
+static int create_perf_stat_counter(int counter)
 {
        struct perf_event_attr *attr = attrs + counter;
+       int thread;
+       int ncreated = 0;
 
        if (scale)
                attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -152,21 +158,33 @@ static void create_perf_stat_counter(int counter, int pid)
                unsigned int cpu;
 
                for (cpu = 0; cpu < nr_cpus; cpu++) {
-                       fd[cpu][counter] = sys_perf_event_open(attr, -1, cpumap[cpu], -1, 0);
-                       if (fd[cpu][counter] < 0 && verbose)
-                               fprintf(stderr, ERR_PERF_OPEN, counter,
-                                       fd[cpu][counter], strerror(errno));
+                       fd[cpu][counter][0] = sys_perf_event_open(attr,
+                                       -1, cpumap[cpu], -1, 0);
+                       if (fd[cpu][counter][0] < 0)
+                               pr_debug(ERR_PERF_OPEN, counter,
+                                        fd[cpu][counter][0], strerror(errno));
+                       else
+                               ++ncreated;
                }
        } else {
-               attr->inherit        = inherit;
-               attr->disabled       = 1;
-               attr->enable_on_exec = 1;
-
-               fd[0][counter] = sys_perf_event_open(attr, pid, -1, -1, 0);
-               if (fd[0][counter] < 0 && verbose)
-                       fprintf(stderr, ERR_PERF_OPEN, counter,
-                               fd[0][counter], strerror(errno));
+               attr->inherit = !no_inherit;
+               if (target_pid == -1 && target_tid == -1) {
+                       attr->disabled = 1;
+                       attr->enable_on_exec = 1;
+               }
+               for (thread = 0; thread < thread_num; thread++) {
+                       fd[0][counter][thread] = sys_perf_event_open(attr,
+                               all_tids[thread], -1, -1, 0);
+                       if (fd[0][counter][thread] < 0)
+                               pr_debug(ERR_PERF_OPEN, counter,
+                                        fd[0][counter][thread],
+                                        strerror(errno));
+                       else
+                               ++ncreated;
+               }
        }
+
+       return ncreated;
 }
 
 /*
@@ -190,25 +208,28 @@ static void read_counter(int counter)
        unsigned int cpu;
        size_t res, nv;
        int scaled;
-       int i;
+       int i, thread;
 
        count[0] = count[1] = count[2] = 0;
 
        nv = scale ? 3 : 1;
        for (cpu = 0; cpu < nr_cpus; cpu++) {
-               if (fd[cpu][counter] < 0)
-                       continue;
-
-               res = read(fd[cpu][counter], single_count, nv * sizeof(u64));
-               assert(res == nv * sizeof(u64));
-
-               close(fd[cpu][counter]);
-               fd[cpu][counter] = -1;
-
-               count[0] += single_count[0];
-               if (scale) {
-                       count[1] += single_count[1];
-                       count[2] += single_count[2];
+               for (thread = 0; thread < thread_num; thread++) {
+                       if (fd[cpu][counter][thread] < 0)
+                               continue;
+
+                       res = read(fd[cpu][counter][thread],
+                                       single_count, nv * sizeof(u64));
+                       assert(res == nv * sizeof(u64));
+
+                       close(fd[cpu][counter][thread]);
+                       fd[cpu][counter][thread] = -1;
+
+                       count[0] += single_count[0];
+                       if (scale) {
+                               count[1] += single_count[1];
+                               count[2] += single_count[2];
+                       }
                }
        }
 
@@ -250,10 +271,9 @@ static int run_perf_stat(int argc __used, const char **argv)
 {
        unsigned long long t0, t1;
        int status = 0;
-       int counter;
-       int pid = target_pid;
+       int counter, ncreated = 0;
        int child_ready_pipe[2], go_pipe[2];
-       const bool forks = (target_pid == -1 && argc > 0);
+       const bool forks = (argc > 0);
        char buf;
 
        if (!system_wide)
@@ -265,10 +285,10 @@ static int run_perf_stat(int argc __used, const char **argv)
        }
 
        if (forks) {
-               if ((pid = fork()) < 0)
+               if ((child_pid = fork()) < 0)
                        perror("failed to fork");
 
-               if (!pid) {
+               if (!child_pid) {
                        close(child_ready_pipe[0]);
                        close(go_pipe[1]);
                        fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -297,7 +317,8 @@ static int run_perf_stat(int argc __used, const char **argv)
                        exit(-1);
                }
 
-               child_pid = pid;
+               if (target_tid == -1 && target_pid == -1 && !system_wide)
+                       all_tids[0] = child_pid;
 
                /*
                 * Wait for the child to be ready to exec.
@@ -310,7 +331,16 @@ static int run_perf_stat(int argc __used, const char **argv)
        }
 
        for (counter = 0; counter < nr_counters; counter++)
-               create_perf_stat_counter(counter, pid);
+               ncreated += create_perf_stat_counter(counter);
+
+       if (ncreated == 0) {
+               pr_err("No permission to collect %sstats.\n"
+                      "Consider tweaking /proc/sys/kernel/perf_event_paranoid.\n",
+                      system_wide ? "system-wide " : "");
+               if (child_pid != -1)
+                       kill(child_pid, SIGTERM);
+               return -1;
+       }
 
        /*
         * Enable counters and exec the command:
@@ -321,7 +351,7 @@ static int run_perf_stat(int argc __used, const char **argv)
                close(go_pipe[1]);
                wait(&status);
        } else {
-               while(!done);
+               while(!done) sleep(1);
        }
 
        t1 = rdclock();
@@ -429,12 +459,14 @@ static void print_stat(int argc, const char **argv)
 
        fprintf(stderr, "\n");
        fprintf(stderr, " Performance counter stats for ");
-       if(target_pid == -1) {
+       if(target_pid == -1 && target_tid == -1) {
                fprintf(stderr, "\'%s", argv[0]);
                for (i = 1; i < argc; i++)
                        fprintf(stderr, " %s", argv[i]);
-       }else
-               fprintf(stderr, "task pid \'%d", target_pid);
+       } else if (target_pid != -1)
+               fprintf(stderr, "process id \'%d", target_pid);
+       else
+               fprintf(stderr, "thread id \'%d", target_tid);
 
        fprintf(stderr, "\'");
        if (run_count > 1)
@@ -459,7 +491,7 @@ static volatile int signr = -1;
 
 static void skip_signal(int signo)
 {
-       if(target_pid != -1)
+       if(child_pid == -1)
                done = 1;
 
        signr = signo;
@@ -486,15 +518,17 @@ static const struct option options[] = {
        OPT_CALLBACK('e', "event", NULL, "event",
                     "event selector. use 'perf list' to list available events",
                     parse_events),
-       OPT_BOOLEAN('i', "inherit", &inherit,
-                   "child tasks inherit counters"),
+       OPT_BOOLEAN('i', "no-inherit", &no_inherit,
+                   "child tasks do not inherit counters"),
        OPT_INTEGER('p', "pid", &target_pid,
-                   "stat events on existing pid"),
+                   "stat events on existing process id"),
+       OPT_INTEGER('t', "tid", &target_tid,
+                   "stat events on existing thread id"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                    "system-wide collection from all CPUs"),
        OPT_BOOLEAN('c', "scale", &scale,
                    "scale/normalize counters"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_INTEGER('r', "repeat", &run_count,
                    "repeat command and print average + stddev (max: 100)"),
@@ -506,10 +540,11 @@ static const struct option options[] = {
 int cmd_stat(int argc, const char **argv, const char *prefix __used)
 {
        int status;
+       int i,j;
 
        argc = parse_options(argc, argv, options, stat_usage,
                PARSE_OPT_STOP_AT_NON_OPTION);
-       if (!argc && target_pid == -1)
+       if (!argc && target_pid == -1 && target_tid == -1)
                usage_with_options(stat_usage, options);
        if (run_count <= 0)
                usage_with_options(stat_usage, options);
@@ -525,6 +560,31 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
        else
                nr_cpus = 1;
 
+       if (target_pid != -1) {
+               target_tid = target_pid;
+               thread_num = find_all_tid(target_pid, &all_tids);
+               if (thread_num <= 0) {
+                       fprintf(stderr, "Can't find all threads of pid %d\n",
+                                       target_pid);
+                       usage_with_options(stat_usage, options);
+               }
+       } else {
+               all_tids=malloc(sizeof(pid_t));
+               if (!all_tids)
+                       return -ENOMEM;
+
+               all_tids[0] = target_tid;
+               thread_num = 1;
+       }
+
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++) {
+                       fd[i][j] = malloc(sizeof(int)*thread_num);
+                       if (!fd[i][j])
+                               return -ENOMEM;
+               }
+       }
+
        /*
         * We dont want to block the signals - that would cause
         * child tasks to inherit that and Ctrl-C would not work.
@@ -543,7 +603,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
                status = run_perf_stat(argc, argv);
        }
 
-       print_stat(argc, argv);
+       if (status != -1)
+               print_stat(argc, argv);
 
        return status;
 }
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
new file mode 100644 (file)
index 0000000..035b9fa
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * builtin-test.c
+ *
+ * Builtin regression testing command: ever growing number of sanity tests
+ */
+#include "builtin.h"
+
+#include "util/cache.h"
+#include "util/debug.h"
+#include "util/parse-options.h"
+#include "util/session.h"
+#include "util/symbol.h"
+#include "util/thread.h"
+
+static long page_size;
+
+static int vmlinux_matches_kallsyms_filter(struct map *map __used, struct symbol *sym)
+{
+       bool *visited = symbol__priv(sym);
+       *visited = true;
+       return 0;
+}
+
+static int test__vmlinux_matches_kallsyms(void)
+{
+       int err = -1;
+       struct rb_node *nd;
+       struct symbol *sym;
+       struct map *kallsyms_map, *vmlinux_map;
+       struct machine kallsyms, vmlinux;
+       enum map_type type = MAP__FUNCTION;
+       struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", };
+
+       /*
+        * Step 1:
+        *
+        * Init the machines that will hold kernel, modules obtained from
+        * both vmlinux + .ko files and from /proc/kallsyms split by modules.
+        */
+       machine__init(&kallsyms, "", HOST_KERNEL_ID);
+       machine__init(&vmlinux, "", HOST_KERNEL_ID);
+
+       /*
+        * Step 2:
+        *
+        * Create the kernel maps for kallsyms and the DSO where we will then
+        * load /proc/kallsyms. Also create the modules maps from /proc/modules
+        * and find the .ko files that match them in /lib/modules/`uname -r`/.
+        */
+       if (machine__create_kernel_maps(&kallsyms) < 0) {
+               pr_debug("machine__create_kernel_maps ");
+               return -1;
+       }
+
+       /*
+        * Step 3:
+        *
+        * Load and split /proc/kallsyms into multiple maps, one per module.
+        */
+       if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) {
+               pr_debug("dso__load_kallsyms ");
+               goto out;
+       }
+
+       /*
+        * Step 4:
+        *
+        * kallsyms will be internally on demand sorted by name so that we can
+        * find the reference relocation * symbol, i.e. the symbol we will use
+        * to see if the running kernel was relocated by checking if it has the
+        * same value in the vmlinux file we load.
+        */
+       kallsyms_map = machine__kernel_map(&kallsyms, type);
+
+       sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL);
+       if (sym == NULL) {
+               pr_debug("dso__find_symbol_by_name ");
+               goto out;
+       }
+
+       ref_reloc_sym.addr = sym->start;
+
+       /*
+        * Step 5:
+        *
+        * Now repeat step 2, this time for the vmlinux file we'll auto-locate.
+        */
+       if (machine__create_kernel_maps(&vmlinux) < 0) {
+               pr_debug("machine__create_kernel_maps ");
+               goto out;
+       }
+
+       vmlinux_map = machine__kernel_map(&vmlinux, type);
+       map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym;
+
+       /*
+        * Step 6:
+        *
+        * Locate a vmlinux file in the vmlinux path that has a buildid that
+        * matches the one of the running kernel.
+        *
+        * While doing that look if we find the ref reloc symbol, if we find it
+        * we'll have its ref_reloc_symbol.unrelocated_addr and then
+        * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines
+        * to fixup the symbols.
+        */
+       if (machine__load_vmlinux_path(&vmlinux, type,
+                                      vmlinux_matches_kallsyms_filter) <= 0) {
+               pr_debug("machine__load_vmlinux_path ");
+               goto out;
+       }
+
+       err = 0;
+       /*
+        * Step 7:
+        *
+        * Now look at the symbols in the vmlinux DSO and check if we find all of them
+        * in the kallsyms dso. For the ones that are in both, check its names and
+        * end addresses too.
+        */
+       for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
+               struct symbol *pair;
+
+               sym  = rb_entry(nd, struct symbol, rb_node);
+               pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
+
+               if (pair && pair->start == sym->start) {
+next_pair:
+                       if (strcmp(sym->name, pair->name) == 0) {
+                               /*
+                                * kallsyms don't have the symbol end, so we
+                                * set that by using the next symbol start - 1,
+                                * in some cases we get this up to a page
+                                * wrong, trace_kmalloc when I was developing
+                                * this code was one such example, 2106 bytes
+                                * off the real size. More than that and we
+                                * _really_ have a problem.
+                                */
+                               s64 skew = sym->end - pair->end;
+                               if (llabs(skew) < page_size)
+                                       continue;
+
+                               pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n",
+                                        sym->start, sym->name, sym->end, pair->end);
+                       } else {
+                               struct rb_node *nnd = rb_prev(&pair->rb_node);
+
+                               if (nnd) {
+                                       struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
+
+                                       if (next->start == sym->start) {
+                                               pair = next;
+                                               goto next_pair;
+                                       }
+                               }
+                               pr_debug("%#Lx: diff name v: %s k: %s\n",
+                                        sym->start, sym->name, pair->name);
+                       }
+               } else
+                       pr_debug("%#Lx: %s not on kallsyms\n", sym->start, sym->name);
+
+               err = -1;
+       }
+
+       if (!verbose)
+               goto out;
+
+       pr_info("Maps only in vmlinux:\n");
+
+       for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
+               /*
+                * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while
+                * the kernel will have the path for the vmlinux file being used,
+                * so use the short name, less descriptive but the same ("[kernel]" in
+                * both cases.
+                */
+               pair = map_groups__find_by_name(&kallsyms.kmaps, type,
+                                               (pos->dso->kernel ?
+                                                       pos->dso->short_name :
+                                                       pos->dso->name));
+               if (pair)
+                       pair->priv = 1;
+               else
+                       map__fprintf(pos, stderr);
+       }
+
+       pr_info("Maps in vmlinux with a different name in kallsyms:\n");
+
+       for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node), *pair;
+
+               pair = map_groups__find(&kallsyms.kmaps, type, pos->start);
+               if (pair == NULL || pair->priv)
+                       continue;
+
+               if (pair->start == pos->start) {
+                       pair->priv = 1;
+                       pr_info(" %Lx-%Lx %Lx %s in kallsyms as",
+                               pos->start, pos->end, pos->pgoff, pos->dso->name);
+                       if (pos->pgoff != pair->pgoff || pos->end != pair->end)
+                               pr_info(": \n*%Lx-%Lx %Lx",
+                                       pair->start, pair->end, pair->pgoff);
+                       pr_info(" %s\n", pair->dso->name);
+                       pair->priv = 1;
+               }
+       }
+
+       pr_info("Maps only in kallsyms:\n");
+
+       for (nd = rb_first(&kallsyms.kmaps.maps[type]);
+            nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node);
+
+               if (!pos->priv)
+                       map__fprintf(pos, stderr);
+       }
+out:
+       return err;
+}
+
+static struct test {
+       const char *desc;
+       int (*func)(void);
+} tests[] = {
+       {
+               .desc = "vmlinux symtab matches kallsyms",
+               .func = test__vmlinux_matches_kallsyms,
+       },
+       {
+               .func = NULL,
+       },
+};
+
+static int __cmd_test(void)
+{
+       int i = 0;
+
+       page_size = sysconf(_SC_PAGE_SIZE);
+
+       while (tests[i].func) {
+               int err;
+               pr_info("%2d: %s:", i + 1, tests[i].desc);
+               pr_debug("\n--- start ---\n");
+               err = tests[i].func();
+               pr_debug("---- end ----\n%s:", tests[i].desc);
+               pr_info(" %s\n", err ? "FAILED!\n" : "Ok");
+               ++i;
+       }
+
+       return 0;
+}
+
+static const char * const test_usage[] = {
+       "perf test [<options>]",
+       NULL,
+};
+
+static const struct option test_options[] = {
+       OPT_INTEGER('v', "verbose", &verbose,
+                   "be more verbose (show symbol address, etc)"),
+       OPT_END()
+};
+
+int cmd_test(int argc, const char **argv, const char *prefix __used)
+{
+       argc = parse_options(argc, argv, test_options, test_usage, 0);
+       if (argc)
+               usage_with_options(test_usage, test_options);
+
+       symbol_conf.priv_size = sizeof(int);
+       symbol_conf.sort_by_name = true;
+       symbol_conf.try_vmlinux_path = true;
+
+       if (symbol__init() < 0)
+               return -1;
+
+       setup_pager();
+
+       return __cmd_test();
+}
index 0d4d8ff..5a52ed9 100644 (file)
@@ -21,7 +21,6 @@
 #include "util/cache.h"
 #include <linux/rbtree.h>
 #include "util/symbol.h"
-#include "util/string.h"
 #include "util/callchain.h"
 #include "util/strlist.h"
 
@@ -43,7 +42,7 @@ static u64            turbo_frequency;
 
 static u64             first_time, last_time;
 
-static int             power_only;
+static bool            power_only;
 
 
 struct per_pid;
@@ -78,8 +77,6 @@ struct per_pid {
 
        struct per_pidcomm *all;
        struct per_pidcomm *current;
-
-       int painted;
 };
 
 
@@ -146,9 +143,6 @@ struct wake_event {
 static struct power_event    *power_events;
 static struct wake_event     *wake_events;
 
-struct sample_wrapper *all_samples;
-
-
 struct process_filter;
 struct process_filter {
        char                    *name;
@@ -569,88 +563,6 @@ static void end_sample_processing(void)
        }
 }
 
-static u64 sample_time(event_t *event, const struct perf_session *session)
-{
-       int cursor;
-
-       cursor = 0;
-       if (session->sample_type & PERF_SAMPLE_IP)
-               cursor++;
-       if (session->sample_type & PERF_SAMPLE_TID)
-               cursor++;
-       if (session->sample_type & PERF_SAMPLE_TIME)
-               return event->sample.array[cursor];
-       return 0;
-}
-
-
-/*
- * We first queue all events, sorted backwards by insertion.
- * The order will get flipped later.
- */
-static int queue_sample_event(event_t *event, struct perf_session *session)
-{
-       struct sample_wrapper *copy, *prev;
-       int size;
-
-       size = event->sample.header.size + sizeof(struct sample_wrapper) + 8;
-
-       copy = malloc(size);
-       if (!copy)
-               return 1;
-
-       memset(copy, 0, size);
-
-       copy->next = NULL;
-       copy->timestamp = sample_time(event, session);
-
-       memcpy(&copy->data, event, event->sample.header.size);
-
-       /* insert in the right place in the list */
-
-       if (!all_samples) {
-               /* first sample ever */
-               all_samples = copy;
-               return 0;
-       }
-
-       if (all_samples->timestamp < copy->timestamp) {
-               /* insert at the head of the list */
-               copy->next = all_samples;
-               all_samples = copy;
-               return 0;
-       }
-
-       prev = all_samples;
-       while (prev->next) {
-               if (prev->next->timestamp < copy->timestamp) {
-                       copy->next = prev->next;
-                       prev->next = copy;
-                       return 0;
-               }
-               prev = prev->next;
-       }
-       /* insert at the end of the list */
-       prev->next = copy;
-
-       return 0;
-}
-
-static void sort_queued_samples(void)
-{
-       struct sample_wrapper *cursor, *next;
-
-       cursor = all_samples;
-       all_samples = NULL;
-
-       while (cursor) {
-               next = cursor->next;
-               cursor->next = all_samples;
-               all_samples = cursor;
-               cursor = next;
-       }
-}
-
 /*
  * Sort the pid datastructure
  */
@@ -1014,31 +926,17 @@ static void write_svg_file(const char *filename)
        svg_close();
 }
 
-static void process_samples(struct perf_session *session)
-{
-       struct sample_wrapper *cursor;
-       event_t *event;
-
-       sort_queued_samples();
-
-       cursor = all_samples;
-       while (cursor) {
-               event = (void *)&cursor->data;
-               cursor = cursor->next;
-               process_sample_event(event, session);
-       }
-}
-
 static struct perf_event_ops event_ops = {
-       .comm   = process_comm_event,
-       .fork   = process_fork_event,
-       .exit   = process_exit_event,
-       .sample = queue_sample_event,
+       .comm                   = process_comm_event,
+       .fork                   = process_fork_event,
+       .exit                   = process_exit_event,
+       .sample                 = process_sample_event,
+       .ordered_samples        = true,
 };
 
 static int __cmd_timechart(void)
 {
-       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
+       struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false);
        int ret = -EINVAL;
 
        if (session == NULL)
@@ -1051,8 +949,6 @@ static int __cmd_timechart(void)
        if (ret)
                goto out_delete;
 
-       process_samples(session);
-
        end_sample_processing();
 
        sort_pids();
@@ -1075,7 +971,6 @@ static const char *record_args[] = {
        "record",
        "-a",
        "-R",
-       "-M",
        "-f",
        "-c", "1",
        "-e", "power:power_start",
index 1f52932..397290a 100644 (file)
@@ -55,9 +55,9 @@
 #include <linux/unistd.h>
 #include <linux/types.h>
 
-static int                     fd[MAX_NR_CPUS][MAX_COUNTERS];
+static int                     *fd[MAX_NR_CPUS][MAX_COUNTERS];
 
-static int                     system_wide                     =      0;
+static bool                    system_wide                     =  false;
 
 static int                     default_interval                =      0;
 
@@ -65,18 +65,21 @@ static int                  count_filter                    =      5;
 static int                     print_entries;
 
 static int                     target_pid                      =     -1;
-static int                     inherit                         =      0;
+static int                     target_tid                      =     -1;
+static pid_t                   *all_tids                       =      NULL;
+static int                     thread_num                      =      0;
+static bool                    inherit                         =  false;
 static int                     profile_cpu                     =     -1;
 static int                     nr_cpus                         =      0;
-static unsigned int            realtime_prio                   =      0;
-static int                     group                           =      0;
+static int                     realtime_prio                   =      0;
+static bool                    group                           =  false;
 static unsigned int            page_size;
 static unsigned int            mmap_pages                      =     16;
 static int                     freq                            =   1000; /* 1 KHz */
 
 static int                     delay_secs                      =      2;
-static int                     zero                            =      0;
-static int                     dump_symtab                     =      0;
+static bool                    zero                            =  false;
+static bool                    dump_symtab                     =  false;
 
 static bool                    hide_kernel_symbols             =  false;
 static bool                    hide_user_symbols               =  false;
@@ -93,7 +96,7 @@ struct source_line {
        struct source_line      *next;
 };
 
-static char                    *sym_filter                     =   NULL;
+static const char              *sym_filter                     =   NULL;
 struct sym_entry               *sym_filter_entry               =   NULL;
 struct sym_entry               *sym_filter_entry_sched         =   NULL;
 static int                     sym_pcnt_filter                 =      5;
@@ -133,7 +136,7 @@ static inline struct symbol *sym_entry__symbol(struct sym_entry *self)
        return ((void *)self) + symbol_conf.priv_size;
 }
 
-static void get_term_dimensions(struct winsize *ws)
+void get_term_dimensions(struct winsize *ws)
 {
        char *s = getenv("LINES");
 
@@ -169,7 +172,7 @@ static void sig_winch_handler(int sig __used)
        update_print_entries(&winsize);
 }
 
-static void parse_source(struct sym_entry *syme)
+static int parse_source(struct sym_entry *syme)
 {
        struct symbol *sym;
        struct sym_entry_source *source;
@@ -180,12 +183,21 @@ static void parse_source(struct sym_entry *syme)
        u64 len;
 
        if (!syme)
-               return;
+               return -1;
+
+       sym = sym_entry__symbol(syme);
+       map = syme->map;
+
+       /*
+        * We can't annotate with just /proc/kallsyms
+        */
+       if (map->dso->origin == DSO__ORIG_KERNEL)
+               return -1;
 
        if (syme->src == NULL) {
                syme->src = zalloc(sizeof(*source));
                if (syme->src == NULL)
-                       return;
+                       return -1;
                pthread_mutex_init(&syme->src->lock, NULL);
        }
 
@@ -195,9 +207,6 @@ static void parse_source(struct sym_entry *syme)
                pthread_mutex_lock(&source->lock);
                goto out_assign;
        }
-
-       sym = sym_entry__symbol(syme);
-       map = syme->map;
        path = map->dso->long_name;
 
        len = sym->end - sym->start;
@@ -209,7 +218,7 @@ static void parse_source(struct sym_entry *syme)
 
        file = popen(command, "r");
        if (!file)
-               return;
+               return -1;
 
        pthread_mutex_lock(&source->lock);
        source->lines_tail = &source->lines;
@@ -245,6 +254,7 @@ static void parse_source(struct sym_entry *syme)
 out_assign:
        sym_filter_entry = syme;
        pthread_mutex_unlock(&source->lock);
+       return 0;
 }
 
 static void __zero_source_counters(struct sym_entry *syme)
@@ -410,7 +420,9 @@ static double sym_weight(const struct sym_entry *sym)
 }
 
 static long                    samples;
-static long                    userspace_samples;
+static long                    kernel_samples, us_samples;
+static long                    exact_samples;
+static long                    guest_us_samples, guest_kernel_samples;
 static const char              CONSOLE_CLEAR[] = "\e[H\e[2J";
 
 static void __list_insert_active_sym(struct sym_entry *syme)
@@ -450,7 +462,11 @@ static void print_sym_table(void)
        int printed = 0, j;
        int counter, snap = !display_weighted ? sym_counter : 0;
        float samples_per_sec = samples/delay_secs;
-       float ksamples_per_sec = (samples-userspace_samples)/delay_secs;
+       float ksamples_per_sec = kernel_samples/delay_secs;
+       float us_samples_per_sec = (us_samples)/delay_secs;
+       float guest_kernel_samples_per_sec = (guest_kernel_samples)/delay_secs;
+       float guest_us_samples_per_sec = (guest_us_samples)/delay_secs;
+       float esamples_percent = (100.0*exact_samples)/samples;
        float sum_ksamples = 0.0;
        struct sym_entry *syme, *n;
        struct rb_root tmp = RB_ROOT;
@@ -458,7 +474,8 @@ static void print_sym_table(void)
        int sym_width = 0, dso_width = 0, dso_short_width = 0;
        const int win_width = winsize.ws_col - 1;
 
-       samples = userspace_samples = 0;
+       samples = us_samples = kernel_samples = exact_samples = 0;
+       guest_kernel_samples = guest_us_samples = 0;
 
        /* Sort the active symbols */
        pthread_mutex_lock(&active_symbols_lock);
@@ -489,9 +506,30 @@ static void print_sym_table(void)
        puts(CONSOLE_CLEAR);
 
        printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
-       printf( "   PerfTop:%8.0f irqs/sec  kernel:%4.1f%% [",
-               samples_per_sec,
-               100.0 - (100.0*((samples_per_sec-ksamples_per_sec)/samples_per_sec)));
+       if (!perf_guest) {
+               printf("   PerfTop:%8.0f irqs/sec  kernel:%4.1f%%"
+                       "  exact: %4.1f%% [",
+                       samples_per_sec,
+                       100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
+                                        samples_per_sec)),
+                       esamples_percent);
+       } else {
+               printf("   PerfTop:%8.0f irqs/sec  kernel:%4.1f%% us:%4.1f%%"
+                       " guest kernel:%4.1f%% guest us:%4.1f%%"
+                       " exact: %4.1f%% [",
+                       samples_per_sec,
+                       100.0 - (100.0 * ((samples_per_sec-ksamples_per_sec) /
+                                         samples_per_sec)),
+                       100.0 - (100.0 * ((samples_per_sec-us_samples_per_sec) /
+                                         samples_per_sec)),
+                       100.0 - (100.0 * ((samples_per_sec -
+                                               guest_kernel_samples_per_sec) /
+                                         samples_per_sec)),
+                       100.0 - (100.0 * ((samples_per_sec -
+                                          guest_us_samples_per_sec) /
+                                         samples_per_sec)),
+                       esamples_percent);
+       }
 
        if (nr_counters == 1 || !display_weighted) {
                printf("%Ld", (u64)attrs[0].sample_period);
@@ -514,13 +552,15 @@ static void print_sym_table(void)
 
        if (target_pid != -1)
                printf(" (target_pid: %d", target_pid);
+       else if (target_tid != -1)
+               printf(" (target_tid: %d", target_tid);
        else
                printf(" (all");
 
        if (profile_cpu != -1)
                printf(", cpu: %d)\n", profile_cpu);
        else {
-               if (target_pid != -1)
+               if (target_tid != -1)
                        printf(")\n");
                else
                        printf(", %d CPUs)\n", nr_cpus);
@@ -582,7 +622,6 @@ static void print_sym_table(void)
 
                syme = rb_entry(nd, struct sym_entry, rb_node);
                sym = sym_entry__symbol(syme);
-
                if (++printed > print_entries || (int)syme->snap_count < count_filter)
                        continue;
 
@@ -746,7 +785,7 @@ static int key_mapped(int c)
        return 0;
 }
 
-static void handle_keypress(int c)
+static void handle_keypress(struct perf_session *session, int c)
 {
        if (!key_mapped(c)) {
                struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -815,7 +854,7 @@ static void handle_keypress(int c)
                case 'Q':
                        printf("exiting.\n");
                        if (dump_symtab)
-                               dsos__fprintf(stderr);
+                               perf_session__fprintf_dsos(session, stderr);
                        exit(0);
                case 's':
                        prompt_symbol(&sym_filter_entry, "Enter details symbol");
@@ -839,7 +878,7 @@ static void handle_keypress(int c)
                        display_weighted = ~display_weighted;
                        break;
                case 'z':
-                       zero = ~zero;
+                       zero = !zero;
                        break;
                default:
                        break;
@@ -851,6 +890,7 @@ static void *display_thread(void *arg __used)
        struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
        struct termios tc, save;
        int delay_msecs, c;
+       struct perf_session *session = (struct perf_session *) arg;
 
        tcgetattr(0, &save);
        tc = save;
@@ -871,7 +911,7 @@ repeat:
        c = getc(stdin);
        tcsetattr(0, TCSAFLUSH, &save);
 
-       handle_keypress(c);
+       handle_keypress(session, c);
        goto repeat;
 
        return NULL;
@@ -942,24 +982,48 @@ static void event__process_sample(const event_t *self,
        u64 ip = self->ip.ip;
        struct sym_entry *syme;
        struct addr_location al;
+       struct machine *machine;
        u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
        ++samples;
 
        switch (origin) {
        case PERF_RECORD_MISC_USER:
-               ++userspace_samples;
+               ++us_samples;
                if (hide_user_symbols)
                        return;
+               machine = perf_session__find_host_machine(session);
                break;
        case PERF_RECORD_MISC_KERNEL:
+               ++kernel_samples;
                if (hide_kernel_symbols)
                        return;
+               machine = perf_session__find_host_machine(session);
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+               ++guest_kernel_samples;
+               machine = perf_session__find_machine(session, self->ip.pid);
                break;
+       case PERF_RECORD_MISC_GUEST_USER:
+               ++guest_us_samples;
+               /*
+                * TODO: we don't process guest user from host side
+                * except simple counting.
+                */
+               return;
        default:
                return;
        }
 
+       if (!machine && perf_guest) {
+               pr_err("Can't find guest [%d]'s kernel information\n",
+                       self->ip.pid);
+               return;
+       }
+
+       if (self->header.misc & PERF_RECORD_MISC_EXACT_IP)
+               exact_samples++;
+
        if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
            al.filtered)
                return;
@@ -976,7 +1040,7 @@ static void event__process_sample(const event_t *self,
                 * --hide-kernel-symbols, even if the user specifies an
                 * invalid --vmlinux ;-)
                 */
-               if (al.map == session->vmlinux_maps[MAP__FUNCTION] &&
+               if (al.map == machine->vmlinux_maps[MAP__FUNCTION] &&
                    RB_EMPTY_ROOT(&al.map->dso->symbols[MAP__FUNCTION])) {
                        pr_err("The %s file can't be used\n",
                               symbol_conf.vmlinux_name);
@@ -990,7 +1054,17 @@ static void event__process_sample(const event_t *self,
        if (sym_filter_entry_sched) {
                sym_filter_entry = sym_filter_entry_sched;
                sym_filter_entry_sched = NULL;
-               parse_source(sym_filter_entry);
+               if (parse_source(sym_filter_entry) < 0) {
+                       struct symbol *sym = sym_entry__symbol(sym_filter_entry);
+
+                       pr_err("Can't annotate %s", sym->name);
+                       if (sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) {
+                               pr_err(": No vmlinux file was found in the path:\n");
+                               vmlinux_path__fprintf(stderr);
+                       } else
+                               pr_err(".\n");
+                       exit(1);
+               }
        }
 
        syme = symbol__priv(al.sym);
@@ -1106,16 +1180,21 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
        md->prev = old;
 }
 
-static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS];
-static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
+static struct pollfd *event_array;
+static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
 
 static void perf_session__mmap_read(struct perf_session *self)
 {
-       int i, counter;
+       int i, counter, thread_index;
 
        for (i = 0; i < nr_cpus; i++) {
                for (counter = 0; counter < nr_counters; counter++)
-                       perf_session__mmap_read_counter(self, &mmap_array[i][counter]);
+                       for (thread_index = 0;
+                               thread_index < thread_num;
+                               thread_index++) {
+                               perf_session__mmap_read_counter(self,
+                                       &mmap_array[i][counter][thread_index]);
+                       }
        }
 }
 
@@ -1126,9 +1205,10 @@ static void start_counter(int i, int counter)
 {
        struct perf_event_attr *attr;
        int cpu;
+       int thread_index;
 
        cpu = profile_cpu;
-       if (target_pid == -1 && profile_cpu == -1)
+       if (target_tid == -1 && profile_cpu == -1)
                cpu = cpumap[i];
 
        attr = attrs + counter;
@@ -1144,55 +1224,58 @@ static void start_counter(int i, int counter)
        attr->inherit           = (cpu < 0) && inherit;
        attr->mmap              = 1;
 
+       for (thread_index = 0; thread_index < thread_num; thread_index++) {
 try_again:
-       fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
-
-       if (fd[i][counter] < 0) {
-               int err = errno;
+               fd[i][counter][thread_index] = sys_perf_event_open(attr,
+                               all_tids[thread_index], cpu, group_fd, 0);
+
+               if (fd[i][counter][thread_index] < 0) {
+                       int err = errno;
+
+                       if (err == EPERM || err == EACCES)
+                               die("No permission - are you root?\n");
+                       /*
+                        * If it's cycles then fall back to hrtimer
+                        * based cpu-clock-tick sw counter, which
+                        * is always available even if no PMU support:
+                        */
+                       if (attr->type == PERF_TYPE_HARDWARE
+                                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
+
+                               if (verbose)
+                                       warning(" ... trying to fall back to cpu-clock-ticks\n");
+
+                               attr->type = PERF_TYPE_SOFTWARE;
+                               attr->config = PERF_COUNT_SW_CPU_CLOCK;
+                               goto try_again;
+                       }
+                       printf("\n");
+                       error("perfcounter syscall returned with %d (%s)\n",
+                                       fd[i][counter][thread_index], strerror(err));
+                       die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
+                       exit(-1);
+               }
+               assert(fd[i][counter][thread_index] >= 0);
+               fcntl(fd[i][counter][thread_index], F_SETFL, O_NONBLOCK);
 
-               if (err == EPERM || err == EACCES)
-                       die("No permission - are you root?\n");
                /*
-                * If it's cycles then fall back to hrtimer
-                * based cpu-clock-tick sw counter, which
-                * is always available even if no PMU support:
+                * First counter acts as the group leader:
                 */
-               if (attr->type == PERF_TYPE_HARDWARE
-                       && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
-
-                       if (verbose)
-                               warning(" ... trying to fall back to cpu-clock-ticks\n");
-
-                       attr->type = PERF_TYPE_SOFTWARE;
-                       attr->config = PERF_COUNT_SW_CPU_CLOCK;
-                       goto try_again;
-               }
-               printf("\n");
-               error("perfcounter syscall returned with %d (%s)\n",
-                       fd[i][counter], strerror(err));
-               die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
-               exit(-1);
+               if (group && group_fd == -1)
+                       group_fd = fd[i][counter][thread_index];
+
+               event_array[nr_poll].fd = fd[i][counter][thread_index];
+               event_array[nr_poll].events = POLLIN;
+               nr_poll++;
+
+               mmap_array[i][counter][thread_index].counter = counter;
+               mmap_array[i][counter][thread_index].prev = 0;
+               mmap_array[i][counter][thread_index].mask = mmap_pages*page_size - 1;
+               mmap_array[i][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
+                               PROT_READ, MAP_SHARED, fd[i][counter][thread_index], 0);
+               if (mmap_array[i][counter][thread_index].base == MAP_FAILED)
+                       die("failed to mmap with %d (%s)\n", errno, strerror(errno));
        }
-       assert(fd[i][counter] >= 0);
-       fcntl(fd[i][counter], F_SETFL, O_NONBLOCK);
-
-       /*
-        * First counter acts as the group leader:
-        */
-       if (group && group_fd == -1)
-               group_fd = fd[i][counter];
-
-       event_array[nr_poll].fd = fd[i][counter];
-       event_array[nr_poll].events = POLLIN;
-       nr_poll++;
-
-       mmap_array[i][counter].counter = counter;
-       mmap_array[i][counter].prev = 0;
-       mmap_array[i][counter].mask = mmap_pages*page_size - 1;
-       mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-                       PROT_READ, MAP_SHARED, fd[i][counter], 0);
-       if (mmap_array[i][counter].base == MAP_FAILED)
-               die("failed to mmap with %d (%s)\n", errno, strerror(errno));
 }
 
 static int __cmd_top(void)
@@ -1204,12 +1287,12 @@ static int __cmd_top(void)
         * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
         * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
         */
-       struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
+       struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false);
        if (session == NULL)
                return -ENOMEM;
 
-       if (target_pid != -1)
-               event__synthesize_thread(target_pid, event__process, session);
+       if (target_tid != -1)
+               event__synthesize_thread(target_tid, event__process, session);
        else
                event__synthesize_threads(event__process, session);
 
@@ -1220,11 +1303,11 @@ static int __cmd_top(void)
        }
 
        /* Wait for a minimal set of events before starting the snapshot */
-       poll(event_array, nr_poll, 100);
+       poll(&event_array[0], nr_poll, 100);
 
        perf_session__mmap_read(session);
 
-       if (pthread_create(&thread, NULL, display_thread, NULL)) {
+       if (pthread_create(&thread, NULL, display_thread, session)) {
                printf("Could not create display thread.\n");
                exit(-1);
        }
@@ -1263,7 +1346,9 @@ static const struct option options[] = {
        OPT_INTEGER('c', "count", &default_interval,
                    "event period to sample"),
        OPT_INTEGER('p', "pid", &target_pid,
-                   "profile events on existing pid"),
+                   "profile events on existing process id"),
+       OPT_INTEGER('t', "tid", &target_tid,
+                   "profile events on existing thread id"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                            "system-wide collection from all CPUs"),
        OPT_INTEGER('C', "CPU", &profile_cpu,
@@ -1272,8 +1357,7 @@ static const struct option options[] = {
                   "file", "vmlinux pathname"),
        OPT_BOOLEAN('K', "hide_kernel_symbols", &hide_kernel_symbols,
                    "hide kernel symbols"),
-       OPT_INTEGER('m', "mmap-pages", &mmap_pages,
-                   "number of mmap data pages"),
+       OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
        OPT_INTEGER('r', "realtime", &realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
        OPT_INTEGER('d', "delay", &delay_secs,
@@ -1296,7 +1380,7 @@ static const struct option options[] = {
                    "display this many functions"),
        OPT_BOOLEAN('U', "hide_user_symbols", &hide_user_symbols,
                    "hide user symbols"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show counter open errors, etc)"),
        OPT_END()
 };
@@ -1304,6 +1388,7 @@ static const struct option options[] = {
 int cmd_top(int argc, const char **argv, const char *prefix __used)
 {
        int counter;
+       int i,j;
 
        page_size = sysconf(_SC_PAGE_SIZE);
 
@@ -1311,8 +1396,39 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
        if (argc)
                usage_with_options(top_usage, options);
 
+       if (target_pid != -1) {
+               target_tid = target_pid;
+               thread_num = find_all_tid(target_pid, &all_tids);
+               if (thread_num <= 0) {
+                       fprintf(stderr, "Can't find all threads of pid %d\n",
+                               target_pid);
+                       usage_with_options(top_usage, options);
+               }
+       } else {
+               all_tids=malloc(sizeof(pid_t));
+               if (!all_tids)
+                       return -ENOMEM;
+
+               all_tids[0] = target_tid;
+               thread_num = 1;
+       }
+
+       for (i = 0; i < MAX_NR_CPUS; i++) {
+               for (j = 0; j < MAX_COUNTERS; j++) {
+                       fd[i][j] = malloc(sizeof(int)*thread_num);
+                       mmap_array[i][j] = zalloc(
+                               sizeof(struct mmap_data)*thread_num);
+                       if (!fd[i][j] || !mmap_array[i][j])
+                               return -ENOMEM;
+               }
+       }
+       event_array = malloc(
+               sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
+       if (!event_array)
+               return -ENOMEM;
+
        /* CPU and PID are mutually exclusive */
-       if (target_pid != -1 && profile_cpu != -1) {
+       if (target_tid > 0 && profile_cpu != -1) {
                printf("WARNING: PID switch overriding CPU\n");
                sleep(1);
                profile_cpu = -1;
@@ -1353,7 +1469,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
                attrs[counter].sample_period = default_interval;
        }
 
-       if (target_pid != -1 || profile_cpu != -1)
+       if (target_tid != -1 || profile_cpu != -1)
                nr_cpus = 1;
        else
                nr_cpus = read_cpu_map();
index 407041d..dddf3f0 100644 (file)
@@ -11,6 +11,8 @@
 
 static char const              *script_name;
 static char const              *generate_script_lang;
+static bool                    debug_ordering;
+static u64                     last_timestamp;
 
 static int default_start_script(const char *script __unused,
                                int argc __unused,
@@ -51,6 +53,8 @@ static void setup_scripting(void)
 
 static int cleanup_scripting(void)
 {
+       pr_debug("\nperf trace script stopped\n");
+
        return scripting_ops->stop_script();
 }
 
@@ -87,6 +91,14 @@ static int process_sample_event(event_t *event, struct perf_session *session)
        }
 
        if (session->sample_type & PERF_SAMPLE_RAW) {
+               if (debug_ordering) {
+                       if (data.time < last_timestamp) {
+                               pr_err("Samples misordered, previous: %llu "
+                                       "this: %llu\n", last_timestamp,
+                                       data.time);
+                       }
+                       last_timestamp = data.time;
+               }
                /*
                 * FIXME: better resolve from pid from the struct trace_entry
                 * field, although it should be the same than this perf
@@ -97,17 +109,31 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                                             data.time, thread->comm);
        }
 
-       session->events_stats.total += data.period;
+       session->hists.stats.total_period += data.period;
        return 0;
 }
 
 static struct perf_event_ops event_ops = {
        .sample = process_sample_event,
        .comm   = event__process_comm,
+       .attr   = event__process_attr,
+       .event_type = event__process_event_type,
+       .tracing_data = event__process_tracing_data,
+       .build_id = event__process_build_id,
+       .ordered_samples = true,
 };
 
+extern volatile int session_done;
+
+static void sig_handler(int sig __unused)
+{
+       session_done = 1;
+}
+
 static int __cmd_trace(struct perf_session *session)
 {
+       signal(SIGINT, sig_handler);
+
        return perf_session__process_events(session, &event_ops);
 }
 
@@ -505,7 +531,7 @@ static const char * const trace_usage[] = {
 static const struct option options[] = {
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
-       OPT_BOOLEAN('v', "verbose", &verbose,
+       OPT_INCR('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('L', "Latency", &latency_format,
                    "show latency attributes (irqs/preemption disabled, etc)"),
@@ -518,6 +544,8 @@ static const struct option options[] = {
                   "generate perf-trace.xx script in specified language"),
        OPT_STRING('i', "input", &input_name, "file",
                    "input file name"),
+       OPT_BOOLEAN('d', "debug-ordering", &debug_ordering,
+                  "check that samples time ordering is monotonic"),
 
        OPT_END()
 };
@@ -548,6 +576,65 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
                suffix = REPORT_SUFFIX;
        }
 
+       if (!suffix && argc >= 2 && strncmp(argv[1], "-", strlen("-")) != 0) {
+               char *record_script_path, *report_script_path;
+               int live_pipe[2];
+               pid_t pid;
+
+               record_script_path = get_script_path(argv[1], RECORD_SUFFIX);
+               if (!record_script_path) {
+                       fprintf(stderr, "record script not found\n");
+                       return -1;
+               }
+
+               report_script_path = get_script_path(argv[1], REPORT_SUFFIX);
+               if (!report_script_path) {
+                       fprintf(stderr, "report script not found\n");
+                       return -1;
+               }
+
+               if (pipe(live_pipe) < 0) {
+                       perror("failed to create pipe");
+                       exit(-1);
+               }
+
+               pid = fork();
+               if (pid < 0) {
+                       perror("failed to fork");
+                       exit(-1);
+               }
+
+               if (!pid) {
+                       dup2(live_pipe[1], 1);
+                       close(live_pipe[0]);
+
+                       __argv = malloc(5 * sizeof(const char *));
+                       __argv[0] = "/bin/sh";
+                       __argv[1] = record_script_path;
+                       __argv[2] = "-o";
+                       __argv[3] = "-";
+                       __argv[4] = NULL;
+
+                       execvp("/bin/sh", (char **)__argv);
+                       exit(-1);
+               }
+
+               dup2(live_pipe[0], 0);
+               close(live_pipe[1]);
+
+               __argv = malloc((argc + 3) * sizeof(const char *));
+               __argv[0] = "/bin/sh";
+               __argv[1] = report_script_path;
+               for (i = 2; i < argc; i++)
+                       __argv[i] = argv[i];
+               __argv[i++] = "-i";
+               __argv[i++] = "-";
+               __argv[i++] = NULL;
+
+               execvp("/bin/sh", (char **)__argv);
+               exit(-1);
+       }
+
        if (suffix) {
                script_path = get_script_path(argv[2], suffix);
                if (!script_path) {
@@ -576,11 +663,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
        if (!script_name)
                setup_pager();
 
-       session = perf_session__new(input_name, O_RDONLY, 0);
+       session = perf_session__new(input_name, O_RDONLY, 0, false);
        if (session == NULL)
                return -ENOMEM;
 
-       if (!perf_session__has_traces(session, "record -R"))
+       if (strcmp(input_name, "-") &&
+           !perf_session__has_traces(session, "record -R"))
                return -EINVAL;
 
        if (generate_script_lang) {
@@ -617,6 +705,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
                err = scripting_ops->start_script(script_name, argc, argv);
                if (err)
                        goto out;
+               pr_debug("perf trace started with script %s\n\n", script_name);
        }
 
        err = __cmd_trace(session);
index 10fe49e..921245b 100644 (file)
@@ -32,5 +32,8 @@ extern int cmd_version(int argc, const char **argv, const char *prefix);
 extern int cmd_probe(int argc, const char **argv, const char *prefix);
 extern int cmd_kmem(int argc, const char **argv, const char *prefix);
 extern int cmd_lock(int argc, const char **argv, const char *prefix);
+extern int cmd_kvm(int argc, const char **argv, const char *prefix);
+extern int cmd_test(int argc, const char **argv, const char *prefix);
+extern int cmd_inject(int argc, const char **argv, const char *prefix);
 
 #endif
index db6ee94..949d77f 100644 (file)
@@ -8,6 +8,7 @@ perf-bench                      mainporcelain common
 perf-buildid-cache             mainporcelain common
 perf-buildid-list              mainporcelain common
 perf-diff                      mainporcelain common
+perf-inject                    mainporcelain common
 perf-list                      mainporcelain common
 perf-sched                     mainporcelain common
 perf-record                    mainporcelain common
@@ -19,3 +20,5 @@ perf-trace                    mainporcelain common
 perf-probe                     mainporcelain common
 perf-kmem                      mainporcelain common
 perf-lock                      mainporcelain common
+perf-kvm                       mainporcelain common
+perf-test                      mainporcelain common
index 910468e..2e7a4f4 100644 (file)
@@ -30,4 +30,7 @@ done
 
 tar cfj $PERF_DATA.tar.bz2 -C $DEBUGDIR -T $MANIFEST
 rm -f $MANIFEST $BUILDIDS
+echo -e "Now please run:\n"
+echo -e "$ tar xvf $PERF_DATA.tar.bz2 -C ~/.debug\n"
+echo "wherever you need to run 'perf report' on."
 exit 0
index cd32c20..08e0e5d 100644 (file)
 #include "util/quote.h"
 #include "util/run-command.h"
 #include "util/parse-events.h"
-#include "util/string.h"
 #include "util/debugfs.h"
 
+bool use_browser;
+
 const char perf_usage_string[] =
        "perf [--version] [--help] COMMAND [ARGS]";
 
@@ -262,6 +263,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
        set_debugfs_path();
 
        status = p->fn(argc, argv, prefix);
+       exit_browser(status);
+
        if (status)
                return status & 0xff;
 
@@ -304,6 +307,9 @@ static void handle_internal_command(int argc, const char **argv)
                { "probe",      cmd_probe,      0 },
                { "kmem",       cmd_kmem,       0 },
                { "lock",       cmd_lock,       0 },
+               { "kvm",        cmd_kvm,        0 },
+               { "test",       cmd_test,       0 },
+               { "inject",     cmd_inject,     0 },
        };
        unsigned int i;
        static const char ext[] = STRIP_EXTENSION;
index 6fb379b..ef7aa0a 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef _PERF_PERF_H
 #define _PERF_PERF_H
 
+struct winsize;
+
+void get_term_dimensions(struct winsize *ws);
+
 #if defined(__i386__)
 #include "../../arch/x86/include/asm/unistd.h"
 #define rmb()          asm volatile("lock; addl $0,0(%%esp)" ::: "memory")
@@ -76,6 +80,7 @@
 
 #include "../../include/linux/perf_event.h"
 #include "util/types.h"
+#include <stdbool.h>
 
 /*
  * prctl(PR_TASK_PERF_EVENTS_DISABLE) will (cheaply) disable all
@@ -102,8 +107,6 @@ static inline unsigned long long rdclock(void)
 #define __user
 #define asmlinkage
 
-#define __used         __attribute__((__unused__))
-
 #define unlikely(x)    __builtin_expect(!!(x), 0)
 #define min(x, y) ({                           \
        typeof(x) _min1 = (x);                  \
@@ -129,4 +132,6 @@ struct ip_callchain {
        u64 ips[0];
 };
 
+extern bool perf_host, perf_guest;
+
 #endif
index f869c48..d94b40c 100644 (file)
@@ -15,6 +15,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
 
 our @EXPORT = qw(
 avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
+clear_term
 );
 
 our $VERSION = '0.01';
@@ -55,6 +56,11 @@ sub nsecs_str {
     return $str;
 }
 
+sub clear_term
+{
+    print "\x1b[H\x1b[2J";
+}
+
 1;
 __END__
 =head1 NAME
index e6cb147..423ad6a 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e kmem:kmalloc -e irq:softirq_entry -e kmem:kfree
+perf record -a -e kmem:kmalloc -e irq:softirq_entry -e kmem:kfree
index f8885d3..eb5846b 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_exit
+perf record -a -e raw_syscalls:sys_exit $@
index 8bfc660..e3a5e55 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide failed syscalls
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/perl/failed-syscalls.pl $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/failed-syscalls.pl $comm
index b25056e..5bfaae5 100644 (file)
@@ -1,2 +1,3 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_enter_write
+perf record -a -e syscalls:sys_enter_read -e syscalls:sys_enter_write $@
+
index eddb9cc..d83070b 100644 (file)
@@ -1,7 +1,13 @@
 #!/bin/bash
 # description: r/w activity for a program, by file
 # args: <comm>
-perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $1
+if [ $# -lt 1 ] ; then
+    echo "usage: rw-by-file <comm>"
+    exit
+fi
+comm=$1
+shift
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/rw-by-file.pl $comm
 
 
 
index 8903979..6e0b2f7 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write
+perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
index 7f44c25..7ef4698 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # description: system-wide r/w activity
-perf trace -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/rw-by-pid.pl
 
 
 
diff --git a/tools/perf/scripts/perl/bin/rwtop-record b/tools/perf/scripts/perl/bin/rwtop-record
new file mode 100644 (file)
index 0000000..6e0b2f7
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -a -e syscalls:sys_enter_read -e syscalls:sys_exit_read -e syscalls:sys_enter_write -e syscalls:sys_exit_write $@
diff --git a/tools/perf/scripts/perl/bin/rwtop-report b/tools/perf/scripts/perl/bin/rwtop-report
new file mode 100644 (file)
index 0000000..93e698c
--- /dev/null
@@ -0,0 +1,23 @@
+#!/bin/bash
+# description: system-wide r/w top
+# args: [interval]
+n_args=0
+for i in "$@"
+do
+    if expr match "$i" "-" > /dev/null ; then
+       break
+    fi
+    n_args=$(( $n_args + 1 ))
+done
+if [ "$n_args" -gt 1 ] ; then
+    echo "usage: rwtop-report [interval]"
+    exit
+fi
+if [ "$n_args" -gt 0 ] ; then
+    interval=$1
+    shift
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/rwtop.pl $interval
+
+
+
index 6abedda..9f2acaa 100644 (file)
@@ -1,5 +1,5 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e sched:sched_switch -e sched:sched_wakeup
+perf record -a -e sched:sched_switch -e sched:sched_wakeup $@
 
 
 
index fce3adc..a0d898f 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # description: system-wide min/max/avg wakeup latency
-perf trace -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/wakeup-latency.pl
 
 
 
index fce6637..85301f2 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion
+perf record -a -e workqueue:workqueue_creation -e workqueue:workqueue_destruction -e workqueue:workqueue_execution -e workqueue:workqueue_insertion $@
index 71cfbd1..3508113 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/bash
 # description: workqueue stats (ins/exe/create/destroy)
-perf trace -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl
+perf trace $@ -s ~/libexec/perf-core/scripts/perl/workqueue-stats.pl
 
 
 
index c18e7e2..94bc25a 100644 (file)
@@ -11,6 +11,8 @@ use Perf::Trace::Core;
 use Perf::Trace::Context;
 use Perf::Trace::Util;
 
+my $for_comm = shift;
+
 my %failed_syscalls;
 
 sub raw_syscalls::sys_exit
@@ -33,6 +35,8 @@ sub trace_end
 
     foreach my $comm (sort {$failed_syscalls{$b} <=> $failed_syscalls{$a}}
                      keys %failed_syscalls) {
-           printf("%-20s  %10s\n", $comm, $failed_syscalls{$comm});
+       next if ($for_comm && $comm ne $for_comm);
+
+       printf("%-20s  %10s\n", $comm, $failed_syscalls{$comm});
     }
 }
index da601fa..9db23c9 100644 (file)
@@ -79,12 +79,12 @@ sub trace_end
     printf("%6s  %-20s  %10s  %10s  %10s\n", "------", "--------------------",
           "-----------", "----------", "----------");
 
-    foreach my $pid (sort {$reads{$b}{bytes_read} <=>
-                              $reads{$a}{bytes_read}} keys %reads) {
-       my $comm = $reads{$pid}{comm};
-       my $total_reads = $reads{$pid}{total_reads};
-       my $bytes_requested = $reads{$pid}{bytes_requested};
-       my $bytes_read = $reads{$pid}{bytes_read};
+    foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=>
+                               ($reads{$a}{bytes_read} || 0) } keys %reads) {
+       my $comm = $reads{$pid}{comm} || "";
+       my $total_reads = $reads{$pid}{total_reads} || 0;
+       my $bytes_requested = $reads{$pid}{bytes_requested} || 0;
+       my $bytes_read = $reads{$pid}{bytes_read} || 0;
 
        printf("%6s  %-20s  %10s  %10s  %10s\n", $pid, $comm,
               $total_reads, $bytes_requested, $bytes_read);
@@ -96,16 +96,23 @@ sub trace_end
     printf("%6s  %20s  %6s  %10s\n", "------", "--------------------",
           "------", "----------");
 
-    foreach my $pid (keys %reads) {
-       my $comm = $reads{$pid}{comm};
-       foreach my $err (sort {$reads{$b}{comm} cmp $reads{$a}{comm}}
-                        keys %{$reads{$pid}{errors}}) {
-           my $errors = $reads{$pid}{errors}{$err};
+    my @errcounts = ();
 
-           printf("%6d  %-20s  %6d  %10s\n", $pid, $comm, $err, $errors);
+    foreach my $pid (keys %reads) {
+       foreach my $error (keys %{$reads{$pid}{errors}}) {
+           my $comm = $reads{$pid}{comm} || "";
+           my $errcount = $reads{$pid}{errors}{$error} || 0;
+           push @errcounts, [$pid, $comm, $error, $errcount];
        }
     }
 
+    @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts;
+
+    for my $i (0 .. $#errcounts) {
+       printf("%6d  %-20s  %6d  %10s\n", $errcounts[$i][0],
+              $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]);
+    }
+
     printf("\nwrite counts by pid:\n\n");
 
     printf("%6s  %20s  %10s  %10s\n", "pid", "comm",
@@ -113,11 +120,11 @@ sub trace_end
     printf("%6s  %-20s  %10s  %10s\n", "------", "--------------------",
           "-----------", "----------");
 
-    foreach my $pid (sort {$writes{$b}{bytes_written} <=>
-                              $writes{$a}{bytes_written}} keys %writes) {
-       my $comm = $writes{$pid}{comm};
-       my $total_writes = $writes{$pid}{total_writes};
-       my $bytes_written = $writes{$pid}{bytes_written};
+    foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=>
+                       ($writes{$a}{bytes_written} || 0)} keys %writes) {
+       my $comm = $writes{$pid}{comm} || "";
+       my $total_writes = $writes{$pid}{total_writes} || 0;
+       my $bytes_written = $writes{$pid}{bytes_written} || 0;
 
        printf("%6s  %-20s  %10s  %10s\n", $pid, $comm,
               $total_writes, $bytes_written);
@@ -129,16 +136,23 @@ sub trace_end
     printf("%6s  %20s  %6s  %10s\n", "------", "--------------------",
           "------", "----------");
 
-    foreach my $pid (keys %writes) {
-       my $comm = $writes{$pid}{comm};
-       foreach my $err (sort {$writes{$b}{comm} cmp $writes{$a}{comm}}
-                        keys %{$writes{$pid}{errors}}) {
-           my $errors = $writes{$pid}{errors}{$err};
+    @errcounts = ();
 
-           printf("%6d  %-20s  %6d  %10s\n", $pid, $comm, $err, $errors);
+    foreach my $pid (keys %writes) {
+       foreach my $error (keys %{$writes{$pid}{errors}}) {
+           my $comm = $writes{$pid}{comm} || "";
+           my $errcount = $writes{$pid}{errors}{$error} || 0;
+           push @errcounts, [$pid, $comm, $error, $errcount];
        }
     }
 
+    @errcounts = sort { $b->[3] <=> $a->[3] } @errcounts;
+
+    for my $i (0 .. $#errcounts) {
+       printf("%6d  %-20s  %6d  %10s\n", $errcounts[$i][0],
+              $errcounts[$i][1], $errcounts[$i][2], $errcounts[$i][3]);
+    }
+
     print_unhandled();
 }
 
diff --git a/tools/perf/scripts/perl/rwtop.pl b/tools/perf/scripts/perl/rwtop.pl
new file mode 100644 (file)
index 0000000..4bb3ecd
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/bin/perl -w
+# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+
+# read/write top
+#
+# Periodically displays system-wide r/w call activity, broken down by
+# pid.  If an [interval] arg is specified, the display will be
+# refreshed every [interval] seconds.  The default interval is 3
+# seconds.
+
+use 5.010000;
+use strict;
+use warnings;
+
+use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
+use lib "./Perf-Trace-Util/lib";
+use Perf::Trace::Core;
+use Perf::Trace::Util;
+
+my $default_interval = 3;
+my $nlines = 20;
+my $print_thread;
+my $print_pending = 0;
+
+my %reads;
+my %writes;
+
+my $interval = shift;
+if (!$interval) {
+    $interval = $default_interval;
+}
+
+sub syscalls::sys_exit_read
+{
+    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+       $common_pid, $common_comm,
+       $nr, $ret) = @_;
+
+    print_check();
+
+    if ($ret > 0) {
+       $reads{$common_pid}{bytes_read} += $ret;
+    } else {
+       if (!defined ($reads{$common_pid}{bytes_read})) {
+           $reads{$common_pid}{bytes_read} = 0;
+       }
+       $reads{$common_pid}{errors}{$ret}++;
+    }
+}
+
+sub syscalls::sys_enter_read
+{
+    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+       $common_pid, $common_comm,
+       $nr, $fd, $buf, $count) = @_;
+
+    print_check();
+
+    $reads{$common_pid}{bytes_requested} += $count;
+    $reads{$common_pid}{total_reads}++;
+    $reads{$common_pid}{comm} = $common_comm;
+}
+
+sub syscalls::sys_exit_write
+{
+    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+       $common_pid, $common_comm,
+       $nr, $ret) = @_;
+
+    print_check();
+
+    if ($ret <= 0) {
+       $writes{$common_pid}{errors}{$ret}++;
+    }
+}
+
+sub syscalls::sys_enter_write
+{
+    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+       $common_pid, $common_comm,
+       $nr, $fd, $buf, $count) = @_;
+
+    print_check();
+
+    $writes{$common_pid}{bytes_written} += $count;
+    $writes{$common_pid}{total_writes}++;
+    $writes{$common_pid}{comm} = $common_comm;
+}
+
+sub trace_begin
+{
+    $SIG{ALRM} = \&set_print_pending;
+    alarm 1;
+}
+
+sub trace_end
+{
+    print_unhandled();
+    print_totals();
+}
+
+sub print_check()
+{
+    if ($print_pending == 1) {
+       $print_pending = 0;
+       print_totals();
+    }
+}
+
+sub set_print_pending()
+{
+    $print_pending = 1;
+    alarm $interval;
+}
+
+sub print_totals
+{
+    my $count;
+
+    $count = 0;
+
+    clear_term();
+
+    printf("\nread counts by pid:\n\n");
+
+    printf("%6s  %20s  %10s  %10s  %10s\n", "pid", "comm",
+          "# reads", "bytes_req", "bytes_read");
+    printf("%6s  %-20s  %10s  %10s  %10s\n", "------", "--------------------",
+          "----------", "----------", "----------");
+
+    foreach my $pid (sort { ($reads{$b}{bytes_read} || 0) <=>
+                              ($reads{$a}{bytes_read} || 0) } keys %reads) {
+       my $comm = $reads{$pid}{comm} || "";
+       my $total_reads = $reads{$pid}{total_reads} || 0;
+       my $bytes_requested = $reads{$pid}{bytes_requested} || 0;
+       my $bytes_read = $reads{$pid}{bytes_read} || 0;
+
+       printf("%6s  %-20s  %10s  %10s  %10s\n", $pid, $comm,
+              $total_reads, $bytes_requested, $bytes_read);
+
+       if (++$count == $nlines) {
+           last;
+       }
+    }
+
+    $count = 0;
+
+    printf("\nwrite counts by pid:\n\n");
+
+    printf("%6s  %20s  %10s  %13s\n", "pid", "comm",
+          "# writes", "bytes_written");
+    printf("%6s  %-20s  %10s  %13s\n", "------", "--------------------",
+          "----------", "-------------");
+
+    foreach my $pid (sort { ($writes{$b}{bytes_written} || 0) <=>
+                       ($writes{$a}{bytes_written} || 0)} keys %writes) {
+       my $comm = $writes{$pid}{comm} || "";
+       my $total_writes = $writes{$pid}{total_writes} || 0;
+       my $bytes_written = $writes{$pid}{bytes_written} || 0;
+
+       printf("%6s  %-20s  %10s  %13s\n", $pid, $comm,
+              $total_writes, $bytes_written);
+
+       if (++$count == $nlines) {
+           last;
+       }
+    }
+
+    %reads = ();
+    %writes = ();
+}
+
+my %unhandled;
+
+sub print_unhandled
+{
+    if ((scalar keys %unhandled) == 0) {
+       return;
+    }
+
+    print "\nunhandled events:\n\n";
+
+    printf("%-40s  %10s\n", "event", "count");
+    printf("%-40s  %10s\n", "----------------------------------------",
+          "-----------");
+
+    foreach my $event_name (keys %unhandled) {
+       printf("%-40s  %10d\n", $event_name, $unhandled{$event_name});
+    }
+}
+
+sub trace_unhandled
+{
+    my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
+       $common_pid, $common_comm) = @_;
+
+    $unhandled{$event_name}++;
+}
index ed58ef2..d9143dc 100644 (file)
@@ -22,8 +22,8 @@ my %last_wakeup;
 
 my $max_wakeup_latency;
 my $min_wakeup_latency;
-my $total_wakeup_latency;
-my $total_wakeups;
+my $total_wakeup_latency = 0;
+my $total_wakeups = 0;
 
 sub sched::sched_switch
 {
@@ -67,8 +67,12 @@ sub trace_end
 {
     printf("wakeup_latency stats:\n\n");
     print "total_wakeups: $total_wakeups\n";
-    printf("avg_wakeup_latency (ns): %u\n",
-          avg($total_wakeup_latency, $total_wakeups));
+    if ($total_wakeups) {
+       printf("avg_wakeup_latency (ns): %u\n",
+              avg($total_wakeup_latency, $total_wakeups));
+    } else {
+       printf("avg_wakeup_latency (ns): N/A\n");
+    }
     printf("min_wakeup_latency (ns): %u\n", $min_wakeup_latency);
     printf("max_wakeup_latency (ns): %u\n", $max_wakeup_latency);
 
index 511302c..b84b126 100644 (file)
@@ -71,9 +71,9 @@ sub trace_end
     printf("%3s %6s %6s\t%-20s\n", "---", "---", "----", "----");
     foreach my $pidhash (@cpus) {
        while ((my $pid, my $wqhash) = each %$pidhash) {
-           my $ins = $$wqhash{'inserted'};
-           my $exe = $$wqhash{'executed'};
-           my $comm = $$wqhash{'comm'};
+           my $ins = $$wqhash{'inserted'} || 0;
+           my $exe = $$wqhash{'executed'} || 0;
+           my $comm = $$wqhash{'comm'} || "";
            if ($ins || $exe) {
                printf("%3u %6u %6u\t%-20s\n", $cpu, $ins, $exe, $comm);
            }
@@ -87,9 +87,9 @@ sub trace_end
     printf("%3s %6s %6s\t%-20s\n", "---", "-------", "---------", "----");
     foreach my $pidhash (@cpus) {
        while ((my $pid, my $wqhash) = each %$pidhash) {
-           my $created = $$wqhash{'created'};
-           my $destroyed = $$wqhash{'destroyed'};
-           my $comm = $$wqhash{'comm'};
+           my $created = $$wqhash{'created'} || 0;
+           my $destroyed = $$wqhash{'destroyed'} || 0;
+           my $comm = $$wqhash{'comm'} || "";
            if ($created || $destroyed) {
                printf("%3u %6u %6u\t%-20s\n", $cpu, $created, $destroyed,
                       $comm);
index 83e9143..9689bc0 100644 (file)
@@ -23,3 +23,6 @@ def nsecs_nsecs(nsecs):
 def nsecs_str(nsecs):
     str = "%5u.%09u" % (nsecs_secs(nsecs), nsecs_nsecs(nsecs)),
     return str
+
+def clear_term():
+    print("\x1b[H\x1b[2J")
index f8885d3..eb5846b 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_exit
+perf record -a -e raw_syscalls:sys_exit $@
index 1e0c0a8..3029354 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide failed syscalls, by pid
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/failed-syscalls-by-pid.py $comm
diff --git a/tools/perf/scripts/python/bin/sctop-record b/tools/perf/scripts/python/bin/sctop-record
new file mode 100644 (file)
index 0000000..1fc5998
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -a -e raw_syscalls:sys_enter $@
diff --git a/tools/perf/scripts/python/bin/sctop-report b/tools/perf/scripts/python/bin/sctop-report
new file mode 100644 (file)
index 0000000..b01c842
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+# description: syscall top
+# args: [comm] [interval]
+n_args=0
+for i in "$@"
+do
+    if expr match "$i" "-" > /dev/null ; then
+       break
+    fi
+    n_args=$(( $n_args + 1 ))
+done
+if [ "$n_args" -gt 2 ] ; then
+    echo "usage: sctop-report [comm] [interval]"
+    exit
+fi
+if [ "$n_args" -gt 1 ] ; then
+    comm=$1
+    interval=$2
+    shift 2
+elif [ "$n_args" -gt 0 ] ; then
+    interval=$1
+    shift
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/sctop.py $comm $interval
index 45a8c50..1fc5998 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+perf record -a -e raw_syscalls:sys_enter $@
index f8044d1..9e9d8dd 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide syscall counts, by pid
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts-by-pid.py $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/syscall-counts-by-pid.py $comm
index 45a8c50..1fc5998 100644 (file)
@@ -1,2 +1,2 @@
 #!/bin/bash
-perf record -c 1 -f -a -M -R -e raw_syscalls:sys_enter
+perf record -a -e raw_syscalls:sys_enter $@
index a366aa6..dc076b6 100644 (file)
@@ -1,4 +1,10 @@
 #!/bin/bash
 # description: system-wide syscall counts
 # args: [comm]
-perf trace -s ~/libexec/perf-core/scripts/python/syscall-counts.py $1
+if [ $# -gt 0 ] ; then
+    if ! expr match "$1" "-" > /dev/null ; then
+       comm=$1
+       shift
+    fi
+fi
+perf trace $@ -s ~/libexec/perf-core/scripts/python/syscall-counts.py $comm
diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py
new file mode 100644 (file)
index 0000000..6cafad4
--- /dev/null
@@ -0,0 +1,78 @@
+# system call top
+# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
+# Licensed under the terms of the GNU GPL License version 2
+#
+# Periodically displays system-wide system call totals, broken down by
+# syscall.  If a [comm] arg is specified, only syscalls called by
+# [comm] are displayed. If an [interval] arg is specified, the display
+# will be refreshed every [interval] seconds.  The default interval is
+# 3 seconds.
+
+import thread
+import time
+import os
+import sys
+
+sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+       '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+from perf_trace_context import *
+from Core import *
+from Util import *
+
+usage = "perf trace -s syscall-counts.py [comm] [interval]\n";
+
+for_comm = None
+default_interval = 3
+interval = default_interval
+
+if len(sys.argv) > 3:
+       sys.exit(usage)
+
+if len(sys.argv) > 2:
+       for_comm = sys.argv[1]
+       interval = int(sys.argv[2])
+elif len(sys.argv) > 1:
+       try:
+               interval = int(sys.argv[1])
+       except ValueError:
+               for_comm = sys.argv[1]
+               interval = default_interval
+
+syscalls = autodict()
+
+def trace_begin():
+       thread.start_new_thread(print_syscall_totals, (interval,))
+       pass
+
+def raw_syscalls__sys_enter(event_name, context, common_cpu,
+       common_secs, common_nsecs, common_pid, common_comm,
+       id, args):
+       if for_comm is not None:
+               if common_comm != for_comm:
+                       return
+       try:
+               syscalls[id] += 1
+       except TypeError:
+               syscalls[id] = 1
+
+def print_syscall_totals(interval):
+       while 1:
+               clear_term()
+               if for_comm is not None:
+                       print "\nsyscall events for %s:\n\n" % (for_comm),
+               else:
+                       print "\nsyscall events:\n\n",
+
+               print "%-40s  %10s\n" % ("event", "count"),
+               print "%-40s  %10s\n" % ("----------------------------------------", \
+                                                "----------"),
+
+               for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \
+                                             reverse = True):
+                       try:
+                               print "%-40d  %10d\n" % (id, val),
+                       except TypeError:
+                               pass
+               syscalls.clear()
+               time.sleep(interval)
index 54552a0..49ece79 100755 (executable)
@@ -1,6 +1,10 @@
 #!/bin/sh
 
-GVF=PERF-VERSION-FILE
+if [ $# -eq 1 ]  ; then
+       OUTPUT=$1
+fi
+
+GVF=${OUTPUT}PERF-VERSION-FILE
 DEF_VER=v0.0.2.PERF
 
 LF='
diff --git a/tools/perf/util/bitmap.c b/tools/perf/util/bitmap.c
new file mode 100644 (file)
index 0000000..5e230ac
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * From lib/bitmap.c
+ * Helper functions for bitmap.h.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+#include <linux/bitmap.h>
+
+int __bitmap_weight(const unsigned long *bitmap, int bits)
+{
+       int k, w = 0, lim = bits/BITS_PER_LONG;
+
+       for (k = 0; k < lim; k++)
+               w += hweight_long(bitmap[k]);
+
+       if (bits % BITS_PER_LONG)
+               w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
+
+       return w;
+}
index 04904b3..0f60a39 100644 (file)
@@ -24,7 +24,7 @@ static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
        }
 
        thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
-                             event->ip.ip, &al);
+                             event->ip.pid, event->ip.ip, &al);
 
        if (al.map != NULL)
                al.map->dso->hit = 1;
index 918eb37..4b9aab7 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __PERF_CACHE_H
 #define __PERF_CACHE_H
 
+#include <stdbool.h>
 #include "util.h"
 #include "strbuf.h"
 #include "../perf.h"
@@ -69,6 +70,19 @@ extern const char *pager_program;
 extern int pager_in_use(void);
 extern int pager_use_color;
 
+extern bool use_browser;
+
+#ifdef NO_NEWT_SUPPORT
+static inline void setup_browser(void)
+{
+       setup_pager();
+}
+static inline void exit_browser(bool wait_for_ok __used) {}
+#else
+void setup_browser(void);
+void exit_browser(bool wait_for_ok);
+#endif
+
 extern const char *editor_program;
 extern const char *excludes_file;
 
index b3b7125..21a52e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, Frederic Weisbecker <fweisbec@gmail.com>
+ * Copyright (C) 2009-2010, Frederic Weisbecker <fweisbec@gmail.com>
  *
  * Handle the callchains from the stream in an ad-hoc radix tree and then
  * sort them in an rbtree.
 
 #include "callchain.h"
 
+bool ip_callchain__valid(struct ip_callchain *chain, event_t *event)
+{
+       unsigned int chain_size = event->header.size;
+       chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
+       return chain->nr * sizeof(u64) <= chain_size;
+}
+
 #define chain_for_each_child(child, parent)    \
        list_for_each_entry(child, &parent->children, brothers)
 
@@ -160,7 +167,7 @@ create_child(struct callchain_node *parent, bool inherit_children)
 {
        struct callchain_node *new;
 
-       new = malloc(sizeof(*new));
+       new = zalloc(sizeof(*new));
        if (!new) {
                perror("not enough memory to create child for code path tree");
                return NULL;
@@ -183,25 +190,36 @@ create_child(struct callchain_node *parent, bool inherit_children)
        return new;
 }
 
+
+struct resolved_ip {
+       u64               ip;
+       struct map_symbol ms;
+};
+
+struct resolved_chain {
+       u64                     nr;
+       struct resolved_ip      ips[0];
+};
+
+
 /*
  * Fill the node with callchain values
  */
 static void
-fill_node(struct callchain_node *node, struct ip_callchain *chain,
-         int start, struct symbol **syms)
+fill_node(struct callchain_node *node, struct resolved_chain *chain, int start)
 {
        unsigned int i;
 
        for (i = start; i < chain->nr; i++) {
                struct callchain_list *call;
 
-               call = malloc(sizeof(*call));
+               call = zalloc(sizeof(*call));
                if (!call) {
                        perror("not enough memory for the code path tree");
                        return;
                }
-               call->ip = chain->ips[i];
-               call->sym = syms[i];
+               call->ip = chain->ips[i].ip;
+               call->ms = chain->ips[i].ms;
                list_add_tail(&call->list, &node->val);
        }
        node->val_nr = chain->nr - start;
@@ -210,13 +228,13 @@ fill_node(struct callchain_node *node, struct ip_callchain *chain,
 }
 
 static void
-add_child(struct callchain_node *parent, struct ip_callchain *chain,
-         int start, struct symbol **syms)
+add_child(struct callchain_node *parent, struct resolved_chain *chain,
+         int start)
 {
        struct callchain_node *new;
 
        new = create_child(parent, false);
-       fill_node(new, chain, start, syms);
+       fill_node(new, chain, start);
 
        new->children_hit = 0;
        new->hit = 1;
@@ -228,9 +246,8 @@ add_child(struct callchain_node *parent, struct ip_callchain *chain,
  * Then create another child to host the given callchain of new branch
  */
 static void
-split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
-               struct callchain_list *to_split, int idx_parents, int idx_local,
-               struct symbol **syms)
+split_add_child(struct callchain_node *parent, struct resolved_chain *chain,
+               struct callchain_list *to_split, int idx_parents, int idx_local)
 {
        struct callchain_node *new;
        struct list_head *old_tail;
@@ -257,7 +274,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
        /* create a new child for the new branch if any */
        if (idx_total < chain->nr) {
                parent->hit = 0;
-               add_child(parent, chain, idx_total, syms);
+               add_child(parent, chain, idx_total);
                parent->children_hit++;
        } else {
                parent->hit = 1;
@@ -265,32 +282,33 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain,
 }
 
 static int
-__append_chain(struct callchain_node *root, struct ip_callchain *chain,
-              unsigned int start, struct symbol **syms);
+__append_chain(struct callchain_node *root, struct resolved_chain *chain,
+              unsigned int start);
 
 static void
-__append_chain_children(struct callchain_node *root, struct ip_callchain *chain,
-                       struct symbol **syms, unsigned int start)
+__append_chain_children(struct callchain_node *root,
+                       struct resolved_chain *chain,
+                       unsigned int start)
 {
        struct callchain_node *rnode;
 
        /* lookup in childrens */
        chain_for_each_child(rnode, root) {
-               unsigned int ret = __append_chain(rnode, chain, start, syms);
+               unsigned int ret = __append_chain(rnode, chain, start);
 
                if (!ret)
                        goto inc_children_hit;
        }
        /* nothing in children, add to the current node */
-       add_child(root, chain, start, syms);
+       add_child(root, chain, start);
 
 inc_children_hit:
        root->children_hit++;
 }
 
 static int
-__append_chain(struct callchain_node *root, struct ip_callchain *chain,
-              unsigned int start, struct symbol **syms)
+__append_chain(struct callchain_node *root, struct resolved_chain *chain,
+              unsigned int start)
 {
        struct callchain_list *cnode;
        unsigned int i = start;
@@ -302,13 +320,19 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
         * anywhere inside a function.
         */
        list_for_each_entry(cnode, &root->val, list) {
+               struct symbol *sym;
+
                if (i == chain->nr)
                        break;
-               if (cnode->sym && syms[i]) {
-                       if (cnode->sym->start != syms[i]->start)
+
+               sym = chain->ips[i].ms.sym;
+
+               if (cnode->ms.sym && sym) {
+                       if (cnode->ms.sym->start != sym->start)
                                break;
-               } else if (cnode->ip != chain->ips[i])
+               } else if (cnode->ip != chain->ips[i].ip)
                        break;
+
                if (!found)
                        found = true;
                i++;
@@ -320,7 +344,7 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
 
        /* we match only a part of the node. Split it and add the new chain */
        if (i - start < root->val_nr) {
-               split_add_child(root, chain, cnode, start, i - start, syms);
+               split_add_child(root, chain, cnode, start, i - start);
                return 0;
        }
 
@@ -331,15 +355,50 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain,
        }
 
        /* We match the node and still have a part remaining */
-       __append_chain_children(root, chain, syms, i);
+       __append_chain_children(root, chain, i);
 
        return 0;
 }
 
-void append_chain(struct callchain_node *root, struct ip_callchain *chain,
-                 struct symbol **syms)
+static void filter_context(struct ip_callchain *old, struct resolved_chain *new,
+                          struct map_symbol *syms)
 {
+       int i, j = 0;
+
+       for (i = 0; i < (int)old->nr; i++) {
+               if (old->ips[i] >= PERF_CONTEXT_MAX)
+                       continue;
+
+               new->ips[j].ip = old->ips[i];
+               new->ips[j].ms = syms[i];
+               j++;
+       }
+
+       new->nr = j;
+}
+
+
+int append_chain(struct callchain_node *root, struct ip_callchain *chain,
+                struct map_symbol *syms)
+{
+       struct resolved_chain *filtered;
+
        if (!chain->nr)
-               return;
-       __append_chain_children(root, chain, syms, 0);
+               return 0;
+
+       filtered = zalloc(sizeof(*filtered) +
+                         chain->nr * sizeof(struct resolved_ip));
+       if (!filtered)
+               return -ENOMEM;
+
+       filter_context(chain, filtered, syms);
+
+       if (!filtered->nr)
+               goto end;
+
+       __append_chain_children(root, filtered, 0);
+end:
+       free(filtered);
+
+       return 0;
 }
index ad4626d..1cba1f5 100644 (file)
@@ -4,6 +4,7 @@
 #include "../perf.h"
 #include <linux/list.h>
 #include <linux/rbtree.h>
+#include "event.h"
 #include "util.h"
 #include "symbol.h"
 
@@ -33,13 +34,14 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *,
 
 struct callchain_param {
        enum chain_mode         mode;
+       u32                     print_limit;
        double                  min_percent;
        sort_chain_func_t       sort;
 };
 
 struct callchain_list {
        u64                     ip;
-       struct symbol           *sym;
+       struct map_symbol       ms;
        struct list_head        list;
 };
 
@@ -56,6 +58,8 @@ static inline u64 cumul_hits(struct callchain_node *node)
 }
 
 int register_callchain_param(struct callchain_param *param);
-void append_chain(struct callchain_node *root, struct ip_callchain *chain,
-                 struct symbol **syms);
+int append_chain(struct callchain_node *root, struct ip_callchain *chain,
+                struct map_symbol *syms);
+
+bool ip_callchain__valid(struct ip_callchain *chain, event_t *event);
 #endif /* __PERF_CALLCHAIN_H */
index e88bca5..e191eb9 100644 (file)
@@ -166,6 +166,31 @@ int perf_color_default_config(const char *var, const char *value, void *cb)
        return perf_default_config(var, value, cb);
 }
 
+static int __color_vsnprintf(char *bf, size_t size, const char *color,
+                            const char *fmt, va_list args, const char *trail)
+{
+       int r = 0;
+
+       /*
+        * Auto-detect:
+        */
+       if (perf_use_color_default < 0) {
+               if (isatty(1) || pager_in_use())
+                       perf_use_color_default = 1;
+               else
+                       perf_use_color_default = 0;
+       }
+
+       if (perf_use_color_default && *color)
+               r += snprintf(bf, size, "%s", color);
+       r += vsnprintf(bf + r, size - r, fmt, args);
+       if (perf_use_color_default && *color)
+               r += snprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
+       if (trail)
+               r += snprintf(bf + r, size - r, "%s", trail);
+       return r;
+}
+
 static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
                va_list args, const char *trail)
 {
@@ -191,11 +216,28 @@ static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
        return r;
 }
 
+int color_vsnprintf(char *bf, size_t size, const char *color,
+                   const char *fmt, va_list args)
+{
+       return __color_vsnprintf(bf, size, color, fmt, args, NULL);
+}
+
 int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
 {
        return __color_vfprintf(fp, color, fmt, args, NULL);
 }
 
+int color_snprintf(char *bf, size_t size, const char *color,
+                  const char *fmt, ...)
+{
+       va_list args;
+       int r;
+
+       va_start(args, fmt);
+       r = color_vsnprintf(bf, size, color, fmt, args);
+       va_end(args);
+       return r;
+}
 
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
 {
@@ -274,3 +316,9 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
 
        return r;
 }
+
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent)
+{
+       const char *color = get_percent_color(percent);
+       return color_snprintf(bf, size, color, fmt, percent);
+}
index 24e8809..dea082b 100644 (file)
@@ -32,10 +32,14 @@ int perf_color_default_config(const char *var, const char *value, void *cb);
 int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty);
 void color_parse(const char *value, const char *var, char *dst);
 void color_parse_mem(const char *value, int len, const char *var, char *dst);
+int color_vsnprintf(char *bf, size_t size, const char *color,
+                   const char *fmt, va_list args);
 int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args);
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
+int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
 int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf);
+int percent_color_snprintf(char *bf, size_t size, const char *fmt, double percent);
 int percent_color_fprintf(FILE *fp, const char *fmt, double percent);
 const char *get_percent_color(double percent);
 
index 0905600..dd824cf 100644 (file)
@@ -6,13 +6,14 @@
 #include <stdarg.h>
 #include <stdio.h>
 
+#include "cache.h"
 #include "color.h"
 #include "event.h"
 #include "debug.h"
 #include "util.h"
 
 int verbose = 0;
-int dump_trace = 0;
+bool dump_trace = false;
 
 int eprintf(int level, const char *fmt, ...)
 {
@@ -21,7 +22,10 @@ int eprintf(int level, const char *fmt, ...)
 
        if (verbose >= level) {
                va_start(args, fmt);
-               ret = vfprintf(stderr, fmt, args);
+               if (use_browser)
+                       ret = browser__show_help(fmt, args);
+               else
+                       ret = vfprintf(stderr, fmt, args);
                va_end(args);
        }
 
index c6c24c5..047ac33 100644 (file)
@@ -2,14 +2,38 @@
 #ifndef __PERF_DEBUG_H
 #define __PERF_DEBUG_H
 
+#include <stdbool.h>
 #include "event.h"
 
 extern int verbose;
-extern int dump_trace;
+extern bool dump_trace;
 
-int eprintf(int level,
-           const char *fmt, ...) __attribute__((format(printf, 2, 3)));
 int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
 void trace_event(event_t *event);
 
+struct ui_progress;
+
+#ifdef NO_NEWT_SUPPORT
+static inline int browser__show_help(const char *format __used, va_list ap __used)
+{
+       return 0;
+}
+
+static inline struct ui_progress *ui_progress__new(const char *title __used,
+                                                  u64 total __used)
+{
+       return (struct ui_progress *)1;
+}
+
+static inline void ui_progress__update(struct ui_progress *self __used,
+                                      u64 curr __used) {}
+
+static inline void ui_progress__delete(struct ui_progress *self __used) {}
+#else
+int browser__show_help(const char *format, va_list ap);
+struct ui_progress *ui_progress__new(const char *title, u64 total);
+void ui_progress__update(struct ui_progress *self, u64 curr);
+void ui_progress__delete(struct ui_progress *self);
+#endif
+
 #endif /* __PERF_DEBUG_H */
index 705ec63..50771b5 100644 (file)
@@ -7,6 +7,23 @@
 #include "strlist.h"
 #include "thread.h"
 
+const char *event__name[] = {
+       [0]                      = "TOTAL",
+       [PERF_RECORD_MMAP]       = "MMAP",
+       [PERF_RECORD_LOST]       = "LOST",
+       [PERF_RECORD_COMM]       = "COMM",
+       [PERF_RECORD_EXIT]       = "EXIT",
+       [PERF_RECORD_THROTTLE]   = "THROTTLE",
+       [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
+       [PERF_RECORD_FORK]       = "FORK",
+       [PERF_RECORD_READ]       = "READ",
+       [PERF_RECORD_SAMPLE]     = "SAMPLE",
+       [PERF_RECORD_HEADER_ATTR]        = "ATTR",
+       [PERF_RECORD_HEADER_EVENT_TYPE]  = "EVENT_TYPE",
+       [PERF_RECORD_HEADER_TRACING_DATA]        = "TRACING_DATA",
+       [PERF_RECORD_HEADER_BUILD_ID]    = "BUILD_ID",
+};
+
 static pid_t event__synthesize_comm(pid_t pid, int full,
                                    event__handler_t process,
                                    struct perf_session *session)
@@ -112,7 +129,11 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                event_t ev = {
                        .header = {
                                .type = PERF_RECORD_MMAP,
-                               .misc = 0, /* Just like the kernel, see kernel/perf_event.c __perf_event_mmap */
+                               /*
+                                * Just like the kernel, see __perf_event_mmap
+                                * in kernel/perf_event.c
+                                */
+                               .misc = PERF_RECORD_MISC_USER,
                         },
                };
                int n;
@@ -130,6 +151,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                        continue;
                pbf += n + 3;
                if (*pbf == 'x') { /* vm_exec */
+                       u64 vm_pgoff;
                        char *execname = strchr(bf, '/');
 
                        /* Catch VDSO */
@@ -139,6 +161,14 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
                        if (execname == NULL)
                                continue;
 
+                       pbf += 3;
+                       n = hex2u64(pbf, &vm_pgoff);
+                       /* pgoff is in bytes, not pages */
+                       if (n >= 0)
+                               ev.mmap.pgoff = vm_pgoff << getpagesize();
+                       else
+                               ev.mmap.pgoff = 0;
+
                        size = strlen(execname);
                        execname[size - 1] = '\0'; /* Remove \n */
                        memcpy(ev.mmap.filename, execname, size);
@@ -158,11 +188,23 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
 }
 
 int event__synthesize_modules(event__handler_t process,
-                             struct perf_session *session)
+                             struct perf_session *session,
+                             struct machine *machine)
 {
        struct rb_node *nd;
+       struct map_groups *kmaps = &machine->kmaps;
+       u16 misc;
+
+       /*
+        * kernel uses 0 for user space maps, see kernel/perf_event.c
+        * __perf_event_mmap
+        */
+       if (machine__is_host(machine))
+               misc = PERF_RECORD_MISC_KERNEL;
+       else
+               misc = PERF_RECORD_MISC_GUEST_KERNEL;
 
-       for (nd = rb_first(&session->kmaps.maps[MAP__FUNCTION]);
+       for (nd = rb_first(&kmaps->maps[MAP__FUNCTION]);
             nd; nd = rb_next(nd)) {
                event_t ev;
                size_t size;
@@ -173,12 +215,13 @@ int event__synthesize_modules(event__handler_t process,
 
                size = ALIGN(pos->dso->long_name_len + 1, sizeof(u64));
                memset(&ev, 0, sizeof(ev));
-               ev.mmap.header.misc = 1; /* kernel uses 0 for user space maps, see kernel/perf_event.c __perf_event_mmap */
+               ev.mmap.header.misc = misc;
                ev.mmap.header.type = PERF_RECORD_MMAP;
                ev.mmap.header.size = (sizeof(ev.mmap) -
                                        (sizeof(ev.mmap.filename) - size));
                ev.mmap.start = pos->start;
                ev.mmap.len   = pos->end - pos->start;
+               ev.mmap.pid   = machine->pid;
 
                memcpy(ev.mmap.filename, pos->dso->long_name,
                       pos->dso->long_name_len + 1);
@@ -241,13 +284,18 @@ static int find_symbol_cb(void *arg, const char *name, char type, u64 start)
 
 int event__synthesize_kernel_mmap(event__handler_t process,
                                  struct perf_session *session,
+                                 struct machine *machine,
                                  const char *symbol_name)
 {
        size_t size;
+       const char *filename, *mmap_name;
+       char path[PATH_MAX];
+       char name_buff[PATH_MAX];
+       struct map *map;
+
        event_t ev = {
                .header = {
                        .type = PERF_RECORD_MMAP,
-                       .misc = 1, /* kernel uses 0 for user space maps, see kernel/perf_event.c __perf_event_mmap */
                },
        };
        /*
@@ -257,16 +305,37 @@ int event__synthesize_kernel_mmap(event__handler_t process,
         */
        struct process_symbol_args args = { .name = symbol_name, };
 
-       if (kallsyms__parse("/proc/kallsyms", &args, find_symbol_cb) <= 0)
+       mmap_name = machine__mmap_name(machine, name_buff, sizeof(name_buff));
+       if (machine__is_host(machine)) {
+               /*
+                * kernel uses PERF_RECORD_MISC_USER for user space maps,
+                * see kernel/perf_event.c __perf_event_mmap
+                */
+               ev.header.misc = PERF_RECORD_MISC_KERNEL;
+               filename = "/proc/kallsyms";
+       } else {
+               ev.header.misc = PERF_RECORD_MISC_GUEST_KERNEL;
+               if (machine__is_default_guest(machine))
+                       filename = (char *) symbol_conf.default_guest_kallsyms;
+               else {
+                       sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+                       filename = path;
+               }
+       }
+
+       if (kallsyms__parse(filename, &args, find_symbol_cb) <= 0)
                return -ENOENT;
 
+       map = machine->vmlinux_maps[MAP__FUNCTION];
        size = snprintf(ev.mmap.filename, sizeof(ev.mmap.filename),
-                       "[kernel.kallsyms.%s]", symbol_name) + 1;
+                       "%s%s", mmap_name, symbol_name) + 1;
        size = ALIGN(size, sizeof(u64));
-       ev.mmap.header.size = (sizeof(ev.mmap) - (sizeof(ev.mmap.filename) - size));
+       ev.mmap.header.size = (sizeof(ev.mmap) -
+                       (sizeof(ev.mmap.filename) - size));
        ev.mmap.pgoff = args.start;
-       ev.mmap.start = session->vmlinux_maps[MAP__FUNCTION]->start;
-       ev.mmap.len   = session->vmlinux_maps[MAP__FUNCTION]->end - ev.mmap.start ;
+       ev.mmap.start = map->start;
+       ev.mmap.len   = map->end - ev.mmap.start;
+       ev.mmap.pid   = machine->pid;
 
        return process(&ev, session);
 }
@@ -316,26 +385,54 @@ int event__process_comm(event_t *self, struct perf_session *session)
 int event__process_lost(event_t *self, struct perf_session *session)
 {
        dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
-       session->events_stats.lost += self->lost.lost;
+       session->hists.stats.total_lost += self->lost.lost;
        return 0;
 }
 
-int event__process_mmap(event_t *self, struct perf_session *session)
+static void event_set_kernel_mmap_len(struct map **maps, event_t *self)
+{
+       maps[MAP__FUNCTION]->start = self->mmap.start;
+       maps[MAP__FUNCTION]->end   = self->mmap.start + self->mmap.len;
+       /*
+        * Be a bit paranoid here, some perf.data file came with
+        * a zero sized synthesized MMAP event for the kernel.
+        */
+       if (maps[MAP__FUNCTION]->end == 0)
+               maps[MAP__FUNCTION]->end = ~0UL;
+}
+
+static int event__process_kernel_mmap(event_t *self,
+                       struct perf_session *session)
 {
-       struct thread *thread;
        struct map *map;
+       char kmmap_prefix[PATH_MAX];
+       struct machine *machine;
+       enum dso_kernel_type kernel_type;
+       bool is_kernel_mmap;
+
+       machine = perf_session__findnew_machine(session, self->mmap.pid);
+       if (!machine) {
+               pr_err("Can't find id %d's machine\n", self->mmap.pid);
+               goto out_problem;
+       }
 
-       dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n",
-                   self->mmap.pid, self->mmap.tid, self->mmap.start,
-                   self->mmap.len, self->mmap.pgoff, self->mmap.filename);
+       machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
+       if (machine__is_host(machine))
+               kernel_type = DSO_TYPE_KERNEL;
+       else
+               kernel_type = DSO_TYPE_GUEST_KERNEL;
 
-       if (self->mmap.pid == 0) {
-               static const char kmmap_prefix[] = "[kernel.kallsyms.";
+       is_kernel_mmap = memcmp(self->mmap.filename,
+                               kmmap_prefix,
+                               strlen(kmmap_prefix)) == 0;
+       if (self->mmap.filename[0] == '/' ||
+           (!is_kernel_mmap && self->mmap.filename[0] == '[')) {
 
-               if (self->mmap.filename[0] == '/') {
-                       char short_module_name[1024];
-                       char *name = strrchr(self->mmap.filename, '/'), *dot;
+               char short_module_name[1024];
+               char *name, *dot;
 
+               if (self->mmap.filename[0] == '/') {
+                       name = strrchr(self->mmap.filename, '/');
                        if (name == NULL)
                                goto out_problem;
 
@@ -343,58 +440,84 @@ int event__process_mmap(event_t *self, struct perf_session *session)
                        dot = strrchr(name, '.');
                        if (dot == NULL)
                                goto out_problem;
-
                        snprintf(short_module_name, sizeof(short_module_name),
-                                "[%.*s]", (int)(dot - name), name);
+                                       "[%.*s]", (int)(dot - name), name);
                        strxfrchar(short_module_name, '-', '_');
-
-                       map = perf_session__new_module_map(session,
-                                                          self->mmap.start,
-                                                          self->mmap.filename);
-                       if (map == NULL)
-                               goto out_problem;
-
-                       name = strdup(short_module_name);
-                       if (name == NULL)
-                               goto out_problem;
-
-                       map->dso->short_name = name;
-                       map->end = map->start + self->mmap.len;
-               } else if (memcmp(self->mmap.filename, kmmap_prefix,
-                               sizeof(kmmap_prefix) - 1) == 0) {
-                       const char *symbol_name = (self->mmap.filename +
-                                                  sizeof(kmmap_prefix) - 1);
+               } else
+                       strcpy(short_module_name, self->mmap.filename);
+
+               map = machine__new_module(machine, self->mmap.start,
+                                         self->mmap.filename);
+               if (map == NULL)
+                       goto out_problem;
+
+               name = strdup(short_module_name);
+               if (name == NULL)
+                       goto out_problem;
+
+               map->dso->short_name = name;
+               map->end = map->start + self->mmap.len;
+       } else if (is_kernel_mmap) {
+               const char *symbol_name = (self->mmap.filename +
+                               strlen(kmmap_prefix));
+               /*
+                * Should be there already, from the build-id table in
+                * the header.
+                */
+               struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
+                                                    kmmap_prefix);
+               if (kernel == NULL)
+                       goto out_problem;
+
+               kernel->kernel = kernel_type;
+               if (__machine__create_kernel_maps(machine, kernel) < 0)
+                       goto out_problem;
+
+               event_set_kernel_mmap_len(machine->vmlinux_maps, self);
+               perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
+                                                        symbol_name,
+                                                        self->mmap.pgoff);
+               if (machine__is_default_guest(machine)) {
                        /*
-                        * Should be there already, from the build-id table in
-                        * the header.
+                        * preload dso of guest kernel and modules
                         */
-                       struct dso *kernel = __dsos__findnew(&dsos__kernel,
-                                                            "[kernel.kallsyms]");
-                       if (kernel == NULL)
-                               goto out_problem;
-
-                       kernel->kernel = 1;
-                       if (__perf_session__create_kernel_maps(session, kernel) < 0)
-                               goto out_problem;
+                       dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
+                                 NULL);
+               }
+       }
+       return 0;
+out_problem:
+       return -1;
+}
 
-                       session->vmlinux_maps[MAP__FUNCTION]->start = self->mmap.start;
-                       session->vmlinux_maps[MAP__FUNCTION]->end   = self->mmap.start + self->mmap.len;
-                       /*
-                        * Be a bit paranoid here, some perf.data file came with
-                        * a zero sized synthesized MMAP event for the kernel.
-                        */
-                       if (session->vmlinux_maps[MAP__FUNCTION]->end == 0)
-                               session->vmlinux_maps[MAP__FUNCTION]->end = ~0UL;
+int event__process_mmap(event_t *self, struct perf_session *session)
+{
+       struct machine *machine;
+       struct thread *thread;
+       struct map *map;
+       u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+       int ret = 0;
 
-                       perf_session__set_kallsyms_ref_reloc_sym(session, symbol_name,
-                                                                self->mmap.pgoff);
-               }
+       dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n",
+                       self->mmap.pid, self->mmap.tid, self->mmap.start,
+                       self->mmap.len, self->mmap.pgoff, self->mmap.filename);
+
+       if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
+           cpumode == PERF_RECORD_MISC_KERNEL) {
+               ret = event__process_kernel_mmap(self, session);
+               if (ret < 0)
+                       goto out_problem;
                return 0;
        }
 
+       machine = perf_session__find_host_machine(session);
+       if (machine == NULL)
+               goto out_problem;
        thread = perf_session__findnew(session, self->mmap.pid);
-       map = map__new(&self->mmap, MAP__FUNCTION,
-                      session->cwd, session->cwdlen);
+       map = map__new(&machine->user_dsos, self->mmap.start,
+                       self->mmap.len, self->mmap.pgoff,
+                       self->mmap.pid, self->mmap.filename,
+                       MAP__FUNCTION, session->cwd, session->cwdlen);
 
        if (thread == NULL || map == NULL)
                goto out_problem;
@@ -434,22 +557,56 @@ int event__process_task(event_t *self, struct perf_session *session)
 
 void thread__find_addr_map(struct thread *self,
                           struct perf_session *session, u8 cpumode,
-                          enum map_type type, u64 addr,
+                          enum map_type type, pid_t pid, u64 addr,
                           struct addr_location *al)
 {
        struct map_groups *mg = &self->mg;
+       struct machine *machine = NULL;
 
        al->thread = self;
        al->addr = addr;
+       al->cpumode = cpumode;
+       al->filtered = false;
 
-       if (cpumode == PERF_RECORD_MISC_KERNEL) {
+       if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
                al->level = 'k';
-               mg = &session->kmaps;
-       } else if (cpumode == PERF_RECORD_MISC_USER)
+               machine = perf_session__find_host_machine(session);
+               if (machine == NULL) {
+                       al->map = NULL;
+                       return;
+               }
+               mg = &machine->kmaps;
+       } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
                al->level = '.';
-       else {
-               al->level = 'H';
+               machine = perf_session__find_host_machine(session);
+       } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
+               al->level = 'g';
+               machine = perf_session__find_machine(session, pid);
+               if (machine == NULL) {
+                       al->map = NULL;
+                       return;
+               }
+               mg = &machine->kmaps;
+       } else {
+               /*
+                * 'u' means guest os user space.
+                * TODO: We don't support guest user space. Might support late.
+                */
+               if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest)
+                       al->level = 'u';
+               else
+                       al->level = 'H';
                al->map = NULL;
+
+               if ((cpumode == PERF_RECORD_MISC_GUEST_USER ||
+                       cpumode == PERF_RECORD_MISC_GUEST_KERNEL) &&
+                       !perf_guest)
+                       al->filtered = true;
+               if ((cpumode == PERF_RECORD_MISC_USER ||
+                       cpumode == PERF_RECORD_MISC_KERNEL) &&
+                       !perf_host)
+                       al->filtered = true;
+
                return;
        }
 try_again:
@@ -464,8 +621,10 @@ try_again:
                 * "[vdso]" dso, but for now lets use the old trick of looking
                 * in the whole kernel symbol list.
                 */
-               if ((long long)al->addr < 0 && mg != &session->kmaps) {
-                       mg = &session->kmaps;
+               if ((long long)al->addr < 0 &&
+                   cpumode == PERF_RECORD_MISC_KERNEL &&
+                   machine && mg != &machine->kmaps) {
+                       mg = &machine->kmaps;
                        goto try_again;
                }
        } else
@@ -474,11 +633,11 @@ try_again:
 
 void thread__find_addr_location(struct thread *self,
                                struct perf_session *session, u8 cpumode,
-                               enum map_type type, u64 addr,
+                               enum map_type type, pid_t pid, u64 addr,
                                struct addr_location *al,
                                symbol_filter_t filter)
 {
-       thread__find_addr_map(self, session, cpumode, type, addr, al);
+       thread__find_addr_map(self, session, cpumode, type, pid, addr, al);
        if (al->map != NULL)
                al->sym = map__find_symbol(al->map, al->addr, filter);
        else
@@ -490,8 +649,10 @@ static void dso__calc_col_width(struct dso *self)
        if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
            (!symbol_conf.dso_list ||
             strlist__has_entry(symbol_conf.dso_list, self->name))) {
-               unsigned int slen = strlen(self->name);
-               if (slen > dsos__col_width)
+               u16 slen = self->short_name_len;
+               if (verbose)
+                       slen = self->long_name_len;
+               if (dsos__col_width < slen)
                        dsos__col_width = slen;
        }
 
@@ -512,31 +673,55 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                goto out_filtered;
 
        dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+       /*
+        * Have we already created the kernel maps for the host machine?
+        *
+        * This should have happened earlier, when we processed the kernel MMAP
+        * events, but for older perf.data files there was no such thing, so do
+        * it now.
+        */
+       if (cpumode == PERF_RECORD_MISC_KERNEL &&
+           session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL)
+               machine__create_kernel_maps(&session->host_machine);
 
-       thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION,
-                                  self->ip.ip, al, filter);
+       thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+                             self->ip.pid, self->ip.ip, al);
        dump_printf(" ...... dso: %s\n",
                    al->map ? al->map->dso->long_name :
                        al->level == 'H' ? "[hypervisor]" : "<not found>");
-       /*
-        * We have to do this here as we may have a dso with no symbol hit that
-        * has a name longer than the ones with symbols sampled.
-        */
-       if (al->map && !sort_dso.elide && !al->map->dso->slen_calculated)
-               dso__calc_col_width(al->map->dso);
-
-       if (symbol_conf.dso_list &&
-           (!al->map || !al->map->dso ||
-            !(strlist__has_entry(symbol_conf.dso_list, al->map->dso->short_name) ||
-              (al->map->dso->short_name != al->map->dso->long_name &&
-               strlist__has_entry(symbol_conf.dso_list, al->map->dso->long_name)))))
-               goto out_filtered;
+       al->sym = NULL;
+
+       if (al->map) {
+               if (symbol_conf.dso_list &&
+                   (!al->map || !al->map->dso ||
+                    !(strlist__has_entry(symbol_conf.dso_list,
+                                         al->map->dso->short_name) ||
+                      (al->map->dso->short_name != al->map->dso->long_name &&
+                       strlist__has_entry(symbol_conf.dso_list,
+                                          al->map->dso->long_name)))))
+                       goto out_filtered;
+               /*
+                * We have to do this here as we may have a dso with no symbol
+                * hit that has a name longer than the ones with symbols
+                * sampled.
+                */
+               if (!sort_dso.elide && !al->map->dso->slen_calculated)
+                       dso__calc_col_width(al->map->dso);
+
+               al->sym = map__find_symbol(al->map, al->addr, filter);
+       } else {
+               const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
+
+               if (dsos__col_width < unresolved_col_width &&
+                   !symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
+                   !symbol_conf.dso_list)
+                       dsos__col_width = unresolved_col_width;
+       }
 
        if (symbol_conf.sym_list && al->sym &&
            !strlist__has_entry(symbol_conf.sym_list, al->sym->name))
                goto out_filtered;
 
-       al->filtered = false;
        return 0;
 
 out_filtered:
@@ -570,6 +755,7 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data)
                array++;
        }
 
+       data->id = -1ULL;
        if (type & PERF_SAMPLE_ID) {
                data->id = *array;
                array++;
index a33b949..8577085 100644 (file)
@@ -68,21 +68,54 @@ struct sample_data {
        u64 addr;
        u64 id;
        u64 stream_id;
-       u32 cpu;
        u64 period;
-       struct ip_callchain *callchain;
+       u32 cpu;
        u32 raw_size;
        void *raw_data;
+       struct ip_callchain *callchain;
 };
 
 #define BUILD_ID_SIZE 20
 
 struct build_id_event {
        struct perf_event_header header;
+       pid_t                    pid;
        u8                       build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
        char                     filename[];
 };
 
+enum perf_user_event_type { /* above any possible kernel type */
+       PERF_RECORD_HEADER_ATTR                 = 64,
+       PERF_RECORD_HEADER_EVENT_TYPE           = 65,
+       PERF_RECORD_HEADER_TRACING_DATA         = 66,
+       PERF_RECORD_HEADER_BUILD_ID             = 67,
+       PERF_RECORD_FINISHED_ROUND              = 68,
+       PERF_RECORD_HEADER_MAX
+};
+
+struct attr_event {
+       struct perf_event_header header;
+       struct perf_event_attr attr;
+       u64 id[];
+};
+
+#define MAX_EVENT_NAME 64
+
+struct perf_trace_event_type {
+       u64     event_id;
+       char    name[MAX_EVENT_NAME];
+};
+
+struct event_type_event {
+       struct perf_event_header header;
+       struct perf_trace_event_type event_type;
+};
+
+struct tracing_data_event {
+       struct perf_event_header header;
+       u32 size;
+};
+
 typedef union event_union {
        struct perf_event_header        header;
        struct ip_event                 ip;
@@ -92,22 +125,12 @@ typedef union event_union {
        struct lost_event               lost;
        struct read_event               read;
        struct sample_event             sample;
+       struct attr_event               attr;
+       struct event_type_event         event_type;
+       struct tracing_data_event       tracing_data;
+       struct build_id_event           build_id;
 } event_t;
 
-struct events_stats {
-       u64 total;
-       u64 lost;
-};
-
-struct event_stat_id {
-       struct rb_node          rb_node;
-       struct rb_root          hists;
-       struct events_stats     stats;
-       u64                     config;
-       u64                     event_stream;
-       u32                     type;
-};
-
 void event__print_totals(void);
 
 struct perf_session;
@@ -119,10 +142,13 @@ int event__synthesize_thread(pid_t pid, event__handler_t process,
 void event__synthesize_threads(event__handler_t process,
                               struct perf_session *session);
 int event__synthesize_kernel_mmap(event__handler_t process,
-                                 struct perf_session *session,
-                                 const char *symbol_name);
+                               struct perf_session *session,
+                               struct machine *machine,
+                               const char *symbol_name);
+
 int event__synthesize_modules(event__handler_t process,
-                             struct perf_session *session);
+                             struct perf_session *session,
+                             struct machine *machine);
 
 int event__process_comm(event_t *self, struct perf_session *session);
 int event__process_lost(event_t *self, struct perf_session *session);
@@ -134,4 +160,6 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
                             struct addr_location *al, symbol_filter_t filter);
 int event__parse_sample(event_t *event, u64 type, struct sample_data *data);
 
+extern const char *event__name[];
+
 #endif /* __PERF_RECORD_H */
index 6c9aa16..8847bec 100644 (file)
@@ -99,13 +99,6 @@ int perf_header__add_attr(struct perf_header *self,
        return 0;
 }
 
-#define MAX_EVENT_NAME 64
-
-struct perf_trace_event_type {
-       u64     event_id;
-       char    name[MAX_EVENT_NAME];
-};
-
 static int event_count;
 static struct perf_trace_event_type *events;
 
@@ -197,7 +190,8 @@ static int write_padded(int fd, const void *bf, size_t count,
                        continue;               \
                else
 
-static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
+static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
+                               u16 misc, int fd)
 {
        struct dso *pos;
 
@@ -212,6 +206,7 @@ static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
                len = ALIGN(len, NAME_ALIGN);
                memset(&b, 0, sizeof(b));
                memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
+               b.pid = pid;
                b.header.misc = misc;
                b.header.size = sizeof(b) + len;
                err = do_write(fd, &b, sizeof(b));
@@ -226,13 +221,32 @@ static int __dsos__write_buildid_table(struct list_head *head, u16 misc, int fd)
        return 0;
 }
 
-static int dsos__write_buildid_table(int fd)
+static int dsos__write_buildid_table(struct perf_header *header, int fd)
 {
-       int err = __dsos__write_buildid_table(&dsos__kernel,
-                                             PERF_RECORD_MISC_KERNEL, fd);
-       if (err == 0)
-               err = __dsos__write_buildid_table(&dsos__user,
-                                                 PERF_RECORD_MISC_USER, fd);
+       struct perf_session *session = container_of(header,
+                       struct perf_session, header);
+       struct rb_node *nd;
+       int err = 0;
+       u16 kmisc, umisc;
+
+       for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               if (machine__is_host(pos)) {
+                       kmisc = PERF_RECORD_MISC_KERNEL;
+                       umisc = PERF_RECORD_MISC_USER;
+               } else {
+                       kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
+                       umisc = PERF_RECORD_MISC_GUEST_USER;
+               }
+
+               err = __dsos__write_buildid_table(&pos->kernel_dsos, pos->pid,
+                                                 kmisc, fd);
+               if (err == 0)
+                       err = __dsos__write_buildid_table(&pos->user_dsos,
+                                                         pos->pid, umisc, fd);
+               if (err)
+                       break;
+       }
        return err;
 }
 
@@ -349,9 +363,12 @@ static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
        return err;
 }
 
-static int dsos__cache_build_ids(void)
+static int dsos__cache_build_ids(struct perf_header *self)
 {
-       int err_kernel, err_user;
+       struct perf_session *session = container_of(self,
+                       struct perf_session, header);
+       struct rb_node *nd;
+       int ret = 0;
        char debugdir[PATH_MAX];
 
        snprintf(debugdir, sizeof(debugdir), "%s/%s", getenv("HOME"),
@@ -360,9 +377,28 @@ static int dsos__cache_build_ids(void)
        if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
                return -1;
 
-       err_kernel = __dsos__cache_build_ids(&dsos__kernel, debugdir);
-       err_user   = __dsos__cache_build_ids(&dsos__user, debugdir);
-       return err_kernel || err_user ? -1 : 0;
+       for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret |= __dsos__cache_build_ids(&pos->kernel_dsos, debugdir);
+               ret |= __dsos__cache_build_ids(&pos->user_dsos, debugdir);
+       }
+       return ret ? -1 : 0;
+}
+
+static bool dsos__read_build_ids(struct perf_header *self, bool with_hits)
+{
+       bool ret = false;
+       struct perf_session *session = container_of(self,
+                       struct perf_session, header);
+       struct rb_node *nd;
+
+       for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret |= __dsos__read_build_ids(&pos->kernel_dsos, with_hits);
+               ret |= __dsos__read_build_ids(&pos->user_dsos, with_hits);
+       }
+
+       return ret;
 }
 
 static int perf_header__adds_write(struct perf_header *self, int fd)
@@ -373,7 +409,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
        u64 sec_start;
        int idx = 0, err;
 
-       if (dsos__read_build_ids(true))
+       if (dsos__read_build_ids(self, true))
                perf_header__set_feat(self, HEADER_BUILD_ID);
 
        nr_sections = bitmap_weight(self->adds_features, HEADER_FEAT_BITS);
@@ -400,7 +436,6 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
                trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
        }
 
-
        if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
                struct perf_file_section *buildid_sec;
 
@@ -408,14 +443,14 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
 
                /* Write build-ids */
                buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
-               err = dsos__write_buildid_table(fd);
+               err = dsos__write_buildid_table(self, fd);
                if (err < 0) {
                        pr_debug("failed to write buildid table\n");
                        goto out_free;
                }
                buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
                                          buildid_sec->offset;
-               dsos__cache_build_ids();
+               dsos__cache_build_ids(self);
        }
 
        lseek(fd, sec_start, SEEK_SET);
@@ -427,6 +462,25 @@ out_free:
        return err;
 }
 
+int perf_header__write_pipe(int fd)
+{
+       struct perf_pipe_file_header f_header;
+       int err;
+
+       f_header = (struct perf_pipe_file_header){
+               .magic     = PERF_MAGIC,
+               .size      = sizeof(f_header),
+       };
+
+       err = do_write(fd, &f_header, sizeof(f_header));
+       if (err < 0) {
+               pr_debug("failed to write perf pipe header\n");
+               return err;
+       }
+
+       return 0;
+}
+
 int perf_header__write(struct perf_header *self, int fd, bool at_exit)
 {
        struct perf_file_header f_header;
@@ -518,25 +572,10 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit)
        return 0;
 }
 
-static int do_read(int fd, void *buf, size_t size)
-{
-       while (size) {
-               int ret = read(fd, buf, size);
-
-               if (ret <= 0)
-                       return -1;
-
-               size -= ret;
-               buf += ret;
-       }
-
-       return 0;
-}
-
 static int perf_header__getbuffer64(struct perf_header *self,
                                    int fd, void *buf, size_t size)
 {
-       if (do_read(fd, buf, size))
+       if (do_read(fd, buf, size) <= 0)
                return -1;
 
        if (self->needs_swap)
@@ -592,7 +631,7 @@ int perf_file_header__read(struct perf_file_header *self,
 {
        lseek(fd, 0, SEEK_SET);
 
-       if (do_read(fd, self, sizeof(*self)) ||
+       if (do_read(fd, self, sizeof(*self)) <= 0 ||
            memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
                return -1;
 
@@ -636,6 +675,93 @@ int perf_file_header__read(struct perf_file_header *self,
        return 0;
 }
 
+static int __event_process_build_id(struct build_id_event *bev,
+                                   char *filename,
+                                   struct perf_session *session)
+{
+       int err = -1;
+       struct list_head *head;
+       struct machine *machine;
+       u16 misc;
+       struct dso *dso;
+       enum dso_kernel_type dso_type;
+
+       machine = perf_session__findnew_machine(session, bev->pid);
+       if (!machine)
+               goto out;
+
+       misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+       switch (misc) {
+       case PERF_RECORD_MISC_KERNEL:
+               dso_type = DSO_TYPE_KERNEL;
+               head = &machine->kernel_dsos;
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+               dso_type = DSO_TYPE_GUEST_KERNEL;
+               head = &machine->kernel_dsos;
+               break;
+       case PERF_RECORD_MISC_USER:
+       case PERF_RECORD_MISC_GUEST_USER:
+               dso_type = DSO_TYPE_USER;
+               head = &machine->user_dsos;
+               break;
+       default:
+               goto out;
+       }
+
+       dso = __dsos__findnew(head, filename);
+       if (dso != NULL) {
+               char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+               dso__set_build_id(dso, &bev->build_id);
+
+               if (filename[0] == '[')
+                       dso->kernel = dso_type;
+
+               build_id__sprintf(dso->build_id, sizeof(dso->build_id),
+                                 sbuild_id);
+               pr_debug("build id event received for %s: %s\n",
+                        dso->long_name, sbuild_id);
+       }
+
+       err = 0;
+out:
+       return err;
+}
+
+static int perf_header__read_build_ids(struct perf_header *self,
+                       int input, u64 offset, u64 size)
+{
+       struct perf_session *session = container_of(self,
+                       struct perf_session, header);
+       struct build_id_event bev;
+       char filename[PATH_MAX];
+       u64 limit = offset + size;
+       int err = -1;
+
+       while (offset < limit) {
+               ssize_t len;
+
+               if (read(input, &bev, sizeof(bev)) != sizeof(bev))
+                       goto out;
+
+               if (self->needs_swap)
+                       perf_event_header__bswap(&bev.header);
+
+               len = bev.header.size - sizeof(bev);
+               if (read(input, filename, len) != len)
+                       goto out;
+
+               __event_process_build_id(&bev, filename, session);
+
+               offset += bev.header.size;
+       }
+       err = 0;
+out:
+       return err;
+}
+
 static int perf_file_section__process(struct perf_file_section *self,
                                      struct perf_header *ph,
                                      int feat, int fd)
@@ -648,7 +774,7 @@ static int perf_file_section__process(struct perf_file_section *self,
 
        switch (feat) {
        case HEADER_TRACE_INFO:
-               trace_report(fd);
+               trace_report(fd, false);
                break;
 
        case HEADER_BUILD_ID:
@@ -662,13 +788,56 @@ static int perf_file_section__process(struct perf_file_section *self,
        return 0;
 }
 
-int perf_header__read(struct perf_header *self, int fd)
+static int perf_file_header__read_pipe(struct perf_pipe_file_header *self,
+                                      struct perf_header *ph, int fd,
+                                      bool repipe)
+{
+       if (do_read(fd, self, sizeof(*self)) <= 0 ||
+           memcmp(&self->magic, __perf_magic, sizeof(self->magic)))
+               return -1;
+
+       if (repipe && do_write(STDOUT_FILENO, self, sizeof(*self)) < 0)
+               return -1;
+
+       if (self->size != sizeof(*self)) {
+               u64 size = bswap_64(self->size);
+
+               if (size != sizeof(*self))
+                       return -1;
+
+               ph->needs_swap = true;
+       }
+
+       return 0;
+}
+
+static int perf_header__read_pipe(struct perf_session *session, int fd)
 {
+       struct perf_header *self = &session->header;
+       struct perf_pipe_file_header f_header;
+
+       if (perf_file_header__read_pipe(&f_header, self, fd,
+                                       session->repipe) < 0) {
+               pr_debug("incompatible file format\n");
+               return -EINVAL;
+       }
+
+       session->fd = fd;
+
+       return 0;
+}
+
+int perf_header__read(struct perf_session *session, int fd)
+{
+       struct perf_header *self = &session->header;
        struct perf_file_header f_header;
        struct perf_file_attr   f_attr;
        u64                     f_id;
        int nr_attrs, nr_ids, i, j;
 
+       if (session->fd_pipe)
+               return perf_header__read_pipe(session, fd);
+
        if (perf_file_header__read(&f_header, self, fd) < 0) {
                pr_debug("incompatible file format\n");
                return -EINVAL;
@@ -753,6 +922,14 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 {
        int i;
 
+       /*
+        * We set id to -1 if the data file doesn't contain sample
+        * ids. Check for this and avoid walking through the entire
+        * list of ids which may be large.
+        */
+       if (id == -1ULL)
+               return NULL;
+
        for (i = 0; i < header->attrs; i++) {
                struct perf_header_attr *attr = header->attr[i];
                int j;
@@ -765,3 +942,231 @@ perf_header__find_attr(u64 id, struct perf_header *header)
 
        return NULL;
 }
+
+int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
+                          event__handler_t process,
+                          struct perf_session *session)
+{
+       event_t *ev;
+       size_t size;
+       int err;
+
+       size = sizeof(struct perf_event_attr);
+       size = ALIGN(size, sizeof(u64));
+       size += sizeof(struct perf_event_header);
+       size += ids * sizeof(u64);
+
+       ev = malloc(size);
+
+       ev->attr.attr = *attr;
+       memcpy(ev->attr.id, id, ids * sizeof(u64));
+
+       ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
+       ev->attr.header.size = size;
+
+       err = process(ev, session);
+
+       free(ev);
+
+       return err;
+}
+
+int event__synthesize_attrs(struct perf_header *self,
+                           event__handler_t process,
+                           struct perf_session *session)
+{
+       struct perf_header_attr *attr;
+       int i, err = 0;
+
+       for (i = 0; i < self->attrs; i++) {
+               attr = self->attr[i];
+
+               err = event__synthesize_attr(&attr->attr, attr->ids, attr->id,
+                                            process, session);
+               if (err) {
+                       pr_debug("failed to create perf header attribute\n");
+                       return err;
+               }
+       }
+
+       return err;
+}
+
+int event__process_attr(event_t *self, struct perf_session *session)
+{
+       struct perf_header_attr *attr;
+       unsigned int i, ids, n_ids;
+
+       attr = perf_header_attr__new(&self->attr.attr);
+       if (attr == NULL)
+               return -ENOMEM;
+
+       ids = self->header.size;
+       ids -= (void *)&self->attr.id - (void *)self;
+       n_ids = ids / sizeof(u64);
+
+       for (i = 0; i < n_ids; i++) {
+               if (perf_header_attr__add_id(attr, self->attr.id[i]) < 0) {
+                       perf_header_attr__delete(attr);
+                       return -ENOMEM;
+               }
+       }
+
+       if (perf_header__add_attr(&session->header, attr) < 0) {
+               perf_header_attr__delete(attr);
+               return -ENOMEM;
+       }
+
+       perf_session__update_sample_type(session);
+
+       return 0;
+}
+
+int event__synthesize_event_type(u64 event_id, char *name,
+                                event__handler_t process,
+                                struct perf_session *session)
+{
+       event_t ev;
+       size_t size = 0;
+       int err = 0;
+
+       memset(&ev, 0, sizeof(ev));
+
+       ev.event_type.event_type.event_id = event_id;
+       memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
+       strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
+
+       ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
+       size = strlen(name);
+       size = ALIGN(size, sizeof(u64));
+       ev.event_type.header.size = sizeof(ev.event_type) -
+               (sizeof(ev.event_type.event_type.name) - size);
+
+       err = process(&ev, session);
+
+       return err;
+}
+
+int event__synthesize_event_types(event__handler_t process,
+                                 struct perf_session *session)
+{
+       struct perf_trace_event_type *type;
+       int i, err = 0;
+
+       for (i = 0; i < event_count; i++) {
+               type = &events[i];
+
+               err = event__synthesize_event_type(type->event_id, type->name,
+                                                  process, session);
+               if (err) {
+                       pr_debug("failed to create perf header event type\n");
+                       return err;
+               }
+       }
+
+       return err;
+}
+
+int event__process_event_type(event_t *self,
+                             struct perf_session *session __unused)
+{
+       if (perf_header__push_event(self->event_type.event_type.event_id,
+                                   self->event_type.event_type.name) < 0)
+               return -ENOMEM;
+
+       return 0;
+}
+
+int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
+                                  int nb_events,
+                                  event__handler_t process,
+                                  struct perf_session *session __unused)
+{
+       event_t ev;
+       ssize_t size = 0, aligned_size = 0, padding;
+       int err = 0;
+
+       memset(&ev, 0, sizeof(ev));
+
+       ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
+       size = read_tracing_data_size(fd, pattrs, nb_events);
+       if (size <= 0)
+               return size;
+       aligned_size = ALIGN(size, sizeof(u64));
+       padding = aligned_size - size;
+       ev.tracing_data.header.size = sizeof(ev.tracing_data);
+       ev.tracing_data.size = aligned_size;
+
+       process(&ev, session);
+
+       err = read_tracing_data(fd, pattrs, nb_events);
+       write_padded(fd, NULL, 0, padding);
+
+       return aligned_size;
+}
+
+int event__process_tracing_data(event_t *self,
+                               struct perf_session *session)
+{
+       ssize_t size_read, padding, size = self->tracing_data.size;
+       off_t offset = lseek(session->fd, 0, SEEK_CUR);
+       char buf[BUFSIZ];
+
+       /* setup for reading amidst mmap */
+       lseek(session->fd, offset + sizeof(struct tracing_data_event),
+             SEEK_SET);
+
+       size_read = trace_report(session->fd, session->repipe);
+
+       padding = ALIGN(size_read, sizeof(u64)) - size_read;
+
+       if (read(session->fd, buf, padding) < 0)
+               die("reading input file");
+       if (session->repipe) {
+               int retw = write(STDOUT_FILENO, buf, padding);
+               if (retw <= 0 || retw != padding)
+                       die("repiping tracing data padding");
+       }
+
+       if (size_read + padding != size)
+               die("tracing data size mismatch");
+
+       return size_read + padding;
+}
+
+int event__synthesize_build_id(struct dso *pos, u16 misc,
+                              event__handler_t process,
+                              struct machine *machine,
+                              struct perf_session *session)
+{
+       event_t ev;
+       size_t len;
+       int err = 0;
+
+       if (!pos->hit)
+               return err;
+
+       memset(&ev, 0, sizeof(ev));
+
+       len = pos->long_name_len + 1;
+       len = ALIGN(len, NAME_ALIGN);
+       memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
+       ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
+       ev.build_id.header.misc = misc;
+       ev.build_id.pid = machine->pid;
+       ev.build_id.header.size = sizeof(ev.build_id) + len;
+       memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
+
+       err = process(&ev, session);
+
+       return err;
+}
+
+int event__process_build_id(event_t *self,
+                           struct perf_session *session)
+{
+       __event_process_build_id(&self->build_id,
+                                self->build_id.filename,
+                                session);
+       return 0;
+}
index 82a6af7..402ac24 100644 (file)
@@ -39,6 +39,11 @@ struct perf_file_header {
        DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
 };
 
+struct perf_pipe_file_header {
+       u64                             magic;
+       u64                             size;
+};
+
 struct perf_header;
 
 int perf_file_header__read(struct perf_file_header *self,
@@ -47,21 +52,22 @@ int perf_file_header__read(struct perf_file_header *self,
 struct perf_header {
        int                     frozen;
        int                     attrs, size;
+       bool                    needs_swap;
        struct perf_header_attr **attr;
        s64                     attr_offset;
        u64                     data_offset;
        u64                     data_size;
        u64                     event_offset;
        u64                     event_size;
-       bool                    needs_swap;
        DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
 };
 
 int perf_header__init(struct perf_header *self);
 void perf_header__exit(struct perf_header *self);
 
-int perf_header__read(struct perf_header *self, int fd);
+int perf_header__read(struct perf_session *session, int fd);
 int perf_header__write(struct perf_header *self, int fd, bool at_exit);
+int perf_header__write_pipe(int fd);
 
 int perf_header__add_attr(struct perf_header *self,
                          struct perf_header_attr *attr);
@@ -89,4 +95,33 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
                          const char *name, bool is_kallsyms);
 int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir);
 
+int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
+                          event__handler_t process,
+                          struct perf_session *session);
+int event__synthesize_attrs(struct perf_header *self,
+                           event__handler_t process,
+                           struct perf_session *session);
+int event__process_attr(event_t *self, struct perf_session *session);
+
+int event__synthesize_event_type(u64 event_id, char *name,
+                                event__handler_t process,
+                                struct perf_session *session);
+int event__synthesize_event_types(event__handler_t process,
+                                 struct perf_session *session);
+int event__process_event_type(event_t *self,
+                             struct perf_session *session);
+
+int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
+                                  int nb_events,
+                                  event__handler_t process,
+                                  struct perf_session *session);
+int event__process_tracing_data(event_t *self,
+                               struct perf_session *session);
+
+int event__synthesize_build_id(struct dso *pos, u16 misc,
+                              event__handler_t process,
+                              struct machine *machine,
+                              struct perf_session *session);
+int event__process_build_id(event_t *self, struct perf_session *session);
+
 #endif /* __PERF_HEADER_H */
index 2be33c7..9a71c94 100644 (file)
@@ -1,3 +1,4 @@
+#include "util.h"
 #include "hist.h"
 #include "session.h"
 #include "sort.h"
@@ -8,25 +9,69 @@ struct callchain_param        callchain_param = {
        .min_percent = 0.5
 };
 
+static void hist_entry__add_cpumode_period(struct hist_entry *self,
+                                          unsigned int cpumode, u64 period)
+{
+       switch (cpumode) {
+       case PERF_RECORD_MISC_KERNEL:
+               self->period_sys += period;
+               break;
+       case PERF_RECORD_MISC_USER:
+               self->period_us += period;
+               break;
+       case PERF_RECORD_MISC_GUEST_KERNEL:
+               self->period_guest_sys += period;
+               break;
+       case PERF_RECORD_MISC_GUEST_USER:
+               self->period_guest_us += period;
+               break;
+       default:
+               break;
+       }
+}
+
 /*
- * histogram, sorted on item, collects counts
+ * histogram, sorted on item, collects periods
  */
 
-struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
-                                                 struct addr_location *al,
-                                                 struct symbol *sym_parent,
-                                                 u64 count, bool *hit)
+static struct hist_entry *hist_entry__new(struct hist_entry *template)
+{
+       size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_node) : 0;
+       struct hist_entry *self = malloc(sizeof(*self) + callchain_size);
+
+       if (self != NULL) {
+               *self = *template;
+               self->nr_events = 1;
+               if (symbol_conf.use_callchain)
+                       callchain_init(self->callchain);
+       }
+
+       return self;
+}
+
+static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry)
 {
-       struct rb_node **p = &hists->rb_node;
+       if (entry->ms.sym && self->max_sym_namelen < entry->ms.sym->namelen)
+               self->max_sym_namelen = entry->ms.sym->namelen;
+       ++self->nr_entries;
+}
+
+struct hist_entry *__hists__add_entry(struct hists *self,
+                                     struct addr_location *al,
+                                     struct symbol *sym_parent, u64 period)
+{
+       struct rb_node **p = &self->entries.rb_node;
        struct rb_node *parent = NULL;
        struct hist_entry *he;
        struct hist_entry entry = {
                .thread = al->thread,
-               .map    = al->map,
-               .sym    = al->sym,
+               .ms = {
+                       .map    = al->map,
+                       .sym    = al->sym,
+               },
                .ip     = al->addr,
                .level  = al->level,
-               .count  = count,
+               .period = period,
                .parent = sym_parent,
        };
        int cmp;
@@ -38,8 +83,9 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
                cmp = hist_entry__cmp(&entry, he);
 
                if (!cmp) {
-                       *hit = true;
-                       return he;
+                       he->period += period;
+                       ++he->nr_events;
+                       goto out;
                }
 
                if (cmp < 0)
@@ -48,13 +94,14 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
                        p = &(*p)->rb_right;
        }
 
-       he = malloc(sizeof(*he));
+       he = hist_entry__new(&entry);
        if (!he)
                return NULL;
-       *he = entry;
        rb_link_node(&he->rb_node, parent, p);
-       rb_insert_color(&he->rb_node, hists);
-       *hit = false;
+       rb_insert_color(&he->rb_node, &self->entries);
+       hists__inc_nr_entries(self, he);
+out:
+       hist_entry__add_cpumode_period(he, al->cpumode, period);
        return he;
 }
 
@@ -65,7 +112,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
        int64_t cmp = 0;
 
        list_for_each_entry(se, &hist_entry__sort_list, list) {
-               cmp = se->cmp(left, right);
+               cmp = se->se_cmp(left, right);
                if (cmp)
                        break;
        }
@@ -82,7 +129,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
        list_for_each_entry(se, &hist_entry__sort_list, list) {
                int64_t (*f)(struct hist_entry *, struct hist_entry *);
 
-               f = se->collapse ?: se->cmp;
+               f = se->se_collapse ?: se->se_cmp;
 
                cmp = f(left, right);
                if (cmp)
@@ -101,7 +148,7 @@ void hist_entry__free(struct hist_entry *he)
  * collapse the histogram
  */
 
-static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
+static bool collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
 {
        struct rb_node **p = &root->rb_node;
        struct rb_node *parent = NULL;
@@ -115,9 +162,9 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
                cmp = hist_entry__collapse(iter, he);
 
                if (!cmp) {
-                       iter->count += he->count;
+                       iter->period += he->period;
                        hist_entry__free(he);
-                       return;
+                       return false;
                }
 
                if (cmp < 0)
@@ -128,9 +175,10 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
 
        rb_link_node(&he->rb_node, parent, p);
        rb_insert_color(&he->rb_node, root);
+       return true;
 }
 
-void perf_session__collapse_resort(struct rb_root *hists)
+void hists__collapse_resort(struct hists *self)
 {
        struct rb_root tmp;
        struct rb_node *next;
@@ -140,72 +188,77 @@ void perf_session__collapse_resort(struct rb_root *hists)
                return;
 
        tmp = RB_ROOT;
-       next = rb_first(hists);
+       next = rb_first(&self->entries);
+       self->nr_entries = 0;
+       self->max_sym_namelen = 0;
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
                next = rb_next(&n->rb_node);
 
-               rb_erase(&n->rb_node, hists);
-               collapse__insert_entry(&tmp, n);
+               rb_erase(&n->rb_node, &self->entries);
+               if (collapse__insert_entry(&tmp, n))
+                       hists__inc_nr_entries(self, n);
        }
 
-       *hists = tmp;
+       self->entries = tmp;
 }
 
 /*
- * reverse the map, sort on count.
+ * reverse the map, sort on period.
  */
 
-static void perf_session__insert_output_hist_entry(struct rb_root *root,
-                                                  struct hist_entry *he,
-                                                  u64 min_callchain_hits)
+static void __hists__insert_output_entry(struct rb_root *entries,
+                                        struct hist_entry *he,
+                                        u64 min_callchain_hits)
 {
-       struct rb_node **p = &root->rb_node;
+       struct rb_node **p = &entries->rb_node;
        struct rb_node *parent = NULL;
        struct hist_entry *iter;
 
        if (symbol_conf.use_callchain)
-               callchain_param.sort(&he->sorted_chain, &he->callchain,
+               callchain_param.sort(&he->sorted_chain, he->callchain,
                                      min_callchain_hits, &callchain_param);
 
        while (*p != NULL) {
                parent = *p;
                iter = rb_entry(parent, struct hist_entry, rb_node);
 
-               if (he->count > iter->count)
+               if (he->period > iter->period)
                        p = &(*p)->rb_left;
                else
                        p = &(*p)->rb_right;
        }
 
        rb_link_node(&he->rb_node, parent, p);
-       rb_insert_color(&he->rb_node, root);
+       rb_insert_color(&he->rb_node, entries);
 }
 
-void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
+void hists__output_resort(struct hists *self)
 {
        struct rb_root tmp;
        struct rb_node *next;
        struct hist_entry *n;
        u64 min_callchain_hits;
 
-       min_callchain_hits =
-               total_samples * (callchain_param.min_percent / 100);
+       min_callchain_hits = self->stats.total_period * (callchain_param.min_percent / 100);
 
        tmp = RB_ROOT;
-       next = rb_first(hists);
+       next = rb_first(&self->entries);
+
+       self->nr_entries = 0;
+       self->max_sym_namelen = 0;
 
        while (next) {
                n = rb_entry(next, struct hist_entry, rb_node);
                next = rb_next(&n->rb_node);
 
-               rb_erase(&n->rb_node, hists);
-               perf_session__insert_output_hist_entry(&tmp, n,
-                                                      min_callchain_hits);
+               rb_erase(&n->rb_node, &self->entries);
+               __hists__insert_output_entry(&tmp, n, min_callchain_hits);
+               hists__inc_nr_entries(self, n);
        }
 
-       *hists = tmp;
+       self->entries = tmp;
 }
 
 static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -237,7 +290,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
 }
 
 static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
-                                    int depth, int depth_mask, int count,
+                                    int depth, int depth_mask, int period,
                                     u64 total_samples, int hits,
                                     int left_margin)
 {
@@ -250,7 +303,7 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
                        ret += fprintf(fp, "|");
                else
                        ret += fprintf(fp, " ");
-               if (!count && i == depth - 1) {
+               if (!period && i == depth - 1) {
                        double percent;
 
                        percent = hits * 100.0 / total_samples;
@@ -258,8 +311,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
                } else
                        ret += fprintf(fp, "%s", "          ");
        }
-       if (chain->sym)
-               ret += fprintf(fp, "%s\n", chain->sym->name);
+       if (chain->ms.sym)
+               ret += fprintf(fp, "%s\n", chain->ms.sym->name);
        else
                ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
 
@@ -278,7 +331,7 @@ static void init_rem_hits(void)
        }
 
        strcpy(rem_sq_bracket->name, "[...]");
-       rem_hits.sym = rem_sq_bracket;
+       rem_hits.ms.sym = rem_sq_bracket;
 }
 
 static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
@@ -293,6 +346,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
        u64 remaining;
        size_t ret = 0;
        int i;
+       uint entries_printed = 0;
 
        if (callchain_param.mode == CHAIN_GRAPH_REL)
                new_total = self->children_hit;
@@ -328,8 +382,6 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
                                                   left_margin);
                i = 0;
                list_for_each_entry(chain, &child->val, list) {
-                       if (chain->ip >= PERF_CONTEXT_MAX)
-                               continue;
                        ret += ipchain__fprintf_graph(fp, chain, depth,
                                                      new_depth_mask, i++,
                                                      new_total,
@@ -341,6 +393,8 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
                                                  new_depth_mask | (1 << depth),
                                                  left_margin);
                node = next;
+               if (++entries_printed == callchain_param.print_limit)
+                       break;
        }
 
        if (callchain_param.mode == CHAIN_GRAPH_REL &&
@@ -366,11 +420,9 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
        bool printed = false;
        int i = 0;
        int ret = 0;
+       u32 entries_printed = 0;
 
        list_for_each_entry(chain, &self->val, list) {
-               if (chain->ip >= PERF_CONTEXT_MAX)
-                       continue;
-
                if (!i++ && sort__first_dimension == SORT_SYM)
                        continue;
 
@@ -385,10 +437,13 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
                } else
                        ret += callchain__fprintf_left_margin(fp, left_margin);
 
-               if (chain->sym)
-                       ret += fprintf(fp, " %s\n", chain->sym->name);
+               if (chain->ms.sym)
+                       ret += fprintf(fp, " %s\n", chain->ms.sym->name);
                else
                        ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
+
+               if (++entries_printed == callchain_param.print_limit)
+                       break;
        }
 
        ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
@@ -411,8 +466,8 @@ static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
        list_for_each_entry(chain, &self->val, list) {
                if (chain->ip >= PERF_CONTEXT_MAX)
                        continue;
-               if (chain->sym)
-                       ret += fprintf(fp, "                %s\n", chain->sym->name);
+               if (chain->ms.sym)
+                       ret += fprintf(fp, "                %s\n", chain->ms.sym->name);
                else
                        ret += fprintf(fp, "                %p\n",
                                        (void *)(long)chain->ip);
@@ -427,6 +482,7 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
        struct rb_node *rb_node;
        struct callchain_node *chain;
        size_t ret = 0;
+       u32 entries_printed = 0;
 
        rb_node = rb_first(&self->sorted_chain);
        while (rb_node) {
@@ -449,55 +505,88 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
                        break;
                }
                ret += fprintf(fp, "\n");
+               if (++entries_printed == callchain_param.print_limit)
+                       break;
                rb_node = rb_next(rb_node);
        }
 
        return ret;
 }
 
-static size_t hist_entry__fprintf(struct hist_entry *self,
-                                 struct perf_session *pair_session,
-                                 bool show_displacement,
-                                 long displacement, FILE *fp,
-                                 u64 session_total)
+int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
+                        struct hists *pair_hists, bool show_displacement,
+                        long displacement, bool color, u64 session_total)
 {
        struct sort_entry *se;
-       u64 count, total;
+       u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
        const char *sep = symbol_conf.field_sep;
-       size_t ret;
+       int ret;
 
        if (symbol_conf.exclude_other && !self->parent)
                return 0;
 
-       if (pair_session) {
-               count = self->pair ? self->pair->count : 0;
-               total = pair_session->events_stats.total;
+       if (pair_hists) {
+               period = self->pair ? self->pair->period : 0;
+               total = pair_hists->stats.total_period;
+               period_sys = self->pair ? self->pair->period_sys : 0;
+               period_us = self->pair ? self->pair->period_us : 0;
+               period_guest_sys = self->pair ? self->pair->period_guest_sys : 0;
+               period_guest_us = self->pair ? self->pair->period_guest_us : 0;
        } else {
-               count = self->count;
+               period = self->period;
                total = session_total;
+               period_sys = self->period_sys;
+               period_us = self->period_us;
+               period_guest_sys = self->period_guest_sys;
+               period_guest_us = self->period_guest_us;
        }
 
-       if (total)
-               ret = percent_color_fprintf(fp, sep ? "%.2f" : "   %6.2f%%",
-                                           (count * 100.0) / total);
-       else
-               ret = fprintf(fp, sep ? "%lld" : "%12lld ", count);
+       if (total) {
+               if (color)
+                       ret = percent_color_snprintf(s, size,
+                                                    sep ? "%.2f" : "   %6.2f%%",
+                                                    (period * 100.0) / total);
+               else
+                       ret = snprintf(s, size, sep ? "%.2f" : "   %6.2f%%",
+                                      (period * 100.0) / total);
+               if (symbol_conf.show_cpu_utilization) {
+                       ret += percent_color_snprintf(s + ret, size - ret,
+                                       sep ? "%.2f" : "   %6.2f%%",
+                                       (period_sys * 100.0) / total);
+                       ret += percent_color_snprintf(s + ret, size - ret,
+                                       sep ? "%.2f" : "   %6.2f%%",
+                                       (period_us * 100.0) / total);
+                       if (perf_guest) {
+                               ret += percent_color_snprintf(s + ret,
+                                               size - ret,
+                                               sep ? "%.2f" : "   %6.2f%%",
+                                               (period_guest_sys * 100.0) /
+                                                               total);
+                               ret += percent_color_snprintf(s + ret,
+                                               size - ret,
+                                               sep ? "%.2f" : "   %6.2f%%",
+                                               (period_guest_us * 100.0) /
+                                                               total);
+                       }
+               }
+       } else
+               ret = snprintf(s, size, sep ? "%lld" : "%12lld ", period);
 
        if (symbol_conf.show_nr_samples) {
                if (sep)
-                       fprintf(fp, "%c%lld", *sep, count);
+                       ret += snprintf(s + ret, size - ret, "%c%lld", *sep, period);
                else
-                       fprintf(fp, "%11lld", count);
+                       ret += snprintf(s + ret, size - ret, "%11lld", period);
        }
 
-       if (pair_session) {
+       if (pair_hists) {
                char bf[32];
                double old_percent = 0, new_percent = 0, diff;
 
                if (total > 0)
-                       old_percent = (count * 100.0) / total;
+                       old_percent = (period * 100.0) / total;
                if (session_total > 0)
-                       new_percent = (self->count * 100.0) / session_total;
+                       new_percent = (self->period * 100.0) / session_total;
 
                diff = new_percent - old_percent;
 
@@ -507,9 +596,9 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
                        snprintf(bf, sizeof(bf), " ");
 
                if (sep)
-                       ret += fprintf(fp, "%c%s", *sep, bf);
+                       ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
                else
-                       ret += fprintf(fp, "%11.11s", bf);
+                       ret += snprintf(s + ret, size - ret, "%11.11s", bf);
 
                if (show_displacement) {
                        if (displacement)
@@ -518,9 +607,9 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
                                snprintf(bf, sizeof(bf), " ");
 
                        if (sep)
-                               fprintf(fp, "%c%s", *sep, bf);
+                               ret += snprintf(s + ret, size - ret, "%c%s", *sep, bf);
                        else
-                               fprintf(fp, "%6.6s", bf);
+                               ret += snprintf(s + ret, size - ret, "%6.6s", bf);
                }
        }
 
@@ -528,33 +617,43 @@ static size_t hist_entry__fprintf(struct hist_entry *self,
                if (se->elide)
                        continue;
 
-               fprintf(fp, "%s", sep ?: "  ");
-               ret += se->print(fp, self, se->width ? *se->width : 0);
+               ret += snprintf(s + ret, size - ret, "%s", sep ?: "  ");
+               ret += se->se_snprintf(self, s + ret, size - ret,
+                                      se->se_width ? *se->se_width : 0);
        }
 
-       ret += fprintf(fp, "\n");
+       return ret;
+}
 
-       if (symbol_conf.use_callchain) {
-               int left_margin = 0;
+int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
+                       bool show_displacement, long displacement, FILE *fp,
+                       u64 session_total)
+{
+       char bf[512];
+       hist_entry__snprintf(self, bf, sizeof(bf), pair_hists,
+                            show_displacement, displacement,
+                            true, session_total);
+       return fprintf(fp, "%s\n", bf);
+}
 
-               if (sort__first_dimension == SORT_COMM) {
-                       se = list_first_entry(&hist_entry__sort_list, typeof(*se),
-                                               list);
-                       left_margin = se->width ? *se->width : 0;
-                       left_margin -= thread__comm_len(self->thread);
-               }
+static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp,
+                                           u64 session_total)
+{
+       int left_margin = 0;
 
-               hist_entry_callchain__fprintf(fp, self, session_total,
-                                             left_margin);
+       if (sort__first_dimension == SORT_COMM) {
+               struct sort_entry *se = list_first_entry(&hist_entry__sort_list,
+                                                        typeof(*se), list);
+               left_margin = se->se_width ? *se->se_width : 0;
+               left_margin -= thread__comm_len(self->thread);
        }
 
-       return ret;
+       return hist_entry_callchain__fprintf(fp, self, session_total,
+                                            left_margin);
 }
 
-size_t perf_session__fprintf_hists(struct rb_root *hists,
-                                  struct perf_session *pair,
-                                  bool show_displacement, FILE *fp,
-                                  u64 session_total)
+size_t hists__fprintf(struct hists *self, struct hists *pair,
+                     bool show_displacement, FILE *fp)
 {
        struct sort_entry *se;
        struct rb_node *nd;
@@ -563,7 +662,7 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
        long displacement = 0;
        unsigned int width;
        const char *sep = symbol_conf.field_sep;
-       char *col_width = symbol_conf.col_width_list_str;
+       const char *col_width = symbol_conf.col_width_list_str;
 
        init_rem_hits();
 
@@ -576,6 +675,24 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
                        fputs("  Samples  ", fp);
        }
 
+       if (symbol_conf.show_cpu_utilization) {
+               if (sep) {
+                       ret += fprintf(fp, "%csys", *sep);
+                       ret += fprintf(fp, "%cus", *sep);
+                       if (perf_guest) {
+                               ret += fprintf(fp, "%cguest sys", *sep);
+                               ret += fprintf(fp, "%cguest us", *sep);
+                       }
+               } else {
+                       ret += fprintf(fp, "  sys  ");
+                       ret += fprintf(fp, "  us  ");
+                       if (perf_guest) {
+                               ret += fprintf(fp, "  guest sys  ");
+                               ret += fprintf(fp, "  guest us  ");
+                       }
+               }
+       }
+
        if (pair) {
                if (sep)
                        ret += fprintf(fp, "%cDelta", *sep);
@@ -594,22 +711,22 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
                if (se->elide)
                        continue;
                if (sep) {
-                       fprintf(fp, "%c%s", *sep, se->header);
+                       fprintf(fp, "%c%s", *sep, se->se_header);
                        continue;
                }
-               width = strlen(se->header);
-               if (se->width) {
+               width = strlen(se->se_header);
+               if (se->se_width) {
                        if (symbol_conf.col_width_list_str) {
                                if (col_width) {
-                                       *se->width = atoi(col_width);
+                                       *se->se_width = atoi(col_width);
                                        col_width = strchr(col_width, ',');
                                        if (col_width)
                                                ++col_width;
                                }
                        }
-                       width = *se->width = max(*se->width, width);
+                       width = *se->se_width = max(*se->se_width, width);
                }
-               fprintf(fp, "  %*s", width, se->header);
+               fprintf(fp, "  %*s", width, se->se_header);
        }
        fprintf(fp, "\n");
 
@@ -631,10 +748,10 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
                        continue;
 
                fprintf(fp, "  ");
-               if (se->width)
-                       width = *se->width;
+               if (se->se_width)
+                       width = *se->se_width;
                else
-                       width = strlen(se->header);
+                       width = strlen(se->se_header);
                for (i = 0; i < width; i++)
                        fprintf(fp, ".");
        }
@@ -642,7 +759,7 @@ size_t perf_session__fprintf_hists(struct rb_root *hists,
        fprintf(fp, "\n#\n");
 
 print_entries:
-       for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
                struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 
                if (show_displacement) {
@@ -654,10 +771,14 @@ print_entries:
                        ++position;
                }
                ret += hist_entry__fprintf(h, pair, show_displacement,
-                                          displacement, fp, session_total);
-               if (h->map == NULL && verbose > 1) {
+                                          displacement, fp, self->stats.total_period);
+
+               if (symbol_conf.use_callchain)
+                       ret += hist_entry__fprintf_callchain(h, fp, self->stats.total_period);
+
+               if (h->ms.map == NULL && verbose > 1) {
                        __map_groups__fprintf_maps(&h->thread->mg,
-                                                  MAP__FUNCTION, fp);
+                                                  MAP__FUNCTION, verbose, fp);
                        fprintf(fp, "%.10s end\n", graph_dotted_line);
                }
        }
@@ -666,3 +787,271 @@ print_entries:
 
        return ret;
 }
+
+enum hist_filter {
+       HIST_FILTER__DSO,
+       HIST_FILTER__THREAD,
+};
+
+void hists__filter_by_dso(struct hists *self, const struct dso *dso)
+{
+       struct rb_node *nd;
+
+       self->nr_entries = self->stats.total_period = 0;
+       self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
+       self->max_sym_namelen = 0;
+
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+               if (symbol_conf.exclude_other && !h->parent)
+                       continue;
+
+               if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
+                       h->filtered |= (1 << HIST_FILTER__DSO);
+                       continue;
+               }
+
+               h->filtered &= ~(1 << HIST_FILTER__DSO);
+               if (!h->filtered) {
+                       ++self->nr_entries;
+                       self->stats.total_period += h->period;
+                       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+                       if (h->ms.sym &&
+                           self->max_sym_namelen < h->ms.sym->namelen)
+                               self->max_sym_namelen = h->ms.sym->namelen;
+               }
+       }
+}
+
+void hists__filter_by_thread(struct hists *self, const struct thread *thread)
+{
+       struct rb_node *nd;
+
+       self->nr_entries = self->stats.total_period = 0;
+       self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
+       self->max_sym_namelen = 0;
+
+       for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+               if (thread != NULL && h->thread != thread) {
+                       h->filtered |= (1 << HIST_FILTER__THREAD);
+                       continue;
+               }
+               h->filtered &= ~(1 << HIST_FILTER__THREAD);
+               if (!h->filtered) {
+                       ++self->nr_entries;
+                       self->stats.total_period += h->period;
+                       self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+                       if (h->ms.sym &&
+                           self->max_sym_namelen < h->ms.sym->namelen)
+                               self->max_sym_namelen = h->ms.sym->namelen;
+               }
+       }
+}
+
+static int symbol__alloc_hist(struct symbol *self)
+{
+       struct sym_priv *priv = symbol__priv(self);
+       const int size = (sizeof(*priv->hist) +
+                         (self->end - self->start) * sizeof(u64));
+
+       priv->hist = zalloc(size);
+       return priv->hist == NULL ? -1 : 0;
+}
+
+int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip)
+{
+       unsigned int sym_size, offset;
+       struct symbol *sym = self->ms.sym;
+       struct sym_priv *priv;
+       struct sym_hist *h;
+
+       if (!sym || !self->ms.map)
+               return 0;
+
+       priv = symbol__priv(sym);
+       if (priv->hist == NULL && symbol__alloc_hist(sym) < 0)
+               return -ENOMEM;
+
+       sym_size = sym->end - sym->start;
+       offset = ip - sym->start;
+
+       pr_debug3("%s: ip=%#Lx\n", __func__, self->ms.map->unmap_ip(self->ms.map, ip));
+
+       if (offset >= sym_size)
+               return 0;
+
+       h = priv->hist;
+       h->sum++;
+       h->ip[offset]++;
+
+       pr_debug3("%#Lx %s: period++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start,
+                 self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]);
+       return 0;
+}
+
+static struct objdump_line *objdump_line__new(s64 offset, char *line)
+{
+       struct objdump_line *self = malloc(sizeof(*self));
+
+       if (self != NULL) {
+               self->offset = offset;
+               self->line = line;
+       }
+
+       return self;
+}
+
+void objdump_line__free(struct objdump_line *self)
+{
+       free(self->line);
+       free(self);
+}
+
+static void objdump__add_line(struct list_head *head, struct objdump_line *line)
+{
+       list_add_tail(&line->node, head);
+}
+
+struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
+                                              struct objdump_line *pos)
+{
+       list_for_each_entry_continue(pos, head, node)
+               if (pos->offset >= 0)
+                       return pos;
+
+       return NULL;
+}
+
+static int hist_entry__parse_objdump_line(struct hist_entry *self, FILE *file,
+                                         struct list_head *head)
+{
+       struct symbol *sym = self->ms.sym;
+       struct objdump_line *objdump_line;
+       char *line = NULL, *tmp, *tmp2, *c;
+       size_t line_len;
+       s64 line_ip, offset = -1;
+
+       if (getline(&line, &line_len, file) < 0)
+               return -1;
+
+       if (!line)
+               return -1;
+
+       while (line_len != 0 && isspace(line[line_len - 1]))
+               line[--line_len] = '\0';
+
+       c = strchr(line, '\n');
+       if (c)
+               *c = 0;
+
+       line_ip = -1;
+
+       /*
+        * Strip leading spaces:
+        */
+       tmp = line;
+       while (*tmp) {
+               if (*tmp != ' ')
+                       break;
+               tmp++;
+       }
+
+       if (*tmp) {
+               /*
+                * Parse hexa addresses followed by ':'
+                */
+               line_ip = strtoull(tmp, &tmp2, 16);
+               if (*tmp2 != ':')
+                       line_ip = -1;
+       }
+
+       if (line_ip != -1) {
+               u64 start = map__rip_2objdump(self->ms.map, sym->start);
+               offset = line_ip - start;
+       }
+
+       objdump_line = objdump_line__new(offset, line);
+       if (objdump_line == NULL) {
+               free(line);
+               return -1;
+       }
+       objdump__add_line(head, objdump_line);
+
+       return 0;
+}
+
+int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
+{
+       struct symbol *sym = self->ms.sym;
+       struct map *map = self->ms.map;
+       struct dso *dso = map->dso;
+       const char *filename = dso->long_name;
+       char command[PATH_MAX * 2];
+       FILE *file;
+       u64 len;
+
+       if (!filename)
+               return -1;
+
+       if (dso->origin == DSO__ORIG_KERNEL) {
+               if (dso->annotate_warned)
+                       return 0;
+               dso->annotate_warned = 1;
+               pr_err("Can't annotate %s: No vmlinux file was found in the "
+                      "path:\n", sym->name);
+               vmlinux_path__fprintf(stderr);
+               return -1;
+       }
+
+       pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__,
+                filename, sym->name, map->unmap_ip(map, sym->start),
+                map->unmap_ip(map, sym->end));
+
+       len = sym->end - sym->start;
+
+       pr_debug("annotating [%p] %30s : [%p] %30s\n",
+                dso, dso->long_name, sym, sym->name);
+
+       snprintf(command, sizeof(command),
+                "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s|expand",
+                map__rip_2objdump(map, sym->start),
+                map__rip_2objdump(map, sym->end),
+                filename, filename);
+
+       pr_debug("Executing: %s\n", command);
+
+       file = popen(command, "r");
+       if (!file)
+               return -1;
+
+       while (!feof(file))
+               if (hist_entry__parse_objdump_line(self, file, head) < 0)
+                       break;
+
+       pclose(file);
+       return 0;
+}
+
+void hists__inc_nr_events(struct hists *self, u32 type)
+{
+       ++self->stats.nr_events[0];
+       ++self->stats.nr_events[type];
+}
+
+size_t hists__fprintf_nr_events(struct hists *self, FILE *fp)
+{
+       int i;
+       size_t ret = 0;
+
+       for (i = 0; i < PERF_RECORD_HEADER_MAX; ++i) {
+               if (!event__name[i])
+                       continue;
+               ret += fprintf(fp, "%10s events: %10d\n",
+                              event__name[i], self->stats.nr_events[i]);
+       }
+
+       return ret;
+}
index 16f360c..6f17dcd 100644 (file)
 
 extern struct callchain_param callchain_param;
 
-struct perf_session;
 struct hist_entry;
 struct addr_location;
 struct symbol;
 struct rb_root;
 
-struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
-                                                 struct addr_location *al,
-                                                 struct symbol *parent,
-                                                 u64 count, bool *hit);
+struct objdump_line {
+       struct list_head node;
+       s64              offset;
+       char             *line;
+};
+
+void objdump_line__free(struct objdump_line *self);
+struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
+                                              struct objdump_line *pos);
+
+struct sym_hist {
+       u64             sum;
+       u64             ip[0];
+};
+
+struct sym_ext {
+       struct rb_node  node;
+       double          percent;
+       char            *path;
+};
+
+struct sym_priv {
+       struct sym_hist *hist;
+       struct sym_ext  *ext;
+};
+
+/*
+ * The kernel collects the number of events it couldn't send in a stretch and
+ * when possible sends this number in a PERF_RECORD_LOST event. The number of
+ * such "chunks" of lost events is stored in .nr_events[PERF_EVENT_LOST] while
+ * total_lost tells exactly how many events the kernel in fact lost, i.e. it is
+ * the sum of all struct lost_event.lost fields reported.
+ *
+ * The total_period is needed because by default auto-freq is used, so
+ * multipling nr_events[PERF_EVENT_SAMPLE] by a frequency isn't possible to get
+ * the total number of low level events, it is necessary to to sum all struct
+ * sample_event.period and stash the result in total_period.
+ */
+struct events_stats {
+       u64 total_period;
+       u64 total_lost;
+       u32 nr_events[PERF_RECORD_HEADER_MAX];
+       u32 nr_unknown_events;
+};
+
+struct hists {
+       struct rb_node          rb_node;
+       struct rb_root          entries;
+       u64                     nr_entries;
+       struct events_stats     stats;
+       u64                     config;
+       u64                     event_stream;
+       u32                     type;
+       u32                     max_sym_namelen;
+};
+
+struct hist_entry *__hists__add_entry(struct hists *self,
+                                     struct addr_location *al,
+                                     struct symbol *parent, u64 period);
 extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
 extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
+int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
+                       bool show_displacement, long displacement, FILE *fp,
+                       u64 total);
+int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
+                        struct hists *pair_hists, bool show_displacement,
+                        long displacement, bool color, u64 total);
 void hist_entry__free(struct hist_entry *);
 
-void perf_session__output_resort(struct rb_root *hists, u64 total_samples);
-void perf_session__collapse_resort(struct rb_root *hists);
-size_t perf_session__fprintf_hists(struct rb_root *hists,
-                                  struct perf_session *pair,
-                                  bool show_displacement, FILE *fp,
-                                  u64 session_total);
+void hists__output_resort(struct hists *self);
+void hists__collapse_resort(struct hists *self);
+
+void hists__inc_nr_events(struct hists *self, u32 type);
+size_t hists__fprintf_nr_events(struct hists *self, FILE *fp);
+
+size_t hists__fprintf(struct hists *self, struct hists *pair,
+                     bool show_displacement, FILE *fp);
+
+int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip);
+int hist_entry__annotate(struct hist_entry *self, struct list_head *head);
+
+void hists__filter_by_dso(struct hists *self, const struct dso *dso);
+void hists__filter_by_thread(struct hists *self, const struct thread *thread);
+
+#ifdef NO_NEWT_SUPPORT
+static inline int hists__browse(struct hists *self __used,
+                               const char *helpline __used,
+                               const char *input_name __used)
+{
+       return 0;
+}
+#else
+int hists__browse(struct hists *self, const char *helpline,
+                 const char *input_name);
+#endif
 #endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/hweight.c b/tools/perf/util/hweight.c
new file mode 100644 (file)
index 0000000..5c1d0d0
--- /dev/null
@@ -0,0 +1,31 @@
+#include <linux/bitops.h>
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+unsigned int hweight32(unsigned int w)
+{
+       unsigned int res = w - ((w >> 1) & 0x55555555);
+       res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+       res = (res + (res >> 4)) & 0x0F0F0F0F;
+       res = res + (res >> 8);
+       return (res + (res >> 16)) & 0x000000FF;
+}
+
+unsigned long hweight64(__u64 w)
+{
+#if BITS_PER_LONG == 32
+       return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+#elif BITS_PER_LONG == 64
+       __u64 res = w - ((w >> 1) & 0x5555555555555555ul);
+       res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
+       res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
+       res = res + (res >> 8);
+       res = res + (res >> 16);
+       return (res + (res >> 32)) & 0x00000000000000FFul;
+#endif
+}
diff --git a/tools/perf/util/include/asm/bitops.h b/tools/perf/util/include/asm/bitops.h
deleted file mode 100644 (file)
index 58e9817..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _PERF_ASM_BITOPS_H_
-#define _PERF_ASM_BITOPS_H_
-
-#include <sys/types.h>
-#include "../../types.h"
-#include <linux/compiler.h>
-
-/* CHECKME: Not sure both always match */
-#define BITS_PER_LONG  __WORDSIZE
-
-#include "../../../../include/asm-generic/bitops/__fls.h"
-#include "../../../../include/asm-generic/bitops/fls.h"
-#include "../../../../include/asm-generic/bitops/fls64.h"
-#include "../../../../include/asm-generic/bitops/__ffs.h"
-#include "../../../../include/asm-generic/bitops/ffz.h"
-#include "../../../../include/asm-generic/bitops/hweight.h"
-
-#endif
diff --git a/tools/perf/util/include/asm/hweight.h b/tools/perf/util/include/asm/hweight.h
new file mode 100644 (file)
index 0000000..36cf26d
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef PERF_HWEIGHT_H
+#define PERF_HWEIGHT_H
+
+#include <linux/types.h>
+unsigned int hweight32(unsigned int w);
+unsigned long hweight64(__u64 w);
+
+#endif /* PERF_HWEIGHT_H */
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
new file mode 100644 (file)
index 0000000..cf6727e
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _PERF_DWARF_REGS_H_
+#define _PERF_DWARF_REGS_H_
+
+#ifdef DWARF_SUPPORT
+const char *get_arch_regstr(unsigned int n);
+#endif
+
+#endif
index 9450763..eda4416 100644 (file)
@@ -1,3 +1,35 @@
-#include "../../../../include/linux/bitmap.h"
-#include "../../../../include/asm-generic/bitops/find.h"
-#include <linux/errno.h>
+#ifndef _PERF_BITOPS_H
+#define _PERF_BITOPS_H
+
+#include <string.h>
+#include <linux/bitops.h>
+
+int __bitmap_weight(const unsigned long *bitmap, int bits);
+
+#define BITMAP_LAST_WORD_MASK(nbits)                                   \
+(                                                                      \
+       ((nbits) % BITS_PER_LONG) ?                                     \
+               (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL               \
+)
+
+#define small_const_nbits(nbits) \
+       (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
+
+static inline void bitmap_zero(unsigned long *dst, int nbits)
+{
+       if (small_const_nbits(nbits))
+               *dst = 0UL;
+       else {
+               int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+               memset(dst, 0, len);
+       }
+}
+
+static inline int bitmap_weight(const unsigned long *src, int nbits)
+{
+       if (small_const_nbits(nbits))
+               return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
+       return __bitmap_weight(src, nbits);
+}
+
+#endif /* _PERF_BITOPS_H */
index 8d63116..bb4ac2e 100644 (file)
@@ -1,13 +1,12 @@
 #ifndef _PERF_LINUX_BITOPS_H_
 #define _PERF_LINUX_BITOPS_H_
 
-#define __KERNEL__
+#include <linux/kernel.h>
+#include <asm/hweight.h>
 
-#define CONFIG_GENERIC_FIND_NEXT_BIT
-#define CONFIG_GENERIC_FIND_FIRST_BIT
-#include "../../../../include/linux/bitops.h"
-
-#undef __KERNEL__
+#define BITS_PER_LONG __WORDSIZE
+#define BITS_PER_BYTE           8
+#define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 
 static inline void set_bit(int nr, unsigned long *addr)
 {
@@ -20,10 +19,9 @@ static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
                (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
 }
 
-unsigned long generic_find_next_zero_le_bit(const unsigned long *addr, unsigned
-               long size, unsigned long offset);
-
-unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned
-               long size, unsigned long offset);
+static inline unsigned long hweight_long(unsigned long w)
+{
+       return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
+}
 
 #endif
index dfb0713..791f9dd 100644 (file)
@@ -7,4 +7,6 @@
 #define __user
 #define __attribute_const__
 
+#define __used         __attribute__((__unused__))
+
 #endif
index f261165..1eb804f 100644 (file)
@@ -28,6 +28,8 @@
        (type *)((char *)__mptr - offsetof(type, member)); })
 #endif
 
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
+
 #ifndef max
 #define max(x, y) ({                           \
        typeof(x) _max1 = (x);                  \
@@ -85,16 +87,19 @@ simple_strtoul(const char *nptr, char **endptr, int base)
        return strtoul(nptr, endptr, base);
 }
 
+int eprintf(int level,
+           const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
 #ifndef pr_fmt
 #define pr_fmt(fmt) fmt
 #endif
 
 #define pr_err(fmt, ...) \
-       do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+       eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_warning(fmt, ...) \
-       do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+       eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_info(fmt, ...) \
-       do { fprintf(stderr, pr_fmt(fmt), ##__VA_ARGS__); } while (0)
+       eprintf(0, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_debug(fmt, ...) \
        eprintf(1, pr_fmt(fmt), ##__VA_ARGS__)
 #define pr_debugN(n, fmt, ...) \
index e509cd5..e672f2f 100644 (file)
@@ -1,9 +1,11 @@
-#include "event.h"
 #include "symbol.h"
+#include <errno.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
-#include "debug.h"
+#include <unistd.h>
+#include "map.h"
 
 const char *map_type__name[MAP__NR_TYPES] = {
        [MAP__FUNCTION] = "Functions",
@@ -36,15 +38,16 @@ void map__init(struct map *self, enum map_type type,
        self->map_ip   = map__map_ip;
        self->unmap_ip = map__unmap_ip;
        RB_CLEAR_NODE(&self->rb_node);
+       self->groups   = NULL;
 }
 
-struct map *map__new(struct mmap_event *event, enum map_type type,
-                    char *cwd, int cwdlen)
+struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
+                    u64 pgoff, u32 pid, char *filename,
+                    enum map_type type, char *cwd, int cwdlen)
 {
        struct map *self = malloc(sizeof(*self));
 
        if (self != NULL) {
-               const char *filename = event->filename;
                char newfilename[PATH_MAX];
                struct dso *dso;
                int anon;
@@ -62,16 +65,15 @@ struct map *map__new(struct mmap_event *event, enum map_type type,
                anon = is_anon_memory(filename);
 
                if (anon) {
-                       snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
+                       snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
                        filename = newfilename;
                }
 
-               dso = dsos__findnew(filename);
+               dso = __dsos__findnew(dsos__list, filename);
                if (dso == NULL)
                        goto out_delete;
 
-               map__init(self, type, event->start, event->start + event->len,
-                         event->pgoff, dso);
+               map__init(self, type, start, start + len, pgoff, dso);
 
                if (anon) {
 set_identity:
@@ -235,3 +237,392 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
                        map->unmap_ip(map, addr);       /* RIP -> IP */
        return ip;
 }
+
+void map_groups__init(struct map_groups *self)
+{
+       int i;
+       for (i = 0; i < MAP__NR_TYPES; ++i) {
+               self->maps[i] = RB_ROOT;
+               INIT_LIST_HEAD(&self->removed_maps[i]);
+       }
+       self->machine = NULL;
+}
+
+void map_groups__flush(struct map_groups *self)
+{
+       int type;
+
+       for (type = 0; type < MAP__NR_TYPES; type++) {
+               struct rb_root *root = &self->maps[type];
+               struct rb_node *next = rb_first(root);
+
+               while (next) {
+                       struct map *pos = rb_entry(next, struct map, rb_node);
+                       next = rb_next(&pos->rb_node);
+                       rb_erase(&pos->rb_node, root);
+                       /*
+                        * We may have references to this map, for
+                        * instance in some hist_entry instances, so
+                        * just move them to a separate list.
+                        */
+                       list_add_tail(&pos->node, &self->removed_maps[pos->type]);
+               }
+       }
+}
+
+struct symbol *map_groups__find_symbol(struct map_groups *self,
+                                      enum map_type type, u64 addr,
+                                      struct map **mapp,
+                                      symbol_filter_t filter)
+{
+       struct map *map = map_groups__find(self, type, addr);
+
+       if (map != NULL) {
+               if (mapp != NULL)
+                       *mapp = map;
+               return map__find_symbol(map, map->map_ip(map, addr), filter);
+       }
+
+       return NULL;
+}
+
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+                                              enum map_type type,
+                                              const char *name,
+                                              struct map **mapp,
+                                              symbol_filter_t filter)
+{
+       struct rb_node *nd;
+
+       for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node);
+               struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
+
+               if (sym == NULL)
+                       continue;
+               if (mapp != NULL)
+                       *mapp = pos;
+               return sym;
+       }
+
+       return NULL;
+}
+
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+                                 enum map_type type, int verbose, FILE *fp)
+{
+       size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
+       struct rb_node *nd;
+
+       for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+               struct map *pos = rb_entry(nd, struct map, rb_node);
+               printed += fprintf(fp, "Map:");
+               printed += map__fprintf(pos, fp);
+               if (verbose > 2) {
+                       printed += dso__fprintf(pos->dso, type, fp);
+                       printed += fprintf(fp, "--\n");
+               }
+       }
+
+       return printed;
+}
+
+size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp)
+{
+       size_t printed = 0, i;
+       for (i = 0; i < MAP__NR_TYPES; ++i)
+               printed += __map_groups__fprintf_maps(self, i, verbose, fp);
+       return printed;
+}
+
+static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
+                                                enum map_type type,
+                                                int verbose, FILE *fp)
+{
+       struct map *pos;
+       size_t printed = 0;
+
+       list_for_each_entry(pos, &self->removed_maps[type], node) {
+               printed += fprintf(fp, "Map:");
+               printed += map__fprintf(pos, fp);
+               if (verbose > 1) {
+                       printed += dso__fprintf(pos->dso, type, fp);
+                       printed += fprintf(fp, "--\n");
+               }
+       }
+       return printed;
+}
+
+static size_t map_groups__fprintf_removed_maps(struct map_groups *self,
+                                              int verbose, FILE *fp)
+{
+       size_t printed = 0, i;
+       for (i = 0; i < MAP__NR_TYPES; ++i)
+               printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp);
+       return printed;
+}
+
+size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp)
+{
+       size_t printed = map_groups__fprintf_maps(self, verbose, fp);
+       printed += fprintf(fp, "Removed maps:\n");
+       return printed + map_groups__fprintf_removed_maps(self, verbose, fp);
+}
+
+int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+                                  int verbose, FILE *fp)
+{
+       struct rb_root *root = &self->maps[map->type];
+       struct rb_node *next = rb_first(root);
+
+       while (next) {
+               struct map *pos = rb_entry(next, struct map, rb_node);
+               next = rb_next(&pos->rb_node);
+
+               if (!map__overlap(pos, map))
+                       continue;
+
+               if (verbose >= 2) {
+                       fputs("overlapping maps:\n", fp);
+                       map__fprintf(map, fp);
+                       map__fprintf(pos, fp);
+               }
+
+               rb_erase(&pos->rb_node, root);
+               /*
+                * We may have references to this map, for instance in some
+                * hist_entry instances, so just move them to a separate
+                * list.
+                */
+               list_add_tail(&pos->node, &self->removed_maps[map->type]);
+               /*
+                * Now check if we need to create new maps for areas not
+                * overlapped by the new map:
+                */
+               if (map->start > pos->start) {
+                       struct map *before = map__clone(pos);
+
+                       if (before == NULL)
+                               return -ENOMEM;
+
+                       before->end = map->start - 1;
+                       map_groups__insert(self, before);
+                       if (verbose >= 2)
+                               map__fprintf(before, fp);
+               }
+
+               if (map->end < pos->end) {
+                       struct map *after = map__clone(pos);
+
+                       if (after == NULL)
+                               return -ENOMEM;
+
+                       after->start = map->end + 1;
+                       map_groups__insert(self, after);
+                       if (verbose >= 2)
+                               map__fprintf(after, fp);
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * XXX This should not really _copy_ te maps, but refcount them.
+ */
+int map_groups__clone(struct map_groups *self,
+                     struct map_groups *parent, enum map_type type)
+{
+       struct rb_node *nd;
+       for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
+               struct map *map = rb_entry(nd, struct map, rb_node);
+               struct map *new = map__clone(map);
+               if (new == NULL)
+                       return -ENOMEM;
+               map_groups__insert(self, new);
+       }
+       return 0;
+}
+
+static u64 map__reloc_map_ip(struct map *map, u64 ip)
+{
+       return ip + (s64)map->pgoff;
+}
+
+static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
+{
+       return ip - (s64)map->pgoff;
+}
+
+void map__reloc_vmlinux(struct map *self)
+{
+       struct kmap *kmap = map__kmap(self);
+       s64 reloc;
+
+       if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
+               return;
+
+       reloc = (kmap->ref_reloc_sym->unrelocated_addr -
+                kmap->ref_reloc_sym->addr);
+
+       if (!reloc)
+               return;
+
+       self->map_ip   = map__reloc_map_ip;
+       self->unmap_ip = map__reloc_unmap_ip;
+       self->pgoff    = reloc;
+}
+
+void maps__insert(struct rb_root *maps, struct map *map)
+{
+       struct rb_node **p = &maps->rb_node;
+       struct rb_node *parent = NULL;
+       const u64 ip = map->start;
+       struct map *m;
+
+       while (*p != NULL) {
+               parent = *p;
+               m = rb_entry(parent, struct map, rb_node);
+               if (ip < m->start)
+                       p = &(*p)->rb_left;
+               else
+                       p = &(*p)->rb_right;
+       }
+
+       rb_link_node(&map->rb_node, parent, p);
+       rb_insert_color(&map->rb_node, maps);
+}
+
+struct map *maps__find(struct rb_root *maps, u64 ip)
+{
+       struct rb_node **p = &maps->rb_node;
+       struct rb_node *parent = NULL;
+       struct map *m;
+
+       while (*p != NULL) {
+               parent = *p;
+               m = rb_entry(parent, struct map, rb_node);
+               if (ip < m->start)
+                       p = &(*p)->rb_left;
+               else if (ip > m->end)
+                       p = &(*p)->rb_right;
+               else
+                       return m;
+       }
+
+       return NULL;
+}
+
+int machine__init(struct machine *self, const char *root_dir, pid_t pid)
+{
+       map_groups__init(&self->kmaps);
+       RB_CLEAR_NODE(&self->rb_node);
+       INIT_LIST_HEAD(&self->user_dsos);
+       INIT_LIST_HEAD(&self->kernel_dsos);
+
+       self->kmaps.machine = self;
+       self->pid           = pid;
+       self->root_dir      = strdup(root_dir);
+       return self->root_dir == NULL ? -ENOMEM : 0;
+}
+
+struct machine *machines__add(struct rb_root *self, pid_t pid,
+                             const char *root_dir)
+{
+       struct rb_node **p = &self->rb_node;
+       struct rb_node *parent = NULL;
+       struct machine *pos, *machine = malloc(sizeof(*machine));
+
+       if (!machine)
+               return NULL;
+
+       if (machine__init(machine, root_dir, pid) != 0) {
+               free(machine);
+               return NULL;
+       }
+
+       while (*p != NULL) {
+               parent = *p;
+               pos = rb_entry(parent, struct machine, rb_node);
+               if (pid < pos->pid)
+                       p = &(*p)->rb_left;
+               else
+                       p = &(*p)->rb_right;
+       }
+
+       rb_link_node(&machine->rb_node, parent, p);
+       rb_insert_color(&machine->rb_node, self);
+
+       return machine;
+}
+
+struct machine *machines__find(struct rb_root *self, pid_t pid)
+{
+       struct rb_node **p = &self->rb_node;
+       struct rb_node *parent = NULL;
+       struct machine *machine;
+       struct machine *default_machine = NULL;
+
+       while (*p != NULL) {
+               parent = *p;
+               machine = rb_entry(parent, struct machine, rb_node);
+               if (pid < machine->pid)
+                       p = &(*p)->rb_left;
+               else if (pid > machine->pid)
+                       p = &(*p)->rb_right;
+               else
+                       return machine;
+               if (!machine->pid)
+                       default_machine = machine;
+       }
+
+       return default_machine;
+}
+
+struct machine *machines__findnew(struct rb_root *self, pid_t pid)
+{
+       char path[PATH_MAX];
+       const char *root_dir;
+       struct machine *machine = machines__find(self, pid);
+
+       if (!machine || machine->pid != pid) {
+               if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID)
+                       root_dir = "";
+               else {
+                       if (!symbol_conf.guestmount)
+                               goto out;
+                       sprintf(path, "%s/%d", symbol_conf.guestmount, pid);
+                       if (access(path, R_OK)) {
+                               pr_err("Can't access file %s\n", path);
+                               goto out;
+                       }
+                       root_dir = path;
+               }
+               machine = machines__add(self, pid, root_dir);
+       }
+
+out:
+       return machine;
+}
+
+void machines__process(struct rb_root *self, machine__process_t process, void *data)
+{
+       struct rb_node *nd;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               process(pos, data);
+       }
+}
+
+char *machine__mmap_name(struct machine *self, char *bf, size_t size)
+{
+       if (machine__is_host(self))
+               snprintf(bf, size, "[%s]", "kernel.kallsyms");
+       else if (machine__is_default_guest(self))
+               snprintf(bf, size, "[%s]", "guest.kernel.kallsyms");
+       else
+               snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid);
+
+       return bf;
+}
index b756368..f391345 100644 (file)
@@ -4,7 +4,9 @@
 #include <linux/compiler.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
-#include <linux/types.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "types.h"
 
 enum map_type {
        MAP__FUNCTION = 0,
@@ -18,6 +20,7 @@ extern const char *map_type__name[MAP__NR_TYPES];
 struct dso;
 struct ref_reloc_sym;
 struct map_groups;
+struct machine;
 
 struct map {
        union {
@@ -27,6 +30,7 @@ struct map {
        u64                     start;
        u64                     end;
        enum map_type           type;
+       u32                     priv;
        u64                     pgoff;
 
        /* ip -> dso rip */
@@ -35,6 +39,7 @@ struct map {
        u64                     (*unmap_ip)(struct map *, u64);
 
        struct dso              *dso;
+       struct map_groups       *groups;
 };
 
 struct kmap {
@@ -42,6 +47,32 @@ struct kmap {
        struct map_groups       *kmaps;
 };
 
+struct map_groups {
+       struct rb_root   maps[MAP__NR_TYPES];
+       struct list_head removed_maps[MAP__NR_TYPES];
+       struct machine   *machine;
+};
+
+/* Native host kernel uses -1 as pid index in machine */
+#define        HOST_KERNEL_ID                  (-1)
+#define        DEFAULT_GUEST_KERNEL_ID         (0)
+
+struct machine {
+       struct rb_node    rb_node;
+       pid_t             pid;
+       char              *root_dir;
+       struct list_head  user_dsos;
+       struct list_head  kernel_dsos;
+       struct map_groups kmaps;
+       struct map        *vmlinux_maps[MAP__NR_TYPES];
+};
+
+static inline
+struct map *machine__kernel_map(struct machine *self, enum map_type type)
+{
+       return self->vmlinux_maps[type];
+}
+
 static inline struct kmap *map__kmap(struct map *self)
 {
        return (struct kmap *)(self + 1);
@@ -68,14 +99,14 @@ u64 map__rip_2objdump(struct map *map, u64 rip);
 u64 map__objdump_2ip(struct map *map, u64 addr);
 
 struct symbol;
-struct mmap_event;
 
 typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
 
 void map__init(struct map *self, enum map_type type,
               u64 start, u64 end, u64 pgoff, struct dso *dso);
-struct map *map__new(struct mmap_event *event, enum map_type,
-                    char *cwd, int cwdlen);
+struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
+                    u64 pgoff, u32 pid, char *filename,
+                    enum map_type type, char *cwd, int cwdlen);
 void map__delete(struct map *self);
 struct map *map__clone(struct map *self);
 int map__overlap(struct map *l, struct map *r);
@@ -91,4 +122,96 @@ void map__fixup_end(struct map *self);
 
 void map__reloc_vmlinux(struct map *self);
 
+size_t __map_groups__fprintf_maps(struct map_groups *self,
+                                 enum map_type type, int verbose, FILE *fp);
+void maps__insert(struct rb_root *maps, struct map *map);
+struct map *maps__find(struct rb_root *maps, u64 addr);
+void map_groups__init(struct map_groups *self);
+int map_groups__clone(struct map_groups *self,
+                     struct map_groups *parent, enum map_type type);
+size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp);
+size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp);
+
+typedef void (*machine__process_t)(struct machine *self, void *data);
+
+void machines__process(struct rb_root *self, machine__process_t process, void *data);
+struct machine *machines__add(struct rb_root *self, pid_t pid,
+                             const char *root_dir);
+struct machine *machines__find_host(struct rb_root *self);
+struct machine *machines__find(struct rb_root *self, pid_t pid);
+struct machine *machines__findnew(struct rb_root *self, pid_t pid);
+char *machine__mmap_name(struct machine *self, char *bf, size_t size);
+int machine__init(struct machine *self, const char *root_dir, pid_t pid);
+
+/*
+ * Default guest kernel is defined by parameter --guestkallsyms
+ * and --guestmodules
+ */
+static inline bool machine__is_default_guest(struct machine *self)
+{
+       return self ? self->pid == DEFAULT_GUEST_KERNEL_ID : false;
+}
+
+static inline bool machine__is_host(struct machine *self)
+{
+       return self ? self->pid == HOST_KERNEL_ID : false;
+}
+
+static inline void map_groups__insert(struct map_groups *self, struct map *map)
+{
+       maps__insert(&self->maps[map->type], map);
+       map->groups = self;
+}
+
+static inline struct map *map_groups__find(struct map_groups *self,
+                                          enum map_type type, u64 addr)
+{
+       return maps__find(&self->maps[type], addr);
+}
+
+struct symbol *map_groups__find_symbol(struct map_groups *self,
+                                      enum map_type type, u64 addr,
+                                      struct map **mapp,
+                                      symbol_filter_t filter);
+
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+                                              enum map_type type,
+                                              const char *name,
+                                              struct map **mapp,
+                                              symbol_filter_t filter);
+
+static inline
+struct symbol *machine__find_kernel_symbol(struct machine *self,
+                                          enum map_type type, u64 addr,
+                                          struct map **mapp,
+                                          symbol_filter_t filter)
+{
+       return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter);
+}
+
+static inline
+struct symbol *machine__find_kernel_function(struct machine *self, u64 addr,
+                                            struct map **mapp,
+                                            symbol_filter_t filter)
+{
+       return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter);
+}
+
+static inline
+struct symbol *map_groups__find_function_by_name(struct map_groups *self,
+                                                const char *name, struct map **mapp,
+                                                symbol_filter_t filter)
+{
+       return map_groups__find_symbol_by_name(self, MAP__FUNCTION, name, mapp, filter);
+}
+
+int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+                                  int verbose, FILE *fp);
+
+struct map *map_groups__find_by_name(struct map_groups *self,
+                                    enum map_type type, const char *name);
+struct map *machine__new_module(struct machine *self, u64 start, const char *filename);
+
+void map_groups__flush(struct map_groups *self);
+
 #endif /* __PERF_MAP_H */
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
new file mode 100644 (file)
index 0000000..ccb7c5b
--- /dev/null
@@ -0,0 +1,1084 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#undef _GNU_SOURCE
+
+#include <slang.h>
+#include <stdlib.h>
+#include <newt.h>
+#include <sys/ttydefaults.h>
+
+#include "cache.h"
+#include "hist.h"
+#include "pstack.h"
+#include "session.h"
+#include "sort.h"
+#include "symbol.h"
+
+#if SLANG_VERSION < 20104
+#define slsmg_printf(msg, args...) SLsmg_printf((char *)msg, ##args)
+#define slsmg_write_nstring(msg, len) SLsmg_write_nstring((char *)msg, len)
+#define sltt_set_color(obj, name, fg, bg) SLtt_set_color(obj,(char *)name,\
+                                                        (char *)fg, (char *)bg)
+#else
+#define slsmg_printf SLsmg_printf
+#define slsmg_write_nstring SLsmg_write_nstring
+#define sltt_set_color SLtt_set_color
+#endif
+
+struct ui_progress {
+       newtComponent form, scale;
+};
+
+struct ui_progress *ui_progress__new(const char *title, u64 total)
+{
+       struct ui_progress *self = malloc(sizeof(*self));
+
+       if (self != NULL) {
+               int cols;
+               newtGetScreenSize(&cols, NULL);
+               cols -= 4;
+               newtCenteredWindow(cols, 1, title);
+               self->form  = newtForm(NULL, NULL, 0);
+               if (self->form == NULL)
+                       goto out_free_self;
+               self->scale = newtScale(0, 0, cols, total);
+               if (self->scale == NULL)
+                       goto out_free_form;
+               newtFormAddComponent(self->form, self->scale);
+               newtRefresh();
+       }
+
+       return self;
+
+out_free_form:
+       newtFormDestroy(self->form);
+out_free_self:
+       free(self);
+       return NULL;
+}
+
+void ui_progress__update(struct ui_progress *self, u64 curr)
+{
+       newtScaleSet(self->scale, curr);
+       newtRefresh();
+}
+
+void ui_progress__delete(struct ui_progress *self)
+{
+       newtFormDestroy(self->form);
+       newtPopWindow();
+       free(self);
+}
+
+static void ui_helpline__pop(void)
+{
+       newtPopHelpLine();
+}
+
+static void ui_helpline__push(const char *msg)
+{
+       newtPushHelpLine(msg);
+}
+
+static void ui_helpline__vpush(const char *fmt, va_list ap)
+{
+       char *s;
+
+       if (vasprintf(&s, fmt, ap) < 0)
+               vfprintf(stderr, fmt, ap);
+       else {
+               ui_helpline__push(s);
+               free(s);
+       }
+}
+
+static void ui_helpline__fpush(const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+       ui_helpline__vpush(fmt, ap);
+       va_end(ap);
+}
+
+static void ui_helpline__puts(const char *msg)
+{
+       ui_helpline__pop();
+       ui_helpline__push(msg);
+}
+
+static char browser__last_msg[1024];
+
+int browser__show_help(const char *format, va_list ap)
+{
+       int ret;
+       static int backlog;
+
+        ret = vsnprintf(browser__last_msg + backlog,
+                       sizeof(browser__last_msg) - backlog, format, ap);
+       backlog += ret;
+
+       if (browser__last_msg[backlog - 1] == '\n') {
+               ui_helpline__puts(browser__last_msg);
+               newtRefresh();
+               backlog = 0;
+       }
+
+       return ret;
+}
+
+static void newt_form__set_exit_keys(newtComponent self)
+{
+       newtFormAddHotKey(self, NEWT_KEY_LEFT);
+       newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
+       newtFormAddHotKey(self, 'Q');
+       newtFormAddHotKey(self, 'q');
+       newtFormAddHotKey(self, CTRL('c'));
+}
+
+static newtComponent newt_form__new(void)
+{
+       newtComponent self = newtForm(NULL, NULL, 0);
+       if (self)
+               newt_form__set_exit_keys(self);
+       return self;
+}
+
+static int popup_menu(int argc, char * const argv[])
+{
+       struct newtExitStruct es;
+       int i, rc = -1, max_len = 5;
+       newtComponent listbox, form = newt_form__new();
+
+       if (form == NULL)
+               return -1;
+
+       listbox = newtListbox(0, 0, argc, NEWT_FLAG_RETURNEXIT);
+       if (listbox == NULL)
+               goto out_destroy_form;
+
+       newtFormAddComponent(form, listbox);
+
+       for (i = 0; i < argc; ++i) {
+               int len = strlen(argv[i]);
+               if (len > max_len)
+                       max_len = len;
+               if (newtListboxAddEntry(listbox, argv[i], (void *)(long)i))
+                       goto out_destroy_form;
+       }
+
+       newtCenteredWindow(max_len, argc, NULL);
+       newtFormRun(form, &es);
+       rc = newtListboxGetCurrent(listbox) - NULL;
+       if (es.reason == NEWT_EXIT_HOTKEY)
+               rc = -1;
+       newtPopWindow();
+out_destroy_form:
+       newtFormDestroy(form);
+       return rc;
+}
+
+static int ui__help_window(const char *text)
+{
+       struct newtExitStruct es;
+       newtComponent tb, form = newt_form__new();
+       int rc = -1;
+       int max_len = 0, nr_lines = 0;
+       const char *t;
+
+       if (form == NULL)
+               return -1;
+
+       t = text;
+       while (1) {
+               const char *sep = strchr(t, '\n');
+               int len;
+
+               if (sep == NULL)
+                       sep = strchr(t, '\0');
+               len = sep - t;
+               if (max_len < len)
+                       max_len = len;
+               ++nr_lines;
+               if (*sep == '\0')
+                       break;
+               t = sep + 1;
+       }
+
+       tb = newtTextbox(0, 0, max_len, nr_lines, 0);
+       if (tb == NULL)
+               goto out_destroy_form;
+
+       newtTextboxSetText(tb, text);
+       newtFormAddComponent(form, tb);
+       newtCenteredWindow(max_len, nr_lines, NULL);
+       newtFormRun(form, &es);
+       newtPopWindow();
+       rc = 0;
+out_destroy_form:
+       newtFormDestroy(form);
+       return rc;
+}
+
+static bool dialog_yesno(const char *msg)
+{
+       /* newtWinChoice should really be accepting const char pointers... */
+       char yes[] = "Yes", no[] = "No";
+       return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
+}
+
+#define HE_COLORSET_TOP                50
+#define HE_COLORSET_MEDIUM     51
+#define HE_COLORSET_NORMAL     52
+#define HE_COLORSET_SELECTED   53
+#define HE_COLORSET_CODE       54
+
+static int ui_browser__percent_color(double percent, bool current)
+{
+       if (current)
+               return HE_COLORSET_SELECTED;
+       if (percent >= MIN_RED)
+               return HE_COLORSET_TOP;
+       if (percent >= MIN_GREEN)
+               return HE_COLORSET_MEDIUM;
+       return HE_COLORSET_NORMAL;
+}
+
+struct ui_browser {
+       newtComponent   form, sb;
+       u64             index, first_visible_entry_idx;
+       void            *first_visible_entry, *entries;
+       u16             top, left, width, height;
+       void            *priv;
+       u32             nr_entries;
+};
+
+static void ui_browser__refresh_dimensions(struct ui_browser *self)
+{
+       int cols, rows;
+       newtGetScreenSize(&cols, &rows);
+
+       if (self->width > cols - 4)
+               self->width = cols - 4;
+       self->height = rows - 5;
+       if (self->height > self->nr_entries)
+               self->height = self->nr_entries;
+       self->top  = (rows - self->height) / 2;
+       self->left = (cols - self->width) / 2;
+}
+
+static void ui_browser__reset_index(struct ui_browser *self)
+{
+        self->index = self->first_visible_entry_idx = 0;
+        self->first_visible_entry = NULL;
+}
+
+static int objdump_line__show(struct objdump_line *self, struct list_head *head,
+                             int width, struct hist_entry *he, int len,
+                             bool current_entry)
+{
+       if (self->offset != -1) {
+               struct symbol *sym = he->ms.sym;
+               unsigned int hits = 0;
+               double percent = 0.0;
+               int color;
+               struct sym_priv *priv = symbol__priv(sym);
+               struct sym_ext *sym_ext = priv->ext;
+               struct sym_hist *h = priv->hist;
+               s64 offset = self->offset;
+               struct objdump_line *next = objdump__get_next_ip_line(head, self);
+
+               while (offset < (s64)len &&
+                      (next == NULL || offset < next->offset)) {
+                       if (sym_ext) {
+                               percent += sym_ext[offset].percent;
+                       } else
+                               hits += h->ip[offset];
+
+                       ++offset;
+               }
+
+               if (sym_ext == NULL && h->sum)
+                       percent = 100.0 * hits / h->sum;
+
+               color = ui_browser__percent_color(percent, current_entry);
+               SLsmg_set_color(color);
+               slsmg_printf(" %7.2f ", percent);
+               if (!current_entry)
+                       SLsmg_set_color(HE_COLORSET_CODE);
+       } else {
+               int color = ui_browser__percent_color(0, current_entry);
+               SLsmg_set_color(color);
+               slsmg_write_nstring(" ", 9);
+       }
+
+       SLsmg_write_char(':');
+       slsmg_write_nstring(" ", 8);
+       if (!*self->line)
+               slsmg_write_nstring(" ", width - 18);
+       else
+               slsmg_write_nstring(self->line, width - 18);
+
+       return 0;
+}
+
+static int ui_browser__refresh_entries(struct ui_browser *self)
+{
+       struct objdump_line *pos;
+       struct list_head *head = self->entries;
+       struct hist_entry *he = self->priv;
+       int row = 0;
+       int len = he->ms.sym->end - he->ms.sym->start;
+
+       if (self->first_visible_entry == NULL || self->first_visible_entry == self->entries)
+                self->first_visible_entry = head->next;
+
+       pos = list_entry(self->first_visible_entry, struct objdump_line, node);
+
+       list_for_each_entry_from(pos, head, node) {
+               bool current_entry = (self->first_visible_entry_idx + row) == self->index;
+               SLsmg_gotorc(self->top + row, self->left);
+               objdump_line__show(pos, head, self->width,
+                                  he, len, current_entry);
+               if (++row == self->height)
+                       break;
+       }
+
+       SLsmg_set_color(HE_COLORSET_NORMAL);
+       SLsmg_fill_region(self->top + row, self->left,
+                         self->height - row, self->width, ' ');
+
+       return 0;
+}
+
+static int ui_browser__run(struct ui_browser *self, const char *title,
+                          struct newtExitStruct *es)
+{
+       if (self->form) {
+               newtFormDestroy(self->form);
+               newtPopWindow();
+       }
+
+       ui_browser__refresh_dimensions(self);
+       newtCenteredWindow(self->width + 2, self->height, title);
+       self->form = newt_form__new();
+       if (self->form == NULL)
+               return -1;
+
+       self->sb = newtVerticalScrollbar(self->width + 1, 0, self->height,
+                                        HE_COLORSET_NORMAL,
+                                        HE_COLORSET_SELECTED);
+       if (self->sb == NULL)
+               return -1;
+
+       newtFormAddHotKey(self->form, NEWT_KEY_UP);
+       newtFormAddHotKey(self->form, NEWT_KEY_DOWN);
+       newtFormAddHotKey(self->form, NEWT_KEY_PGUP);
+       newtFormAddHotKey(self->form, NEWT_KEY_PGDN);
+       newtFormAddHotKey(self->form, NEWT_KEY_HOME);
+       newtFormAddHotKey(self->form, NEWT_KEY_END);
+
+       if (ui_browser__refresh_entries(self) < 0)
+               return -1;
+       newtFormAddComponent(self->form, self->sb);
+
+       while (1) {
+               unsigned int offset;
+
+               newtFormRun(self->form, es);
+
+               if (es->reason != NEWT_EXIT_HOTKEY)
+                       break;
+               switch (es->u.key) {
+               case NEWT_KEY_DOWN:
+                       if (self->index == self->nr_entries - 1)
+                               break;
+                       ++self->index;
+                       if (self->index == self->first_visible_entry_idx + self->height) {
+                               struct list_head *pos = self->first_visible_entry;
+                               ++self->first_visible_entry_idx;
+                               self->first_visible_entry = pos->next;
+                       }
+                       break;
+               case NEWT_KEY_UP:
+                       if (self->index == 0)
+                               break;
+                       --self->index;
+                       if (self->index < self->first_visible_entry_idx) {
+                               struct list_head *pos = self->first_visible_entry;
+                               --self->first_visible_entry_idx;
+                               self->first_visible_entry = pos->prev;
+                       }
+                       break;
+               case NEWT_KEY_PGDN:
+                       if (self->first_visible_entry_idx + self->height > self->nr_entries - 1)
+                               break;
+
+                       offset = self->height;
+                       if (self->index + offset > self->nr_entries - 1)
+                               offset = self->nr_entries - 1 - self->index;
+                       self->index += offset;
+                       self->first_visible_entry_idx += offset;
+
+                       while (offset--) {
+                               struct list_head *pos = self->first_visible_entry;
+                               self->first_visible_entry = pos->next;
+                       }
+
+                       break;
+               case NEWT_KEY_PGUP:
+                       if (self->first_visible_entry_idx == 0)
+                               break;
+
+                       if (self->first_visible_entry_idx < self->height)
+                               offset = self->first_visible_entry_idx;
+                       else
+                               offset = self->height;
+
+                       self->index -= offset;
+                       self->first_visible_entry_idx -= offset;
+
+                       while (offset--) {
+                               struct list_head *pos = self->first_visible_entry;
+                               self->first_visible_entry = pos->prev;
+                       }
+                       break;
+               case NEWT_KEY_HOME:
+                       ui_browser__reset_index(self);
+                       break;
+               case NEWT_KEY_END: {
+                       struct list_head *head = self->entries;
+                       offset = self->height - 1;
+
+                       if (offset > self->nr_entries)
+                               offset = self->nr_entries;
+
+                       self->index = self->first_visible_entry_idx = self->nr_entries - 1 - offset;
+                       self->first_visible_entry = head->prev;
+                       while (offset-- != 0) {
+                               struct list_head *pos = self->first_visible_entry;
+                               self->first_visible_entry = pos->prev;
+                       }
+               }
+                       break;
+               case NEWT_KEY_ESCAPE:
+               case NEWT_KEY_LEFT:
+               case CTRL('c'):
+               case 'Q':
+               case 'q':
+                       return 0;
+               default:
+                       continue;
+               }
+               if (ui_browser__refresh_entries(self) < 0)
+                       return -1;
+       }
+       return 0;
+}
+
+/*
+ * When debugging newt problems it was useful to be able to "unroll"
+ * the calls to newtCheckBoxTreeAdd{Array,Item}, so that we can generate
+ * a source file with the sequence of calls to these methods, to then
+ * tweak the arrays to get the intended results, so I'm keeping this code
+ * here, may be useful again in the future.
+ */
+#undef NEWT_DEBUG
+
+static void newt_checkbox_tree__add(newtComponent tree, const char *str,
+                                   void *priv, int *indexes)
+{
+#ifdef NEWT_DEBUG
+       /* Print the newtCheckboxTreeAddArray to tinker with its index arrays */
+       int i = 0, len = 40 - strlen(str);
+
+       fprintf(stderr,
+               "\tnewtCheckboxTreeAddItem(tree, %*.*s\"%s\", (void *)%p, 0, ",
+               len, len, " ", str, priv);
+       while (indexes[i] != NEWT_ARG_LAST) {
+               if (indexes[i] != NEWT_ARG_APPEND)
+                       fprintf(stderr, " %d,", indexes[i]);
+               else
+                       fprintf(stderr, " %s,", "NEWT_ARG_APPEND");
+               ++i;
+       }
+       fprintf(stderr, " %s", " NEWT_ARG_LAST);\n");
+       fflush(stderr);
+#endif
+       newtCheckboxTreeAddArray(tree, str, priv, 0, indexes);
+}
+
+static char *callchain_list__sym_name(struct callchain_list *self,
+                                     char *bf, size_t bfsize)
+{
+       if (self->ms.sym)
+               return self->ms.sym->name;
+
+       snprintf(bf, bfsize, "%#Lx", self->ip);
+       return bf;
+}
+
+static void __callchain__append_graph_browser(struct callchain_node *self,
+                                             newtComponent tree, u64 total,
+                                             int *indexes, int depth)
+{
+       struct rb_node *node;
+       u64 new_total, remaining;
+       int idx = 0;
+
+       if (callchain_param.mode == CHAIN_GRAPH_REL)
+               new_total = self->children_hit;
+       else
+               new_total = total;
+
+       remaining = new_total;
+       node = rb_first(&self->rb_root);
+       while (node) {
+               struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
+               struct rb_node *next = rb_next(node);
+               u64 cumul = cumul_hits(child);
+               struct callchain_list *chain;
+               int first = true, printed = 0;
+               int chain_idx = -1;
+               remaining -= cumul;
+
+               indexes[depth] = NEWT_ARG_APPEND;
+               indexes[depth + 1] = NEWT_ARG_LAST;
+
+               list_for_each_entry(chain, &child->val, list) {
+                       char ipstr[BITS_PER_LONG / 4 + 1],
+                            *alloc_str = NULL;
+                       const char *str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
+
+                       if (first) {
+                               double percent = cumul * 100.0 / new_total;
+
+                               first = false;
+                               if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
+                                       str = "Not enough memory!";
+                               else
+                                       str = alloc_str;
+                       } else {
+                               indexes[depth] = idx;
+                               indexes[depth + 1] = NEWT_ARG_APPEND;
+                               indexes[depth + 2] = NEWT_ARG_LAST;
+                               ++chain_idx;
+                       }
+                       newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
+                       free(alloc_str);
+                       ++printed;
+               }
+
+               indexes[depth] = idx;
+               if (chain_idx != -1)
+                       indexes[depth + 1] = chain_idx;
+               if (printed != 0)
+                       ++idx;
+               __callchain__append_graph_browser(child, tree, new_total, indexes,
+                                                 depth + (chain_idx != -1 ? 2 : 1));
+               node = next;
+       }
+}
+
+static void callchain__append_graph_browser(struct callchain_node *self,
+                                           newtComponent tree, u64 total,
+                                           int *indexes, int parent_idx)
+{
+       struct callchain_list *chain;
+       int i = 0;
+
+       indexes[1] = NEWT_ARG_APPEND;
+       indexes[2] = NEWT_ARG_LAST;
+
+       list_for_each_entry(chain, &self->val, list) {
+               char ipstr[BITS_PER_LONG / 4 + 1], *str;
+
+               if (chain->ip >= PERF_CONTEXT_MAX)
+                       continue;
+
+               if (!i++ && sort__first_dimension == SORT_SYM)
+                       continue;
+
+               str = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
+               newt_checkbox_tree__add(tree, str, &chain->ms, indexes);
+       }
+
+       indexes[1] = parent_idx;
+       indexes[2] = NEWT_ARG_APPEND;
+       indexes[3] = NEWT_ARG_LAST;
+       __callchain__append_graph_browser(self, tree, total, indexes, 2);
+}
+
+static void hist_entry__append_callchain_browser(struct hist_entry *self,
+                                                newtComponent tree, u64 total, int parent_idx)
+{
+       struct rb_node *rb_node;
+       int indexes[1024] = { [0] = parent_idx, };
+       int idx = 0;
+       struct callchain_node *chain;
+
+       rb_node = rb_first(&self->sorted_chain);
+       while (rb_node) {
+               chain = rb_entry(rb_node, struct callchain_node, rb_node);
+               switch (callchain_param.mode) {
+               case CHAIN_FLAT:
+                       break;
+               case CHAIN_GRAPH_ABS: /* falldown */
+               case CHAIN_GRAPH_REL:
+                       callchain__append_graph_browser(chain, tree, total, indexes, idx++);
+                       break;
+               case CHAIN_NONE:
+               default:
+                       break;
+               }
+               rb_node = rb_next(rb_node);
+       }
+}
+
+static size_t hist_entry__append_browser(struct hist_entry *self,
+                                        newtComponent tree, u64 total)
+{
+       char s[256];
+       size_t ret;
+
+       if (symbol_conf.exclude_other && !self->parent)
+               return 0;
+
+       ret = hist_entry__snprintf(self, s, sizeof(s), NULL,
+                                  false, 0, false, total);
+       if (symbol_conf.use_callchain) {
+               int indexes[2];
+
+               indexes[0] = NEWT_ARG_APPEND;
+               indexes[1] = NEWT_ARG_LAST;
+               newt_checkbox_tree__add(tree, s, &self->ms, indexes);
+       } else
+               newtListboxAppendEntry(tree, s, &self->ms);
+
+       return ret;
+}
+
+static void hist_entry__annotate_browser(struct hist_entry *self)
+{
+       struct ui_browser browser;
+       struct newtExitStruct es;
+       struct objdump_line *pos, *n;
+       LIST_HEAD(head);
+
+       if (self->ms.sym == NULL)
+               return;
+
+       if (hist_entry__annotate(self, &head) < 0)
+               return;
+
+       ui_helpline__push("Press <- or ESC to exit");
+
+       memset(&browser, 0, sizeof(browser));
+       browser.entries = &head;
+       browser.priv = self;
+       list_for_each_entry(pos, &head, node) {
+               size_t line_len = strlen(pos->line);
+               if (browser.width < line_len)
+                       browser.width = line_len;
+               ++browser.nr_entries;
+       }
+
+       browser.width += 18; /* Percentage */
+       ui_browser__run(&browser, self->ms.sym->name, &es);
+       newtFormDestroy(browser.form);
+       newtPopWindow();
+       list_for_each_entry_safe(pos, n, &head, node) {
+               list_del(&pos->node);
+               objdump_line__free(pos);
+       }
+       ui_helpline__pop();
+}
+
+static const void *newt__symbol_tree_get_current(newtComponent self)
+{
+       if (symbol_conf.use_callchain)
+               return newtCheckboxTreeGetCurrent(self);
+       return newtListboxGetCurrent(self);
+}
+
+static void hist_browser__selection(newtComponent self, void *data)
+{
+       const struct map_symbol **symbol_ptr = data;
+       *symbol_ptr = newt__symbol_tree_get_current(self);
+}
+
+struct hist_browser {
+       newtComponent           form, tree;
+       const struct map_symbol *selection;
+};
+
+static struct hist_browser *hist_browser__new(void)
+{
+       struct hist_browser *self = malloc(sizeof(*self));
+
+       if (self != NULL)
+               self->form = NULL;
+
+       return self;
+}
+
+static void hist_browser__delete(struct hist_browser *self)
+{
+       newtFormDestroy(self->form);
+       newtPopWindow();
+       free(self);
+}
+
+static int hist_browser__populate(struct hist_browser *self, struct hists *hists,
+                                 const char *title)
+{
+       int max_len = 0, idx, cols, rows;
+       struct ui_progress *progress;
+       struct rb_node *nd;
+       u64 curr_hist = 0;
+       char seq[] = ".", unit;
+       char str[256];
+       unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
+
+       if (self->form) {
+               newtFormDestroy(self->form);
+               newtPopWindow();
+       }
+
+       nr_events = convert_unit(nr_events, &unit);
+       snprintf(str, sizeof(str), "Events: %lu%c                            ",
+                nr_events, unit);
+       newtDrawRootText(0, 0, str);
+
+       newtGetScreenSize(NULL, &rows);
+
+       if (symbol_conf.use_callchain)
+               self->tree = newtCheckboxTreeMulti(0, 0, rows - 5, seq,
+                                                  NEWT_FLAG_SCROLL);
+       else
+               self->tree = newtListbox(0, 0, rows - 5,
+                                       (NEWT_FLAG_SCROLL |
+                                        NEWT_FLAG_RETURNEXIT));
+
+       newtComponentAddCallback(self->tree, hist_browser__selection,
+                                &self->selection);
+
+       progress = ui_progress__new("Adding entries to the browser...",
+                                   hists->nr_entries);
+       if (progress == NULL)
+               return -1;
+
+       idx = 0;
+       for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
+               struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+               int len;
+
+               if (h->filtered)
+                       continue;
+
+               len = hist_entry__append_browser(h, self->tree, hists->stats.total_period);
+               if (len > max_len)
+                       max_len = len;
+               if (symbol_conf.use_callchain)
+                       hist_entry__append_callchain_browser(h, self->tree,
+                                                            hists->stats.total_period, idx++);
+               ++curr_hist;
+               if (curr_hist % 5)
+                       ui_progress__update(progress, curr_hist);
+       }
+
+       ui_progress__delete(progress);
+
+       newtGetScreenSize(&cols, &rows);
+
+       if (max_len > cols)
+               max_len = cols - 3;
+
+       if (!symbol_conf.use_callchain)
+               newtListboxSetWidth(self->tree, max_len);
+
+       newtCenteredWindow(max_len + (symbol_conf.use_callchain ? 5 : 0),
+                          rows - 5, title);
+       self->form = newt_form__new();
+       if (self->form == NULL)
+               return -1;
+
+       newtFormAddHotKey(self->form, 'A');
+       newtFormAddHotKey(self->form, 'a');
+       newtFormAddHotKey(self->form, 'D');
+       newtFormAddHotKey(self->form, 'd');
+       newtFormAddHotKey(self->form, 'T');
+       newtFormAddHotKey(self->form, 't');
+       newtFormAddHotKey(self->form, '?');
+       newtFormAddHotKey(self->form, 'H');
+       newtFormAddHotKey(self->form, 'h');
+       newtFormAddHotKey(self->form, NEWT_KEY_F1);
+       newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
+       newtFormAddComponents(self->form, self->tree, NULL);
+       self->selection = newt__symbol_tree_get_current(self->tree);
+
+       return 0;
+}
+
+static struct hist_entry *hist_browser__selected_entry(struct hist_browser *self)
+{
+       int *indexes;
+
+       if (!symbol_conf.use_callchain)
+               goto out;
+
+       indexes = newtCheckboxTreeFindItem(self->tree, (void *)self->selection);
+       if (indexes) {
+               bool is_hist_entry = indexes[1] == NEWT_ARG_LAST;
+               free(indexes);
+               if (is_hist_entry)
+                       goto out;
+       }
+       return NULL;
+out:
+       return container_of(self->selection, struct hist_entry, ms);
+}
+
+static struct thread *hist_browser__selected_thread(struct hist_browser *self)
+{
+       struct hist_entry *he = hist_browser__selected_entry(self);
+       return he ? he->thread : NULL;
+}
+
+static int hist_browser__title(char *bf, size_t size, const char *input_name,
+                              const struct dso *dso, const struct thread *thread)
+{
+       int printed = 0;
+
+       if (thread)
+               printed += snprintf(bf + printed, size - printed,
+                                   "Thread: %s(%d)",
+                                   (thread->comm_set ?  thread->comm : ""),
+                                   thread->pid);
+       if (dso)
+               printed += snprintf(bf + printed, size - printed,
+                                   "%sDSO: %s", thread ? " " : "",
+                                   dso->short_name);
+       return printed ?: snprintf(bf, size, "Report: %s", input_name);
+}
+
+int hists__browse(struct hists *self, const char *helpline, const char *input_name)
+{
+       struct hist_browser *browser = hist_browser__new();
+       struct pstack *fstack = pstack__new(2);
+       const struct thread *thread_filter = NULL;
+       const struct dso *dso_filter = NULL;
+       struct newtExitStruct es;
+       char msg[160];
+       int err = -1;
+
+       if (browser == NULL)
+               return -1;
+
+       fstack = pstack__new(2);
+       if (fstack == NULL)
+               goto out;
+
+       ui_helpline__push(helpline);
+
+       hist_browser__title(msg, sizeof(msg), input_name,
+                           dso_filter, thread_filter);
+       if (hist_browser__populate(browser, self, msg) < 0)
+               goto out_free_stack;
+
+       while (1) {
+               const struct thread *thread;
+               const struct dso *dso;
+               char *options[16];
+               int nr_options = 0, choice = 0, i,
+                   annotate = -2, zoom_dso = -2, zoom_thread = -2;
+
+               newtFormRun(browser->form, &es);
+
+               thread = hist_browser__selected_thread(browser);
+               dso = browser->selection->map ? browser->selection->map->dso : NULL;
+
+               if (es.reason == NEWT_EXIT_HOTKEY) {
+                       if (es.u.key == NEWT_KEY_F1)
+                               goto do_help;
+
+                       switch (toupper(es.u.key)) {
+                       case 'A':
+                               goto do_annotate;
+                       case 'D':
+                               goto zoom_dso;
+                       case 'T':
+                               goto zoom_thread;
+                       case 'H':
+                       case '?':
+do_help:
+                               ui__help_window("->        Zoom into DSO/Threads & Annotate current symbol\n"
+                                               "<-        Zoom out\n"
+                                               "a         Annotate current symbol\n"
+                                               "h/?/F1    Show this window\n"
+                                               "d         Zoom into current DSO\n"
+                                               "t         Zoom into current Thread\n"
+                                               "q/CTRL+C  Exit browser");
+                               continue;
+                       default:;
+                       }
+                       if (toupper(es.u.key) == 'Q' ||
+                           es.u.key == CTRL('c'))
+                               break;
+                       if (es.u.key == NEWT_KEY_ESCAPE) {
+                               if (dialog_yesno("Do you really want to exit?"))
+                                       break;
+                               else
+                                       continue;
+                       }
+
+                       if (es.u.key == NEWT_KEY_LEFT) {
+                               const void *top;
+
+                               if (pstack__empty(fstack))
+                                       continue;
+                               top = pstack__pop(fstack);
+                               if (top == &dso_filter)
+                                       goto zoom_out_dso;
+                               if (top == &thread_filter)
+                                       goto zoom_out_thread;
+                               continue;
+                       }
+               }
+
+               if (browser->selection->sym != NULL &&
+                   asprintf(&options[nr_options], "Annotate %s",
+                            browser->selection->sym->name) > 0)
+                       annotate = nr_options++;
+
+               if (thread != NULL &&
+                   asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
+                            (thread_filter ? "out of" : "into"),
+                            (thread->comm_set ? thread->comm : ""),
+                            thread->pid) > 0)
+                       zoom_thread = nr_options++;
+
+               if (dso != NULL &&
+                   asprintf(&options[nr_options], "Zoom %s %s DSO",
+                            (dso_filter ? "out of" : "into"),
+                            (dso->kernel ? "the Kernel" : dso->short_name)) > 0)
+                       zoom_dso = nr_options++;
+
+               options[nr_options++] = (char *)"Exit";
+
+               choice = popup_menu(nr_options, options);
+
+               for (i = 0; i < nr_options - 1; ++i)
+                       free(options[i]);
+
+               if (choice == nr_options - 1)
+                       break;
+
+               if (choice == -1)
+                       continue;
+
+               if (choice == annotate) {
+                       struct hist_entry *he;
+do_annotate:
+                       if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
+                               ui_helpline__puts("No vmlinux file found, can't "
+                                                "annotate with just a "
+                                                "kallsyms file");
+                               continue;
+                       }
+
+                       he = hist_browser__selected_entry(browser);
+                       if (he == NULL)
+                               continue;
+
+                       hist_entry__annotate_browser(he);
+               } else if (choice == zoom_dso) {
+zoom_dso:
+                       if (dso_filter) {
+                               pstack__remove(fstack, &dso_filter);
+zoom_out_dso:
+                               ui_helpline__pop();
+                               dso_filter = NULL;
+                       } else {
+                               if (dso == NULL)
+                                       continue;
+                               ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s DSO\"",
+                                                  dso->kernel ? "the Kernel" : dso->short_name);
+                               dso_filter = dso;
+                               pstack__push(fstack, &dso_filter);
+                       }
+                       hists__filter_by_dso(self, dso_filter);
+                       hist_browser__title(msg, sizeof(msg), input_name,
+                                           dso_filter, thread_filter);
+                       if (hist_browser__populate(browser, self, msg) < 0)
+                               goto out;
+               } else if (choice == zoom_thread) {
+zoom_thread:
+                       if (thread_filter) {
+                               pstack__remove(fstack, &thread_filter);
+zoom_out_thread:
+                               ui_helpline__pop();
+                               thread_filter = NULL;
+                       } else {
+                               ui_helpline__fpush("To zoom out press <- or -> + \"Zoom out of %s(%d) thread\"",
+                                                  thread->comm_set ? thread->comm : "",
+                                                  thread->pid);
+                               thread_filter = thread;
+                               pstack__push(fstack, &thread_filter);
+                       }
+                       hists__filter_by_thread(self, thread_filter);
+                       hist_browser__title(msg, sizeof(msg), input_name,
+                                           dso_filter, thread_filter);
+                       if (hist_browser__populate(browser, self, msg) < 0)
+                               goto out;
+               }
+       }
+       err = 0;
+out_free_stack:
+       pstack__delete(fstack);
+out:
+       hist_browser__delete(browser);
+       return err;
+}
+
+static struct newtPercentTreeColors {
+       const char *topColorFg, *topColorBg;
+       const char *mediumColorFg, *mediumColorBg;
+       const char *normalColorFg, *normalColorBg;
+       const char *selColorFg, *selColorBg;
+       const char *codeColorFg, *codeColorBg;
+} defaultPercentTreeColors = {
+       "red",       "lightgray",
+       "green",     "lightgray",
+       "black",     "lightgray",
+       "lightgray", "magenta",
+       "blue",      "lightgray",
+};
+
+void setup_browser(void)
+{
+       struct newtPercentTreeColors *c = &defaultPercentTreeColors;
+       if (!isatty(1))
+               return;
+
+       use_browser = true;
+       newtInit();
+       newtCls();
+       ui_helpline__puts(" ");
+       sltt_set_color(HE_COLORSET_TOP, NULL, c->topColorFg, c->topColorBg);
+       sltt_set_color(HE_COLORSET_MEDIUM, NULL, c->mediumColorFg, c->mediumColorBg);
+       sltt_set_color(HE_COLORSET_NORMAL, NULL, c->normalColorFg, c->normalColorBg);
+       sltt_set_color(HE_COLORSET_SELECTED, NULL, c->selColorFg, c->selColorBg);
+       sltt_set_color(HE_COLORSET_CODE, NULL, c->codeColorFg, c->codeColorBg);
+}
+
+void exit_browser(bool wait_for_ok)
+{
+       if (use_browser) {
+               if (wait_for_ok) {
+                       char title[] = "Fatal Error", ok[] = "Ok";
+                       newtWinMessage(title, ok, browser__last_msg);
+               }
+               newtFinished();
+       }
+}
index 05d0c5c..9bf0f40 100644 (file)
@@ -5,6 +5,7 @@
 #include "parse-events.h"
 #include "exec_cmd.h"
 #include "string.h"
+#include "symbol.h"
 #include "cache.h"
 #include "header.h"
 #include "debugfs.h"
@@ -409,7 +410,6 @@ static enum event_result
 parse_single_tracepoint_event(char *sys_name,
                              const char *evt_name,
                              unsigned int evt_length,
-                             char *flags,
                              struct perf_event_attr *attr,
                              const char **strp)
 {
@@ -418,14 +418,6 @@ parse_single_tracepoint_event(char *sys_name,
        u64 id;
        int fd;
 
-       if (flags) {
-               if (!strncmp(flags, "record", strlen(flags))) {
-                       attr->sample_type |= PERF_SAMPLE_RAW;
-                       attr->sample_type |= PERF_SAMPLE_TIME;
-                       attr->sample_type |= PERF_SAMPLE_CPU;
-               }
-       }
-
        snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
                 sys_name, evt_name);
 
@@ -444,6 +436,13 @@ parse_single_tracepoint_event(char *sys_name,
        attr->type = PERF_TYPE_TRACEPOINT;
        *strp = evt_name + evt_length;
 
+       attr->sample_type |= PERF_SAMPLE_RAW;
+       attr->sample_type |= PERF_SAMPLE_TIME;
+       attr->sample_type |= PERF_SAMPLE_CPU;
+
+       attr->sample_period = 1;
+
+
        return EVT_HANDLED;
 }
 
@@ -532,8 +531,7 @@ static enum event_result parse_tracepoint_event(const char **strp,
                                                       flags);
        } else
                return parse_single_tracepoint_event(sys_name, evt_name,
-                                                    evt_length, flags,
-                                                    attr, strp);
+                                                    evt_length, attr, strp);
 }
 
 static enum event_result
@@ -690,19 +688,29 @@ static enum event_result
 parse_event_modifier(const char **strp, struct perf_event_attr *attr)
 {
        const char *str = *strp;
-       int eu = 1, ek = 1, eh = 1;
+       int exclude = 0;
+       int eu = 0, ek = 0, eh = 0, precise = 0;
 
        if (*str++ != ':')
                return 0;
        while (*str) {
-               if (*str == 'u')
+               if (*str == 'u') {
+                       if (!exclude)
+                               exclude = eu = ek = eh = 1;
                        eu = 0;
-               else if (*str == 'k')
+               } else if (*str == 'k') {
+                       if (!exclude)
+                               exclude = eu = ek = eh = 1;
                        ek = 0;
-               else if (*str == 'h')
+               } else if (*str == 'h') {
+                       if (!exclude)
+                               exclude = eu = ek = eh = 1;
                        eh = 0;
-               else
+               } else if (*str == 'p') {
+                       precise++;
+               } else
                        break;
+
                ++str;
        }
        if (str >= *strp + 2) {
@@ -710,6 +718,7 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr)
                attr->exclude_user   = eu;
                attr->exclude_kernel = ek;
                attr->exclude_hv     = eh;
+               attr->precise_ip     = precise;
                return 1;
        }
        return 0;
@@ -934,7 +943,8 @@ void print_events(void)
 
        printf("\n");
        printf("  %-42s [%s]\n",
-               "rNNN", event_type_descriptors[PERF_TYPE_RAW]);
+               "rNNN (see 'perf list --help' on how to encode it)",
+              event_type_descriptors[PERF_TYPE_RAW]);
        printf("\n");
 
        printf("  %-42s [%s]\n",
index b8c1f64..fc4ab3f 100644 (file)
@@ -13,6 +13,7 @@ struct tracepoint_path {
 };
 
 extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
+extern bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events);
 
 extern int                     nr_counters;
 
index efebd5b..99d02aa 100644 (file)
@@ -49,8 +49,9 @@ static int get_value(struct parse_opt_ctx_t *p,
                                break;
                        /* FALLTHROUGH */
                case OPTION_BOOLEAN:
+               case OPTION_INCR:
                case OPTION_BIT:
-               case OPTION_SET_INT:
+               case OPTION_SET_UINT:
                case OPTION_SET_PTR:
                        return opterror(opt, "takes no value", flags);
                case OPTION_END:
@@ -58,7 +59,9 @@ static int get_value(struct parse_opt_ctx_t *p,
                case OPTION_GROUP:
                case OPTION_STRING:
                case OPTION_INTEGER:
+               case OPTION_UINTEGER:
                case OPTION_LONG:
+               case OPTION_U64:
                default:
                        break;
                }
@@ -73,11 +76,15 @@ static int get_value(struct parse_opt_ctx_t *p,
                return 0;
 
        case OPTION_BOOLEAN:
+               *(bool *)opt->value = unset ? false : true;
+               return 0;
+
+       case OPTION_INCR:
                *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
                return 0;
 
-       case OPTION_SET_INT:
-               *(int *)opt->value = unset ? 0 : opt->defval;
+       case OPTION_SET_UINT:
+               *(unsigned int *)opt->value = unset ? 0 : opt->defval;
                return 0;
 
        case OPTION_SET_PTR:
@@ -120,6 +127,22 @@ static int get_value(struct parse_opt_ctx_t *p,
                        return opterror(opt, "expects a numerical value", flags);
                return 0;
 
+       case OPTION_UINTEGER:
+               if (unset) {
+                       *(unsigned int *)opt->value = 0;
+                       return 0;
+               }
+               if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+                       *(unsigned int *)opt->value = opt->defval;
+                       return 0;
+               }
+               if (get_arg(p, opt, flags, &arg))
+                       return -1;
+               *(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
+               if (*s)
+                       return opterror(opt, "expects a numerical value", flags);
+               return 0;
+
        case OPTION_LONG:
                if (unset) {
                        *(long *)opt->value = 0;
@@ -136,6 +159,22 @@ static int get_value(struct parse_opt_ctx_t *p,
                        return opterror(opt, "expects a numerical value", flags);
                return 0;
 
+       case OPTION_U64:
+               if (unset) {
+                       *(u64 *)opt->value = 0;
+                       return 0;
+               }
+               if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
+                       *(u64 *)opt->value = opt->defval;
+                       return 0;
+               }
+               if (get_arg(p, opt, flags, &arg))
+                       return -1;
+               *(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
+               if (*s)
+                       return opterror(opt, "expects a numerical value", flags);
+               return 0;
+
        case OPTION_END:
        case OPTION_ARGUMENT:
        case OPTION_GROUP:
@@ -441,7 +480,10 @@ int usage_with_options_internal(const char * const *usagestr,
                switch (opts->type) {
                case OPTION_ARGUMENT:
                        break;
+               case OPTION_LONG:
+               case OPTION_U64:
                case OPTION_INTEGER:
+               case OPTION_UINTEGER:
                        if (opts->flags & PARSE_OPT_OPTARG)
                                if (opts->long_name)
                                        pos += fprintf(stderr, "[=<n>]");
@@ -473,14 +515,14 @@ int usage_with_options_internal(const char * const *usagestr,
                                        pos += fprintf(stderr, " ...");
                        }
                        break;
-               default: /* OPTION_{BIT,BOOLEAN,SET_INT,SET_PTR} */
+               default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
                case OPTION_END:
                case OPTION_GROUP:
                case OPTION_BIT:
                case OPTION_BOOLEAN:
-               case OPTION_SET_INT:
+               case OPTION_INCR:
+               case OPTION_SET_UINT:
                case OPTION_SET_PTR:
-               case OPTION_LONG:
                        break;
                }
 
@@ -500,6 +542,7 @@ int usage_with_options_internal(const char * const *usagestr,
 void usage_with_options(const char * const *usagestr,
                        const struct option *opts)
 {
+       exit_browser(false);
        usage_with_options_internal(usagestr, opts, 0);
        exit(129);
 }
index 948805a..c7d72dc 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __PERF_PARSE_OPTIONS_H
 #define __PERF_PARSE_OPTIONS_H
 
+#include <linux/kernel.h>
+#include <stdbool.h>
+
 enum parse_opt_type {
        /* special types */
        OPTION_END,
@@ -8,14 +11,17 @@ enum parse_opt_type {
        OPTION_GROUP,
        /* options with no arguments */
        OPTION_BIT,
-       OPTION_BOOLEAN, /* _INCR would have been a better name */
-       OPTION_SET_INT,
+       OPTION_BOOLEAN,
+       OPTION_INCR,
+       OPTION_SET_UINT,
        OPTION_SET_PTR,
        /* options with arguments (usually) */
        OPTION_STRING,
        OPTION_INTEGER,
        OPTION_LONG,
        OPTION_CALLBACK,
+       OPTION_U64,
+       OPTION_UINTEGER,
 };
 
 enum parse_opt_flags {
@@ -73,7 +79,7 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
  *
  * `defval`::
  *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
- *   OPTION_{BIT,SET_INT,SET_PTR} store the {mask,integer,pointer} to put in
+ *   OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
  *   the value when met.
  *   CALLBACKS can use it like they want.
  */
@@ -90,16 +96,21 @@ struct option {
        intptr_t defval;
 };
 
+#define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
+
 #define OPT_END()                   { .type = OPTION_END }
 #define OPT_ARGUMENT(l, h)          { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) }
 #define OPT_GROUP(h)                { .type = OPTION_GROUP, .help = (h) }
-#define OPT_BIT(s, l, v, h, b)      { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (b) }
-#define OPT_BOOLEAN(s, l, v, h)     { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
-#define OPT_SET_INT(s, l, v, h, i)  { .type = OPTION_SET_INT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (i) }
+#define OPT_BIT(s, l, v, h, b)      { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
+#define OPT_BOOLEAN(s, l, v, h)     { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) }
+#define OPT_INCR(s, l, v, h)        { .type = OPTION_INCR, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
+#define OPT_SET_UINT(s, l, v, h, i)  { .type = OPTION_SET_UINT, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h), .defval = (i) }
 #define OPT_SET_PTR(s, l, v, h, p)  { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) }
-#define OPT_INTEGER(s, l, v, h)     { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
-#define OPT_LONG(s, l, v, h)        { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = (v), .help = (h) }
-#define OPT_STRING(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h) }
+#define OPT_INTEGER(s, l, v, h)     { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
+#define OPT_UINTEGER(s, l, v, h)    { .type = OPTION_UINTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h) }
+#define OPT_LONG(s, l, v, h)        { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
+#define OPT_U64(s, l, v, h)         { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
+#define OPT_STRING(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) }
 #define OPT_DATE(s, l, v, h) \
        { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
 #define OPT_CALLBACK(s, l, v, a, h, f) \
index 7c004b6..914c670 100644 (file)
 #include <limits.h>
 
 #undef _GNU_SOURCE
+#include "util.h"
 #include "event.h"
 #include "string.h"
 #include "strlist.h"
 #include "debug.h"
 #include "cache.h"
 #include "color.h"
-#include "parse-events.h"  /* For debugfs_path */
+#include "symbol.h"
+#include "thread.h"
+#include "debugfs.h"
+#include "trace-event.h"       /* For __unused */
 #include "probe-event.h"
+#include "probe-finder.h"
 
 #define MAX_CMDLEN 256
 #define MAX_PROBE_ARGS 128
 #define PERFPROBE_GROUP "probe"
 
-#define semantic_error(msg ...) die("Semantic error :" msg)
+bool probe_event_dry_run;      /* Dry run flag */
+
+#define semantic_error(msg ...) pr_err("Semantic error :" msg)
 
 /* If there is no space to write, returns -E2BIG. */
 static int e_snprintf(char *str, size_t size, const char *format, ...)
@@ -64,7 +71,275 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
        return ret;
 }
 
-void parse_line_range_desc(const char *arg, struct line_range *lr)
+static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
+static struct machine machine;
+
+/* Initialize symbol maps and path of vmlinux */
+static int init_vmlinux(void)
+{
+       struct dso *kernel;
+       int ret;
+
+       symbol_conf.sort_by_name = true;
+       if (symbol_conf.vmlinux_name == NULL)
+               symbol_conf.try_vmlinux_path = true;
+       else
+               pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
+       ret = symbol__init();
+       if (ret < 0) {
+               pr_debug("Failed to init symbol map.\n");
+               goto out;
+       }
+
+       ret = machine__init(&machine, "/", 0);
+       if (ret < 0)
+               goto out;
+
+       kernel = dso__new_kernel(symbol_conf.vmlinux_name);
+       if (kernel == NULL)
+               die("Failed to create kernel dso.");
+
+       ret = __machine__create_kernel_maps(&machine, kernel);
+       if (ret < 0)
+               pr_debug("Failed to create kernel maps.\n");
+
+out:
+       if (ret < 0)
+               pr_warning("Failed to init vmlinux path.\n");
+       return ret;
+}
+
+#ifdef DWARF_SUPPORT
+static int open_vmlinux(void)
+{
+       if (map__load(machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) {
+               pr_debug("Failed to load kernel map.\n");
+               return -EINVAL;
+       }
+       pr_debug("Try to open %s\n", machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name);
+       return open(machine.vmlinux_maps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
+}
+
+/* Convert trace point to probe point with debuginfo */
+static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+                                      struct perf_probe_point *pp)
+{
+       struct symbol *sym;
+       int fd, ret = -ENOENT;
+
+       sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
+                                      tp->symbol, NULL);
+       if (sym) {
+               fd = open_vmlinux();
+               if (fd >= 0) {
+                       ret = find_perf_probe_point(fd,
+                                                sym->start + tp->offset, pp);
+                       close(fd);
+               }
+       }
+       if (ret <= 0) {
+               pr_debug("Failed to find corresponding probes from "
+                        "debuginfo. Use kprobe event information.\n");
+               pp->function = strdup(tp->symbol);
+               if (pp->function == NULL)
+                       return -ENOMEM;
+               pp->offset = tp->offset;
+       }
+       pp->retprobe = tp->retprobe;
+
+       return 0;
+}
+
+/* Try to find perf_probe_event with debuginfo */
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+                                          struct kprobe_trace_event **tevs,
+                                          int max_tevs)
+{
+       bool need_dwarf = perf_probe_event_need_dwarf(pev);
+       int fd, ntevs;
+
+       fd = open_vmlinux();
+       if (fd < 0) {
+               if (need_dwarf) {
+                       pr_warning("Failed to open debuginfo file.\n");
+                       return fd;
+               }
+               pr_debug("Could not open vmlinux. Try to use symbols.\n");
+               return 0;
+       }
+
+       /* Searching trace events corresponding to probe event */
+       ntevs = find_kprobe_trace_events(fd, pev, tevs, max_tevs);
+       close(fd);
+
+       if (ntevs > 0) {        /* Succeeded to find trace events */
+               pr_debug("find %d kprobe_trace_events.\n", ntevs);
+               return ntevs;
+       }
+
+       if (ntevs == 0) {       /* No error but failed to find probe point. */
+               pr_warning("Probe point '%s' not found.\n",
+                          synthesize_perf_probe_point(&pev->point));
+               return -ENOENT;
+       }
+       /* Error path : ntevs < 0 */
+       pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
+       if (ntevs == -EBADF) {
+               pr_warning("Warning: No dwarf info found in the vmlinux - "
+                       "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
+               if (!need_dwarf) {
+                       pr_debug("Trying to use symbols.\nn");
+                       return 0;
+               }
+       }
+       return ntevs;
+}
+
+#define LINEBUF_SIZE 256
+#define NR_ADDITIONAL_LINES 2
+
+static int show_one_line(FILE *fp, int l, bool skip, bool show_num)
+{
+       char buf[LINEBUF_SIZE];
+       const char *color = PERF_COLOR_BLUE;
+
+       if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+               goto error;
+       if (!skip) {
+               if (show_num)
+                       fprintf(stdout, "%7d  %s", l, buf);
+               else
+                       color_fprintf(stdout, color, "         %s", buf);
+       }
+
+       while (strlen(buf) == LINEBUF_SIZE - 1 &&
+              buf[LINEBUF_SIZE - 2] != '\n') {
+               if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
+                       goto error;
+               if (!skip) {
+                       if (show_num)
+                               fprintf(stdout, "%s", buf);
+                       else
+                               color_fprintf(stdout, color, "%s", buf);
+               }
+       }
+
+       return 0;
+error:
+       if (feof(fp))
+               pr_warning("Source file is shorter than expected.\n");
+       else
+               pr_warning("File read error: %s\n", strerror(errno));
+
+       return -1;
+}
+
+/*
+ * Show line-range always requires debuginfo to find source file and
+ * line number.
+ */
+int show_line_range(struct line_range *lr)
+{
+       int l = 1;
+       struct line_node *ln;
+       FILE *fp;
+       int fd, ret;
+
+       /* Search a line range */
+       ret = init_vmlinux();
+       if (ret < 0)
+               return ret;
+
+       fd = open_vmlinux();
+       if (fd < 0) {
+               pr_warning("Failed to open debuginfo file.\n");
+               return fd;
+       }
+
+       ret = find_line_range(fd, lr);
+       close(fd);
+       if (ret == 0) {
+               pr_warning("Specified source line is not found.\n");
+               return -ENOENT;
+       } else if (ret < 0) {
+               pr_warning("Debuginfo analysis failed. (%d)\n", ret);
+               return ret;
+       }
+
+       setup_pager();
+
+       if (lr->function)
+               fprintf(stdout, "<%s:%d>\n", lr->function,
+                       lr->start - lr->offset);
+       else
+               fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
+
+       fp = fopen(lr->path, "r");
+       if (fp == NULL) {
+               pr_warning("Failed to open %s: %s\n", lr->path,
+                          strerror(errno));
+               return -errno;
+       }
+       /* Skip to starting line number */
+       while (l < lr->start && ret >= 0)
+               ret = show_one_line(fp, l++, true, false);
+       if (ret < 0)
+               goto end;
+
+       list_for_each_entry(ln, &lr->line_list, list) {
+               while (ln->line > l && ret >= 0)
+                       ret = show_one_line(fp, (l++) - lr->offset,
+                                           false, false);
+               if (ret >= 0)
+                       ret = show_one_line(fp, (l++) - lr->offset,
+                                           false, true);
+               if (ret < 0)
+                       goto end;
+       }
+
+       if (lr->end == INT_MAX)
+               lr->end = l + NR_ADDITIONAL_LINES;
+       while (l <= lr->end && !feof(fp) && ret >= 0)
+               ret = show_one_line(fp, (l++) - lr->offset, false, false);
+end:
+       fclose(fp);
+       return ret;
+}
+
+#else  /* !DWARF_SUPPORT */
+
+static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
+                                       struct perf_probe_point *pp)
+{
+       pp->function = strdup(tp->symbol);
+       if (pp->function == NULL)
+               return -ENOMEM;
+       pp->offset = tp->offset;
+       pp->retprobe = tp->retprobe;
+
+       return 0;
+}
+
+static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
+                               struct kprobe_trace_event **tevs __unused,
+                               int max_tevs __unused)
+{
+       if (perf_probe_event_need_dwarf(pev)) {
+               pr_warning("Debuginfo-analysis is not supported.\n");
+               return -ENOSYS;
+       }
+       return 0;
+}
+
+int show_line_range(struct line_range *lr __unused)
+{
+       pr_warning("Debuginfo-analysis is not supported.\n");
+       return -ENOSYS;
+}
+
+#endif
+
+int parse_line_range_desc(const char *arg, struct line_range *lr)
 {
        const char *ptr;
        char *tmp;
@@ -75,29 +350,45 @@ void parse_line_range_desc(const char *arg, struct line_range *lr)
         */
        ptr = strchr(arg, ':');
        if (ptr) {
-               lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
-               if (*tmp == '+')
-                       lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
-                                                                   &tmp, 0);
-               else if (*tmp == '-')
-                       lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
+               lr->start = (int)strtoul(ptr + 1, &tmp, 0);
+               if (*tmp == '+') {
+                       lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0);
+                       lr->end--;      /*
+                                        * Adjust the number of lines here.
+                                        * If the number of lines == 1, the
+                                        * the end of line should be equal to
+                                        * the start of line.
+                                        */
+               } else if (*tmp == '-')
+                       lr->end = (int)strtoul(tmp + 1, &tmp, 0);
                else
-                       lr->end = 0;
-               pr_debug("Line range is %u to %u\n", lr->start, lr->end);
-               if (lr->end && lr->start > lr->end)
+                       lr->end = INT_MAX;
+               pr_debug("Line range is %d to %d\n", lr->start, lr->end);
+               if (lr->start > lr->end) {
                        semantic_error("Start line must be smaller"
-                                      " than end line.");
-               if (*tmp != '\0')
-                       semantic_error("Tailing with invalid character '%d'.",
+                                      " than end line.\n");
+                       return -EINVAL;
+               }
+               if (*tmp != '\0') {
+                       semantic_error("Tailing with invalid character '%d'.\n",
                                       *tmp);
+                       return -EINVAL;
+               }
                tmp = strndup(arg, (ptr - arg));
-       } else
+       } else {
                tmp = strdup(arg);
+               lr->end = INT_MAX;
+       }
+
+       if (tmp == NULL)
+               return -ENOMEM;
 
        if (strchr(tmp, '.'))
                lr->file = tmp;
        else
                lr->function = tmp;
+
+       return 0;
 }
 
 /* Check the name is good for event/group */
@@ -113,8 +404,9 @@ static bool check_event_name(const char *name)
 }
 
 /* Parse probepoint definition. */
-static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
+static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
+       struct perf_probe_point *pp = &pev->point;
        char *ptr, *tmp;
        char c, nc = 0;
        /*
@@ -129,13 +421,19 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
        if (ptr && *ptr == '=') {       /* Event name */
                *ptr = '\0';
                tmp = ptr + 1;
-               ptr = strchr(arg, ':');
-               if (ptr)        /* Group name is not supported yet. */
-                       semantic_error("Group name is not supported yet.");
-               if (!check_event_name(arg))
+               if (strchr(arg, ':')) {
+                       semantic_error("Group name is not supported yet.\n");
+                       return -ENOTSUP;
+               }
+               if (!check_event_name(arg)) {
                        semantic_error("%s is bad for event name -it must "
-                                      "follow C symbol-naming rule.", arg);
-               pp->event = strdup(arg);
+                                      "follow C symbol-naming rule.\n", arg);
+                       return -EINVAL;
+               }
+               pev->event = strdup(arg);
+               if (pev->event == NULL)
+                       return -ENOMEM;
+               pev->group = NULL;
                arg = tmp;
        }
 
@@ -145,12 +443,15 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                *ptr++ = '\0';
        }
 
+       tmp = strdup(arg);
+       if (tmp == NULL)
+               return -ENOMEM;
+
        /* Check arg is function or file and copy it */
-       if (strchr(arg, '.'))   /* File */
-               pp->file = strdup(arg);
+       if (strchr(tmp, '.'))   /* File */
+               pp->file = tmp;
        else                    /* Function */
-               pp->function = strdup(arg);
-       DIE_IF(pp->file == NULL && pp->function == NULL);
+               pp->function = tmp;
 
        /* Parse other options */
        while (ptr) {
@@ -158,6 +459,8 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                c = nc;
                if (c == ';') { /* Lazy pattern must be the last part */
                        pp->lazy_line = strdup(arg);
+                       if (pp->lazy_line == NULL)
+                               return -ENOMEM;
                        break;
                }
                ptr = strpbrk(arg, ";:+@%");
@@ -168,266 +471,658 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                switch (c) {
                case ':':       /* Line number */
                        pp->line = strtoul(arg, &tmp, 0);
-                       if (*tmp != '\0')
+                       if (*tmp != '\0') {
                                semantic_error("There is non-digit char"
-                                              " in line number.");
+                                              " in line number.\n");
+                               return -EINVAL;
+                       }
                        break;
                case '+':       /* Byte offset from a symbol */
                        pp->offset = strtoul(arg, &tmp, 0);
-                       if (*tmp != '\0')
+                       if (*tmp != '\0') {
                                semantic_error("There is non-digit character"
-                                               " in offset.");
+                                               " in offset.\n");
+                               return -EINVAL;
+                       }
                        break;
                case '@':       /* File name */
-                       if (pp->file)
-                               semantic_error("SRC@SRC is not allowed.");
+                       if (pp->file) {
+                               semantic_error("SRC@SRC is not allowed.\n");
+                               return -EINVAL;
+                       }
                        pp->file = strdup(arg);
-                       DIE_IF(pp->file == NULL);
+                       if (pp->file == NULL)
+                               return -ENOMEM;
                        break;
                case '%':       /* Probe places */
                        if (strcmp(arg, "return") == 0) {
                                pp->retprobe = 1;
-                       } else  /* Others not supported yet */
-                               semantic_error("%%%s is not supported.", arg);
+                       } else {        /* Others not supported yet */
+                               semantic_error("%%%s is not supported.\n", arg);
+                               return -ENOTSUP;
+                       }
                        break;
-               default:
-                       DIE_IF("Program has a bug.");
+               default:        /* Buggy case */
+                       pr_err("This program has a bug at %s:%d.\n",
+                               __FILE__, __LINE__);
+                       return -ENOTSUP;
                        break;
                }
        }
 
        /* Exclusion check */
-       if (pp->lazy_line && pp->line)
+       if (pp->lazy_line && pp->line) {
                semantic_error("Lazy pattern can't be used with line number.");
+               return -EINVAL;
+       }
 
-       if (pp->lazy_line && pp->offset)
+       if (pp->lazy_line && pp->offset) {
                semantic_error("Lazy pattern can't be used with offset.");
+               return -EINVAL;
+       }
 
-       if (pp->line && pp->offset)
+       if (pp->line && pp->offset) {
                semantic_error("Offset can't be used with line number.");
+               return -EINVAL;
+       }
 
-       if (!pp->line && !pp->lazy_line && pp->file && !pp->function)
+       if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
                semantic_error("File always requires line number or "
                               "lazy pattern.");
+               return -EINVAL;
+       }
 
-       if (pp->offset && !pp->function)
+       if (pp->offset && !pp->function) {
                semantic_error("Offset requires an entry function.");
+               return -EINVAL;
+       }
 
-       if (pp->retprobe && !pp->function)
+       if (pp->retprobe && !pp->function) {
                semantic_error("Return probe requires an entry function.");
+               return -EINVAL;
+       }
 
-       if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe)
+       if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
                semantic_error("Offset/Line/Lazy pattern can't be used with "
                               "return probe.");
+               return -EINVAL;
+       }
 
-       pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n",
+       pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
                 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
                 pp->lazy_line);
+       return 0;
 }
 
-/* Parse perf-probe event definition */
-void parse_perf_probe_event(const char *str, struct probe_point *pp,
-                           bool *need_dwarf)
+/* Parse perf-probe event argument */
+static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
 {
-       char **argv;
-       int argc, i;
+       char *tmp;
+       struct perf_probe_arg_field **fieldp;
+
+       pr_debug("parsing arg: %s into ", str);
 
-       *need_dwarf = false;
+       tmp = strchr(str, '=');
+       if (tmp) {
+               arg->name = strndup(str, tmp - str);
+               if (arg->name == NULL)
+                       return -ENOMEM;
+               pr_debug("name:%s ", arg->name);
+               str = tmp + 1;
+       }
 
-       argv = argv_split(str, &argc);
-       if (!argv)
-               die("argv_split failed.");
-       if (argc > MAX_PROBE_ARGS + 1)
-               semantic_error("Too many arguments");
+       tmp = strchr(str, ':');
+       if (tmp) {      /* Type setting */
+               *tmp = '\0';
+               arg->type = strdup(tmp + 1);
+               if (arg->type == NULL)
+                       return -ENOMEM;
+               pr_debug("type:%s ", arg->type);
+       }
 
+       tmp = strpbrk(str, "-.");
+       if (!is_c_varname(str) || !tmp) {
+               /* A variable, register, symbol or special value */
+               arg->var = strdup(str);
+               if (arg->var == NULL)
+                       return -ENOMEM;
+               pr_debug("%s\n", arg->var);
+               return 0;
+       }
+
+       /* Structure fields */
+       arg->var = strndup(str, tmp - str);
+       if (arg->var == NULL)
+               return -ENOMEM;
+       pr_debug("%s, ", arg->var);
+       fieldp = &arg->field;
+
+       do {
+               *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
+               if (*fieldp == NULL)
+                       return -ENOMEM;
+               if (*tmp == '.') {
+                       str = tmp + 1;
+                       (*fieldp)->ref = false;
+               } else if (tmp[1] == '>') {
+                       str = tmp + 2;
+                       (*fieldp)->ref = true;
+               } else {
+                       semantic_error("Argument parse error: %s\n", str);
+                       return -EINVAL;
+               }
+
+               tmp = strpbrk(str, "-.");
+               if (tmp) {
+                       (*fieldp)->name = strndup(str, tmp - str);
+                       if ((*fieldp)->name == NULL)
+                               return -ENOMEM;
+                       pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
+                       fieldp = &(*fieldp)->next;
+               }
+       } while (tmp);
+       (*fieldp)->name = strdup(str);
+       if ((*fieldp)->name == NULL)
+               return -ENOMEM;
+       pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
+
+       /* If no name is specified, set the last field name */
+       if (!arg->name) {
+               arg->name = strdup((*fieldp)->name);
+               if (arg->name == NULL)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+/* Parse perf-probe event command */
+int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
+{
+       char **argv;
+       int argc, i, ret = 0;
+
+       argv = argv_split(cmd, &argc);
+       if (!argv) {
+               pr_debug("Failed to split arguments.\n");
+               return -ENOMEM;
+       }
+       if (argc - 1 > MAX_PROBE_ARGS) {
+               semantic_error("Too many probe arguments (%d).\n", argc - 1);
+               ret = -ERANGE;
+               goto out;
+       }
        /* Parse probe point */
-       parse_perf_probe_probepoint(argv[0], pp);
-       if (pp->file || pp->line || pp->lazy_line)
-               *need_dwarf = true;
+       ret = parse_perf_probe_point(argv[0], pev);
+       if (ret < 0)
+               goto out;
 
        /* Copy arguments and ensure return probe has no C argument */
-       pp->nr_args = argc - 1;
-       pp->args = zalloc(sizeof(char *) * pp->nr_args);
-       for (i = 0; i < pp->nr_args; i++) {
-               pp->args[i] = strdup(argv[i + 1]);
-               if (!pp->args[i])
-                       die("Failed to copy argument.");
-               if (is_c_varname(pp->args[i])) {
-                       if (pp->retprobe)
-                               semantic_error("You can't specify local"
-                                               " variable for kretprobe");
-                       *need_dwarf = true;
+       pev->nargs = argc - 1;
+       pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
+       if (pev->args == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       for (i = 0; i < pev->nargs && ret >= 0; i++) {
+               ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
+               if (ret >= 0 &&
+                   is_c_varname(pev->args[i].var) && pev->point.retprobe) {
+                       semantic_error("You can't specify local variable for"
+                                      " kretprobe.\n");
+                       ret = -EINVAL;
                }
        }
-
+out:
        argv_free(argv);
+
+       return ret;
+}
+
+/* Return true if this perf_probe_event requires debuginfo */
+bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
+{
+       int i;
+
+       if (pev->point.file || pev->point.line || pev->point.lazy_line)
+               return true;
+
+       for (i = 0; i < pev->nargs; i++)
+               if (is_c_varname(pev->args[i].var))
+                       return true;
+
+       return false;
 }
 
 /* Parse kprobe_events event into struct probe_point */
-void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
+int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
 {
+       struct kprobe_trace_point *tp = &tev->point;
        char pr;
        char *p;
        int ret, i, argc;
        char **argv;
 
-       pr_debug("Parsing kprobe_events: %s\n", str);
-       argv = argv_split(str, &argc);
-       if (!argv)
-               die("argv_split failed.");
-       if (argc < 2)
-               semantic_error("Too less arguments.");
+       pr_debug("Parsing kprobe_events: %s\n", cmd);
+       argv = argv_split(cmd, &argc);
+       if (!argv) {
+               pr_debug("Failed to split arguments.\n");
+               return -ENOMEM;
+       }
+       if (argc < 2) {
+               semantic_error("Too few probe arguments.\n");
+               ret = -ERANGE;
+               goto out;
+       }
 
        /* Scan event and group name. */
        ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
-                    &pr, (float *)(void *)&pp->group,
-                    (float *)(void *)&pp->event);
-       if (ret != 3)
-               semantic_error("Failed to parse event name: %s", argv[0]);
-       pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
+                    &pr, (float *)(void *)&tev->group,
+                    (float *)(void *)&tev->event);
+       if (ret != 3) {
+               semantic_error("Failed to parse event name: %s\n", argv[0]);
+               ret = -EINVAL;
+               goto out;
+       }
+       pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
 
-       pp->retprobe = (pr == 'r');
+       tp->retprobe = (pr == 'r');
 
        /* Scan function name and offset */
-       ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
-                    &pp->offset);
+       ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
+                    &tp->offset);
        if (ret == 1)
-               pp->offset = 0;
-
-       /* kprobe_events doesn't have this information */
-       pp->line = 0;
-       pp->file = NULL;
+               tp->offset = 0;
 
-       pp->nr_args = argc - 2;
-       pp->args = zalloc(sizeof(char *) * pp->nr_args);
-       for (i = 0; i < pp->nr_args; i++) {
+       tev->nargs = argc - 2;
+       tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
+       if (tev->args == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       for (i = 0; i < tev->nargs; i++) {
                p = strchr(argv[i + 2], '=');
                if (p)  /* We don't need which register is assigned. */
-                       *p = '\0';
-               pp->args[i] = strdup(argv[i + 2]);
-               if (!pp->args[i])
-                       die("Failed to copy argument.");
+                       *p++ = '\0';
+               else
+                       p = argv[i + 2];
+               tev->args[i].name = strdup(argv[i + 2]);
+               /* TODO: parse regs and offset */
+               tev->args[i].value = strdup(p);
+               if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
        }
-
+       ret = 0;
+out:
        argv_free(argv);
+       return ret;
 }
 
-/* Synthesize only probe point (not argument) */
-int synthesize_perf_probe_point(struct probe_point *pp)
+/* Compose only probe arg */
+int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
 {
-       char *buf;
-       char offs[64] = "", line[64] = "";
+       struct perf_probe_arg_field *field = pa->field;
        int ret;
+       char *tmp = buf;
 
-       pp->probes[0] = buf = zalloc(MAX_CMDLEN);
-       pp->found = 1;
-       if (!buf)
-               die("Failed to allocate memory by zalloc.");
+       if (pa->name && pa->var)
+               ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
+       else
+               ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
+       if (ret <= 0)
+               goto error;
+       tmp += ret;
+       len -= ret;
+
+       while (field) {
+               ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".",
+                                field->name);
+               if (ret <= 0)
+                       goto error;
+               tmp += ret;
+               len -= ret;
+               field = field->next;
+       }
+
+       if (pa->type) {
+               ret = e_snprintf(tmp, len, ":%s", pa->type);
+               if (ret <= 0)
+                       goto error;
+               tmp += ret;
+               len -= ret;
+       }
+
+       return tmp - buf;
+error:
+       pr_debug("Failed to synthesize perf probe argument: %s",
+                strerror(-ret));
+       return ret;
+}
+
+/* Compose only probe point (not argument) */
+static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
+{
+       char *buf, *tmp;
+       char offs[32] = "", line[32] = "", file[32] = "";
+       int ret, len;
+
+       buf = zalloc(MAX_CMDLEN);
+       if (buf == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
        if (pp->offset) {
-               ret = e_snprintf(offs, 64, "+%d", pp->offset);
+               ret = e_snprintf(offs, 32, "+%lu", pp->offset);
                if (ret <= 0)
                        goto error;
        }
        if (pp->line) {
-               ret = e_snprintf(line, 64, ":%d", pp->line);
+               ret = e_snprintf(line, 32, ":%d", pp->line);
+               if (ret <= 0)
+                       goto error;
+       }
+       if (pp->file) {
+               len = strlen(pp->file) - 31;
+               if (len < 0)
+                       len = 0;
+               tmp = strchr(pp->file + len, '/');
+               if (!tmp)
+                       tmp = pp->file + len;
+               ret = e_snprintf(file, 32, "@%s", tmp + 1);
                if (ret <= 0)
                        goto error;
        }
 
        if (pp->function)
-               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
-                                offs, pp->retprobe ? "%return" : "", line);
+               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
+                                offs, pp->retprobe ? "%return" : "", line,
+                                file);
        else
-               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
-       if (ret <= 0) {
+               ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
+       if (ret <= 0)
+               goto error;
+
+       return buf;
 error:
-               free(pp->probes[0]);
-               pp->probes[0] = NULL;
-               pp->found = 0;
-       }
-       return ret;
+       pr_debug("Failed to synthesize perf probe point: %s",
+                strerror(-ret));
+       if (buf)
+               free(buf);
+       return NULL;
 }
 
-int synthesize_perf_probe_event(struct probe_point *pp)
+#if 0
+char *synthesize_perf_probe_command(struct perf_probe_event *pev)
 {
        char *buf;
        int i, len, ret;
 
-       len = synthesize_perf_probe_point(pp);
-       if (len < 0)
-               return 0;
+       buf = synthesize_perf_probe_point(&pev->point);
+       if (!buf)
+               return NULL;
 
-       buf = pp->probes[0];
-       for (i = 0; i < pp->nr_args; i++) {
+       len = strlen(buf);
+       for (i = 0; i < pev->nargs; i++) {
                ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
-                                pp->args[i]);
-               if (ret <= 0)
-                       goto error;
+                                pev->args[i].name);
+               if (ret <= 0) {
+                       free(buf);
+                       return NULL;
+               }
                len += ret;
        }
-       pp->found = 1;
 
-       return pp->found;
-error:
-       free(pp->probes[0]);
-       pp->probes[0] = NULL;
+       return buf;
+}
+#endif
+
+static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
+                                            char **buf, size_t *buflen,
+                                            int depth)
+{
+       int ret;
+       if (ref->next) {
+               depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
+                                                        buflen, depth + 1);
+               if (depth < 0)
+                       goto out;
+       }
+
+       ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
+       if (ret < 0)
+               depth = ret;
+       else {
+               *buf += ret;
+               *buflen -= ret;
+       }
+out:
+       return depth;
 
-       return ret;
 }
 
-int synthesize_trace_kprobe_event(struct probe_point *pp)
+static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
+                                      char *buf, size_t buflen)
 {
+       int ret, depth = 0;
+       char *tmp = buf;
+
+       /* Argument name or separator */
+       if (arg->name)
+               ret = e_snprintf(buf, buflen, " %s=", arg->name);
+       else
+               ret = e_snprintf(buf, buflen, " ");
+       if (ret < 0)
+               return ret;
+       buf += ret;
+       buflen -= ret;
+
+       /* Dereferencing arguments */
+       if (arg->ref) {
+               depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
+                                                         &buflen, 1);
+               if (depth < 0)
+                       return depth;
+       }
+
+       /* Print argument value */
+       ret = e_snprintf(buf, buflen, "%s", arg->value);
+       if (ret < 0)
+               return ret;
+       buf += ret;
+       buflen -= ret;
+
+       /* Closing */
+       while (depth--) {
+               ret = e_snprintf(buf, buflen, ")");
+               if (ret < 0)
+                       return ret;
+               buf += ret;
+               buflen -= ret;
+       }
+       /* Print argument type */
+       if (arg->type) {
+               ret = e_snprintf(buf, buflen, ":%s", arg->type);
+               if (ret <= 0)
+                       return ret;
+               buf += ret;
+       }
+
+       return buf - tmp;
+}
+
+char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
+{
+       struct kprobe_trace_point *tp = &tev->point;
        char *buf;
        int i, len, ret;
 
-       pp->probes[0] = buf = zalloc(MAX_CMDLEN);
-       if (!buf)
-               die("Failed to allocate memory by zalloc.");
-       ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
-       if (ret <= 0)
+       buf = zalloc(MAX_CMDLEN);
+       if (buf == NULL)
+               return NULL;
+
+       len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
+                        tp->retprobe ? 'r' : 'p',
+                        tev->group, tev->event,
+                        tp->symbol, tp->offset);
+       if (len <= 0)
                goto error;
-       len = ret;
 
-       for (i = 0; i < pp->nr_args; i++) {
-               ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
-                                pp->args[i]);
+       for (i = 0; i < tev->nargs; i++) {
+               ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
+                                                 MAX_CMDLEN - len);
                if (ret <= 0)
                        goto error;
                len += ret;
        }
-       pp->found = 1;
 
-       return pp->found;
+       return buf;
 error:
-       free(pp->probes[0]);
-       pp->probes[0] = NULL;
+       free(buf);
+       return NULL;
+}
+
+int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
+                               struct perf_probe_event *pev)
+{
+       char buf[64] = "";
+       int i, ret;
+
+       /* Convert event/group name */
+       pev->event = strdup(tev->event);
+       pev->group = strdup(tev->group);
+       if (pev->event == NULL || pev->group == NULL)
+               return -ENOMEM;
+
+       /* Convert trace_point to probe_point */
+       ret = convert_to_perf_probe_point(&tev->point, &pev->point);
+       if (ret < 0)
+               return ret;
+
+       /* Convert trace_arg to probe_arg */
+       pev->nargs = tev->nargs;
+       pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
+       if (pev->args == NULL)
+               return -ENOMEM;
+       for (i = 0; i < tev->nargs && ret >= 0; i++) {
+               if (tev->args[i].name)
+                       pev->args[i].name = strdup(tev->args[i].name);
+               else {
+                       ret = synthesize_kprobe_trace_arg(&tev->args[i],
+                                                         buf, 64);
+                       pev->args[i].name = strdup(buf);
+               }
+               if (pev->args[i].name == NULL && ret >= 0)
+                       ret = -ENOMEM;
+       }
+
+       if (ret < 0)
+               clear_perf_probe_event(pev);
 
        return ret;
 }
 
-static int open_kprobe_events(int flags, int mode)
+void clear_perf_probe_event(struct perf_probe_event *pev)
+{
+       struct perf_probe_point *pp = &pev->point;
+       struct perf_probe_arg_field *field, *next;
+       int i;
+
+       if (pev->event)
+               free(pev->event);
+       if (pev->group)
+               free(pev->group);
+       if (pp->file)
+               free(pp->file);
+       if (pp->function)
+               free(pp->function);
+       if (pp->lazy_line)
+               free(pp->lazy_line);
+       for (i = 0; i < pev->nargs; i++) {
+               if (pev->args[i].name)
+                       free(pev->args[i].name);
+               if (pev->args[i].var)
+                       free(pev->args[i].var);
+               if (pev->args[i].type)
+                       free(pev->args[i].type);
+               field = pev->args[i].field;
+               while (field) {
+                       next = field->next;
+                       if (field->name)
+                               free(field->name);
+                       free(field);
+                       field = next;
+               }
+       }
+       if (pev->args)
+               free(pev->args);
+       memset(pev, 0, sizeof(*pev));
+}
+
+void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
+{
+       struct kprobe_trace_arg_ref *ref, *next;
+       int i;
+
+       if (tev->event)
+               free(tev->event);
+       if (tev->group)
+               free(tev->group);
+       if (tev->point.symbol)
+               free(tev->point.symbol);
+       for (i = 0; i < tev->nargs; i++) {
+               if (tev->args[i].name)
+                       free(tev->args[i].name);
+               if (tev->args[i].value)
+                       free(tev->args[i].value);
+               if (tev->args[i].type)
+                       free(tev->args[i].type);
+               ref = tev->args[i].ref;
+               while (ref) {
+                       next = ref->next;
+                       free(ref);
+                       ref = next;
+               }
+       }
+       if (tev->args)
+               free(tev->args);
+       memset(tev, 0, sizeof(*tev));
+}
+
+static int open_kprobe_events(bool readwrite)
 {
        char buf[PATH_MAX];
+       const char *__debugfs;
        int ret;
 
-       ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
-       if (ret < 0)
-               die("Failed to make kprobe_events path.");
+       __debugfs = debugfs_find_mountpoint();
+       if (__debugfs == NULL) {
+               pr_warning("Debugfs is not mounted.\n");
+               return -ENOENT;
+       }
+
+       ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
+       if (ret >= 0) {
+               pr_debug("Opening %s write=%d\n", buf, readwrite);
+               if (readwrite && !probe_event_dry_run)
+                       ret = open(buf, O_RDWR, O_APPEND);
+               else
+                       ret = open(buf, O_RDONLY, 0);
+       }
 
-       ret = open(buf, flags, mode);
        if (ret < 0) {
                if (errno == ENOENT)
-                       die("kprobe_events file does not exist -"
-                           " please rebuild with CONFIG_KPROBE_EVENT.");
+                       pr_warning("kprobe_events file does not exist - please"
+                                " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
                else
-                       die("Could not open kprobe_events file: %s",
-                           strerror(errno));
+                       pr_warning("Failed to open kprobe_events file: %s\n",
+                                  strerror(errno));
        }
        return ret;
 }
 
 /* Get raw string list of current kprobe_events */
-static struct strlist *get_trace_kprobe_event_rawlist(int fd)
+static struct strlist *get_kprobe_trace_command_rawlist(int fd)
 {
        int ret, idx;
        FILE *fp;
@@ -447,271 +1142,486 @@ static struct strlist *get_trace_kprobe_event_rawlist(int fd)
                if (p[idx] == '\n')
                        p[idx] = '\0';
                ret = strlist__add(sl, buf);
-               if (ret < 0)
-                       die("strlist__add failed: %s", strerror(-ret));
+               if (ret < 0) {
+                       pr_debug("strlist__add failed: %s\n", strerror(-ret));
+                       strlist__delete(sl);
+                       return NULL;
+               }
        }
        fclose(fp);
 
        return sl;
 }
 
-/* Free and zero clear probe_point */
-static void clear_probe_point(struct probe_point *pp)
-{
-       int i;
-
-       if (pp->event)
-               free(pp->event);
-       if (pp->group)
-               free(pp->group);
-       if (pp->function)
-               free(pp->function);
-       if (pp->file)
-               free(pp->file);
-       if (pp->lazy_line)
-               free(pp->lazy_line);
-       for (i = 0; i < pp->nr_args; i++)
-               free(pp->args[i]);
-       if (pp->args)
-               free(pp->args);
-       for (i = 0; i < pp->found; i++)
-               free(pp->probes[i]);
-       memset(pp, 0, sizeof(*pp));
-}
-
 /* Show an event */
-static void show_perf_probe_event(const char *event, const char *place,
-                                 struct probe_point *pp)
+static int show_perf_probe_event(struct perf_probe_event *pev)
 {
        int i, ret;
        char buf[128];
+       char *place;
+
+       /* Synthesize only event probe point */
+       place = synthesize_perf_probe_point(&pev->point);
+       if (!place)
+               return -EINVAL;
 
-       ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
+       ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
        if (ret < 0)
-               die("Failed to copy event: %s", strerror(-ret));
-       printf("  %-40s (on %s", buf, place);
+               return ret;
+
+       printf("  %-20s (on %s", buf, place);
 
-       if (pp->nr_args > 0) {
+       if (pev->nargs > 0) {
                printf(" with");
-               for (i = 0; i < pp->nr_args; i++)
-                       printf(" %s", pp->args[i]);
+               for (i = 0; i < pev->nargs; i++) {
+                       ret = synthesize_perf_probe_arg(&pev->args[i],
+                                                       buf, 128);
+                       if (ret < 0)
+                               break;
+                       printf(" %s", buf);
+               }
        }
        printf(")\n");
+       free(place);
+       return ret;
 }
 
 /* List up current perf-probe events */
-void show_perf_probe_events(void)
+int show_perf_probe_events(void)
 {
-       int fd;
-       struct probe_point pp;
+       int fd, ret;
+       struct kprobe_trace_event tev;
+       struct perf_probe_event pev;
        struct strlist *rawlist;
        struct str_node *ent;
 
        setup_pager();
-       memset(&pp, 0, sizeof(pp));
+       ret = init_vmlinux();
+       if (ret < 0)
+               return ret;
+
+       memset(&tev, 0, sizeof(tev));
+       memset(&pev, 0, sizeof(pev));
 
-       fd = open_kprobe_events(O_RDONLY, 0);
-       rawlist = get_trace_kprobe_event_rawlist(fd);
+       fd = open_kprobe_events(false);
+       if (fd < 0)
+               return fd;
+
+       rawlist = get_kprobe_trace_command_rawlist(fd);
        close(fd);
+       if (!rawlist)
+               return -ENOENT;
 
        strlist__for_each(ent, rawlist) {
-               parse_trace_kprobe_event(ent->s, &pp);
-               /* Synthesize only event probe point */
-               synthesize_perf_probe_point(&pp);
-               /* Show an event */
-               show_perf_probe_event(pp.event, pp.probes[0], &pp);
-               clear_probe_point(&pp);
+               ret = parse_kprobe_trace_command(ent->s, &tev);
+               if (ret >= 0) {
+                       ret = convert_to_perf_probe_event(&tev, &pev);
+                       if (ret >= 0)
+                               ret = show_perf_probe_event(&pev);
+               }
+               clear_perf_probe_event(&pev);
+               clear_kprobe_trace_event(&tev);
+               if (ret < 0)
+                       break;
        }
-
        strlist__delete(rawlist);
+
+       return ret;
 }
 
 /* Get current perf-probe event names */
-static struct strlist *get_perf_event_names(int fd, bool include_group)
+static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
 {
        char buf[128];
        struct strlist *sl, *rawlist;
        struct str_node *ent;
-       struct probe_point pp;
+       struct kprobe_trace_event tev;
+       int ret = 0;
 
-       memset(&pp, 0, sizeof(pp));
-       rawlist = get_trace_kprobe_event_rawlist(fd);
+       memset(&tev, 0, sizeof(tev));
 
+       rawlist = get_kprobe_trace_command_rawlist(fd);
        sl = strlist__new(true, NULL);
        strlist__for_each(ent, rawlist) {
-               parse_trace_kprobe_event(ent->s, &pp);
+               ret = parse_kprobe_trace_command(ent->s, &tev);
+               if (ret < 0)
+                       break;
                if (include_group) {
-                       if (e_snprintf(buf, 128, "%s:%s", pp.group,
-                                      pp.event) < 0)
-                               die("Failed to copy group:event name.");
-                       strlist__add(sl, buf);
+                       ret = e_snprintf(buf, 128, "%s:%s", tev.group,
+                                       tev.event);
+                       if (ret >= 0)
+                               ret = strlist__add(sl, buf);
                } else
-                       strlist__add(sl, pp.event);
-               clear_probe_point(&pp);
+                       ret = strlist__add(sl, tev.event);
+               clear_kprobe_trace_event(&tev);
+               if (ret < 0)
+                       break;
        }
-
        strlist__delete(rawlist);
 
+       if (ret < 0) {
+               strlist__delete(sl);
+               return NULL;
+       }
        return sl;
 }
 
-static void write_trace_kprobe_event(int fd, const char *buf)
+static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
 {
-       int ret;
+       int ret = 0;
+       char *buf = synthesize_kprobe_trace_command(tev);
+
+       if (!buf) {
+               pr_debug("Failed to synthesize kprobe trace event.\n");
+               return -EINVAL;
+       }
 
        pr_debug("Writing event: %s\n", buf);
-       ret = write(fd, buf, strlen(buf));
-       if (ret <= 0)
-               die("Failed to write event: %s", strerror(errno));
+       if (!probe_event_dry_run) {
+               ret = write(fd, buf, strlen(buf));
+               if (ret <= 0)
+                       pr_warning("Failed to write event: %s\n",
+                                  strerror(errno));
+       }
+       free(buf);
+       return ret;
 }
 
-static void get_new_event_name(char *buf, size_t len, const char *base,
-                              struct strlist *namelist, bool allow_suffix)
+static int get_new_event_name(char *buf, size_t len, const char *base,
+                             struct strlist *namelist, bool allow_suffix)
 {
        int i, ret;
 
        /* Try no suffix */
        ret = e_snprintf(buf, len, "%s", base);
-       if (ret < 0)
-               die("snprintf() failed: %s", strerror(-ret));
+       if (ret < 0) {
+               pr_debug("snprintf() failed: %s\n", strerror(-ret));
+               return ret;
+       }
        if (!strlist__has_entry(namelist, buf))
-               return;
+               return 0;
 
        if (!allow_suffix) {
                pr_warning("Error: event \"%s\" already exists. "
                           "(Use -f to force duplicates.)\n", base);
-               die("Can't add new event.");
+               return -EEXIST;
        }
 
        /* Try to add suffix */
        for (i = 1; i < MAX_EVENT_INDEX; i++) {
                ret = e_snprintf(buf, len, "%s_%d", base, i);
-               if (ret < 0)
-                       die("snprintf() failed: %s", strerror(-ret));
+               if (ret < 0) {
+                       pr_debug("snprintf() failed: %s\n", strerror(-ret));
+                       return ret;
+               }
                if (!strlist__has_entry(namelist, buf))
                        break;
        }
-       if (i == MAX_EVENT_INDEX)
-               die("Too many events are on the same function.");
+       if (i == MAX_EVENT_INDEX) {
+               pr_warning("Too many events are on the same function.\n");
+               ret = -ERANGE;
+       }
+
+       return ret;
 }
 
-void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
-                            bool force_add)
+static int __add_kprobe_trace_events(struct perf_probe_event *pev,
+                                    struct kprobe_trace_event *tevs,
+                                    int ntevs, bool allow_suffix)
 {
-       int i, j, fd;
-       struct probe_point *pp;
-       char buf[MAX_CMDLEN];
-       char event[64];
+       int i, fd, ret;
+       struct kprobe_trace_event *tev = NULL;
+       char buf[64];
+       const char *event, *group;
        struct strlist *namelist;
-       bool allow_suffix;
 
-       fd = open_kprobe_events(O_RDWR, O_APPEND);
+       fd = open_kprobe_events(true);
+       if (fd < 0)
+               return fd;
        /* Get current event names */
-       namelist = get_perf_event_names(fd, false);
-
-       for (j = 0; j < nr_probes; j++) {
-               pp = probes + j;
-               if (!pp->event)
-                       pp->event = strdup(pp->function);
-               if (!pp->group)
-                       pp->group = strdup(PERFPROBE_GROUP);
-               DIE_IF(!pp->event || !pp->group);
-               /* If force_add is true, suffix search is allowed */
-               allow_suffix = force_add;
-               for (i = 0; i < pp->found; i++) {
-                       /* Get an unused new event name */
-                       get_new_event_name(event, 64, pp->event, namelist,
-                                          allow_suffix);
-                       snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
-                                pp->retprobe ? 'r' : 'p',
-                                pp->group, event,
-                                pp->probes[i]);
-                       write_trace_kprobe_event(fd, buf);
-                       printf("Added new event:\n");
-                       /* Get the first parameter (probe-point) */
-                       sscanf(pp->probes[i], "%s", buf);
-                       show_perf_probe_event(event, buf, pp);
-                       /* Add added event name to namelist */
-                       strlist__add(namelist, event);
-                       /*
-                        * Probes after the first probe which comes from same
-                        * user input are always allowed to add suffix, because
-                        * there might be several addresses corresponding to
-                        * one code line.
-                        */
-                       allow_suffix = true;
+       namelist = get_kprobe_trace_event_names(fd, false);
+       if (!namelist) {
+               pr_debug("Failed to get current event list.\n");
+               return -EIO;
+       }
+
+       ret = 0;
+       printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
+       for (i = 0; i < ntevs; i++) {
+               tev = &tevs[i];
+               if (pev->event)
+                       event = pev->event;
+               else
+                       if (pev->point.function)
+                               event = pev->point.function;
+                       else
+                               event = tev->point.symbol;
+               if (pev->group)
+                       group = pev->group;
+               else
+                       group = PERFPROBE_GROUP;
+
+               /* Get an unused new event name */
+               ret = get_new_event_name(buf, 64, event,
+                                        namelist, allow_suffix);
+               if (ret < 0)
+                       break;
+               event = buf;
+
+               tev->event = strdup(event);
+               tev->group = strdup(group);
+               if (tev->event == NULL || tev->group == NULL) {
+                       ret = -ENOMEM;
+                       break;
                }
+               ret = write_kprobe_trace_event(fd, tev);
+               if (ret < 0)
+                       break;
+               /* Add added event name to namelist */
+               strlist__add(namelist, event);
+
+               /* Trick here - save current event/group */
+               event = pev->event;
+               group = pev->group;
+               pev->event = tev->event;
+               pev->group = tev->group;
+               show_perf_probe_event(pev);
+               /* Trick here - restore current event/group */
+               pev->event = (char *)event;
+               pev->group = (char *)group;
+
+               /*
+                * Probes after the first probe which comes from same
+                * user input are always allowed to add suffix, because
+                * there might be several addresses corresponding to
+                * one code line.
+                */
+               allow_suffix = true;
+       }
+
+       if (ret >= 0) {
+               /* Show how to use the event. */
+               printf("\nYou can now use it on all perf tools, such as:\n\n");
+               printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
+                        tev->event);
        }
-       /* Show how to use the event. */
-       printf("\nYou can now use it on all perf tools, such as:\n\n");
-       printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
 
        strlist__delete(namelist);
        close(fd);
+       return ret;
+}
+
+static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
+                                         struct kprobe_trace_event **tevs,
+                                         int max_tevs)
+{
+       struct symbol *sym;
+       int ret = 0, i;
+       struct kprobe_trace_event *tev;
+
+       /* Convert perf_probe_event with debuginfo */
+       ret = try_to_find_kprobe_trace_events(pev, tevs, max_tevs);
+       if (ret != 0)
+               return ret;
+
+       /* Allocate trace event buffer */
+       tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
+       if (tev == NULL)
+               return -ENOMEM;
+
+       /* Copy parameters */
+       tev->point.symbol = strdup(pev->point.function);
+       if (tev->point.symbol == NULL) {
+               ret = -ENOMEM;
+               goto error;
+       }
+       tev->point.offset = pev->point.offset;
+       tev->nargs = pev->nargs;
+       if (tev->nargs) {
+               tev->args = zalloc(sizeof(struct kprobe_trace_arg)
+                                  * tev->nargs);
+               if (tev->args == NULL) {
+                       ret = -ENOMEM;
+                       goto error;
+               }
+               for (i = 0; i < tev->nargs; i++) {
+                       if (pev->args[i].name) {
+                               tev->args[i].name = strdup(pev->args[i].name);
+                               if (tev->args[i].name == NULL) {
+                                       ret = -ENOMEM;
+                                       goto error;
+                               }
+                       }
+                       tev->args[i].value = strdup(pev->args[i].var);
+                       if (tev->args[i].value == NULL) {
+                               ret = -ENOMEM;
+                               goto error;
+                       }
+                       if (pev->args[i].type) {
+                               tev->args[i].type = strdup(pev->args[i].type);
+                               if (tev->args[i].type == NULL) {
+                                       ret = -ENOMEM;
+                                       goto error;
+                               }
+                       }
+               }
+       }
+
+       /* Currently just checking function name from symbol map */
+       sym = map__find_symbol_by_name(machine.vmlinux_maps[MAP__FUNCTION],
+                                      tev->point.symbol, NULL);
+       if (!sym) {
+               pr_warning("Kernel symbol \'%s\' not found.\n",
+                          tev->point.symbol);
+               ret = -ENOENT;
+               goto error;
+       }
+
+       return 1;
+error:
+       clear_kprobe_trace_event(tev);
+       free(tev);
+       *tevs = NULL;
+       return ret;
+}
+
+struct __event_package {
+       struct perf_probe_event         *pev;
+       struct kprobe_trace_event       *tevs;
+       int                             ntevs;
+};
+
+int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
+                         bool force_add, int max_tevs)
+{
+       int i, j, ret;
+       struct __event_package *pkgs;
+
+       pkgs = zalloc(sizeof(struct __event_package) * npevs);
+       if (pkgs == NULL)
+               return -ENOMEM;
+
+       /* Init vmlinux path */
+       ret = init_vmlinux();
+       if (ret < 0)
+               return ret;
+
+       /* Loop 1: convert all events */
+       for (i = 0; i < npevs; i++) {
+               pkgs[i].pev = &pevs[i];
+               /* Convert with or without debuginfo */
+               ret  = convert_to_kprobe_trace_events(pkgs[i].pev,
+                                                     &pkgs[i].tevs, max_tevs);
+               if (ret < 0)
+                       goto end;
+               pkgs[i].ntevs = ret;
+       }
+
+       /* Loop 2: add all events */
+       for (i = 0; i < npevs && ret >= 0; i++)
+               ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
+                                               pkgs[i].ntevs, force_add);
+end:
+       /* Loop 3: cleanup trace events  */
+       for (i = 0; i < npevs; i++)
+               for (j = 0; j < pkgs[i].ntevs; j++)
+                       clear_kprobe_trace_event(&pkgs[i].tevs[j]);
+
+       return ret;
 }
 
-static void __del_trace_kprobe_event(int fd, struct str_node *ent)
+static int __del_trace_kprobe_event(int fd, struct str_node *ent)
 {
        char *p;
        char buf[128];
+       int ret;
 
        /* Convert from perf-probe event to trace-kprobe event */
-       if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
-               die("Failed to copy event.");
+       ret = e_snprintf(buf, 128, "-:%s", ent->s);
+       if (ret < 0)
+               goto error;
+
        p = strchr(buf + 2, ':');
-       if (!p)
-               die("Internal error: %s should have ':' but not.", ent->s);
+       if (!p) {
+               pr_debug("Internal error: %s should have ':' but not.\n",
+                        ent->s);
+               ret = -ENOTSUP;
+               goto error;
+       }
        *p = '/';
 
-       write_trace_kprobe_event(fd, buf);
+       pr_debug("Writing event: %s\n", buf);
+       ret = write(fd, buf, strlen(buf));
+       if (ret < 0)
+               goto error;
+
        printf("Remove event: %s\n", ent->s);
+       return 0;
+error:
+       pr_warning("Failed to delete event: %s\n", strerror(-ret));
+       return ret;
 }
 
-static void del_trace_kprobe_event(int fd, const char *group,
-                                  const char *event, struct strlist *namelist)
+static int del_trace_kprobe_event(int fd, const char *group,
+                                 const char *event, struct strlist *namelist)
 {
        char buf[128];
        struct str_node *ent, *n;
-       int found = 0;
+       int found = 0, ret = 0;
 
-       if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
-               die("Failed to copy event.");
+       ret = e_snprintf(buf, 128, "%s:%s", group, event);
+       if (ret < 0) {
+               pr_err("Failed to copy event.");
+               return ret;
+       }
 
        if (strpbrk(buf, "*?")) { /* Glob-exp */
                strlist__for_each_safe(ent, n, namelist)
                        if (strglobmatch(ent->s, buf)) {
                                found++;
-                               __del_trace_kprobe_event(fd, ent);
+                               ret = __del_trace_kprobe_event(fd, ent);
+                               if (ret < 0)
+                                       break;
                                strlist__remove(namelist, ent);
                        }
        } else {
                ent = strlist__find(namelist, buf);
                if (ent) {
                        found++;
-                       __del_trace_kprobe_event(fd, ent);
-                       strlist__remove(namelist, ent);
+                       ret = __del_trace_kprobe_event(fd, ent);
+                       if (ret >= 0)
+                               strlist__remove(namelist, ent);
                }
        }
-       if (found == 0)
-               pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
+       if (found == 0 && ret >= 0)
+               pr_info("Info: Event \"%s\" does not exist.\n", buf);
+
+       return ret;
 }
 
-void del_trace_kprobe_events(struct strlist *dellist)
+int del_perf_probe_events(struct strlist *dellist)
 {
-       int fd;
+       int fd, ret = 0;
        const char *group, *event;
        char *p, *str;
        struct str_node *ent;
        struct strlist *namelist;
 
-       fd = open_kprobe_events(O_RDWR, O_APPEND);
+       fd = open_kprobe_events(true);
+       if (fd < 0)
+               return fd;
+
        /* Get current event names */
-       namelist = get_perf_event_names(fd, true);
+       namelist = get_kprobe_trace_event_names(fd, true);
+       if (namelist == NULL)
+               return -EINVAL;
 
        strlist__for_each(ent, dellist) {
                str = strdup(ent->s);
-               if (!str)
-                       die("Failed to copy event.");
+               if (str == NULL) {
+                       ret = -ENOMEM;
+                       break;
+               }
                pr_debug("Parsing: %s\n", str);
                p = strchr(str, ':');
                if (p) {
@@ -723,80 +1633,14 @@ void del_trace_kprobe_events(struct strlist *dellist)
                        event = str;
                }
                pr_debug("Group: %s, Event: %s\n", group, event);
-               del_trace_kprobe_event(fd, group, event, namelist);
+               ret = del_trace_kprobe_event(fd, group, event, namelist);
                free(str);
+               if (ret < 0)
+                       break;
        }
        strlist__delete(namelist);
        close(fd);
-}
 
-#define LINEBUF_SIZE 256
-#define NR_ADDITIONAL_LINES 2
-
-static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
-{
-       char buf[LINEBUF_SIZE];
-       const char *color = PERF_COLOR_BLUE;
-
-       if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-               goto error;
-       if (!skip) {
-               if (show_num)
-                       fprintf(stdout, "%7u  %s", l, buf);
-               else
-                       color_fprintf(stdout, color, "         %s", buf);
-       }
-
-       while (strlen(buf) == LINEBUF_SIZE - 1 &&
-              buf[LINEBUF_SIZE - 2] != '\n') {
-               if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
-                       goto error;
-               if (!skip) {
-                       if (show_num)
-                               fprintf(stdout, "%s", buf);
-                       else
-                               color_fprintf(stdout, color, "%s", buf);
-               }
-       }
-       return;
-error:
-       if (feof(fp))
-               die("Source file is shorter than expected.");
-       else
-               die("File read error: %s", strerror(errno));
+       return ret;
 }
 
-void show_line_range(struct line_range *lr)
-{
-       unsigned int l = 1;
-       struct line_node *ln;
-       FILE *fp;
-
-       setup_pager();
-
-       if (lr->function)
-               fprintf(stdout, "<%s:%d>\n", lr->function,
-                       lr->start - lr->offset);
-       else
-               fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
-
-       fp = fopen(lr->path, "r");
-       if (fp == NULL)
-               die("Failed to open %s: %s", lr->path, strerror(errno));
-       /* Skip to starting line number */
-       while (l < lr->start)
-               show_one_line(fp, l++, true, false);
-
-       list_for_each_entry(ln, &lr->line_list, list) {
-               while (ln->line > l)
-                       show_one_line(fp, (l++) - lr->offset, false, false);
-               show_one_line(fp, (l++) - lr->offset, false, true);
-       }
-
-       if (lr->end == INT_MAX)
-               lr->end = l + NR_ADDITIONAL_LINES;
-       while (l < lr->end && !feof(fp))
-               show_one_line(fp, (l++) - lr->offset, false, false);
-
-       fclose(fp);
-}
index 711287d..e9db1a2 100644 (file)
 #define _PROBE_EVENT_H
 
 #include <stdbool.h>
-#include "probe-finder.h"
 #include "strlist.h"
 
-extern void parse_line_range_desc(const char *arg, struct line_range *lr);
-extern void parse_perf_probe_event(const char *str, struct probe_point *pp,
-                                  bool *need_dwarf);
-extern int synthesize_perf_probe_point(struct probe_point *pp);
-extern int synthesize_perf_probe_event(struct probe_point *pp);
-extern void parse_trace_kprobe_event(const char *str, struct probe_point *pp);
-extern int synthesize_trace_kprobe_event(struct probe_point *pp);
-extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
-                                   bool force_add);
-extern void del_trace_kprobe_events(struct strlist *dellist);
-extern void show_perf_probe_events(void);
-extern void show_line_range(struct line_range *lr);
+extern bool probe_event_dry_run;
+
+/* kprobe-tracer tracing point */
+struct kprobe_trace_point {
+       char            *symbol;        /* Base symbol */
+       unsigned long   offset;         /* Offset from symbol */
+       bool            retprobe;       /* Return probe flag */
+};
+
+/* kprobe-tracer tracing argument referencing offset */
+struct kprobe_trace_arg_ref {
+       struct kprobe_trace_arg_ref     *next;  /* Next reference */
+       long                            offset; /* Offset value */
+};
+
+/* kprobe-tracer tracing argument */
+struct kprobe_trace_arg {
+       char                            *name;  /* Argument name */
+       char                            *value; /* Base value */
+       char                            *type;  /* Type name */
+       struct kprobe_trace_arg_ref     *ref;   /* Referencing offset */
+};
+
+/* kprobe-tracer tracing event (point + arg) */
+struct kprobe_trace_event {
+       char                            *event; /* Event name */
+       char                            *group; /* Group name */
+       struct kprobe_trace_point       point;  /* Trace point */
+       int                             nargs;  /* Number of args */
+       struct kprobe_trace_arg         *args;  /* Arguments */
+};
+
+/* Perf probe probing point */
+struct perf_probe_point {
+       char            *file;          /* File path */
+       char            *function;      /* Function name */
+       int             line;           /* Line number */
+       bool            retprobe;       /* Return probe flag */
+       char            *lazy_line;     /* Lazy matching pattern */
+       unsigned long   offset;         /* Offset from function entry */
+};
+
+/* Perf probe probing argument field chain */
+struct perf_probe_arg_field {
+       struct perf_probe_arg_field     *next;  /* Next field */
+       char                            *name;  /* Name of the field */
+       bool                            ref;    /* Referencing flag */
+};
+
+/* Perf probe probing argument */
+struct perf_probe_arg {
+       char                            *name;  /* Argument name */
+       char                            *var;   /* Variable name */
+       char                            *type;  /* Type name */
+       struct perf_probe_arg_field     *field; /* Structure fields */
+};
+
+/* Perf probe probing event (point + arg) */
+struct perf_probe_event {
+       char                    *event; /* Event name */
+       char                    *group; /* Group name */
+       struct perf_probe_point point;  /* Probe point */
+       int                     nargs;  /* Number of arguments */
+       struct perf_probe_arg   *args;  /* Arguments */
+};
+
+
+/* Line number container */
+struct line_node {
+       struct list_head        list;
+       int                     line;
+};
+
+/* Line range */
+struct line_range {
+       char                    *file;          /* File name */
+       char                    *function;      /* Function name */
+       int                     start;          /* Start line number */
+       int                     end;            /* End line number */
+       int                     offset;         /* Start line offset */
+       char                    *path;          /* Real path name */
+       struct list_head        line_list;      /* Visible lines */
+};
+
+/* Command string to events */
+extern int parse_perf_probe_command(const char *cmd,
+                                   struct perf_probe_event *pev);
+extern int parse_kprobe_trace_command(const char *cmd,
+                                     struct kprobe_trace_event *tev);
+
+/* Events to command string */
+extern char *synthesize_perf_probe_command(struct perf_probe_event *pev);
+extern char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev);
+extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf,
+                                    size_t len);
+
+/* Check the perf_probe_event needs debuginfo */
+extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
+
+/* Convert from kprobe_trace_event to perf_probe_event */
+extern int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
+                                      struct perf_probe_event *pev);
+
+/* Release event contents */
+extern void clear_perf_probe_event(struct perf_probe_event *pev);
+extern void clear_kprobe_trace_event(struct kprobe_trace_event *tev);
+
+/* Command string to line-range */
+extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
+
+
+extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
+                                bool force_add, int max_probe_points);
+extern int del_perf_probe_events(struct strlist *dellist);
+extern int show_perf_probe_events(void);
+extern int show_line_range(struct line_range *lr);
+
 
 /* Maximum index number of event-name postfix */
 #define MAX_EVENT_INDEX        1024
index c171a24..562b144 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <ctype.h>
+#include <dwarf-regs.h>
 
 #include "string.h"
 #include "event.h"
 #include "util.h"
 #include "probe-finder.h"
 
-
-/*
- * Generic dwarf analysis helpers
- */
-
-#define X86_32_MAX_REGS 8
-const char *x86_32_regs_table[X86_32_MAX_REGS] = {
-       "%ax",
-       "%cx",
-       "%dx",
-       "%bx",
-       "$stack",       /* Stack address instead of %sp */
-       "%bp",
-       "%si",
-       "%di",
-};
-
-#define X86_64_MAX_REGS 16
-const char *x86_64_regs_table[X86_64_MAX_REGS] = {
-       "%ax",
-       "%dx",
-       "%cx",
-       "%bx",
-       "%si",
-       "%di",
-       "%bp",
-       "%sp",
-       "%r8",
-       "%r9",
-       "%r10",
-       "%r11",
-       "%r12",
-       "%r13",
-       "%r14",
-       "%r15",
-};
-
-/* TODO: switching by dwarf address size */
-#ifdef __x86_64__
-#define ARCH_MAX_REGS X86_64_MAX_REGS
-#define arch_regs_table x86_64_regs_table
-#else
-#define ARCH_MAX_REGS X86_32_MAX_REGS
-#define arch_regs_table x86_32_regs_table
-#endif
-
-/* Return architecture dependent register string (for kprobe-tracer) */
-static const char *get_arch_regstr(unsigned int n)
-{
-       return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
-}
+/* Kprobe tracer basic type is up to u64 */
+#define MAX_BASIC_TYPE_BITS    64
 
 /*
  * Compare the tail of two strings.
@@ -108,7 +60,7 @@ static int strtailcmp(const char *s1, const char *s2)
 /* Line number list operations */
 
 /* Add a line to line number list */
-static void line_list__add_line(struct list_head *head, unsigned int line)
+static int line_list__add_line(struct list_head *head, int line)
 {
        struct line_node *ln;
        struct list_head *p;
@@ -119,21 +71,23 @@ static void line_list__add_line(struct list_head *head, unsigned int line)
                        p = &ln->list;
                        goto found;
                } else if (ln->line == line)    /* Already exist */
-                       return ;
+                       return 1;
        }
        /* List is empty, or the smallest entry */
        p = head;
 found:
        pr_debug("line list: add a line %u\n", line);
        ln = zalloc(sizeof(struct line_node));
-       DIE_IF(ln == NULL);
+       if (ln == NULL)
+               return -ENOMEM;
        ln->line = line;
        INIT_LIST_HEAD(&ln->list);
        list_add(&ln->list, p);
+       return 0;
 }
 
 /* Check if the line in line number list */
-static int line_list__has_line(struct list_head *head, unsigned int line)
+static int line_list__has_line(struct list_head *head, int line)
 {
        struct line_node *ln;
 
@@ -184,9 +138,129 @@ static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
                if (strtailcmp(src, fname) == 0)
                        break;
        }
+       if (i == nfiles)
+               return NULL;
        return src;
 }
 
+/* Compare diename and tname */
+static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
+{
+       const char *name;
+       name = dwarf_diename(dw_die);
+       return name ? strcmp(tname, name) : -1;
+}
+
+/* Get type die, but skip qualifiers and typedef */
+static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
+{
+       Dwarf_Attribute attr;
+       int tag;
+
+       do {
+               if (dwarf_attr(vr_die, DW_AT_type, &attr) == NULL ||
+                   dwarf_formref_die(&attr, die_mem) == NULL)
+                       return NULL;
+
+               tag = dwarf_tag(die_mem);
+               vr_die = die_mem;
+       } while (tag == DW_TAG_const_type ||
+                tag == DW_TAG_restrict_type ||
+                tag == DW_TAG_volatile_type ||
+                tag == DW_TAG_shared_type ||
+                tag == DW_TAG_typedef);
+
+       return die_mem;
+}
+
+static bool die_is_signed_type(Dwarf_Die *tp_die)
+{
+       Dwarf_Attribute attr;
+       Dwarf_Word ret;
+
+       if (dwarf_attr(tp_die, DW_AT_encoding, &attr) == NULL ||
+           dwarf_formudata(&attr, &ret) != 0)
+               return false;
+
+       return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
+               ret == DW_ATE_signed_fixed);
+}
+
+static int die_get_byte_size(Dwarf_Die *tp_die)
+{
+       Dwarf_Attribute attr;
+       Dwarf_Word ret;
+
+       if (dwarf_attr(tp_die, DW_AT_byte_size, &attr) == NULL ||
+           dwarf_formudata(&attr, &ret) != 0)
+               return 0;
+
+       return (int)ret;
+}
+
+/* Get data_member_location offset */
+static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
+{
+       Dwarf_Attribute attr;
+       Dwarf_Op *expr;
+       size_t nexpr;
+       int ret;
+
+       if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
+               return -ENOENT;
+
+       if (dwarf_formudata(&attr, offs) != 0) {
+               /* DW_AT_data_member_location should be DW_OP_plus_uconst */
+               ret = dwarf_getlocation(&attr, &expr, &nexpr);
+               if (ret < 0 || nexpr == 0)
+                       return -ENOENT;
+
+               if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
+                       pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
+                                expr[0].atom, nexpr);
+                       return -ENOTSUP;
+               }
+               *offs = (Dwarf_Word)expr[0].number;
+       }
+       return 0;
+}
+
+/* Return values for die_find callbacks */
+enum {
+       DIE_FIND_CB_FOUND = 0,          /* End of Search */
+       DIE_FIND_CB_CHILD = 1,          /* Search only children */
+       DIE_FIND_CB_SIBLING = 2,        /* Search only siblings */
+       DIE_FIND_CB_CONTINUE = 3,       /* Search children and siblings */
+};
+
+/* Search a child die */
+static Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
+                                int (*callback)(Dwarf_Die *, void *),
+                                void *data, Dwarf_Die *die_mem)
+{
+       Dwarf_Die child_die;
+       int ret;
+
+       ret = dwarf_child(rt_die, die_mem);
+       if (ret != 0)
+               return NULL;
+
+       do {
+               ret = callback(die_mem, data);
+               if (ret == DIE_FIND_CB_FOUND)
+                       return die_mem;
+
+               if ((ret & DIE_FIND_CB_CHILD) &&
+                   die_find_child(die_mem, callback, data, &child_die)) {
+                       memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
+                       return die_mem;
+               }
+       } while ((ret & DIE_FIND_CB_SIBLING) &&
+                dwarf_siblingof(die_mem, die_mem) == 0);
+
+       return NULL;
+}
+
 struct __addr_die_search_param {
        Dwarf_Addr      addr;
        Dwarf_Die       *die_mem;
@@ -205,8 +279,8 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
 }
 
 /* Search a real subprogram including this line, */
-static Dwarf_Die *die_get_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
-                                         Dwarf_Die *die_mem)
+static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
+                                          Dwarf_Die *die_mem)
 {
        struct __addr_die_search_param ad;
        ad.addr = addr;
@@ -218,77 +292,64 @@ static Dwarf_Die *die_get_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
                return die_mem;
 }
 
-/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
-static Dwarf_Die *die_get_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
-                                    Dwarf_Die *die_mem)
+/* die_find callback for inline function search */
+static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
 {
-       Dwarf_Die child_die;
-       int ret;
+       Dwarf_Addr *addr = data;
 
-       ret = dwarf_child(sp_die, die_mem);
-       if (ret != 0)
-               return NULL;
+       if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
+           dwarf_haspc(die_mem, *addr))
+               return DIE_FIND_CB_FOUND;
 
-       do {
-               if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
-                   dwarf_haspc(die_mem, addr))
-                       return die_mem;
-
-               if (die_get_inlinefunc(die_mem, addr, &child_die)) {
-                       memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
-                       return die_mem;
-               }
-       } while (dwarf_siblingof(die_mem, die_mem) == 0);
-
-       return NULL;
+       return DIE_FIND_CB_CONTINUE;
 }
 
-/* Compare diename and tname */
-static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
+/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
+static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
+                                     Dwarf_Die *die_mem)
 {
-       const char *name;
-       name = dwarf_diename(dw_die);
-       DIE_IF(name == NULL);
-       return strcmp(tname, name);
+       return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
 }
 
-/* Get entry pc(or low pc, 1st entry of ranges)  of the die */
-static Dwarf_Addr die_get_entrypc(Dwarf_Die *dw_die)
+static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
 {
-       Dwarf_Addr epc;
-       int ret;
+       const char *name = data;
+       int tag;
 
-       ret = dwarf_entrypc(dw_die, &epc);
-       DIE_IF(ret == -1);
-       return epc;
+       tag = dwarf_tag(die_mem);
+       if ((tag == DW_TAG_formal_parameter ||
+            tag == DW_TAG_variable) &&
+           (die_compare_name(die_mem, name) == 0))
+               return DIE_FIND_CB_FOUND;
+
+       return DIE_FIND_CB_CONTINUE;
 }
 
-/* Get a variable die */
+/* Find a variable called 'name' */
 static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name,
                                    Dwarf_Die *die_mem)
 {
-       Dwarf_Die child_die;
-       int tag;
-       int ret;
+       return die_find_child(sp_die, __die_find_variable_cb, (void *)name,
+                             die_mem);
+}
 
-       ret = dwarf_child(sp_die, die_mem);
-       if (ret != 0)
-               return NULL;
+static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
+{
+       const char *name = data;
 
-       do {
-               tag = dwarf_tag(die_mem);
-               if ((tag == DW_TAG_formal_parameter ||
-                    tag == DW_TAG_variable) &&
-                   (die_compare_name(die_mem, name) == 0))
-                       return die_mem;
+       if ((dwarf_tag(die_mem) == DW_TAG_member) &&
+           (die_compare_name(die_mem, name) == 0))
+               return DIE_FIND_CB_FOUND;
 
-               if (die_find_variable(die_mem, name, &child_die)) {
-                       memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
-                       return die_mem;
-               }
-       } while (dwarf_siblingof(die_mem, die_mem) == 0);
+       return DIE_FIND_CB_SIBLING;
+}
 
-       return NULL;
+/* Find a member called 'name' */
+static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
+                                 Dwarf_Die *die_mem)
+{
+       return die_find_child(st_die, __die_find_member_cb, (void *)name,
+                             die_mem);
 }
 
 /*
@@ -296,19 +357,22 @@ static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name,
  */
 
 /* Show a location */
-static void show_location(Dwarf_Op *op, struct probe_finder *pf)
+static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
 {
        unsigned int regn;
        Dwarf_Word offs = 0;
-       int deref = 0, ret;
+       bool ref = false;
        const char *regs;
+       struct kprobe_trace_arg *tvar = pf->tvar;
 
-       /* TODO: support CFA */
        /* If this is based on frame buffer, set the offset */
        if (op->atom == DW_OP_fbreg) {
-               if (pf->fb_ops == NULL)
-                       die("The attribute of frame base is not supported.\n");
-               deref = 1;
+               if (pf->fb_ops == NULL) {
+                       pr_warning("The attribute of frame base is not "
+                                  "supported.\n");
+                       return -ENOTSUP;
+               }
+               ref = true;
                offs = op->number;
                op = &pf->fb_ops[0];
        }
@@ -316,35 +380,164 @@ static void show_location(Dwarf_Op *op, struct probe_finder *pf)
        if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
                regn = op->atom - DW_OP_breg0;
                offs += op->number;
-               deref = 1;
+               ref = true;
        } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
                regn = op->atom - DW_OP_reg0;
        } else if (op->atom == DW_OP_bregx) {
                regn = op->number;
                offs += op->number2;
-               deref = 1;
+               ref = true;
        } else if (op->atom == DW_OP_regx) {
                regn = op->number;
-       } else
-               die("DW_OP %d is not supported.", op->atom);
+       } else {
+               pr_warning("DW_OP %x is not supported.\n", op->atom);
+               return -ENOTSUP;
+       }
 
        regs = get_arch_regstr(regn);
-       if (!regs)
-               die("%u exceeds max register number.", regn);
+       if (!regs) {
+               pr_warning("Mapping for DWARF register number %u missing on this architecture.", regn);
+               return -ERANGE;
+       }
+
+       tvar->value = strdup(regs);
+       if (tvar->value == NULL)
+               return -ENOMEM;
+
+       if (ref) {
+               tvar->ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
+               if (tvar->ref == NULL)
+                       return -ENOMEM;
+               tvar->ref->offset = (long)offs;
+       }
+       return 0;
+}
+
+static int convert_variable_type(Dwarf_Die *vr_die,
+                                struct kprobe_trace_arg *targ)
+{
+       Dwarf_Die type;
+       char buf[16];
+       int ret;
+
+       if (die_get_real_type(vr_die, &type) == NULL) {
+               pr_warning("Failed to get a type information of %s.\n",
+                          dwarf_diename(vr_die));
+               return -ENOENT;
+       }
+
+       ret = die_get_byte_size(&type) * 8;
+       if (ret) {
+               /* Check the bitwidth */
+               if (ret > MAX_BASIC_TYPE_BITS) {
+                       pr_info("%s exceeds max-bitwidth."
+                               " Cut down to %d bits.\n",
+                               dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
+                       ret = MAX_BASIC_TYPE_BITS;
+               }
+
+               ret = snprintf(buf, 16, "%c%d",
+                              die_is_signed_type(&type) ? 's' : 'u', ret);
+               if (ret < 0 || ret >= 16) {
+                       if (ret >= 16)
+                               ret = -E2BIG;
+                       pr_warning("Failed to convert variable type: %s\n",
+                                  strerror(-ret));
+                       return ret;
+               }
+               targ->type = strdup(buf);
+               if (targ->type == NULL)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
+                                   struct perf_probe_arg_field *field,
+                                   struct kprobe_trace_arg_ref **ref_ptr,
+                                   Dwarf_Die *die_mem)
+{
+       struct kprobe_trace_arg_ref *ref = *ref_ptr;
+       Dwarf_Die type;
+       Dwarf_Word offs;
+       int ret;
+
+       pr_debug("converting %s in %s\n", field->name, varname);
+       if (die_get_real_type(vr_die, &type) == NULL) {
+               pr_warning("Failed to get the type of %s.\n", varname);
+               return -ENOENT;
+       }
+
+       /* Check the pointer and dereference */
+       if (dwarf_tag(&type) == DW_TAG_pointer_type) {
+               if (!field->ref) {
+                       pr_err("Semantic error: %s must be referred by '->'\n",
+                              field->name);
+                       return -EINVAL;
+               }
+               /* Get the type pointed by this pointer */
+               if (die_get_real_type(&type, &type) == NULL) {
+                       pr_warning("Failed to get the type of %s.\n", varname);
+                       return -ENOENT;
+               }
+               /* Verify it is a data structure  */
+               if (dwarf_tag(&type) != DW_TAG_structure_type) {
+                       pr_warning("%s is not a data structure.\n", varname);
+                       return -EINVAL;
+               }
+
+               ref = zalloc(sizeof(struct kprobe_trace_arg_ref));
+               if (ref == NULL)
+                       return -ENOMEM;
+               if (*ref_ptr)
+                       (*ref_ptr)->next = ref;
+               else
+                       *ref_ptr = ref;
+       } else {
+               /* Verify it is a data structure  */
+               if (dwarf_tag(&type) != DW_TAG_structure_type) {
+                       pr_warning("%s is not a data structure.\n", varname);
+                       return -EINVAL;
+               }
+               if (field->ref) {
+                       pr_err("Semantic error: %s must be referred by '.'\n",
+                              field->name);
+                       return -EINVAL;
+               }
+               if (!ref) {
+                       pr_warning("Structure on a register is not "
+                                  "supported yet.\n");
+                       return -ENOTSUP;
+               }
+       }
+
+       if (die_find_member(&type, field->name, die_mem) == NULL) {
+               pr_warning("%s(tyep:%s) has no member %s.\n", varname,
+                          dwarf_diename(&type), field->name);
+               return -EINVAL;
+       }
 
-       if (deref)
-               ret = snprintf(pf->buf, pf->len, " %s=%+jd(%s)",
-                              pf->var, (intmax_t)offs, regs);
+       /* Get the offset of the field */
+       ret = die_get_data_member_location(die_mem, &offs);
+       if (ret < 0) {
+               pr_warning("Failed to get the offset of %s.\n", field->name);
+               return ret;
+       }
+       ref->offset += (long)offs;
+
+       /* Converting next field */
+       if (field->next)
+               return convert_variable_fields(die_mem, field->name,
+                                       field->next, &ref, die_mem);
        else
-               ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs);
-       DIE_IF(ret < 0);
-       DIE_IF(ret >= pf->len);
+               return 0;
 }
 
 /* Show a variables in kprobe event format */
-static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
+static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 {
        Dwarf_Attribute attr;
+       Dwarf_Die die_mem;
        Dwarf_Op *expr;
        size_t nexpr;
        int ret;
@@ -356,142 +549,191 @@ static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
        if (ret <= 0 || nexpr == 0)
                goto error;
 
-       show_location(expr, pf);
+       ret = convert_location(expr, pf);
+       if (ret == 0 && pf->pvar->field) {
+               ret = convert_variable_fields(vr_die, pf->pvar->var,
+                                             pf->pvar->field, &pf->tvar->ref,
+                                             &die_mem);
+               vr_die = &die_mem;
+       }
+       if (ret == 0) {
+               if (pf->pvar->type) {
+                       pf->tvar->type = strdup(pf->pvar->type);
+                       if (pf->tvar->type == NULL)
+                               ret = -ENOMEM;
+               } else
+                       ret = convert_variable_type(vr_die, pf->tvar);
+       }
        /* *expr will be cached in libdw. Don't free it. */
-       return ;
+       return ret;
 error:
        /* TODO: Support const_value */
-       die("Failed to find the location of %s at this address.\n"
-           " Perhaps, it has been optimized out.", pf->var);
+       pr_err("Failed to find the location of %s at this address.\n"
+              " Perhaps, it has been optimized out.\n", pf->pvar->var);
+       return -ENOENT;
 }
 
 /* Find a variable in a subprogram die */
-static void find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
+static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
-       int ret;
        Dwarf_Die vr_die;
+       char buf[32], *ptr;
+       int ret;
 
-       /* TODO: Support struct members and arrays */
-       if (!is_c_varname(pf->var)) {
-               /* Output raw parameters */
-               ret = snprintf(pf->buf, pf->len, " %s", pf->var);
-               DIE_IF(ret < 0);
-               DIE_IF(ret >= pf->len);
-               return ;
+       /* TODO: Support arrays */
+       if (pf->pvar->name)
+               pf->tvar->name = strdup(pf->pvar->name);
+       else {
+               ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
+               if (ret < 0)
+                       return ret;
+               ptr = strchr(buf, ':'); /* Change type separator to _ */
+               if (ptr)
+                       *ptr = '_';
+               pf->tvar->name = strdup(buf);
+       }
+       if (pf->tvar->name == NULL)
+               return -ENOMEM;
+
+       if (!is_c_varname(pf->pvar->var)) {
+               /* Copy raw parameters */
+               pf->tvar->value = strdup(pf->pvar->var);
+               if (pf->tvar->value == NULL)
+                       return -ENOMEM;
+               else
+                       return 0;
        }
 
-       pr_debug("Searching '%s' variable in context.\n", pf->var);
+       pr_debug("Searching '%s' variable in context.\n",
+                pf->pvar->var);
        /* Search child die for local variables and parameters. */
-       if (!die_find_variable(sp_die, pf->var, &vr_die))
-               die("Failed to find '%s' in this function.", pf->var);
-
-       show_variable(&vr_die, pf);
+       if (!die_find_variable(sp_die, pf->pvar->var, &vr_die)) {
+               pr_warning("Failed to find '%s' in this function.\n",
+                          pf->pvar->var);
+               return -ENOENT;
+       }
+       return convert_variable(&vr_die, pf);
 }
 
 /* Show a probe point to output buffer */
-static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
+static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
-       struct probe_point *pp = pf->pp;
+       struct kprobe_trace_event *tev;
        Dwarf_Addr eaddr;
        Dwarf_Die die_mem;
        const char *name;
-       char tmp[MAX_PROBE_BUFFER];
-       int ret, i, len;
+       int ret, i;
        Dwarf_Attribute fb_attr;
        size_t nops;
 
+       if (pf->ntevs == pf->max_tevs) {
+               pr_warning("Too many( > %d) probe point found.\n",
+                          pf->max_tevs);
+               return -ERANGE;
+       }
+       tev = &pf->tevs[pf->ntevs++];
+
        /* If no real subprogram, find a real one */
        if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
-               sp_die = die_get_real_subprogram(&pf->cu_die,
+               sp_die = die_find_real_subprogram(&pf->cu_die,
                                                 pf->addr, &die_mem);
-               if (!sp_die)
-                       die("Probe point is not found in subprograms.");
+               if (!sp_die) {
+                       pr_warning("Failed to find probe point in any "
+                                  "functions.\n");
+                       return -ENOENT;
+               }
        }
 
-       /* Output name of probe point */
+       /* Copy the name of probe point */
        name = dwarf_diename(sp_die);
        if (name) {
-               dwarf_entrypc(sp_die, &eaddr);
-               ret = snprintf(tmp, MAX_PROBE_BUFFER, "%s+%lu", name,
-                               (unsigned long)(pf->addr - eaddr));
-               /* Copy the function name if possible */
-               if (!pp->function) {
-                       pp->function = strdup(name);
-                       pp->offset = (size_t)(pf->addr - eaddr);
+               if (dwarf_entrypc(sp_die, &eaddr) != 0) {
+                       pr_warning("Failed to get entry pc of %s\n",
+                                  dwarf_diename(sp_die));
+                       return -ENOENT;
                }
-       } else {
+               tev->point.symbol = strdup(name);
+               if (tev->point.symbol == NULL)
+                       return -ENOMEM;
+               tev->point.offset = (unsigned long)(pf->addr - eaddr);
+       } else
                /* This function has no name. */
-               ret = snprintf(tmp, MAX_PROBE_BUFFER, "0x%jx",
-                              (uintmax_t)pf->addr);
-               if (!pp->function) {
-                       /* TODO: Use _stext */
-                       pp->function = strdup("");
-                       pp->offset = (size_t)pf->addr;
-               }
-       }
-       DIE_IF(ret < 0);
-       DIE_IF(ret >= MAX_PROBE_BUFFER);
-       len = ret;
-       pr_debug("Probe point found: %s\n", tmp);
+               tev->point.offset = (unsigned long)pf->addr;
+
+       pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
+                tev->point.offset);
 
        /* Get the frame base attribute/ops */
        dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
        ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
-       if (ret <= 0 || nops == 0)
+       if (ret <= 0 || nops == 0) {
                pf->fb_ops = NULL;
+       } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
+                  pf->cfi != NULL) {
+               Dwarf_Frame *frame;
+               if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
+                   dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
+                       pr_warning("Failed to get CFA on 0x%jx\n",
+                                  (uintmax_t)pf->addr);
+                       return -ENOENT;
+               }
+       }
 
        /* Find each argument */
-       /* TODO: use dwarf_cfi_addrframe */
-       for (i = 0; i < pp->nr_args; i++) {
-               pf->var = pp->args[i];
-               pf->buf = &tmp[len];
-               pf->len = MAX_PROBE_BUFFER - len;
-               find_variable(sp_die, pf);
-               len += strlen(pf->buf);
+       tev->nargs = pf->pev->nargs;
+       tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
+       if (tev->args == NULL)
+               return -ENOMEM;
+       for (i = 0; i < pf->pev->nargs; i++) {
+               pf->pvar = &pf->pev->args[i];
+               pf->tvar = &tev->args[i];
+               ret = find_variable(sp_die, pf);
+               if (ret != 0)
+                       return ret;
        }
 
        /* *pf->fb_ops will be cached in libdw. Don't free it. */
        pf->fb_ops = NULL;
-
-       if (pp->found == MAX_PROBES)
-               die("Too many( > %d) probe point found.\n", MAX_PROBES);
-
-       pp->probes[pp->found] = strdup(tmp);
-       pp->found++;
+       return 0;
 }
 
 /* Find probe point from its line number */
-static void find_probe_point_by_line(struct probe_finder *pf)
+static int find_probe_point_by_line(struct probe_finder *pf)
 {
        Dwarf_Lines *lines;
        Dwarf_Line *line;
        size_t nlines, i;
        Dwarf_Addr addr;
        int lineno;
-       int ret;
+       int ret = 0;
 
-       ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines);
-       DIE_IF(ret != 0);
+       if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
+               pr_warning("No source lines found in this CU.\n");
+               return -ENOENT;
+       }
 
-       for (i = 0; i < nlines; i++) {
+       for (i = 0; i < nlines && ret == 0; i++) {
                line = dwarf_onesrcline(lines, i);
-               dwarf_lineno(line, &lineno);
-               if (lineno != pf->lno)
+               if (dwarf_lineno(line, &lineno) != 0 ||
+                   lineno != pf->lno)
                        continue;
 
                /* TODO: Get fileno from line, but how? */
                if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
                        continue;
 
-               ret = dwarf_lineaddr(line, &addr);
-               DIE_IF(ret != 0);
+               if (dwarf_lineaddr(line, &addr) != 0) {
+                       pr_warning("Failed to get the address of the line.\n");
+                       return -ENOENT;
+               }
                pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n",
                         (int)i, lineno, (uintmax_t)addr);
                pf->addr = addr;
 
-               show_probe_point(NULL, pf);
+               ret = convert_probe_point(NULL, pf);
                /* Continuing, because target line might be inlined. */
        }
+       return ret;
 }
 
 /* Find lines which match lazy pattern */
@@ -499,16 +741,27 @@ static int find_lazy_match_lines(struct list_head *head,
                                 const char *fname, const char *pat)
 {
        char *fbuf, *p1, *p2;
-       int fd, line, nlines = 0;
+       int fd, ret, line, nlines = 0;
        struct stat st;
 
        fd = open(fname, O_RDONLY);
-       if (fd < 0)
-               die("failed to open %s", fname);
-       DIE_IF(fstat(fd, &st) < 0);
-       fbuf = malloc(st.st_size + 2);
-       DIE_IF(fbuf == NULL);
-       DIE_IF(read(fd, fbuf, st.st_size) < 0);
+       if (fd < 0) {
+               pr_warning("Failed to open %s: %s\n", fname, strerror(-fd));
+               return fd;
+       }
+
+       ret = fstat(fd, &st);
+       if (ret < 0) {
+               pr_warning("Failed to get the size of %s: %s\n",
+                          fname, strerror(errno));
+               return ret;
+       }
+       fbuf = xmalloc(st.st_size + 2);
+       ret = read(fd, fbuf, st.st_size);
+       if (ret < 0) {
+               pr_warning("Failed to read %s: %s\n", fname, strerror(errno));
+               return ret;
+       }
        close(fd);
        fbuf[st.st_size] = '\n';        /* Dummy line */
        fbuf[st.st_size + 1] = '\0';
@@ -528,7 +781,7 @@ static int find_lazy_match_lines(struct list_head *head,
 }
 
 /* Find probe points from lazy pattern  */
-static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
+static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
 {
        Dwarf_Lines *lines;
        Dwarf_Line *line;
@@ -536,37 +789,46 @@ static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
        Dwarf_Addr addr;
        Dwarf_Die die_mem;
        int lineno;
-       int ret;
+       int ret = 0;
 
        if (list_empty(&pf->lcache)) {
                /* Matching lazy line pattern */
                ret = find_lazy_match_lines(&pf->lcache, pf->fname,
-                                           pf->pp->lazy_line);
-               if (ret <= 0)
-                       die("No matched lines found in %s.", pf->fname);
+                                           pf->pev->point.lazy_line);
+               if (ret == 0) {
+                       pr_debug("No matched lines found in %s.\n", pf->fname);
+                       return 0;
+               } else if (ret < 0)
+                       return ret;
        }
 
-       ret = dwarf_getsrclines(&pf->cu_die, &lines, &nlines);
-       DIE_IF(ret != 0);
-       for (i = 0; i < nlines; i++) {
+       if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
+               pr_warning("No source lines found in this CU.\n");
+               return -ENOENT;
+       }
+
+       for (i = 0; i < nlines && ret >= 0; i++) {
                line = dwarf_onesrcline(lines, i);
 
-               dwarf_lineno(line, &lineno);
-               if (!line_list__has_line(&pf->lcache, lineno))
+               if (dwarf_lineno(line, &lineno) != 0 ||
+                   !line_list__has_line(&pf->lcache, lineno))
                        continue;
 
                /* TODO: Get fileno from line, but how? */
                if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
                        continue;
 
-               ret = dwarf_lineaddr(line, &addr);
-               DIE_IF(ret != 0);
+               if (dwarf_lineaddr(line, &addr) != 0) {
+                       pr_debug("Failed to get the address of line %d.\n",
+                                lineno);
+                       continue;
+               }
                if (sp_die) {
                        /* Address filtering 1: does sp_die include addr? */
                        if (!dwarf_haspc(sp_die, addr))
                                continue;
                        /* Address filtering 2: No child include addr? */
-                       if (die_get_inlinefunc(sp_die, addr, &die_mem))
+                       if (die_find_inlinefunc(sp_die, addr, &die_mem))
                                continue;
                }
 
@@ -574,27 +836,44 @@ static void find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
                         (int)i, lineno, (unsigned long long)addr);
                pf->addr = addr;
 
-               show_probe_point(sp_die, pf);
+               ret = convert_probe_point(sp_die, pf);
                /* Continuing, because target line might be inlined. */
        }
        /* TODO: deallocate lines, but how? */
+       return ret;
 }
 
+/* Callback parameter with return value */
+struct dwarf_callback_param {
+       void *data;
+       int retval;
+};
+
 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
 {
-       struct probe_finder *pf = (struct probe_finder *)data;
-       struct probe_point *pp = pf->pp;
+       struct dwarf_callback_param *param = data;
+       struct probe_finder *pf = param->data;
+       struct perf_probe_point *pp = &pf->pev->point;
+       Dwarf_Addr addr;
 
        if (pp->lazy_line)
-               find_probe_point_lazy(in_die, pf);
+               param->retval = find_probe_point_lazy(in_die, pf);
        else {
                /* Get probe address */
-               pf->addr = die_get_entrypc(in_die);
+               if (dwarf_entrypc(in_die, &addr) != 0) {
+                       pr_warning("Failed to get entry pc of %s.\n",
+                                  dwarf_diename(in_die));
+                       param->retval = -ENOENT;
+                       return DWARF_CB_ABORT;
+               }
+               pf->addr = addr;
                pf->addr += pp->offset;
                pr_debug("found inline addr: 0x%jx\n",
                         (uintmax_t)pf->addr);
 
-               show_probe_point(in_die, pf);
+               param->retval = convert_probe_point(in_die, pf);
+               if (param->retval < 0)
+                       return DWARF_CB_ABORT;
        }
 
        return DWARF_CB_OK;
@@ -603,59 +882,88 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
 /* Search function from function name */
 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 {
-       struct probe_finder *pf = (struct probe_finder *)data;
-       struct probe_point *pp = pf->pp;
+       struct dwarf_callback_param *param = data;
+       struct probe_finder *pf = param->data;
+       struct perf_probe_point *pp = &pf->pev->point;
 
        /* Check tag and diename */
        if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
            die_compare_name(sp_die, pp->function) != 0)
-               return 0;
+               return DWARF_CB_OK;
 
        pf->fname = dwarf_decl_file(sp_die);
        if (pp->line) { /* Function relative line */
                dwarf_decl_line(sp_die, &pf->lno);
                pf->lno += pp->line;
-               find_probe_point_by_line(pf);
+               param->retval = find_probe_point_by_line(pf);
        } else if (!dwarf_func_inline(sp_die)) {
                /* Real function */
                if (pp->lazy_line)
-                       find_probe_point_lazy(sp_die, pf);
+                       param->retval = find_probe_point_lazy(sp_die, pf);
                else {
-                       pf->addr = die_get_entrypc(sp_die);
+                       if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
+                               pr_warning("Failed to get entry pc of %s.\n",
+                                          dwarf_diename(sp_die));
+                               param->retval = -ENOENT;
+                               return DWARF_CB_ABORT;
+                       }
                        pf->addr += pp->offset;
                        /* TODO: Check the address in this function */
-                       show_probe_point(sp_die, pf);
+                       param->retval = convert_probe_point(sp_die, pf);
                }
-       } else
+       } else {
+               struct dwarf_callback_param _param = {.data = (void *)pf,
+                                                     .retval = 0};
                /* Inlined function: search instances */
-               dwarf_func_inline_instances(sp_die, probe_point_inline_cb, pf);
+               dwarf_func_inline_instances(sp_die, probe_point_inline_cb,
+                                           &_param);
+               param->retval = _param.retval;
+       }
 
-       return 1; /* Exit; no same symbol in this CU. */
+       return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
 }
 
-static void find_probe_point_by_func(struct probe_finder *pf)
+static int find_probe_point_by_func(struct probe_finder *pf)
 {
-       dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, pf, 0);
+       struct dwarf_callback_param _param = {.data = (void *)pf,
+                                             .retval = 0};
+       dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
+       return _param.retval;
 }
 
-/* Find a probe point */
-int find_probe_point(int fd, struct probe_point *pp)
+/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
+int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
+                            struct kprobe_trace_event **tevs, int max_tevs)
 {
-       struct probe_finder pf = {.pp = pp};
+       struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs};
+       struct perf_probe_point *pp = &pev->point;
        Dwarf_Off off, noff;
        size_t cuhl;
        Dwarf_Die *diep;
        Dwarf *dbg;
+       int ret = 0;
+
+       pf.tevs = zalloc(sizeof(struct kprobe_trace_event) * max_tevs);
+       if (pf.tevs == NULL)
+               return -ENOMEM;
+       *tevs = pf.tevs;
+       pf.ntevs = 0;
 
        dbg = dwarf_begin(fd, DWARF_C_READ);
-       if (!dbg)
-               return -ENOENT;
+       if (!dbg) {
+               pr_warning("No dwarf info found in the vmlinux - "
+                       "please rebuild with CONFIG_DEBUG_INFO=y.\n");
+               return -EBADF;
+       }
+
+       /* Get the call frame information from this dwarf */
+       pf.cfi = dwarf_getcfi(dbg);
 
-       pp->found = 0;
        off = 0;
        line_list__init(&pf.lcache);
        /* Loop on CUs (Compilation Unit) */
-       while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
+       while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) &&
+              ret >= 0) {
                /* Get the DIE(Debugging Information Entry) of this CU */
                diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die);
                if (!diep)
@@ -669,12 +977,12 @@ int find_probe_point(int fd, struct probe_point *pp)
 
                if (!pp->file || pf.fname) {
                        if (pp->function)
-                               find_probe_point_by_func(&pf);
+                               ret = find_probe_point_by_func(&pf);
                        else if (pp->lazy_line)
-                               find_probe_point_lazy(NULL, &pf);
+                               ret = find_probe_point_lazy(NULL, &pf);
                        else {
                                pf.lno = pp->line;
-                               find_probe_point_by_line(&pf);
+                               ret = find_probe_point_by_line(&pf);
                        }
                }
                off = noff;
@@ -682,41 +990,169 @@ int find_probe_point(int fd, struct probe_point *pp)
        line_list__free(&pf.lcache);
        dwarf_end(dbg);
 
-       return pp->found;
+       return (ret < 0) ? ret : pf.ntevs;
+}
+
+/* Reverse search */
+int find_perf_probe_point(int fd, unsigned long addr,
+                         struct perf_probe_point *ppt)
+{
+       Dwarf_Die cudie, spdie, indie;
+       Dwarf *dbg;
+       Dwarf_Line *line;
+       Dwarf_Addr laddr, eaddr;
+       const char *tmp;
+       int lineno, ret = 0;
+       bool found = false;
+
+       dbg = dwarf_begin(fd, DWARF_C_READ);
+       if (!dbg)
+               return -EBADF;
+
+       /* Find cu die */
+       if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr, &cudie)) {
+               ret = -EINVAL;
+               goto end;
+       }
+
+       /* Find a corresponding line */
+       line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
+       if (line) {
+               if (dwarf_lineaddr(line, &laddr) == 0 &&
+                   (Dwarf_Addr)addr == laddr &&
+                   dwarf_lineno(line, &lineno) == 0) {
+                       tmp = dwarf_linesrc(line, NULL, NULL);
+                       if (tmp) {
+                               ppt->line = lineno;
+                               ppt->file = strdup(tmp);
+                               if (ppt->file == NULL) {
+                                       ret = -ENOMEM;
+                                       goto end;
+                               }
+                               found = true;
+                       }
+               }
+       }
+
+       /* Find a corresponding function */
+       if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
+               tmp = dwarf_diename(&spdie);
+               if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
+                       goto end;
+
+               if (ppt->line) {
+                       if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
+                                               &indie)) {
+                               /* addr in an inline function */
+                               tmp = dwarf_diename(&indie);
+                               if (!tmp)
+                                       goto end;
+                               ret = dwarf_decl_line(&indie, &lineno);
+                       } else {
+                               if (eaddr == addr) {    /* Function entry */
+                                       lineno = ppt->line;
+                                       ret = 0;
+                               } else
+                                       ret = dwarf_decl_line(&spdie, &lineno);
+                       }
+                       if (ret == 0) {
+                               /* Make a relative line number */
+                               ppt->line -= lineno;
+                               goto found;
+                       }
+               }
+               /* We don't have a line number, let's use offset */
+               ppt->offset = addr - (unsigned long)eaddr;
+found:
+               ppt->function = strdup(tmp);
+               if (ppt->function == NULL) {
+                       ret = -ENOMEM;
+                       goto end;
+               }
+               found = true;
+       }
+
+end:
+       dwarf_end(dbg);
+       if (ret >= 0)
+               ret = found ? 1 : 0;
+       return ret;
+}
+
+/* Add a line and store the src path */
+static int line_range_add_line(const char *src, unsigned int lineno,
+                              struct line_range *lr)
+{
+       /* Copy real path */
+       if (!lr->path) {
+               lr->path = strdup(src);
+               if (lr->path == NULL)
+                       return -ENOMEM;
+       }
+       return line_list__add_line(&lr->line_list, lineno);
+}
+
+/* Search function declaration lines */
+static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data)
+{
+       struct dwarf_callback_param *param = data;
+       struct line_finder *lf = param->data;
+       const char *src;
+       int lineno;
+
+       src = dwarf_decl_file(sp_die);
+       if (src && strtailcmp(src, lf->fname) != 0)
+               return DWARF_CB_OK;
+
+       if (dwarf_decl_line(sp_die, &lineno) != 0 ||
+           (lf->lno_s > lineno || lf->lno_e < lineno))
+               return DWARF_CB_OK;
+
+       param->retval = line_range_add_line(src, lineno, lf->lr);
+       if (param->retval < 0)
+               return DWARF_CB_ABORT;
+       return DWARF_CB_OK;
+}
+
+static int find_line_range_func_decl_lines(struct line_finder *lf)
+{
+       struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
+       dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, &param, 0);
+       return param.retval;
 }
 
 /* Find line range from its line number */
-static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
+static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
 {
        Dwarf_Lines *lines;
        Dwarf_Line *line;
        size_t nlines, i;
        Dwarf_Addr addr;
-       int lineno;
-       int ret;
+       int lineno, ret = 0;
        const char *src;
        Dwarf_Die die_mem;
 
        line_list__init(&lf->lr->line_list);
-       ret = dwarf_getsrclines(&lf->cu_die, &lines, &nlines);
-       DIE_IF(ret != 0);
+       if (dwarf_getsrclines(&lf->cu_die, &lines, &nlines) != 0) {
+               pr_warning("No source lines found in this CU.\n");
+               return -ENOENT;
+       }
 
+       /* Search probable lines on lines list */
        for (i = 0; i < nlines; i++) {
                line = dwarf_onesrcline(lines, i);
-               ret = dwarf_lineno(line, &lineno);
-               DIE_IF(ret != 0);
-               if (lf->lno_s > lineno || lf->lno_e < lineno)
+               if (dwarf_lineno(line, &lineno) != 0 ||
+                   (lf->lno_s > lineno || lf->lno_e < lineno))
                        continue;
 
                if (sp_die) {
                        /* Address filtering 1: does sp_die include addr? */
-                       ret = dwarf_lineaddr(line, &addr);
-                       DIE_IF(ret != 0);
-                       if (!dwarf_haspc(sp_die, addr))
+                       if (dwarf_lineaddr(line, &addr) != 0 ||
+                           !dwarf_haspc(sp_die, addr))
                                continue;
 
                        /* Address filtering 2: No child include addr? */
-                       if (die_get_inlinefunc(sp_die, addr, &die_mem))
+                       if (die_find_inlinefunc(sp_die, addr, &die_mem))
                                continue;
                }
 
@@ -725,30 +1161,49 @@ static void find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
                if (strtailcmp(src, lf->fname) != 0)
                        continue;
 
-               /* Copy real path */
-               if (!lf->lr->path)
-                       lf->lr->path = strdup(src);
-               line_list__add_line(&lf->lr->line_list, (unsigned int)lineno);
+               ret = line_range_add_line(src, lineno, lf->lr);
+               if (ret < 0)
+                       return ret;
        }
+
+       /*
+        * Dwarf lines doesn't include function declarations. We have to
+        * check functions list or given function.
+        */
+       if (sp_die) {
+               src = dwarf_decl_file(sp_die);
+               if (src && dwarf_decl_line(sp_die, &lineno) == 0 &&
+                   (lf->lno_s <= lineno && lf->lno_e >= lineno))
+                       ret = line_range_add_line(src, lineno, lf->lr);
+       } else
+               ret = find_line_range_func_decl_lines(lf);
+
        /* Update status */
-       if (!list_empty(&lf->lr->line_list))
-               lf->found = 1;
+       if (ret >= 0)
+               if (!list_empty(&lf->lr->line_list))
+                       ret = lf->found = 1;
+               else
+                       ret = 0;        /* Lines are not found */
        else {
                free(lf->lr->path);
                lf->lr->path = NULL;
        }
+       return ret;
 }
 
 static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
 {
-       find_line_range_by_line(in_die, (struct line_finder *)data);
+       struct dwarf_callback_param *param = data;
+
+       param->retval = find_line_range_by_line(in_die, param->data);
        return DWARF_CB_ABORT;  /* No need to find other instances */
 }
 
 /* Search function from function name */
 static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
 {
-       struct line_finder *lf = (struct line_finder *)data;
+       struct dwarf_callback_param *param = data;
+       struct line_finder *lf = param->data;
        struct line_range *lr = lf->lr;
 
        if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
@@ -757,44 +1212,55 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
                dwarf_decl_line(sp_die, &lr->offset);
                pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
                lf->lno_s = lr->offset + lr->start;
-               if (!lr->end)
+               if (lf->lno_s < 0)      /* Overflow */
+                       lf->lno_s = INT_MAX;
+               lf->lno_e = lr->offset + lr->end;
+               if (lf->lno_e < 0)      /* Overflow */
                        lf->lno_e = INT_MAX;
-               else
-                       lf->lno_e = lr->offset + lr->end;
+               pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
                lr->start = lf->lno_s;
                lr->end = lf->lno_e;
-               if (dwarf_func_inline(sp_die))
+               if (dwarf_func_inline(sp_die)) {
+                       struct dwarf_callback_param _param;
+                       _param.data = (void *)lf;
+                       _param.retval = 0;
                        dwarf_func_inline_instances(sp_die,
-                                                   line_range_inline_cb, lf);
-               else
-                       find_line_range_by_line(sp_die, lf);
-               return 1;
+                                                   line_range_inline_cb,
+                                                   &_param);
+                       param->retval = _param.retval;
+               } else
+                       param->retval = find_line_range_by_line(sp_die, lf);
+               return DWARF_CB_ABORT;
        }
-       return 0;
+       return DWARF_CB_OK;
 }
 
-static void find_line_range_by_func(struct line_finder *lf)
+static int find_line_range_by_func(struct line_finder *lf)
 {
-       dwarf_getfuncs(&lf->cu_die, line_range_search_cb, lf, 0);
+       struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
+       dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
+       return param.retval;
 }
 
 int find_line_range(int fd, struct line_range *lr)
 {
        struct line_finder lf = {.lr = lr, .found = 0};
-       int ret;
+       int ret = 0;
        Dwarf_Off off = 0, noff;
        size_t cuhl;
        Dwarf_Die *diep;
        Dwarf *dbg;
 
        dbg = dwarf_begin(fd, DWARF_C_READ);
-       if (!dbg)
-               return -ENOENT;
+       if (!dbg) {
+               pr_warning("No dwarf info found in the vmlinux - "
+                       "please rebuild with CONFIG_DEBUG_INFO=y.\n");
+               return -EBADF;
+       }
 
        /* Loop on CUs (Compilation Unit) */
-       while (!lf.found) {
-               ret = dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL);
-               if (ret != 0)
+       while (!lf.found && ret >= 0) {
+               if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
                        break;
 
                /* Get the DIE(Debugging Information Entry) of this CU */
@@ -810,20 +1276,18 @@ int find_line_range(int fd, struct line_range *lr)
 
                if (!lr->file || lf.fname) {
                        if (lr->function)
-                               find_line_range_by_func(&lf);
+                               ret = find_line_range_by_func(&lf);
                        else {
                                lf.lno_s = lr->start;
-                               if (!lr->end)
-                                       lf.lno_e = INT_MAX;
-                               else
-                                       lf.lno_e = lr->end;
-                               find_line_range_by_line(NULL, &lf);
+                               lf.lno_e = lr->end;
+                               ret = find_line_range_by_line(NULL, &lf);
                        }
                }
                off = noff;
        }
        pr_debug("path: %lx\n", (unsigned long)lr->path);
        dwarf_end(dbg);
-       return lf.found;
+
+       return (ret < 0) ? ret : lf.found;
 }
 
index 21f7354..66f1980 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include "util.h"
+#include "probe-event.h"
 
 #define MAX_PATH_LEN            256
 #define MAX_PROBE_BUFFER       1024
@@ -14,67 +15,39 @@ static inline int is_c_varname(const char *name)
        return isalpha(name[0]) || name[0] == '_';
 }
 
-struct probe_point {
-       char                    *event;                 /* Event name */
-       char                    *group;                 /* Event group */
+#ifdef DWARF_SUPPORT
+/* Find kprobe_trace_events specified by perf_probe_event from debuginfo */
+extern int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
+                                   struct kprobe_trace_event **tevs,
+                                   int max_tevs);
 
-       /* Inputs */
-       char                    *file;                  /* File name */
-       int                     line;                   /* Line number */
-       char                    *lazy_line;             /* Lazy line pattern */
+/* Find a perf_probe_point from debuginfo */
+extern int find_perf_probe_point(int fd, unsigned long addr,
+                                struct perf_probe_point *ppt);
 
-       char                    *function;              /* Function name */
-       int                     offset;                 /* Offset bytes */
-
-       int                     nr_args;                /* Number of arguments */
-       char                    **args;                 /* Arguments */
-
-       int                     retprobe;               /* Return probe */
-
-       /* Output */
-       int                     found;                  /* Number of found probe points */
-       char                    *probes[MAX_PROBES];    /* Output buffers (will be allocated)*/
-};
-
-/* Line number container */
-struct line_node {
-       struct list_head        list;
-       unsigned int            line;
-};
-
-/* Line range */
-struct line_range {
-       char                    *file;                  /* File name */
-       char                    *function;              /* Function name */
-       unsigned int            start;                  /* Start line number */
-       unsigned int            end;                    /* End line number */
-       int                     offset;                 /* Start line offset */
-       char                    *path;                  /* Real path name */
-       struct list_head        line_list;              /* Visible lines */
-};
-
-#ifndef NO_DWARF_SUPPORT
-extern int find_probe_point(int fd, struct probe_point *pp);
 extern int find_line_range(int fd, struct line_range *lr);
 
 #include <dwarf.h>
 #include <libdw.h>
 
 struct probe_finder {
-       struct probe_point      *pp;            /* Target probe point */
+       struct perf_probe_event *pev;           /* Target probe event */
+       struct kprobe_trace_event *tevs;        /* Result trace events */
+       int                     ntevs;          /* Number of trace events */
+       int                     max_tevs;       /* Max number of trace events */
 
        /* For function searching */
-       Dwarf_Addr              addr;           /* Address */
-       const char              *fname;         /* File name */
        int                     lno;            /* Line number */
+       Dwarf_Addr              addr;           /* Address */
+       const char              *fname;         /* Real file name */
        Dwarf_Die               cu_die;         /* Current CU */
+       struct list_head        lcache;         /* Line cache for lazy match */
 
        /* For variable searching */
+       Dwarf_CFI               *cfi;           /* Call Frame Information */
        Dwarf_Op                *fb_ops;        /* Frame base attribute */
-       const char              *var;           /* Current variable name */
-       char                    *buf;           /* Current output buffer */
-       int                     len;            /* Length of output buffer */
-       struct list_head        lcache;         /* Line cache for lazy match */
+       struct perf_probe_arg   *pvar;          /* Current target variable */
+       struct kprobe_trace_arg *tvar;          /* Current result variable */
 };
 
 struct line_finder {
@@ -87,6 +60,6 @@ struct line_finder {
        int                     found;
 };
 
-#endif /* NO_DWARF_SUPPORT */
+#endif /* DWARF_SUPPORT */
 
 #endif /*_PROBE_FINDER_H */
diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c
new file mode 100644 (file)
index 0000000..13d36fa
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Simple pointer stack
+ *
+ * (c) 2010 Arnaldo Carvalho de Melo <acme@redhat.com>
+ */
+
+#include "util.h"
+#include "pstack.h"
+#include <linux/kernel.h>
+#include <stdlib.h>
+
+struct pstack {
+       unsigned short  top;
+       unsigned short  max_nr_entries;
+       void            *entries[0];
+};
+
+struct pstack *pstack__new(unsigned short max_nr_entries)
+{
+       struct pstack *self = zalloc((sizeof(*self) +
+                                    max_nr_entries * sizeof(void *)));
+       if (self != NULL)
+               self->max_nr_entries = max_nr_entries;
+       return self;
+}
+
+void pstack__delete(struct pstack *self)
+{
+       free(self);
+}
+
+bool pstack__empty(const struct pstack *self)
+{
+       return self->top == 0;
+}
+
+void pstack__remove(struct pstack *self, void *key)
+{
+       unsigned short i = self->top, last_index = self->top - 1;
+
+       while (i-- != 0) {
+               if (self->entries[i] == key) {
+                       if (i < last_index)
+                               memmove(self->entries + i,
+                                       self->entries + i + 1,
+                                       (last_index - i) * sizeof(void *));
+                       --self->top;
+                       return;
+               }
+       }
+       pr_err("%s: %p not on the pstack!\n", __func__, key);
+}
+
+void pstack__push(struct pstack *self, void *key)
+{
+       if (self->top == self->max_nr_entries) {
+               pr_err("%s: top=%d, overflow!\n", __func__, self->top);
+               return;
+       }
+       self->entries[self->top++] = key;
+}
+
+void *pstack__pop(struct pstack *self)
+{
+       void *ret;
+
+       if (self->top == 0) {
+               pr_err("%s: underflow!\n", __func__);
+               return NULL;
+       }
+
+       ret = self->entries[--self->top];
+       self->entries[self->top] = NULL;
+       return ret;
+}
diff --git a/tools/perf/util/pstack.h b/tools/perf/util/pstack.h
new file mode 100644 (file)
index 0000000..5ad0702
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _PERF_PSTACK_
+#define _PERF_PSTACK_
+
+struct pstack;
+struct pstack *pstack__new(unsigned short max_nr_entries);
+void pstack__delete(struct pstack *self);
+bool pstack__empty(const struct pstack *self);
+void pstack__remove(struct pstack *self, void *key);
+void pstack__push(struct pstack *self, void *key);
+void *pstack__pop(struct pstack *self);
+
+#endif /* _PERF_PSTACK_ */
index 5376378..b059dc5 100644 (file)
@@ -371,7 +371,6 @@ static int perl_start_script(const char *script, int argc, const char **argv)
        run_start_sub();
 
        free(command_line);
-       fprintf(stderr, "perf trace started with Perl script %s\n\n", script);
        return 0;
 error:
        perl_free(my_perl);
@@ -394,8 +393,6 @@ static int perl_stop_script(void)
        perl_destruct(my_perl);
        perl_free(my_perl);
 
-       fprintf(stderr, "\nperf trace Perl script stopped\n");
-
        return 0;
 }
 
index 6a72f14..81f39ca 100644 (file)
@@ -374,8 +374,6 @@ static int python_start_script(const char *script, int argc, const char **argv)
        }
 
        free(command_line);
-       fprintf(stderr, "perf trace started with Python script %s\n\n",
-               script);
 
        return err;
 error:
@@ -407,8 +405,6 @@ out:
        Py_XDECREF(main_module);
        Py_Finalize();
 
-       fprintf(stderr, "\nperf trace Python script stopped\n");
-
        return err;
 }
 
index eed1cb8..25bfca4 100644 (file)
@@ -14,6 +14,16 @@ static int perf_session__open(struct perf_session *self, bool force)
 {
        struct stat input_stat;
 
+       if (!strcmp(self->filename, "-")) {
+               self->fd_pipe = true;
+               self->fd = STDIN_FILENO;
+
+               if (perf_header__read(self, self->fd) < 0)
+                       pr_err("incompatible file format");
+
+               return 0;
+       }
+
        self->fd = open(self->filename, O_RDONLY);
        if (self->fd < 0) {
                pr_err("failed to open file: %s", self->filename);
@@ -38,7 +48,7 @@ static int perf_session__open(struct perf_session *self, bool force)
                goto out_close;
        }
 
-       if (perf_header__read(&self->header, self->fd) < 0) {
+       if (perf_header__read(self, self->fd) < 0) {
                pr_err("incompatible file format");
                goto out_close;
        }
@@ -52,12 +62,21 @@ out_close:
        return -1;
 }
 
-static inline int perf_session__create_kernel_maps(struct perf_session *self)
+void perf_session__update_sample_type(struct perf_session *self)
+{
+       self->sample_type = perf_header__sample_type(&self->header);
+}
+
+int perf_session__create_kernel_maps(struct perf_session *self)
 {
-       return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
+       int ret = machine__create_kernel_maps(&self->host_machine);
+
+       if (ret >= 0)
+               ret = machines__create_guest_kernel_maps(&self->machines);
+       return ret;
 }
 
-struct perf_session *perf_session__new(const char *filename, int mode, bool force)
+struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe)
 {
        size_t len = filename ? strlen(filename) + 1 : 0;
        struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -70,13 +89,15 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
 
        memcpy(self->filename, filename, len);
        self->threads = RB_ROOT;
-       self->stats_by_id = RB_ROOT;
+       self->hists_tree = RB_ROOT;
        self->last_match = NULL;
        self->mmap_window = 32;
        self->cwd = NULL;
        self->cwdlen = 0;
-       self->unknown_events = 0;
-       map_groups__init(&self->kmaps);
+       self->machines = RB_ROOT;
+       self->repipe = repipe;
+       INIT_LIST_HEAD(&self->ordered_samples.samples_head);
+       machine__init(&self->host_machine, "", HOST_KERNEL_ID);
 
        if (mode == O_RDONLY) {
                if (perf_session__open(self, force) < 0)
@@ -90,7 +111,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
                        goto out_delete;
        }
 
-       self->sample_type = perf_header__sample_type(&self->header);
+       perf_session__update_sample_type(self);
 out:
        return self;
 out_free:
@@ -117,22 +138,17 @@ static bool symbol__match_parent_regex(struct symbol *sym)
        return 0;
 }
 
-struct symbol **perf_session__resolve_callchain(struct perf_session *self,
-                                               struct thread *thread,
-                                               struct ip_callchain *chain,
-                                               struct symbol **parent)
+struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
+                                                  struct thread *thread,
+                                                  struct ip_callchain *chain,
+                                                  struct symbol **parent)
 {
        u8 cpumode = PERF_RECORD_MISC_USER;
-       struct symbol **syms = NULL;
        unsigned int i;
+       struct map_symbol *syms = calloc(chain->nr, sizeof(*syms));
 
-       if (symbol_conf.use_callchain) {
-               syms = calloc(chain->nr, sizeof(*syms));
-               if (!syms) {
-                       fprintf(stderr, "Can't allocate memory for symbols\n");
-                       exit(-1);
-               }
-       }
+       if (!syms)
+               return NULL;
 
        for (i = 0; i < chain->nr; i++) {
                u64 ip = chain->ips[i];
@@ -152,15 +168,17 @@ struct symbol **perf_session__resolve_callchain(struct perf_session *self,
                        continue;
                }
 
+               al.filtered = false;
                thread__find_addr_location(thread, self, cpumode,
-                                          MAP__FUNCTION, ip, &al, NULL);
+                               MAP__FUNCTION, thread->pid, ip, &al, NULL);
                if (al.sym != NULL) {
                        if (sort__has_parent && !*parent &&
                            symbol__match_parent_regex(al.sym))
                                *parent = al.sym;
                        if (!symbol_conf.use_callchain)
                                break;
-                       syms[i] = al.sym;
+                       syms[i].map = al.map;
+                       syms[i].sym = al.sym;
                }
        }
 
@@ -174,6 +192,18 @@ static int process_event_stub(event_t *event __used,
        return 0;
 }
 
+static int process_finished_round_stub(event_t *event __used,
+                                      struct perf_session *session __used,
+                                      struct perf_event_ops *ops __used)
+{
+       dump_printf(": unhandled!\n");
+       return 0;
+}
+
+static int process_finished_round(event_t *event,
+                                 struct perf_session *session,
+                                 struct perf_event_ops *ops);
+
 static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
 {
        if (handler->sample == NULL)
@@ -194,29 +224,20 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
                handler->throttle = process_event_stub;
        if (handler->unthrottle == NULL)
                handler->unthrottle = process_event_stub;
-}
-
-static const char *event__name[] = {
-       [0]                      = "TOTAL",
-       [PERF_RECORD_MMAP]       = "MMAP",
-       [PERF_RECORD_LOST]       = "LOST",
-       [PERF_RECORD_COMM]       = "COMM",
-       [PERF_RECORD_EXIT]       = "EXIT",
-       [PERF_RECORD_THROTTLE]   = "THROTTLE",
-       [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
-       [PERF_RECORD_FORK]       = "FORK",
-       [PERF_RECORD_READ]       = "READ",
-       [PERF_RECORD_SAMPLE]     = "SAMPLE",
-};
-
-unsigned long event__total[PERF_RECORD_MAX];
-
-void event__print_totals(void)
-{
-       int i;
-       for (i = 0; i < PERF_RECORD_MAX; ++i)
-               pr_info("%10s events: %10ld\n",
-                       event__name[i], event__total[i]);
+       if (handler->attr == NULL)
+               handler->attr = process_event_stub;
+       if (handler->event_type == NULL)
+               handler->event_type = process_event_stub;
+       if (handler->tracing_data == NULL)
+               handler->tracing_data = process_event_stub;
+       if (handler->build_id == NULL)
+               handler->build_id = process_event_stub;
+       if (handler->finished_round == NULL) {
+               if (handler->ordered_samples)
+                       handler->finished_round = process_finished_round;
+               else
+                       handler->finished_round = process_finished_round_stub;
+       }
 }
 
 void mem_bswap_64(void *src, int byte_size)
@@ -270,6 +291,37 @@ static void event__read_swap(event_t *self)
        self->read.id           = bswap_64(self->read.id);
 }
 
+static void event__attr_swap(event_t *self)
+{
+       size_t size;
+
+       self->attr.attr.type            = bswap_32(self->attr.attr.type);
+       self->attr.attr.size            = bswap_32(self->attr.attr.size);
+       self->attr.attr.config          = bswap_64(self->attr.attr.config);
+       self->attr.attr.sample_period   = bswap_64(self->attr.attr.sample_period);
+       self->attr.attr.sample_type     = bswap_64(self->attr.attr.sample_type);
+       self->attr.attr.read_format     = bswap_64(self->attr.attr.read_format);
+       self->attr.attr.wakeup_events   = bswap_32(self->attr.attr.wakeup_events);
+       self->attr.attr.bp_type         = bswap_32(self->attr.attr.bp_type);
+       self->attr.attr.bp_addr         = bswap_64(self->attr.attr.bp_addr);
+       self->attr.attr.bp_len          = bswap_64(self->attr.attr.bp_len);
+
+       size = self->header.size;
+       size -= (void *)&self->attr.id - (void *)self;
+       mem_bswap_64(self->attr.id, size);
+}
+
+static void event__event_type_swap(event_t *self)
+{
+       self->event_type.event_type.event_id =
+               bswap_64(self->event_type.event_type.event_id);
+}
+
+static void event__tracing_data_swap(event_t *self)
+{
+       self->tracing_data.size = bswap_32(self->tracing_data.size);
+}
+
 typedef void (*event__swap_op)(event_t *self);
 
 static event__swap_op event__swap_ops[] = {
@@ -280,9 +332,212 @@ static event__swap_op event__swap_ops[] = {
        [PERF_RECORD_LOST]   = event__all64_swap,
        [PERF_RECORD_READ]   = event__read_swap,
        [PERF_RECORD_SAMPLE] = event__all64_swap,
-       [PERF_RECORD_MAX]    = NULL,
+       [PERF_RECORD_HEADER_ATTR]   = event__attr_swap,
+       [PERF_RECORD_HEADER_EVENT_TYPE]   = event__event_type_swap,
+       [PERF_RECORD_HEADER_TRACING_DATA]   = event__tracing_data_swap,
+       [PERF_RECORD_HEADER_BUILD_ID]   = NULL,
+       [PERF_RECORD_HEADER_MAX]    = NULL,
 };
 
+struct sample_queue {
+       u64                     timestamp;
+       struct sample_event     *event;
+       struct list_head        list;
+};
+
+static void flush_sample_queue(struct perf_session *s,
+                              struct perf_event_ops *ops)
+{
+       struct list_head *head = &s->ordered_samples.samples_head;
+       u64 limit = s->ordered_samples.next_flush;
+       struct sample_queue *tmp, *iter;
+
+       if (!ops->ordered_samples || !limit)
+               return;
+
+       list_for_each_entry_safe(iter, tmp, head, list) {
+               if (iter->timestamp > limit)
+                       return;
+
+               if (iter == s->ordered_samples.last_inserted)
+                       s->ordered_samples.last_inserted = NULL;
+
+               ops->sample((event_t *)iter->event, s);
+
+               s->ordered_samples.last_flush = iter->timestamp;
+               list_del(&iter->list);
+               free(iter->event);
+               free(iter);
+       }
+}
+
+/*
+ * When perf record finishes a pass on every buffers, it records this pseudo
+ * event.
+ * We record the max timestamp t found in the pass n.
+ * Assuming these timestamps are monotonic across cpus, we know that if
+ * a buffer still has events with timestamps below t, they will be all
+ * available and then read in the pass n + 1.
+ * Hence when we start to read the pass n + 2, we can safely flush every
+ * events with timestamps below t.
+ *
+ *    ============ PASS n =================
+ *       CPU 0         |   CPU 1
+ *                     |
+ *    cnt1 timestamps  |   cnt2 timestamps
+ *          1          |         2
+ *          2          |         3
+ *          -          |         4  <--- max recorded
+ *
+ *    ============ PASS n + 1 ==============
+ *       CPU 0         |   CPU 1
+ *                     |
+ *    cnt1 timestamps  |   cnt2 timestamps
+ *          3          |         5
+ *          4          |         6
+ *          5          |         7 <---- max recorded
+ *
+ *      Flush every events below timestamp 4
+ *
+ *    ============ PASS n + 2 ==============
+ *       CPU 0         |   CPU 1
+ *                     |
+ *    cnt1 timestamps  |   cnt2 timestamps
+ *          6          |         8
+ *          7          |         9
+ *          -          |         10
+ *
+ *      Flush every events below timestamp 7
+ *      etc...
+ */
+static int process_finished_round(event_t *event __used,
+                                 struct perf_session *session,
+                                 struct perf_event_ops *ops)
+{
+       flush_sample_queue(session, ops);
+       session->ordered_samples.next_flush = session->ordered_samples.max_timestamp;
+
+       return 0;
+}
+
+static void __queue_sample_end(struct sample_queue *new, struct list_head *head)
+{
+       struct sample_queue *iter;
+
+       list_for_each_entry_reverse(iter, head, list) {
+               if (iter->timestamp < new->timestamp) {
+                       list_add(&new->list, &iter->list);
+                       return;
+               }
+       }
+
+       list_add(&new->list, head);
+}
+
+static void __queue_sample_before(struct sample_queue *new,
+                                 struct sample_queue *iter,
+                                 struct list_head *head)
+{
+       list_for_each_entry_continue_reverse(iter, head, list) {
+               if (iter->timestamp < new->timestamp) {
+                       list_add(&new->list, &iter->list);
+                       return;
+               }
+       }
+
+       list_add(&new->list, head);
+}
+
+static void __queue_sample_after(struct sample_queue *new,
+                                struct sample_queue *iter,
+                                struct list_head *head)
+{
+       list_for_each_entry_continue(iter, head, list) {
+               if (iter->timestamp > new->timestamp) {
+                       list_add_tail(&new->list, &iter->list);
+                       return;
+               }
+       }
+       list_add_tail(&new->list, head);
+}
+
+/* The queue is ordered by time */
+static void __queue_sample_event(struct sample_queue *new,
+                                struct perf_session *s)
+{
+       struct sample_queue *last_inserted = s->ordered_samples.last_inserted;
+       struct list_head *head = &s->ordered_samples.samples_head;
+
+
+       if (!last_inserted) {
+               __queue_sample_end(new, head);
+               return;
+       }
+
+       /*
+        * Most of the time the current event has a timestamp
+        * very close to the last event inserted, unless we just switched
+        * to another event buffer. Having a sorting based on a list and
+        * on the last inserted event that is close to the current one is
+        * probably more efficient than an rbtree based sorting.
+        */
+       if (last_inserted->timestamp >= new->timestamp)
+               __queue_sample_before(new, last_inserted, head);
+       else
+               __queue_sample_after(new, last_inserted, head);
+}
+
+static int queue_sample_event(event_t *event, struct sample_data *data,
+                             struct perf_session *s)
+{
+       u64 timestamp = data->time;
+       struct sample_queue *new;
+
+
+       if (timestamp < s->ordered_samples.last_flush) {
+               printf("Warning: Timestamp below last timeslice flush\n");
+               return -EINVAL;
+       }
+
+       new = malloc(sizeof(*new));
+       if (!new)
+               return -ENOMEM;
+
+       new->timestamp = timestamp;
+
+       new->event = malloc(event->header.size);
+       if (!new->event) {
+               free(new);
+               return -ENOMEM;
+       }
+
+       memcpy(new->event, event, event->header.size);
+
+       __queue_sample_event(new, s);
+       s->ordered_samples.last_inserted = new;
+
+       if (new->timestamp > s->ordered_samples.max_timestamp)
+               s->ordered_samples.max_timestamp = new->timestamp;
+
+       return 0;
+}
+
+static int perf_session__process_sample(event_t *event, struct perf_session *s,
+                                       struct perf_event_ops *ops)
+{
+       struct sample_data data;
+
+       if (!ops->ordered_samples)
+               return ops->sample(event, s);
+
+       bzero(&data, sizeof(struct sample_data));
+       event__parse_sample(event, s->sample_type, &data);
+
+       queue_sample_event(event, &data, s);
+
+       return 0;
+}
+
 static int perf_session__process_event(struct perf_session *self,
                                       event_t *event,
                                       struct perf_event_ops *ops,
@@ -290,12 +545,11 @@ static int perf_session__process_event(struct perf_session *self,
 {
        trace_event(event);
 
-       if (event->header.type < PERF_RECORD_MAX) {
+       if (event->header.type < PERF_RECORD_HEADER_MAX) {
                dump_printf("%#Lx [%#x]: PERF_RECORD_%s",
                            offset + head, event->header.size,
                            event__name[event->header.type]);
-               ++event__total[0];
-               ++event__total[event->header.type];
+               hists__inc_nr_events(&self->hists, event->header.type);
        }
 
        if (self->header.needs_swap && event__swap_ops[event->header.type])
@@ -303,7 +557,7 @@ static int perf_session__process_event(struct perf_session *self,
 
        switch (event->header.type) {
        case PERF_RECORD_SAMPLE:
-               return ops->sample(event, self);
+               return perf_session__process_sample(event, self, ops);
        case PERF_RECORD_MMAP:
                return ops->mmap(event, self);
        case PERF_RECORD_COMM:
@@ -320,8 +574,20 @@ static int perf_session__process_event(struct perf_session *self,
                return ops->throttle(event, self);
        case PERF_RECORD_UNTHROTTLE:
                return ops->unthrottle(event, self);
+       case PERF_RECORD_HEADER_ATTR:
+               return ops->attr(event, self);
+       case PERF_RECORD_HEADER_EVENT_TYPE:
+               return ops->event_type(event, self);
+       case PERF_RECORD_HEADER_TRACING_DATA:
+               /* setup for reading amidst mmap */
+               lseek(self->fd, offset + head, SEEK_SET);
+               return ops->tracing_data(event, self);
+       case PERF_RECORD_HEADER_BUILD_ID:
+               return ops->build_id(event, self);
+       case PERF_RECORD_FINISHED_ROUND:
+               return ops->finished_round(event, self, ops);
        default:
-               self->unknown_events++;
+               ++self->hists.stats.nr_unknown_events;
                return -1;
        }
 }
@@ -333,56 +599,114 @@ void perf_event_header__bswap(struct perf_event_header *self)
        self->size = bswap_16(self->size);
 }
 
-int perf_header__read_build_ids(struct perf_header *self,
-                               int input, u64 offset, u64 size)
+static struct thread *perf_session__register_idle_thread(struct perf_session *self)
 {
-       struct build_id_event bev;
-       char filename[PATH_MAX];
-       u64 limit = offset + size;
-       int err = -1;
-
-       while (offset < limit) {
-               struct dso *dso;
-               ssize_t len;
-               struct list_head *head = &dsos__user;
+       struct thread *thread = perf_session__findnew(self, 0);
 
-               if (read(input, &bev, sizeof(bev)) != sizeof(bev))
-                       goto out;
+       if (thread == NULL || thread__set_comm(thread, "swapper")) {
+               pr_err("problem inserting idle task.\n");
+               thread = NULL;
+       }
 
-               if (self->needs_swap)
-                       perf_event_header__bswap(&bev.header);
+       return thread;
+}
 
-               len = bev.header.size - sizeof(bev);
-               if (read(input, filename, len) != len)
-                       goto out;
+int do_read(int fd, void *buf, size_t size)
+{
+       void *buf_start = buf;
 
-               if (bev.header.misc & PERF_RECORD_MISC_KERNEL)
-                       head = &dsos__kernel;
+       while (size) {
+               int ret = read(fd, buf, size);
 
-               dso = __dsos__findnew(head, filename);
-               if (dso != NULL) {
-                       dso__set_build_id(dso, &bev.build_id);
-                       if (head == &dsos__kernel && filename[0] == '[')
-                               dso->kernel = 1;
-               }
+               if (ret <= 0)
+                       return ret;
 
-               offset += bev.header.size;
+               size -= ret;
+               buf += ret;
        }
-       err = 0;
-out:
-       return err;
+
+       return buf - buf_start;
 }
 
-static struct thread *perf_session__register_idle_thread(struct perf_session *self)
+#define session_done() (*(volatile int *)(&session_done))
+volatile int session_done;
+
+static int __perf_session__process_pipe_events(struct perf_session *self,
+                                              struct perf_event_ops *ops)
 {
-       struct thread *thread = perf_session__findnew(self, 0);
+       event_t event;
+       uint32_t size;
+       int skip = 0;
+       u64 head;
+       int err;
+       void *p;
 
-       if (thread == NULL || thread__set_comm(thread, "swapper")) {
-               pr_err("problem inserting idle task.\n");
-               thread = NULL;
+       perf_event_ops__fill_defaults(ops);
+
+       head = 0;
+more:
+       err = do_read(self->fd, &event, sizeof(struct perf_event_header));
+       if (err <= 0) {
+               if (err == 0)
+                       goto done;
+
+               pr_err("failed to read event header\n");
+               goto out_err;
        }
 
-       return thread;
+       if (self->header.needs_swap)
+               perf_event_header__bswap(&event.header);
+
+       size = event.header.size;
+       if (size == 0)
+               size = 8;
+
+       p = &event;
+       p += sizeof(struct perf_event_header);
+
+       if (size - sizeof(struct perf_event_header)) {
+               err = do_read(self->fd, p,
+                             size - sizeof(struct perf_event_header));
+               if (err <= 0) {
+                       if (err == 0) {
+                               pr_err("unexpected end of event stream\n");
+                               goto done;
+                       }
+
+                       pr_err("failed to read event data\n");
+                       goto out_err;
+               }
+       }
+
+       if (size == 0 ||
+           (skip = perf_session__process_event(self, &event, ops,
+                                               0, head)) < 0) {
+               dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
+                           head, event.header.size, event.header.type);
+               /*
+                * assume we lost track of the stream, check alignment, and
+                * increment a single u64 in the hope to catch on again 'soon'.
+                */
+               if (unlikely(head & 7))
+                       head &= ~7ULL;
+
+               size = 8;
+       }
+
+       head += size;
+
+       dump_printf("\n%#Lx [%#x]: event: %d\n",
+                   head, event.header.size, event.header.type);
+
+       if (skip > 0)
+               head += skip;
+
+       if (!session_done())
+               goto more;
+done:
+       err = 0;
+out_err:
+       return err;
 }
 
 int __perf_session__process_events(struct perf_session *self,
@@ -396,6 +720,10 @@ int __perf_session__process_events(struct perf_session *self,
        event_t *event;
        uint32_t size;
        char *buf;
+       struct ui_progress *progress = ui_progress__new("Processing events...",
+                                                       self->size);
+       if (progress == NULL)
+               return -1;
 
        perf_event_ops__fill_defaults(ops);
 
@@ -424,6 +752,7 @@ remap:
 
 more:
        event = (event_t *)(buf + head);
+       ui_progress__update(progress, offset);
 
        if (self->header.needs_swap)
                perf_event_header__bswap(&event->header);
@@ -473,7 +802,11 @@ more:
                goto more;
 done:
        err = 0;
+       /* do the final flush for ordered samples */
+       self->ordered_samples.next_flush = ULLONG_MAX;
+       flush_sample_queue(self, ops);
 out_err:
+       ui_progress__delete(progress);
        return err;
 }
 
@@ -502,9 +835,13 @@ out_getcwd_err:
                self->cwdlen = strlen(self->cwd);
        }
 
-       err = __perf_session__process_events(self, self->header.data_offset,
-                                            self->header.data_size,
-                                            self->size, ops);
+       if (!self->fd_pipe)
+               err = __perf_session__process_events(self,
+                                                    self->header.data_offset,
+                                                    self->header.data_size,
+                                                    self->size, ops);
+       else
+               err = __perf_session__process_pipe_events(self, ops);
 out_err:
        return err;
 }
@@ -519,56 +856,41 @@ bool perf_session__has_traces(struct perf_session *self, const char *msg)
        return true;
 }
 
-int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
+int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
                                             const char *symbol_name,
                                             u64 addr)
 {
        char *bracket;
        enum map_type i;
+       struct ref_reloc_sym *ref;
 
-       self->ref_reloc_sym.name = strdup(symbol_name);
-       if (self->ref_reloc_sym.name == NULL)
+       ref = zalloc(sizeof(struct ref_reloc_sym));
+       if (ref == NULL)
                return -ENOMEM;
 
-       bracket = strchr(self->ref_reloc_sym.name, ']');
+       ref->name = strdup(symbol_name);
+       if (ref->name == NULL) {
+               free(ref);
+               return -ENOMEM;
+       }
+
+       bracket = strchr(ref->name, ']');
        if (bracket)
                *bracket = '\0';
 
-       self->ref_reloc_sym.addr = addr;
+       ref->addr = addr;
 
        for (i = 0; i < MAP__NR_TYPES; ++i) {
-               struct kmap *kmap = map__kmap(self->vmlinux_maps[i]);
-               kmap->ref_reloc_sym = &self->ref_reloc_sym;
+               struct kmap *kmap = map__kmap(maps[i]);
+               kmap->ref_reloc_sym = ref;
        }
 
        return 0;
 }
 
-static u64 map__reloc_map_ip(struct map *map, u64 ip)
-{
-       return ip + (s64)map->pgoff;
-}
-
-static u64 map__reloc_unmap_ip(struct map *map, u64 ip)
-{
-       return ip - (s64)map->pgoff;
-}
-
-void map__reloc_vmlinux(struct map *self)
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp)
 {
-       struct kmap *kmap = map__kmap(self);
-       s64 reloc;
-
-       if (!kmap->ref_reloc_sym || !kmap->ref_reloc_sym->unrelocated_addr)
-               return;
-
-       reloc = (kmap->ref_reloc_sym->unrelocated_addr -
-                kmap->ref_reloc_sym->addr);
-
-       if (!reloc)
-               return;
-
-       self->map_ip   = map__reloc_map_ip;
-       self->unmap_ip = map__reloc_unmap_ip;
-       self->pgoff    = reloc;
+       return __dsos__fprintf(&self->host_machine.kernel_dsos, fp) +
+              __dsos__fprintf(&self->host_machine.user_dsos, fp) +
+              machines__fprintf_dsos(&self->machines, fp);
 }
index 5c33417..e7fce48 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __PERF_SESSION_H
 #define __PERF_SESSION_H
 
+#include "hist.h"
 #include "event.h"
 #include "header.h"
 #include "symbol.h"
@@ -8,45 +9,69 @@
 #include <linux/rbtree.h>
 #include "../../../include/linux/perf_event.h"
 
+struct sample_queue;
 struct ip_callchain;
 struct thread;
 
+struct ordered_samples {
+       u64                     last_flush;
+       u64                     next_flush;
+       u64                     max_timestamp;
+       struct list_head        samples_head;
+       struct sample_queue     *last_inserted;
+};
+
 struct perf_session {
        struct perf_header      header;
        unsigned long           size;
        unsigned long           mmap_window;
-       struct map_groups       kmaps;
        struct rb_root          threads;
        struct thread           *last_match;
-       struct map              *vmlinux_maps[MAP__NR_TYPES];
-       struct events_stats     events_stats;
-       struct rb_root          stats_by_id;
-       unsigned long           event_total[PERF_RECORD_MAX];
-       unsigned long           unknown_events;
-       struct rb_root          hists;
+       struct machine          host_machine;
+       struct rb_root          machines;
+       struct rb_root          hists_tree;
+       /*
+        * FIXME: should point to the first entry in hists_tree and
+        *        be a hists instance. Right now its only 'report'
+        *        that is using ->hists_tree while all the rest use
+        *        ->hists.
+        */
+       struct hists            hists;
        u64                     sample_type;
-       struct ref_reloc_sym    ref_reloc_sym;
        int                     fd;
+       bool                    fd_pipe;
+       bool                    repipe;
        int                     cwdlen;
        char                    *cwd;
+       struct ordered_samples  ordered_samples;
        char filename[0];
 };
 
+struct perf_event_ops;
+
 typedef int (*event_op)(event_t *self, struct perf_session *session);
+typedef int (*event_op2)(event_t *self, struct perf_session *session,
+                        struct perf_event_ops *ops);
 
 struct perf_event_ops {
-       event_op sample,
-                mmap,
-                comm,
-                fork,
-                exit,
-                lost,
-                read,
-                throttle,
-                unthrottle;
+       event_op        sample,
+                       mmap,
+                       comm,
+                       fork,
+                       exit,
+                       lost,
+                       read,
+                       throttle,
+                       unthrottle,
+                       attr,
+                       event_type,
+                       tracing_data,
+                       build_id;
+       event_op2       finished_round;
+       bool            ordered_samples;
 };
 
-struct perf_session *perf_session__new(const char *filename, int mode, bool force);
+struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe);
 void perf_session__delete(struct perf_session *self);
 
 void perf_event_header__bswap(struct perf_event_header *self);
@@ -57,33 +82,66 @@ int __perf_session__process_events(struct perf_session *self,
 int perf_session__process_events(struct perf_session *self,
                                 struct perf_event_ops *event_ops);
 
-struct symbol **perf_session__resolve_callchain(struct perf_session *self,
-                                               struct thread *thread,
-                                               struct ip_callchain *chain,
-                                               struct symbol **parent);
+struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
+                                                  struct thread *thread,
+                                                  struct ip_callchain *chain,
+                                                  struct symbol **parent);
 
 bool perf_session__has_traces(struct perf_session *self, const char *msg);
 
-int perf_header__read_build_ids(struct perf_header *self, int input,
-                               u64 offset, u64 file_size);
-
-int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
+int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
                                             const char *symbol_name,
                                             u64 addr);
 
 void mem_bswap_64(void *src, int byte_size);
 
-static inline int __perf_session__create_kernel_maps(struct perf_session *self,
-                                               struct dso *kernel)
+int perf_session__create_kernel_maps(struct perf_session *self);
+
+int do_read(int fd, void *buf, size_t size);
+void perf_session__update_sample_type(struct perf_session *self);
+
+static inline
+struct machine *perf_session__find_host_machine(struct perf_session *self)
+{
+       return &self->host_machine;
+}
+
+static inline
+struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid)
+{
+       if (pid == HOST_KERNEL_ID)
+               return &self->host_machine;
+       return machines__find(&self->machines, pid);
+}
+
+static inline
+struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid)
+{
+       if (pid == HOST_KERNEL_ID)
+               return &self->host_machine;
+       return machines__findnew(&self->machines, pid);
+}
+
+static inline
+void perf_session__process_machines(struct perf_session *self,
+                                   machine__process_t process)
+{
+       process(&self->host_machine, self);
+       return machines__process(&self->machines, process, self);
+}
+
+size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
+
+static inline
+size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp,
+                                         bool with_hits)
 {
-       return __map_groups__create_kernel_maps(&self->kmaps,
-                                               self->vmlinux_maps, kernel);
+       return machines__fprintf_dsos_buildid(&self->machines, fp, with_hits);
 }
 
-static inline struct map *
-       perf_session__new_module_map(struct perf_session *self,
-                                    u64 start, const char *filename)
+static inline
+size_t perf_session__fprintf_nr_events(struct perf_session *self, FILE *fp)
 {
-       return map_groups__new_module(&self->kmaps, start, filename);
+       return hists__fprintf_nr_events(&self->hists, fp);
 }
 #endif /* __PERF_SESSION_H */
index cb0f327..2316cb5 100644 (file)
@@ -1,10 +1,10 @@
 #include "sort.h"
 
 regex_t                parent_regex;
-char           default_parent_pattern[] = "^sys_|^do_page_fault";
-char           *parent_pattern = default_parent_pattern;
-char           default_sort_order[] = "comm,dso,symbol";
-char           *sort_order = default_sort_order;
+const char     default_parent_pattern[] = "^sys_|^do_page_fault";
+const char     *parent_pattern = default_parent_pattern;
+const char     default_sort_order[] = "comm,dso,symbol";
+const char     *sort_order = default_sort_order;
 int            sort__need_collapse = 0;
 int            sort__has_parent = 0;
 
@@ -18,39 +18,50 @@ char * field_sep;
 
 LIST_HEAD(hist_entry__sort_list);
 
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width);
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+                                    size_t size, unsigned int width);
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width);
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width);
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width);
+
 struct sort_entry sort_thread = {
-       .header = "Command:  Pid",
-       .cmp    = sort__thread_cmp,
-       .print  = sort__thread_print,
-       .width  = &threads__col_width,
+       .se_header      = "Command:  Pid",
+       .se_cmp         = sort__thread_cmp,
+       .se_snprintf    = hist_entry__thread_snprintf,
+       .se_width       = &threads__col_width,
 };
 
 struct sort_entry sort_comm = {
-       .header         = "Command",
-       .cmp            = sort__comm_cmp,
-       .collapse       = sort__comm_collapse,
-       .print          = sort__comm_print,
-       .width          = &comms__col_width,
+       .se_header      = "Command",
+       .se_cmp         = sort__comm_cmp,
+       .se_collapse    = sort__comm_collapse,
+       .se_snprintf    = hist_entry__comm_snprintf,
+       .se_width       = &comms__col_width,
 };
 
 struct sort_entry sort_dso = {
-       .header = "Shared Object",
-       .cmp    = sort__dso_cmp,
-       .print  = sort__dso_print,
-       .width  = &dsos__col_width,
+       .se_header      = "Shared Object",
+       .se_cmp         = sort__dso_cmp,
+       .se_snprintf    = hist_entry__dso_snprintf,
+       .se_width       = &dsos__col_width,
 };
 
 struct sort_entry sort_sym = {
-       .header = "Symbol",
-       .cmp    = sort__sym_cmp,
-       .print  = sort__sym_print,
+       .se_header      = "Symbol",
+       .se_cmp         = sort__sym_cmp,
+       .se_snprintf    = hist_entry__sym_snprintf,
 };
 
 struct sort_entry sort_parent = {
-       .header = "Parent symbol",
-       .cmp    = sort__parent_cmp,
-       .print  = sort__parent_print,
-       .width  = &parent_symbol__col_width,
+       .se_header      = "Parent symbol",
+       .se_cmp         = sort__parent_cmp,
+       .se_snprintf    = hist_entry__parent_snprintf,
+       .se_width       = &parent_symbol__col_width,
 };
 
 struct sort_dimension {
@@ -85,45 +96,38 @@ sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
        return right->thread->pid - left->thread->pid;
 }
 
-int repsep_fprintf(FILE *fp, const char *fmt, ...)
+static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
 {
        int n;
        va_list ap;
 
        va_start(ap, fmt);
-       if (!field_sep)
-               n = vfprintf(fp, fmt, ap);
-       else {
-               char *bf = NULL;
-               n = vasprintf(&bf, fmt, ap);
-               if (n > 0) {
-                       char *sep = bf;
-
-                       while (1) {
-                               sep = strchr(sep, *field_sep);
-                               if (sep == NULL)
-                                       break;
-                               *sep = '.';
-                       }
+       n = vsnprintf(bf, size, fmt, ap);
+       if (field_sep && n > 0) {
+               char *sep = bf;
+
+               while (1) {
+                       sep = strchr(sep, *field_sep);
+                       if (sep == NULL)
+                               break;
+                       *sep = '.';
                }
-               fputs(bf, fp);
-               free(bf);
        }
        va_end(ap);
        return n;
 }
 
-size_t
-sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__thread_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width)
 {
-       return repsep_fprintf(fp, "%*s:%5d", width - 6,
+       return repsep_snprintf(bf, size, "%*s:%5d", width,
                              self->thread->comm ?: "", self->thread->pid);
 }
 
-size_t
-sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__comm_snprintf(struct hist_entry *self, char *bf,
+                                    size_t size, unsigned int width)
 {
-       return repsep_fprintf(fp, "%*s", width, self->thread->comm);
+       return repsep_snprintf(bf, size, "%*s", width, self->thread->comm);
 }
 
 /* --sort dso */
@@ -131,8 +135,8 @@ sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
 int64_t
 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-       struct dso *dso_l = left->map ? left->map->dso : NULL;
-       struct dso *dso_r = right->map ? right->map->dso : NULL;
+       struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL;
+       struct dso *dso_r = right->ms.map ? right->ms.map->dso : NULL;
        const char *dso_name_l, *dso_name_r;
 
        if (!dso_l || !dso_r)
@@ -149,16 +153,16 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
        return strcmp(dso_name_l, dso_name_r);
 }
 
-size_t
-sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__dso_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width)
 {
-       if (self->map && self->map->dso) {
-               const char *dso_name = !verbose ? self->map->dso->short_name :
-                                                 self->map->dso->long_name;
-               return repsep_fprintf(fp, "%-*s", width, dso_name);
+       if (self->ms.map && self->ms.map->dso) {
+               const char *dso_name = !verbose ? self->ms.map->dso->short_name :
+                                                 self->ms.map->dso->long_name;
+               return repsep_snprintf(bf, size, "%-*s", width, dso_name);
        }
 
-       return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
+       return repsep_snprintf(bf, size, "%*Lx", width, self->ip);
 }
 
 /* --sort symbol */
@@ -168,31 +172,31 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
 {
        u64 ip_l, ip_r;
 
-       if (left->sym == right->sym)
+       if (left->ms.sym == right->ms.sym)
                return 0;
 
-       ip_l = left->sym ? left->sym->start : left->ip;
-       ip_r = right->sym ? right->sym->start : right->ip;
+       ip_l = left->ms.sym ? left->ms.sym->start : left->ip;
+       ip_r = right->ms.sym ? right->ms.sym->start : right->ip;
 
        return (int64_t)(ip_r - ip_l);
 }
 
-
-size_t
-sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
+static int hist_entry__sym_snprintf(struct hist_entry *self, char *bf,
+                                   size_t size, unsigned int width __used)
 {
        size_t ret = 0;
 
        if (verbose) {
-               char o = self->map ? dso__symtab_origin(self->map->dso) : '!';
-               ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, o);
+               char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!';
+               ret += repsep_snprintf(bf, size, "%#018llx %c ", self->ip, o);
        }
 
-       ret += repsep_fprintf(fp, "[%c] ", self->level);
-       if (self->sym)
-               ret += repsep_fprintf(fp, "%s", self->sym->name);
+       ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level);
+       if (self->ms.sym)
+               ret += repsep_snprintf(bf + ret, size - ret, "%s",
+                                      self->ms.sym->name);
        else
-               ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
+               ret += repsep_snprintf(bf + ret, size - ret, "%#016llx", self->ip);
 
        return ret;
 }
@@ -231,10 +235,10 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
        return strcmp(sym_l->name, sym_r->name);
 }
 
-size_t
-sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
+static int hist_entry__parent_snprintf(struct hist_entry *self, char *bf,
+                                      size_t size, unsigned int width)
 {
-       return repsep_fprintf(fp, "%-*s", width,
+       return repsep_snprintf(bf, size, "%-*s", width,
                              self->parent ? self->parent->name : "[other]");
 }
 
@@ -251,7 +255,7 @@ int sort_dimension__add(const char *tok)
                if (strncasecmp(tok, sd->name, strlen(tok)))
                        continue;
 
-               if (sd->entry->collapse)
+               if (sd->entry->se_collapse)
                        sort__need_collapse = 1;
 
                if (sd->entry == &sort_parent) {
@@ -260,9 +264,8 @@ int sort_dimension__add(const char *tok)
                                char err[BUFSIZ];
 
                                regerror(ret, &parent_regex, err, sizeof(err));
-                               fprintf(stderr, "Invalid regex: %s\n%s",
-                                       parent_pattern, err);
-                               exit(-1);
+                               pr_err("Invalid regex: %s\n%s", parent_pattern, err);
+                               return -EINVAL;
                        }
                        sort__has_parent = 1;
                }
index 753f9ea..0d61c40 100644 (file)
 #include "sort.h"
 
 extern regex_t parent_regex;
-extern char *sort_order;
-extern char default_parent_pattern[];
-extern char *parent_pattern;
-extern char default_sort_order[];
+extern const char *sort_order;
+extern const char default_parent_pattern[];
+extern const char *parent_pattern;
+extern const char default_sort_order[];
 extern int sort__need_collapse;
 extern int sort__has_parent;
 extern char *field_sep;
@@ -43,19 +43,24 @@ extern enum sort_type sort__first_dimension;
 
 struct hist_entry {
        struct rb_node          rb_node;
-       u64                     count;
+       u64                     period;
+       u64                     period_sys;
+       u64                     period_us;
+       u64                     period_guest_sys;
+       u64                     period_guest_us;
+       struct map_symbol       ms;
        struct thread           *thread;
-       struct map              *map;
-       struct symbol           *sym;
        u64                     ip;
+       u32                     nr_events;
        char                    level;
-       struct symbol     *parent;
-       struct callchain_node   callchain;
+       u8                      filtered;
+       struct symbol           *parent;
        union {
                unsigned long     position;
                struct hist_entry *pair;
                struct rb_root    sorted_chain;
        };
+       struct callchain_node   callchain[0];
 };
 
 enum sort_type {
@@ -73,12 +78,13 @@ enum sort_type {
 struct sort_entry {
        struct list_head list;
 
-       const char *header;
+       const char *se_header;
 
-       int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
-       int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
-       size_t  (*print)(FILE *fp, struct hist_entry *, unsigned int width);
-       unsigned int *width;
+       int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
+       int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
+       int     (*se_snprintf)(struct hist_entry *self, char *bf, size_t size,
+                              unsigned int width);
+       unsigned int *se_width;
        bool    elide;
 };
 
@@ -87,7 +93,6 @@ extern struct list_head hist_entry__sort_list;
 
 void setup_sorting(const char * const usagestr[], const struct option *opts);
 
-extern int repsep_fprintf(FILE *fp, const char *fmt, ...);
 extern size_t sort__thread_print(FILE *, struct hist_entry *, unsigned int);
 extern size_t sort__comm_print(FILE *, struct hist_entry *, unsigned int);
 extern size_t sort__dso_print(FILE *, struct hist_entry *, unsigned int);
index a175949..0409fc7 100644 (file)
@@ -1,48 +1,5 @@
-#include "string.h"
 #include "util.h"
-
-static int hex(char ch)
-{
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       if ((ch >= 'A') && (ch <= 'F'))
-               return ch - 'A' + 10;
-       return -1;
-}
-
-/*
- * While we find nice hex chars, build a long_val.
- * Return number of chars processed.
- */
-int hex2u64(const char *ptr, u64 *long_val)
-{
-       const char *p = ptr;
-       *long_val = 0;
-
-       while (*p) {
-               const int hex_val = hex(*p);
-
-               if (hex_val < 0)
-                       break;
-
-               *long_val = (*long_val << 4) | hex_val;
-               p++;
-       }
-
-       return p - ptr;
-}
-
-char *strxfrchar(char *s, char from, char to)
-{
-       char *p = s;
-
-       while ((p = strchr(p, from)) != NULL)
-               *p++ = to;
-
-       return s;
-}
+#include "string.h"
 
 #define K 1024LL
 /*
diff --git a/tools/perf/util/string.h b/tools/perf/util/string.h
deleted file mode 100644 (file)
index 542e44d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef __PERF_STRING_H_
-#define __PERF_STRING_H_
-
-#include <stdbool.h>
-#include "types.h"
-
-int hex2u64(const char *ptr, u64 *val);
-char *strxfrchar(char *s, char from, char to);
-s64 perf_atoll(const char *str);
-char **argv_split(const char *str, int *argcp);
-void argv_free(char **argv);
-bool strglobmatch(const char *str, const char *pat);
-bool strlazymatch(const char *str, const char *pat);
-
-#define _STR(x) #x
-#define STR(x) _STR(x)
-
-#endif /* __PERF_STRING_H */
index c458c4a..a06131f 100644 (file)
@@ -1,13 +1,19 @@
-#include "util.h"
-#include "../perf.h"
-#include "sort.h"
-#include "string.h"
+#define _GNU_SOURCE
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "symbol.h"
-#include "thread.h"
+#include "strlist.h"
 
-#include "debug.h"
-
-#include <asm/bug.h>
 #include <libelf.h>
 #include <gelf.h>
 #include <elf.h>
 #define NT_GNU_BUILD_ID 3
 #endif
 
-enum dso_origin {
-       DSO__ORIG_KERNEL = 0,
-       DSO__ORIG_JAVA_JIT,
-       DSO__ORIG_BUILD_ID_CACHE,
-       DSO__ORIG_FEDORA,
-       DSO__ORIG_UBUNTU,
-       DSO__ORIG_BUILDID,
-       DSO__ORIG_DSO,
-       DSO__ORIG_KMODULE,
-       DSO__ORIG_NOT_FOUND,
-};
-
 static void dsos__add(struct list_head *head, struct dso *dso);
 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
 static int dso__load_kernel_sym(struct dso *self, struct map *map,
                                symbol_filter_t filter);
+static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
+                       symbol_filter_t filter);
 static int vmlinux_path__nr_entries;
 static char **vmlinux_path;
 
@@ -126,16 +122,17 @@ static void map_groups__fixup_end(struct map_groups *self)
 static struct symbol *symbol__new(u64 start, u64 len, const char *name)
 {
        size_t namelen = strlen(name) + 1;
-       struct symbol *self = zalloc(symbol_conf.priv_size +
-                                    sizeof(*self) + namelen);
+       struct symbol *self = calloc(1, (symbol_conf.priv_size +
+                                        sizeof(*self) + namelen));
        if (self == NULL)
                return NULL;
 
        if (symbol_conf.priv_size)
                self = ((void *)self) + symbol_conf.priv_size;
 
-       self->start = start;
-       self->end   = len ? start + len - 1 : start;
+       self->start   = start;
+       self->end     = len ? start + len - 1 : start;
+       self->namelen = namelen - 1;
 
        pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
 
@@ -178,7 +175,7 @@ static void dso__set_basename(struct dso *self)
 
 struct dso *dso__new(const char *name)
 {
-       struct dso *self = zalloc(sizeof(*self) + strlen(name) + 1);
+       struct dso *self = calloc(1, sizeof(*self) + strlen(name) + 1);
 
        if (self != NULL) {
                int i;
@@ -192,6 +189,8 @@ struct dso *dso__new(const char *name)
                self->loaded = 0;
                self->sorted_by_name = 0;
                self->has_build_id = 0;
+               self->kernel = DSO_TYPE_USER;
+               INIT_LIST_HEAD(&self->node);
        }
 
        return self;
@@ -408,12 +407,9 @@ int kallsyms__parse(const char *filename, void *arg,
                char *symbol_name;
 
                line_len = getline(&line, &n, file);
-               if (line_len < 0)
+               if (line_len < 0 || !line)
                        break;
 
-               if (!line)
-                       goto out_failure;
-
                line[--line_len] = '\0'; /* \n */
 
                len = hex2u64(line, &start);
@@ -465,6 +461,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
         * map__split_kallsyms, when we have split the maps per module
         */
        symbols__insert(root, sym);
+
        return 0;
 }
 
@@ -489,6 +486,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                               symbol_filter_t filter)
 {
        struct map_groups *kmaps = map__kmap(map)->kmaps;
+       struct machine *machine = kmaps->machine;
        struct map *curr_map = map;
        struct symbol *pos;
        int count = 0;
@@ -510,15 +508,33 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        *module++ = '\0';
 
                        if (strcmp(curr_map->dso->short_name, module)) {
-                               curr_map = map_groups__find_by_name(kmaps, map->type, module);
+                               if (curr_map != map &&
+                                   self->kernel == DSO_TYPE_GUEST_KERNEL &&
+                                   machine__is_default_guest(machine)) {
+                                       /*
+                                        * We assume all symbols of a module are
+                                        * continuous in * kallsyms, so curr_map
+                                        * points to a module and all its
+                                        * symbols are in its kmap. Mark it as
+                                        * loaded.
+                                        */
+                                       dso__set_loaded(curr_map->dso,
+                                                       curr_map->type);
+                               }
+
+                               curr_map = map_groups__find_by_name(kmaps,
+                                                       map->type, module);
                                if (curr_map == NULL) {
-                                       pr_debug("/proc/{kallsyms,modules} "
+                                       pr_debug("%s/proc/{kallsyms,modules} "
                                                 "inconsistency while looking "
-                                                "for \"%s\" module!\n", module);
-                                       return -1;
+                                                "for \"%s\" module!\n",
+                                                machine->root_dir, module);
+                                       curr_map = map;
+                                       goto discard_symbol;
                                }
 
-                               if (curr_map->dso->loaded)
+                               if (curr_map->dso->loaded &&
+                                   !machine__is_default_guest(machine))
                                        goto discard_symbol;
                        }
                        /*
@@ -531,13 +547,21 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
                        char dso_name[PATH_MAX];
                        struct dso *dso;
 
-                       snprintf(dso_name, sizeof(dso_name), "[kernel].%d",
-                                kernel_range++);
+                       if (self->kernel == DSO_TYPE_GUEST_KERNEL)
+                               snprintf(dso_name, sizeof(dso_name),
+                                       "[guest.kernel].%d",
+                                       kernel_range++);
+                       else
+                               snprintf(dso_name, sizeof(dso_name),
+                                       "[kernel].%d",
+                                       kernel_range++);
 
                        dso = dso__new(dso_name);
                        if (dso == NULL)
                                return -1;
 
+                       dso->kernel = self->kernel;
+
                        curr_map = map__new2(pos->start, dso, map->type);
                        if (curr_map == NULL) {
                                dso__delete(dso);
@@ -561,6 +585,12 @@ discard_symbol:            rb_erase(&pos->rb_node, root);
                }
        }
 
+       if (curr_map != map &&
+           self->kernel == DSO_TYPE_GUEST_KERNEL &&
+           machine__is_default_guest(kmaps->machine)) {
+               dso__set_loaded(curr_map->dso, curr_map->type);
+       }
+
        return count;
 }
 
@@ -571,7 +601,10 @@ int dso__load_kallsyms(struct dso *self, const char *filename,
                return -1;
 
        symbols__fixup_end(&self->symbols[map->type]);
-       self->origin = DSO__ORIG_KERNEL;
+       if (self->kernel == DSO_TYPE_GUEST_KERNEL)
+               self->origin = DSO__ORIG_GUEST_KERNEL;
+       else
+               self->origin = DSO__ORIG_KERNEL;
 
        return dso__split_kallsyms(self, map, filter);
 }
@@ -870,8 +903,8 @@ out_close:
        if (err == 0)
                return nr;
 out:
-       pr_warning("%s: problems reading %s PLT info.\n",
-                  __func__, self->long_name);
+       pr_debug("%s: problems reading %s PLT info.\n",
+                __func__, self->long_name);
        return 0;
 }
 
@@ -958,7 +991,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
        nr_syms = shdr.sh_size / shdr.sh_entsize;
 
        memset(&sym, 0, sizeof(sym));
-       if (!self->kernel) {
+       if (self->kernel == DSO_TYPE_USER) {
                self->adjust_symbols = (ehdr.e_type == ET_EXEC ||
                                elf_section_by_name(elf, &ehdr, &shdr,
                                                     ".gnu.prelink_undo",
@@ -990,7 +1023,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 
                section_name = elf_sec__name(&shdr, secstrs);
 
-               if (self->kernel || kmodule) {
+               if (self->kernel != DSO_TYPE_USER || kmodule) {
                        char dso_name[PATH_MAX];
 
                        if (strcmp(section_name,
@@ -1017,6 +1050,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
                                curr_dso = dso__new(dso_name);
                                if (curr_dso == NULL)
                                        goto out_elf_end;
+                               curr_dso->kernel = self->kernel;
                                curr_map = map__new2(start, curr_dso,
                                                     map->type);
                                if (curr_map == NULL) {
@@ -1025,9 +1059,9 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
                                }
                                curr_map->map_ip = identity__map_ip;
                                curr_map->unmap_ip = identity__map_ip;
-                               curr_dso->origin = DSO__ORIG_KERNEL;
+                               curr_dso->origin = self->origin;
                                map_groups__insert(kmap->kmaps, curr_map);
-                               dsos__add(&dsos__kernel, curr_dso);
+                               dsos__add(&self->node, curr_dso);
                                dso__set_loaded(curr_dso, map->type);
                        } else
                                curr_dso = curr_map->dso;
@@ -1089,7 +1123,7 @@ static bool dso__build_id_equal(const struct dso *self, u8 *build_id)
        return memcmp(self->build_id, build_id, sizeof(self->build_id)) == 0;
 }
 
-static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
 {
        bool have_build_id = false;
        struct dso *pos;
@@ -1107,13 +1141,6 @@ static bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
        return have_build_id;
 }
 
-bool dsos__read_build_ids(bool with_hits)
-{
-       bool kbuildids = __dsos__read_build_ids(&dsos__kernel, with_hits),
-            ubuildids = __dsos__read_build_ids(&dsos__user, with_hits);
-       return kbuildids || ubuildids;
-}
-
 /*
  * Align offset to 4 bytes as needed for note name and descriptor data.
  */
@@ -1248,6 +1275,8 @@ char dso__symtab_origin(const struct dso *self)
                [DSO__ORIG_BUILDID] =  'b',
                [DSO__ORIG_DSO] =      'd',
                [DSO__ORIG_KMODULE] =  'K',
+               [DSO__ORIG_GUEST_KERNEL] =  'g',
+               [DSO__ORIG_GUEST_KMODULE] =  'G',
        };
 
        if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
@@ -1263,11 +1292,20 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
        char build_id_hex[BUILD_ID_SIZE * 2 + 1];
        int ret = -1;
        int fd;
+       struct machine *machine;
+       const char *root_dir;
 
        dso__set_loaded(self, map->type);
 
-       if (self->kernel)
+       if (self->kernel == DSO_TYPE_KERNEL)
                return dso__load_kernel_sym(self, map, filter);
+       else if (self->kernel == DSO_TYPE_GUEST_KERNEL)
+               return dso__load_guest_kernel_sym(self, map, filter);
+
+       if (map->groups && map->groups->machine)
+               machine = map->groups->machine;
+       else
+               machine = NULL;
 
        name = malloc(size);
        if (!name)
@@ -1321,6 +1359,13 @@ more:
                case DSO__ORIG_DSO:
                        snprintf(name, size, "%s", self->long_name);
                        break;
+               case DSO__ORIG_GUEST_KMODULE:
+                       if (map->groups && map->groups->machine)
+                               root_dir = map->groups->machine->root_dir;
+                       else
+                               root_dir = "";
+                       snprintf(name, size, "%s%s", root_dir, self->long_name);
+                       break;
 
                default:
                        goto out;
@@ -1374,7 +1419,8 @@ struct map *map_groups__find_by_name(struct map_groups *self,
        return NULL;
 }
 
-static int dso__kernel_module_get_build_id(struct dso *self)
+static int dso__kernel_module_get_build_id(struct dso *self,
+                               const char *root_dir)
 {
        char filename[PATH_MAX];
        /*
@@ -1384,8 +1430,8 @@ static int dso__kernel_module_get_build_id(struct dso *self)
        const char *name = self->short_name + 1;
 
        snprintf(filename, sizeof(filename),
-                "/sys/module/%.*s/notes/.note.gnu.build-id",
-                (int)strlen(name - 1), name);
+                "%s/sys/module/%.*s/notes/.note.gnu.build-id",
+                root_dir, (int)strlen(name) - 1, name);
 
        if (sysfs__read_build_id(filename, self->build_id,
                                 sizeof(self->build_id)) == 0)
@@ -1394,26 +1440,33 @@ static int dso__kernel_module_get_build_id(struct dso *self)
        return 0;
 }
 
-static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirname)
+static int map_groups__set_modules_path_dir(struct map_groups *self,
+                               const char *dir_name)
 {
        struct dirent *dent;
-       DIR *dir = opendir(dirname);
+       DIR *dir = opendir(dir_name);
 
        if (!dir) {
-               pr_debug("%s: cannot open %s dir\n", __func__, dirname);
+               pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
                return -1;
        }
 
        while ((dent = readdir(dir)) != NULL) {
                char path[PATH_MAX];
+               struct stat st;
 
-               if (dent->d_type == DT_DIR) {
+               /*sshfs might return bad dent->d_type, so we have to stat*/
+               sprintf(path, "%s/%s", dir_name, dent->d_name);
+               if (stat(path, &st))
+                       continue;
+
+               if (S_ISDIR(st.st_mode)) {
                        if (!strcmp(dent->d_name, ".") ||
                            !strcmp(dent->d_name, ".."))
                                continue;
 
                        snprintf(path, sizeof(path), "%s/%s",
-                                dirname, dent->d_name);
+                                dir_name, dent->d_name);
                        if (map_groups__set_modules_path_dir(self, path) < 0)
                                goto failure;
                } else {
@@ -1433,13 +1486,13 @@ static int map_groups__set_modules_path_dir(struct map_groups *self, char *dirna
                                continue;
 
                        snprintf(path, sizeof(path), "%s/%s",
-                                dirname, dent->d_name);
+                                dir_name, dent->d_name);
 
                        long_name = strdup(path);
                        if (long_name == NULL)
                                goto failure;
                        dso__set_long_name(map->dso, long_name);
-                       dso__kernel_module_get_build_id(map->dso);
+                       dso__kernel_module_get_build_id(map->dso, "");
                }
        }
 
@@ -1449,18 +1502,47 @@ failure:
        return -1;
 }
 
-static int map_groups__set_modules_path(struct map_groups *self)
+static char *get_kernel_version(const char *root_dir)
 {
-       struct utsname uts;
+       char version[PATH_MAX];
+       FILE *file;
+       char *name, *tmp;
+       const char *prefix = "Linux version ";
+
+       sprintf(version, "%s/proc/version", root_dir);
+       file = fopen(version, "r");
+       if (!file)
+               return NULL;
+
+       version[0] = '\0';
+       tmp = fgets(version, sizeof(version), file);
+       fclose(file);
+
+       name = strstr(version, prefix);
+       if (!name)
+               return NULL;
+       name += strlen(prefix);
+       tmp = strchr(name, ' ');
+       if (tmp)
+               *tmp = '\0';
+
+       return strdup(name);
+}
+
+static int machine__set_modules_path(struct machine *self)
+{
+       char *version;
        char modules_path[PATH_MAX];
 
-       if (uname(&uts) < 0)
+       version = get_kernel_version(self->root_dir);
+       if (!version)
                return -1;
 
-       snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel",
-                uts.release);
+       snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
+                self->root_dir, version);
+       free(version);
 
-       return map_groups__set_modules_path_dir(self, modules_path);
+       return map_groups__set_modules_path_dir(&self->kmaps, modules_path);
 }
 
 /*
@@ -1470,8 +1552,8 @@ static int map_groups__set_modules_path(struct map_groups *self)
  */
 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
 {
-       struct map *self = zalloc(sizeof(*self) +
-                                 (dso->kernel ? sizeof(struct kmap) : 0));
+       struct map *self = calloc(1, (sizeof(*self) +
+                                     (dso->kernel ? sizeof(struct kmap) : 0)));
        if (self != NULL) {
                /*
                 * ->end will be filled after we load all the symbols
@@ -1482,11 +1564,11 @@ static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
        return self;
 }
 
-struct map *map_groups__new_module(struct map_groups *self, u64 start,
-                                  const char *filename)
+struct map *machine__new_module(struct machine *self, u64 start,
+                               const char *filename)
 {
        struct map *map;
-       struct dso *dso = __dsos__findnew(&dsos__kernel, filename);
+       struct dso *dso = __dsos__findnew(&self->kernel_dsos, filename);
 
        if (dso == NULL)
                return NULL;
@@ -1495,18 +1577,31 @@ struct map *map_groups__new_module(struct map_groups *self, u64 start,
        if (map == NULL)
                return NULL;
 
-       dso->origin = DSO__ORIG_KMODULE;
-       map_groups__insert(self, map);
+       if (machine__is_host(self))
+               dso->origin = DSO__ORIG_KMODULE;
+       else
+               dso->origin = DSO__ORIG_GUEST_KMODULE;
+       map_groups__insert(&self->kmaps, map);
        return map;
 }
 
-static int map_groups__create_modules(struct map_groups *self)
+static int machine__create_modules(struct machine *self)
 {
        char *line = NULL;
        size_t n;
-       FILE *file = fopen("/proc/modules", "r");
+       FILE *file;
        struct map *map;
+       const char *modules;
+       char path[PATH_MAX];
+
+       if (machine__is_default_guest(self))
+               modules = symbol_conf.default_guest_modules;
+       else {
+               sprintf(path, "%s/proc/modules", self->root_dir);
+               modules = path;
+       }
 
+       file = fopen(modules, "r");
        if (file == NULL)
                return -1;
 
@@ -1538,16 +1633,16 @@ static int map_groups__create_modules(struct map_groups *self)
                *sep = '\0';
 
                snprintf(name, sizeof(name), "[%s]", line);
-               map = map_groups__new_module(self, start, name);
+               map = machine__new_module(self, start, name);
                if (map == NULL)
                        goto out_delete_line;
-               dso__kernel_module_get_build_id(map->dso);
+               dso__kernel_module_get_build_id(map->dso, self->root_dir);
        }
 
        free(line);
        fclose(file);
 
-       return map_groups__set_modules_path(self);
+       return machine__set_modules_path(self);
 
 out_delete_line:
        free(line);
@@ -1714,8 +1809,56 @@ out_fixup:
        return err;
 }
 
-LIST_HEAD(dsos__user);
-LIST_HEAD(dsos__kernel);
+static int dso__load_guest_kernel_sym(struct dso *self, struct map *map,
+                               symbol_filter_t filter)
+{
+       int err;
+       const char *kallsyms_filename = NULL;
+       struct machine *machine;
+       char path[PATH_MAX];
+
+       if (!map->groups) {
+               pr_debug("Guest kernel map hasn't the point to groups\n");
+               return -1;
+       }
+       machine = map->groups->machine;
+
+       if (machine__is_default_guest(machine)) {
+               /*
+                * if the user specified a vmlinux filename, use it and only
+                * it, reporting errors to the user if it cannot be used.
+                * Or use file guest_kallsyms inputted by user on commandline
+                */
+               if (symbol_conf.default_guest_vmlinux_name != NULL) {
+                       err = dso__load_vmlinux(self, map,
+                               symbol_conf.default_guest_vmlinux_name, filter);
+                       goto out_try_fixup;
+               }
+
+               kallsyms_filename = symbol_conf.default_guest_kallsyms;
+               if (!kallsyms_filename)
+                       return -1;
+       } else {
+               sprintf(path, "%s/proc/kallsyms", machine->root_dir);
+               kallsyms_filename = path;
+       }
+
+       err = dso__load_kallsyms(self, kallsyms_filename, map, filter);
+       if (err > 0)
+               pr_debug("Using %s for symbols\n", kallsyms_filename);
+
+out_try_fixup:
+       if (err > 0) {
+               if (kallsyms_filename != NULL) {
+                       machine__mmap_name(machine, path, sizeof(path));
+                       dso__set_long_name(self, strdup(path));
+               }
+               map__fixup_start(map);
+               map__fixup_end(map);
+       }
+
+       return err;
+}
 
 static void dsos__add(struct list_head *head, struct dso *dso)
 {
@@ -1747,21 +1890,32 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name)
        return dso;
 }
 
-static void __dsos__fprintf(struct list_head *head, FILE *fp)
+size_t __dsos__fprintf(struct list_head *head, FILE *fp)
 {
        struct dso *pos;
+       size_t ret = 0;
 
        list_for_each_entry(pos, head, node) {
                int i;
                for (i = 0; i < MAP__NR_TYPES; ++i)
-                       dso__fprintf(pos, i, fp);
+                       ret += dso__fprintf(pos, i, fp);
        }
+
+       return ret;
 }
 
-void dsos__fprintf(FILE *fp)
+size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp)
 {
-       __dsos__fprintf(&dsos__kernel, fp);
-       __dsos__fprintf(&dsos__user, fp);
+       struct rb_node *nd;
+       size_t ret = 0;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret += __dsos__fprintf(&pos->kernel_dsos, fp);
+               ret += __dsos__fprintf(&pos->user_dsos, fp);
+       }
+
+       return ret;
 }
 
 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
@@ -1779,10 +1933,17 @@ static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
        return ret;
 }
 
-size_t dsos__fprintf_buildid(FILE *fp, bool with_hits)
+size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits)
 {
-       return (__dsos__fprintf_buildid(&dsos__kernel, fp, with_hits) +
-               __dsos__fprintf_buildid(&dsos__user, fp, with_hits));
+       struct rb_node *nd;
+       size_t ret = 0;
+
+       for (nd = rb_first(self); nd; nd = rb_next(nd)) {
+               struct machine *pos = rb_entry(nd, struct machine, rb_node);
+               ret += __dsos__fprintf_buildid(&pos->kernel_dsos, fp, with_hits);
+               ret += __dsos__fprintf_buildid(&pos->user_dsos, fp, with_hits);
+       }
+       return ret;
 }
 
 struct dso *dso__new_kernel(const char *name)
@@ -1791,55 +1952,98 @@ struct dso *dso__new_kernel(const char *name)
 
        if (self != NULL) {
                dso__set_short_name(self, "[kernel]");
-               self->kernel     = 1;
+               self->kernel = DSO_TYPE_KERNEL;
        }
 
        return self;
 }
 
-void dso__read_running_kernel_build_id(struct dso *self)
+static struct dso *dso__new_guest_kernel(struct machine *machine,
+                                       const char *name)
 {
-       if (sysfs__read_build_id("/sys/kernel/notes", self->build_id,
+       char bf[PATH_MAX];
+       struct dso *self = dso__new(name ?: machine__mmap_name(machine, bf, sizeof(bf)));
+
+       if (self != NULL) {
+               dso__set_short_name(self, "[guest.kernel]");
+               self->kernel = DSO_TYPE_GUEST_KERNEL;
+       }
+
+       return self;
+}
+
+void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine)
+{
+       char path[PATH_MAX];
+
+       if (machine__is_default_guest(machine))
+               return;
+       sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
+       if (sysfs__read_build_id(path, self->build_id,
                                 sizeof(self->build_id)) == 0)
                self->has_build_id = true;
 }
 
-static struct dso *dsos__create_kernel(const char *vmlinux)
+static struct dso *machine__create_kernel(struct machine *self)
 {
-       struct dso *kernel = dso__new_kernel(vmlinux);
+       const char *vmlinux_name = NULL;
+       struct dso *kernel;
 
-       if (kernel != NULL) {
-               dso__read_running_kernel_build_id(kernel);
-               dsos__add(&dsos__kernel, kernel);
+       if (machine__is_host(self)) {
+               vmlinux_name = symbol_conf.vmlinux_name;
+               kernel = dso__new_kernel(vmlinux_name);
+       } else {
+               if (machine__is_default_guest(self))
+                       vmlinux_name = symbol_conf.default_guest_vmlinux_name;
+               kernel = dso__new_guest_kernel(self, vmlinux_name);
        }
 
+       if (kernel != NULL) {
+               dso__read_running_kernel_build_id(kernel, self);
+               dsos__add(&self->kernel_dsos, kernel);
+       }
        return kernel;
 }
 
-int __map_groups__create_kernel_maps(struct map_groups *self,
-                                    struct map *vmlinux_maps[MAP__NR_TYPES],
-                                    struct dso *kernel)
+int __machine__create_kernel_maps(struct machine *self, struct dso *kernel)
 {
        enum map_type type;
 
        for (type = 0; type < MAP__NR_TYPES; ++type) {
                struct kmap *kmap;
 
-               vmlinux_maps[type] = map__new2(0, kernel, type);
-               if (vmlinux_maps[type] == NULL)
+               self->vmlinux_maps[type] = map__new2(0, kernel, type);
+               if (self->vmlinux_maps[type] == NULL)
                        return -1;
 
-               vmlinux_maps[type]->map_ip =
-                       vmlinux_maps[type]->unmap_ip = identity__map_ip;
+               self->vmlinux_maps[type]->map_ip =
+                       self->vmlinux_maps[type]->unmap_ip = identity__map_ip;
 
-               kmap = map__kmap(vmlinux_maps[type]);
-               kmap->kmaps = self;
-               map_groups__insert(self, vmlinux_maps[type]);
+               kmap = map__kmap(self->vmlinux_maps[type]);
+               kmap->kmaps = &self->kmaps;
+               map_groups__insert(&self->kmaps, self->vmlinux_maps[type]);
        }
 
        return 0;
 }
 
+int machine__create_kernel_maps(struct machine *self)
+{
+       struct dso *kernel = machine__create_kernel(self);
+
+       if (kernel == NULL ||
+           __machine__create_kernel_maps(self, kernel) < 0)
+               return -1;
+
+       if (symbol_conf.use_modules && machine__create_modules(self) < 0)
+               pr_debug("Problems creating module maps, continuing anyway...\n");
+       /*
+        * Now that we have all the maps created, just set the ->end of them:
+        */
+       map_groups__fixup_end(&self->kmaps);
+       return 0;
+}
+
 static void vmlinux_path__exit(void)
 {
        while (--vmlinux_path__nr_entries >= 0) {
@@ -1895,6 +2099,17 @@ out_fail:
        return -1;
 }
 
+size_t vmlinux_path__fprintf(FILE *fp)
+{
+       int i;
+       size_t printed = 0;
+
+       for (i = 0; i < vmlinux_path__nr_entries; ++i)
+               printed += fprintf(fp, "[%d] %s\n", i, vmlinux_path[i]);
+
+       return printed;
+}
+
 static int setup_list(struct strlist **list, const char *list_str,
                      const char *list_name)
 {
@@ -1945,22 +2160,129 @@ out_free_comm_list:
        return -1;
 }
 
-int map_groups__create_kernel_maps(struct map_groups *self,
-                                  struct map *vmlinux_maps[MAP__NR_TYPES])
+int machines__create_kernel_maps(struct rb_root *self, pid_t pid)
 {
-       struct dso *kernel = dsos__create_kernel(symbol_conf.vmlinux_name);
+       struct machine *machine = machines__findnew(self, pid);
 
-       if (kernel == NULL)
+       if (machine == NULL)
                return -1;
 
-       if (__map_groups__create_kernel_maps(self, vmlinux_maps, kernel) < 0)
-               return -1;
+       return machine__create_kernel_maps(machine);
+}
 
-       if (symbol_conf.use_modules && map_groups__create_modules(self) < 0)
-               pr_debug("Problems creating module maps, continuing anyway...\n");
-       /*
-        * Now that we have all the maps created, just set the ->end of them:
-        */
-       map_groups__fixup_end(self);
-       return 0;
+static int hex(char ch)
+{
+       if ((ch >= '0') && (ch <= '9'))
+               return ch - '0';
+       if ((ch >= 'a') && (ch <= 'f'))
+               return ch - 'a' + 10;
+       if ((ch >= 'A') && (ch <= 'F'))
+               return ch - 'A' + 10;
+       return -1;
+}
+
+/*
+ * While we find nice hex chars, build a long_val.
+ * Return number of chars processed.
+ */
+int hex2u64(const char *ptr, u64 *long_val)
+{
+       const char *p = ptr;
+       *long_val = 0;
+
+       while (*p) {
+               const int hex_val = hex(*p);
+
+               if (hex_val < 0)
+                       break;
+
+               *long_val = (*long_val << 4) | hex_val;
+               p++;
+       }
+
+       return p - ptr;
+}
+
+char *strxfrchar(char *s, char from, char to)
+{
+       char *p = s;
+
+       while ((p = strchr(p, from)) != NULL)
+               *p++ = to;
+
+       return s;
+}
+
+int machines__create_guest_kernel_maps(struct rb_root *self)
+{
+       int ret = 0;
+       struct dirent **namelist = NULL;
+       int i, items = 0;
+       char path[PATH_MAX];
+       pid_t pid;
+
+       if (symbol_conf.default_guest_vmlinux_name ||
+           symbol_conf.default_guest_modules ||
+           symbol_conf.default_guest_kallsyms) {
+               machines__create_kernel_maps(self, DEFAULT_GUEST_KERNEL_ID);
+       }
+
+       if (symbol_conf.guestmount) {
+               items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
+               if (items <= 0)
+                       return -ENOENT;
+               for (i = 0; i < items; i++) {
+                       if (!isdigit(namelist[i]->d_name[0])) {
+                               /* Filter out . and .. */
+                               continue;
+                       }
+                       pid = atoi(namelist[i]->d_name);
+                       sprintf(path, "%s/%s/proc/kallsyms",
+                               symbol_conf.guestmount,
+                               namelist[i]->d_name);
+                       ret = access(path, R_OK);
+                       if (ret) {
+                               pr_debug("Can't access file %s\n", path);
+                               goto failure;
+                       }
+                       machines__create_kernel_maps(self, pid);
+               }
+failure:
+               free(namelist);
+       }
+
+       return ret;
+}
+
+int machine__load_kallsyms(struct machine *self, const char *filename,
+                          enum map_type type, symbol_filter_t filter)
+{
+       struct map *map = self->vmlinux_maps[type];
+       int ret = dso__load_kallsyms(map->dso, filename, map, filter);
+
+       if (ret > 0) {
+               dso__set_loaded(map->dso, type);
+               /*
+                * Since /proc/kallsyms will have multiple sessions for the
+                * kernel, with modules between them, fixup the end of all
+                * sections.
+                */
+               __map_groups__fixup_end(&self->kmaps, type);
+       }
+
+       return ret;
+}
+
+int machine__load_vmlinux_path(struct machine *self, enum map_type type,
+                              symbol_filter_t filter)
+{
+       struct map *map = self->vmlinux_maps[type];
+       int ret = dso__load_vmlinux_path(map->dso, map, filter);
+
+       if (ret > 0) {
+               dso__set_loaded(map->dso, type);
+               map__reloc_vmlinux(map);
+       }
+
+       return ret;
 }
index f30a374..032469e 100644 (file)
@@ -3,10 +3,11 @@
 
 #include <linux/types.h>
 #include <stdbool.h>
-#include "types.h"
+#include <stdint.h>
+#include "map.h"
 #include <linux/list.h>
 #include <linux/rbtree.h>
-#include "event.h"
+#include <stdio.h>
 
 #define DEBUG_CACHE_DIR ".debug"
 
@@ -29,6 +30,9 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
 #endif
 #endif
 
+int hex2u64(const char *ptr, u64 *val);
+char *strxfrchar(char *s, char from, char to);
+
 /*
  * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
  * for newer versions we can use mmap to reduce memory usage:
@@ -44,10 +48,13 @@ static inline char *bfd_demangle(void __used *v, const char __used *c,
 #define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */
 #endif
 
+#define BUILD_ID_SIZE 20
+
 struct symbol {
        struct rb_node  rb_node;
        u64             start;
        u64             end;
+       u16             namelen;
        char            name[0];
 };
 
@@ -63,10 +70,15 @@ struct symbol_conf {
                        show_nr_samples,
                        use_callchain,
                        exclude_other,
-                       full_paths;
+                       full_paths,
+                       show_cpu_utilization;
        const char      *vmlinux_name,
                        *field_sep;
-       char            *dso_list_str,
+       const char      *default_guest_vmlinux_name,
+                       *default_guest_kallsyms,
+                       *default_guest_modules;
+       const char      *guestmount;
+       const char      *dso_list_str,
                        *comm_list_str,
                        *sym_list_str,
                        *col_width_list_str;
@@ -88,6 +100,11 @@ struct ref_reloc_sym {
        u64             unrelocated_addr;
 };
 
+struct map_symbol {
+       struct map    *map;
+       struct symbol *sym;
+};
+
 struct addr_location {
        struct thread *thread;
        struct map    *map;
@@ -95,6 +112,13 @@ struct addr_location {
        u64           addr;
        char          level;
        bool          filtered;
+       unsigned int  cpumode;
+};
+
+enum dso_kernel_type {
+       DSO_TYPE_USER = 0,
+       DSO_TYPE_KERNEL,
+       DSO_TYPE_GUEST_KERNEL
 };
 
 struct dso {
@@ -104,8 +128,9 @@ struct dso {
        u8               adjust_symbols:1;
        u8               slen_calculated:1;
        u8               has_build_id:1;
-       u8               kernel:1;
+       enum dso_kernel_type    kernel;
        u8               hit:1;
+       u8               annotate_warned:1;
        unsigned char    origin;
        u8               sorted_by_name;
        u8               loaded;
@@ -131,42 +156,65 @@ static inline void dso__set_loaded(struct dso *self, enum map_type type)
 
 void dso__sort_by_name(struct dso *self, enum map_type type);
 
-extern struct list_head dsos__user, dsos__kernel;
-
 struct dso *__dsos__findnew(struct list_head *head, const char *name);
 
-static inline struct dso *dsos__findnew(const char *name)
-{
-       return __dsos__findnew(&dsos__user, name);
-}
-
 int dso__load(struct dso *self, struct map *map, symbol_filter_t filter);
 int dso__load_vmlinux_path(struct dso *self, struct map *map,
                           symbol_filter_t filter);
 int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map,
                       symbol_filter_t filter);
-void dsos__fprintf(FILE *fp);
-size_t dsos__fprintf_buildid(FILE *fp, bool with_hits);
+int machine__load_kallsyms(struct machine *self, const char *filename,
+                          enum map_type type, symbol_filter_t filter);
+int machine__load_vmlinux_path(struct machine *self, enum map_type type,
+                              symbol_filter_t filter);
+
+size_t __dsos__fprintf(struct list_head *head, FILE *fp);
+
+size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp);
+size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits);
 
 size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
 size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
+
+enum dso_origin {
+       DSO__ORIG_KERNEL = 0,
+       DSO__ORIG_GUEST_KERNEL,
+       DSO__ORIG_JAVA_JIT,
+       DSO__ORIG_BUILD_ID_CACHE,
+       DSO__ORIG_FEDORA,
+       DSO__ORIG_UBUNTU,
+       DSO__ORIG_BUILDID,
+       DSO__ORIG_DSO,
+       DSO__ORIG_GUEST_KMODULE,
+       DSO__ORIG_KMODULE,
+       DSO__ORIG_NOT_FOUND,
+};
+
 char dso__symtab_origin(const struct dso *self);
 void dso__set_long_name(struct dso *self, char *name);
 void dso__set_build_id(struct dso *self, void *build_id);
-void dso__read_running_kernel_build_id(struct dso *self);
+void dso__read_running_kernel_build_id(struct dso *self, struct machine *machine);
 struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
 struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
                                        const char *name);
 
 int filename__read_build_id(const char *filename, void *bf, size_t size);
 int sysfs__read_build_id(const char *filename, void *bf, size_t size);
-bool dsos__read_build_ids(bool with_hits);
+bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
 int build_id__sprintf(const u8 *self, int len, char *bf);
 int kallsyms__parse(const char *filename, void *arg,
                    int (*process_symbol)(void *arg, const char *name,
                                          char type, u64 start));
 
+int __machine__create_kernel_maps(struct machine *self, struct dso *kernel);
+int machine__create_kernel_maps(struct machine *self);
+
+int machines__create_kernel_maps(struct rb_root *self, pid_t pid);
+int machines__create_guest_kernel_maps(struct rb_root *self);
+
 int symbol__init(void);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
 
+size_t vmlinux_path__fprintf(FILE *fp);
+
 #endif /* __PERF_SYMBOL */
index fa96831..1f7ecd4 100644 (file)
@@ -7,13 +7,35 @@
 #include "util.h"
 #include "debug.h"
 
-void map_groups__init(struct map_groups *self)
+int find_all_tid(int pid, pid_t ** all_tid)
 {
+       char name[256];
+       int items;
+       struct dirent **namelist = NULL;
+       int ret = 0;
        int i;
-       for (i = 0; i < MAP__NR_TYPES; ++i) {
-               self->maps[i] = RB_ROOT;
-               INIT_LIST_HEAD(&self->removed_maps[i]);
+
+       sprintf(name, "/proc/%d/task", pid);
+       items = scandir(name, &namelist, NULL, NULL);
+       if (items <= 0)
+                return -ENOENT;
+       *all_tid = malloc(sizeof(pid_t) * items);
+       if (!*all_tid) {
+               ret = -ENOMEM;
+               goto failure;
        }
+
+       for (i = 0; i < items; i++)
+               (*all_tid)[i] = atoi(namelist[i]->d_name);
+
+       ret = items;
+
+failure:
+       for (i=0; i<items; i++)
+               free(namelist[i]);
+       free(namelist);
+
+       return ret;
 }
 
 static struct thread *thread__new(pid_t pid)
@@ -31,28 +53,6 @@ static struct thread *thread__new(pid_t pid)
        return self;
 }
 
-static void map_groups__flush(struct map_groups *self)
-{
-       int type;
-
-       for (type = 0; type < MAP__NR_TYPES; type++) {
-               struct rb_root *root = &self->maps[type];
-               struct rb_node *next = rb_first(root);
-
-               while (next) {
-                       struct map *pos = rb_entry(next, struct map, rb_node);
-                       next = rb_next(&pos->rb_node);
-                       rb_erase(&pos->rb_node, root);
-                       /*
-                        * We may have references to this map, for
-                        * instance in some hist_entry instances, so
-                        * just move them to a separate list.
-                        */
-                       list_add_tail(&pos->node, &self->removed_maps[pos->type]);
-               }
-       }
-}
-
 int thread__set_comm(struct thread *self, const char *comm)
 {
        int err;
@@ -79,69 +79,10 @@ int thread__comm_len(struct thread *self)
        return self->comm_len;
 }
 
-size_t __map_groups__fprintf_maps(struct map_groups *self,
-                                 enum map_type type, FILE *fp)
-{
-       size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
-       struct rb_node *nd;
-
-       for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
-               struct map *pos = rb_entry(nd, struct map, rb_node);
-               printed += fprintf(fp, "Map:");
-               printed += map__fprintf(pos, fp);
-               if (verbose > 2) {
-                       printed += dso__fprintf(pos->dso, type, fp);
-                       printed += fprintf(fp, "--\n");
-               }
-       }
-
-       return printed;
-}
-
-size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp)
-{
-       size_t printed = 0, i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               printed += __map_groups__fprintf_maps(self, i, fp);
-       return printed;
-}
-
-static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
-                                                enum map_type type, FILE *fp)
-{
-       struct map *pos;
-       size_t printed = 0;
-
-       list_for_each_entry(pos, &self->removed_maps[type], node) {
-               printed += fprintf(fp, "Map:");
-               printed += map__fprintf(pos, fp);
-               if (verbose > 1) {
-                       printed += dso__fprintf(pos->dso, type, fp);
-                       printed += fprintf(fp, "--\n");
-               }
-       }
-       return printed;
-}
-
-static size_t map_groups__fprintf_removed_maps(struct map_groups *self, FILE *fp)
-{
-       size_t printed = 0, i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               printed += __map_groups__fprintf_removed_maps(self, i, fp);
-       return printed;
-}
-
-static size_t map_groups__fprintf(struct map_groups *self, FILE *fp)
-{
-       size_t printed = map_groups__fprintf_maps(self, fp);
-       printed += fprintf(fp, "Removed maps:\n");
-       return printed + map_groups__fprintf_removed_maps(self, fp);
-}
-
 static size_t thread__fprintf(struct thread *self, FILE *fp)
 {
        return fprintf(fp, "Thread %d %s\n", self->pid, self->comm) +
-              map_groups__fprintf(&self->mg, fp);
+              map_groups__fprintf(&self->mg, verbose, fp);
 }
 
 struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
@@ -183,127 +124,12 @@ struct thread *perf_session__findnew(struct perf_session *self, pid_t pid)
        return th;
 }
 
-static int map_groups__fixup_overlappings(struct map_groups *self,
-                                         struct map *map)
-{
-       struct rb_root *root = &self->maps[map->type];
-       struct rb_node *next = rb_first(root);
-
-       while (next) {
-               struct map *pos = rb_entry(next, struct map, rb_node);
-               next = rb_next(&pos->rb_node);
-
-               if (!map__overlap(pos, map))
-                       continue;
-
-               if (verbose >= 2) {
-                       fputs("overlapping maps:\n", stderr);
-                       map__fprintf(map, stderr);
-                       map__fprintf(pos, stderr);
-               }
-
-               rb_erase(&pos->rb_node, root);
-               /*
-                * We may have references to this map, for instance in some
-                * hist_entry instances, so just move them to a separate
-                * list.
-                */
-               list_add_tail(&pos->node, &self->removed_maps[map->type]);
-               /*
-                * Now check if we need to create new maps for areas not
-                * overlapped by the new map:
-                */
-               if (map->start > pos->start) {
-                       struct map *before = map__clone(pos);
-
-                       if (before == NULL)
-                               return -ENOMEM;
-
-                       before->end = map->start - 1;
-                       map_groups__insert(self, before);
-                       if (verbose >= 2)
-                               map__fprintf(before, stderr);
-               }
-
-               if (map->end < pos->end) {
-                       struct map *after = map__clone(pos);
-
-                       if (after == NULL)
-                               return -ENOMEM;
-
-                       after->start = map->end + 1;
-                       map_groups__insert(self, after);
-                       if (verbose >= 2)
-                               map__fprintf(after, stderr);
-               }
-       }
-
-       return 0;
-}
-
-void maps__insert(struct rb_root *maps, struct map *map)
-{
-       struct rb_node **p = &maps->rb_node;
-       struct rb_node *parent = NULL;
-       const u64 ip = map->start;
-       struct map *m;
-
-       while (*p != NULL) {
-               parent = *p;
-               m = rb_entry(parent, struct map, rb_node);
-               if (ip < m->start)
-                       p = &(*p)->rb_left;
-               else
-                       p = &(*p)->rb_right;
-       }
-
-       rb_link_node(&map->rb_node, parent, p);
-       rb_insert_color(&map->rb_node, maps);
-}
-
-struct map *maps__find(struct rb_root *maps, u64 ip)
-{
-       struct rb_node **p = &maps->rb_node;
-       struct rb_node *parent = NULL;
-       struct map *m;
-
-       while (*p != NULL) {
-               parent = *p;
-               m = rb_entry(parent, struct map, rb_node);
-               if (ip < m->start)
-                       p = &(*p)->rb_left;
-               else if (ip > m->end)
-                       p = &(*p)->rb_right;
-               else
-                       return m;
-       }
-
-       return NULL;
-}
-
 void thread__insert_map(struct thread *self, struct map *map)
 {
-       map_groups__fixup_overlappings(&self->mg, map);
+       map_groups__fixup_overlappings(&self->mg, map, verbose, stderr);
        map_groups__insert(&self->mg, map);
 }
 
-/*
- * XXX This should not really _copy_ te maps, but refcount them.
- */
-static int map_groups__clone(struct map_groups *self,
-                            struct map_groups *parent, enum map_type type)
-{
-       struct rb_node *nd;
-       for (nd = rb_first(&parent->maps[type]); nd; nd = rb_next(nd)) {
-               struct map *map = rb_entry(nd, struct map, rb_node);
-               struct map *new = map__clone(map);
-               if (new == NULL)
-                       return -ENOMEM;
-               map_groups__insert(self, new);
-       }
-       return 0;
-}
-
 int thread__fork(struct thread *self, struct thread *parent)
 {
        int i;
@@ -336,15 +162,3 @@ size_t perf_session__fprintf(struct perf_session *self, FILE *fp)
 
        return ret;
 }
-
-struct symbol *map_groups__find_symbol(struct map_groups *self,
-                                      enum map_type type, u64 addr,
-                                      symbol_filter_t filter)
-{
-       struct map *map = map_groups__find(self, type, addr);
-
-       if (map != NULL)
-               return map__find_symbol(map, map->map_ip(map, addr), filter);
-
-       return NULL;
-}
index dcf7030..1dfd9ff 100644 (file)
@@ -5,14 +5,6 @@
 #include <unistd.h>
 #include "symbol.h"
 
-struct map_groups {
-       struct rb_root          maps[MAP__NR_TYPES];
-       struct list_head        removed_maps[MAP__NR_TYPES];
-};
-
-size_t __map_groups__fprintf_maps(struct map_groups *self,
-                                 enum map_type type, FILE *fp);
-
 struct thread {
        struct rb_node          rb_node;
        struct map_groups       mg;
@@ -23,29 +15,16 @@ struct thread {
        int                     comm_len;
 };
 
-void map_groups__init(struct map_groups *self);
+struct perf_session;
+
+int find_all_tid(int pid, pid_t ** all_tid);
 int thread__set_comm(struct thread *self, const char *comm);
 int thread__comm_len(struct thread *self);
 struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
 void thread__insert_map(struct thread *self, struct map *map);
 int thread__fork(struct thread *self, struct thread *parent);
-size_t map_groups__fprintf_maps(struct map_groups *self, FILE *fp);
 size_t perf_session__fprintf(struct perf_session *self, FILE *fp);
 
-void maps__insert(struct rb_root *maps, struct map *map);
-struct map *maps__find(struct rb_root *maps, u64 addr);
-
-static inline void map_groups__insert(struct map_groups *self, struct map *map)
-{
-        maps__insert(&self->maps[map->type], map);
-}
-
-static inline struct map *map_groups__find(struct map_groups *self,
-                                          enum map_type type, u64 addr)
-{
-       return maps__find(&self->maps[type], addr);
-}
-
 static inline struct map *thread__find_map(struct thread *self,
                                           enum map_type type, u64 addr)
 {
@@ -54,34 +33,12 @@ static inline struct map *thread__find_map(struct thread *self,
 
 void thread__find_addr_map(struct thread *self,
                           struct perf_session *session, u8 cpumode,
-                          enum map_type type, u64 addr,
+                          enum map_type type, pid_t pid, u64 addr,
                           struct addr_location *al);
 
 void thread__find_addr_location(struct thread *self,
                                struct perf_session *session, u8 cpumode,
-                               enum map_type type, u64 addr,
+                               enum map_type type, pid_t pid, u64 addr,
                                struct addr_location *al,
                                symbol_filter_t filter);
-struct symbol *map_groups__find_symbol(struct map_groups *self,
-                                      enum map_type type, u64 addr,
-                                      symbol_filter_t filter);
-
-static inline struct symbol *map_groups__find_function(struct map_groups *self,
-                                                      u64 addr,
-                                                      symbol_filter_t filter)
-{
-       return map_groups__find_symbol(self, MAP__FUNCTION, addr, filter);
-}
-
-struct map *map_groups__find_by_name(struct map_groups *self,
-                                    enum map_type type, const char *name);
-
-int __map_groups__create_kernel_maps(struct map_groups *self,
-                                    struct map *vmlinux_maps[MAP__NR_TYPES],
-                                    struct dso *kernel);
-int map_groups__create_kernel_maps(struct map_groups *self,
-                                  struct map *vmlinux_maps[MAP__NR_TYPES]);
-
-struct map *map_groups__new_module(struct map_groups *self, u64 start,
-                                  const char *filename);
 #endif /* __PERF_THREAD_H */
index 5ea8973..b157260 100644 (file)
@@ -154,10 +154,17 @@ static void put_tracing_file(char *file)
        free(file);
 }
 
+static ssize_t calc_data_size;
+
 static ssize_t write_or_die(const void *buf, size_t len)
 {
        int ret;
 
+       if (calc_data_size) {
+               calc_data_size += len;
+               return len;
+       }
+
        ret = write(output_fd, buf, len);
        if (ret < 0)
                die("writing to '%s'", output_file);
@@ -480,6 +487,17 @@ get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
        return nr_tracepoints > 0 ? path.next : NULL;
 }
 
+bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events)
+{
+       int i;
+
+       for (i = 0; i < nb_events; i++)
+               if (pattrs[i].type == PERF_TYPE_TRACEPOINT)
+                       return true;
+
+       return false;
+}
+
 int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
 {
        char buf[BUFSIZ];
@@ -526,3 +544,20 @@ int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
 
        return 0;
 }
+
+ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
+                              int nb_events)
+{
+       ssize_t size;
+       int err = 0;
+
+       calc_data_size = 1;
+       err = read_tracing_data(fd, pattrs, nb_events);
+       size = calc_data_size - 1;
+       calc_data_size = 0;
+
+       if (err < 0)
+               return err;
+
+       return size;
+}
index 9b3c20f..73a0222 100644 (file)
@@ -37,10 +37,12 @@ int header_page_ts_offset;
 int header_page_ts_size;
 int header_page_size_offset;
 int header_page_size_size;
+int header_page_overwrite_offset;
+int header_page_overwrite_size;
 int header_page_data_offset;
 int header_page_data_size;
 
-int latency_format;
+bool latency_format;
 
 static char *input_buf;
 static unsigned long long input_buf_ptr;
@@ -628,23 +630,32 @@ static int test_type(enum event_type type, enum event_type expect)
        return 0;
 }
 
-static int test_type_token(enum event_type type, char *token,
-                   enum event_type expect, const char *expect_tok)
+static int __test_type_token(enum event_type type, char *token,
+                            enum event_type expect, const char *expect_tok,
+                            bool warn)
 {
        if (type != expect) {
-               warning("Error: expected type %d but read %d",
-                   expect, type);
+               if (warn)
+                       warning("Error: expected type %d but read %d",
+                               expect, type);
                return -1;
        }
 
        if (strcmp(token, expect_tok) != 0) {
-               warning("Error: expected '%s' but read '%s'",
-                   expect_tok, token);
+               if (warn)
+                       warning("Error: expected '%s' but read '%s'",
+                               expect_tok, token);
                return -1;
        }
        return 0;
 }
 
+static int test_type_token(enum event_type type, char *token,
+                          enum event_type expect, const char *expect_tok)
+{
+       return __test_type_token(type, token, expect, expect_tok, true);
+}
+
 static int __read_expect_type(enum event_type expect, char **tok, int newline_ok)
 {
        enum event_type type;
@@ -661,7 +672,8 @@ static int read_expect_type(enum event_type expect, char **tok)
        return __read_expect_type(expect, tok, 1);
 }
 
-static int __read_expected(enum event_type expect, const char *str, int newline_ok)
+static int __read_expected(enum event_type expect, const char *str,
+                          int newline_ok, bool warn)
 {
        enum event_type type;
        char *token;
@@ -672,7 +684,7 @@ static int __read_expected(enum event_type expect, const char *str, int newline_
        else
                type = read_token_item(&token);
 
-       ret = test_type_token(type, token, expect, str);
+       ret = __test_type_token(type, token, expect, str, warn);
 
        free_token(token);
 
@@ -681,12 +693,12 @@ static int __read_expected(enum event_type expect, const char *str, int newline_
 
 static int read_expected(enum event_type expect, const char *str)
 {
-       return __read_expected(expect, str, 1);
+       return __read_expected(expect, str, 1, true);
 }
 
 static int read_expected_item(enum event_type expect, const char *str)
 {
-       return __read_expected(expect, str, 0);
+       return __read_expected(expect, str, 0, true);
 }
 
 static char *event_read_name(void)
@@ -744,7 +756,7 @@ static int field_is_string(struct format_field *field)
 
 static int field_is_dynamic(struct format_field *field)
 {
-       if (!strcmp(field->type, "__data_loc"))
+       if (!strncmp(field->type, "__data_loc", 10))
                return 1;
 
        return 0;
@@ -1925,7 +1937,7 @@ void *raw_field_ptr(struct event *event, const char *name, void *data)
        if (!field)
                return NULL;
 
-       if (field->flags & FIELD_IS_STRING) {
+       if (field->flags & FIELD_IS_DYNAMIC) {
                int offset;
 
                offset = *(int *)(data + field->offset);
@@ -3087,88 +3099,6 @@ static void print_args(struct print_arg *args)
        }
 }
 
-static void parse_header_field(const char *field,
-                              int *offset, int *size)
-{
-       char *token;
-       int type;
-
-       if (read_expected(EVENT_ITEM, "field") < 0)
-               return;
-       if (read_expected(EVENT_OP, ":") < 0)
-               return;
-
-       /* type */
-       if (read_expect_type(EVENT_ITEM, &token) < 0)
-               goto fail;
-       free_token(token);
-
-       if (read_expected(EVENT_ITEM, field) < 0)
-               return;
-       if (read_expected(EVENT_OP, ";") < 0)
-               return;
-       if (read_expected(EVENT_ITEM, "offset") < 0)
-               return;
-       if (read_expected(EVENT_OP, ":") < 0)
-               return;
-       if (read_expect_type(EVENT_ITEM, &token) < 0)
-               goto fail;
-       *offset = atoi(token);
-       free_token(token);
-       if (read_expected(EVENT_OP, ";") < 0)
-               return;
-       if (read_expected(EVENT_ITEM, "size") < 0)
-               return;
-       if (read_expected(EVENT_OP, ":") < 0)
-               return;
-       if (read_expect_type(EVENT_ITEM, &token) < 0)
-               goto fail;
-       *size = atoi(token);
-       free_token(token);
-       if (read_expected(EVENT_OP, ";") < 0)
-               return;
-       type = read_token(&token);
-       if (type != EVENT_NEWLINE) {
-               /* newer versions of the kernel have a "signed" type */
-               if (type != EVENT_ITEM)
-                       goto fail;
-
-               if (strcmp(token, "signed") != 0)
-                       goto fail;
-
-               free_token(token);
-
-               if (read_expected(EVENT_OP, ":") < 0)
-                       return;
-
-               if (read_expect_type(EVENT_ITEM, &token))
-                       goto fail;
-
-               free_token(token);
-               if (read_expected(EVENT_OP, ";") < 0)
-                       return;
-
-               if (read_expect_type(EVENT_NEWLINE, &token))
-                       goto fail;
-       }
- fail:
-       free_token(token);
-}
-
-int parse_header_page(char *buf, unsigned long size)
-{
-       init_input_buf(buf, size);
-
-       parse_header_field("timestamp", &header_page_ts_offset,
-                          &header_page_ts_size);
-       parse_header_field("commit", &header_page_size_offset,
-                          &header_page_size_size);
-       parse_header_field("data", &header_page_data_offset,
-                          &header_page_data_size);
-
-       return 0;
-}
-
 int parse_ftrace_file(char *buf, unsigned long size)
 {
        struct format_field *field;
index 7cd1193..cb54cd0 100644 (file)
@@ -50,14 +50,51 @@ static int long_size;
 
 static unsigned long   page_size;
 
+static ssize_t calc_data_size;
+static bool repipe;
+
+/* If it fails, the next read will report it */
+static void skip(int size)
+{
+       lseek(input_fd, size, SEEK_CUR);
+}
+
+static int do_read(int fd, void *buf, int size)
+{
+       int rsize = size;
+
+       while (size) {
+               int ret = read(fd, buf, size);
+
+               if (ret <= 0)
+                       return -1;
+
+               if (repipe) {
+                       int retw = write(STDOUT_FILENO, buf, ret);
+
+                       if (retw <= 0 || retw != ret)
+                               die("repiping input file");
+               }
+
+               size -= ret;
+               buf += ret;
+       }
+
+       return rsize;
+}
+
 static int read_or_die(void *data, int size)
 {
        int r;
 
-       r = read(input_fd, data, size);
-       if (r != size)
+       r = do_read(input_fd, data, size);
+       if (r <= 0)
                die("reading input file (size expected=%d received=%d)",
                    size, r);
+
+       if (calc_data_size)
+               calc_data_size += r;
+
        return r;
 }
 
@@ -82,57 +119,36 @@ static char *read_string(void)
        char buf[BUFSIZ];
        char *str = NULL;
        int size = 0;
-       int i;
        off_t r;
+       char c;
 
        for (;;) {
-               r = read(input_fd, buf, BUFSIZ);
+               r = read(input_fd, &c, 1);
                if (r < 0)
                        die("reading input file");
 
                if (!r)
                        die("no data");
 
-               for (i = 0; i < r; i++) {
-                       if (!buf[i])
-                               break;
-               }
-               if (i < r)
-                       break;
+               if (repipe) {
+                       int retw = write(STDOUT_FILENO, &c, 1);
 
-               if (str) {
-                       size += BUFSIZ;
-                       str = realloc(str, size);
-                       if (!str)
-                               die("malloc of size %d", size);
-                       memcpy(str + (size - BUFSIZ), buf, BUFSIZ);
-               } else {
-                       size = BUFSIZ;
-                       str = malloc_or_die(size);
-                       memcpy(str, buf, size);
+                       if (retw <= 0 || retw != r)
+                               die("repiping input file string");
                }
-       }
 
-       /* trailing \0: */
-       i++;
-
-       /* move the file descriptor to the end of the string */
-       r = lseek(input_fd, -(r - i), SEEK_CUR);
-       if (r == (off_t)-1)
-               die("lseek");
-
-       if (str) {
-               size += i;
-               str = realloc(str, size);
-               if (!str)
-                       die("malloc of size %d", size);
-               memcpy(str + (size - i), buf, i);
-       } else {
-               size = i;
-               str = malloc_or_die(i);
-               memcpy(str, buf, i);
+               buf[size++] = c;
+
+               if (!c)
+                       break;
        }
 
+       if (calc_data_size)
+               calc_data_size += size;
+
+       str = malloc_or_die(size);
+       memcpy(str, buf, size);
+
        return str;
 }
 
@@ -174,7 +190,6 @@ static void read_ftrace_printk(void)
 static void read_header_files(void)
 {
        unsigned long long size;
-       char *header_page;
        char *header_event;
        char buf[BUFSIZ];
 
@@ -184,10 +199,7 @@ static void read_header_files(void)
                die("did not read header page");
 
        size = read8();
-       header_page = malloc_or_die(size);
-       read_or_die(header_page, size);
-       parse_header_page(header_page, size);
-       free(header_page);
+       skip(size);
 
        /*
         * The size field in the page is of type long,
@@ -459,7 +471,7 @@ struct record *trace_read_data(int cpu)
        return data;
 }
 
-void trace_report(int fd)
+ssize_t trace_report(int fd, bool __repipe)
 {
        char buf[BUFSIZ];
        char test[] = { 23, 8, 68 };
@@ -467,6 +479,10 @@ void trace_report(int fd)
        int show_version = 0;
        int show_funcs = 0;
        int show_printk = 0;
+       ssize_t size;
+
+       calc_data_size = 1;
+       repipe = __repipe;
 
        input_fd = fd;
 
@@ -499,14 +515,18 @@ void trace_report(int fd)
        read_proc_kallsyms();
        read_ftrace_printk();
 
+       size = calc_data_size - 1;
+       calc_data_size = 0;
+       repipe = false;
+
        if (show_funcs) {
                print_funcs();
-               return;
+               return size;
        }
        if (show_printk) {
                print_printk();
-               return;
+               return size;
        }
 
-       return;
+       return size;
 }
index c3269b9..406d452 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __PERF_TRACE_EVENTS_H
 #define __PERF_TRACE_EVENTS_H
 
+#include <stdbool.h>
 #include "parse-events.h"
 
 #define __unused __attribute__((unused))
@@ -162,7 +163,7 @@ struct record *trace_read_data(int cpu);
 
 void parse_set_info(int nr_cpus, int long_sz);
 
-void trace_report(int fd);
+ssize_t trace_report(int fd, bool repipe);
 
 void *malloc_or_die(unsigned int size);
 
@@ -241,9 +242,8 @@ extern int header_page_size_size;
 extern int header_page_data_offset;
 extern int header_page_data_size;
 
-extern int latency_format;
+extern bool latency_format;
 
-int parse_header_page(char *buf, unsigned long size);
 int trace_parse_common_type(void *data);
 int trace_parse_common_pid(void *data);
 int parse_common_pc(void *data);
@@ -258,6 +258,8 @@ void *raw_field_ptr(struct event *event, const char *name, void *data);
 unsigned long long eval_flag(const char *flag);
 
 int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
+ssize_t read_tracing_data_size(int fd, struct perf_event_attr *pattrs,
+                              int nb_events);
 
 /* taken from kernel/trace/trace.h */
 enum trace_flag_type {
index f9b890f..2142656 100644 (file)
@@ -92,3 +92,25 @@ out_close_from:
 out:
        return err;
 }
+
+unsigned long convert_unit(unsigned long value, char *unit)
+{
+       *unit = ' ';
+
+       if (value > 1000) {
+               value /= 1000;
+               *unit = 'K';
+       }
+
+       if (value > 1000) {
+               value /= 1000;
+               *unit = 'M';
+       }
+
+       if (value > 1000) {
+               value /= 1000;
+               *unit = 'G';
+       }
+
+       return value;
+}
index 0f5b2a6..0795bf3 100644 (file)
 #define _ALL_SOURCE 1
 #define _GNU_SOURCE 1
 #define _BSD_SOURCE 1
+#define HAS_BOOL
 
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
 #include <fcntl.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -78,6 +80,7 @@
 #include <pwd.h>
 #include <inttypes.h>
 #include "../../../include/linux/magic.h"
+#include "types.h"
 
 
 #ifndef NO_ICONV
@@ -295,6 +298,13 @@ extern void *xmemdupz(const void *data, size_t len);
 extern char *xstrndup(const char *str, size_t len);
 extern void *xrealloc(void *ptr, size_t size) __attribute__((weak));
 
+static inline void *xzalloc(size_t size)
+{
+       void *buf = xmalloc(size);
+
+       return memset(buf, 0, size);
+}
+
 static inline void *zalloc(size_t size)
 {
        return calloc(1, size);
@@ -309,6 +319,7 @@ static inline int has_extension(const char *filename, const char *ext)
 {
        size_t len = strlen(filename);
        size_t extlen = strlen(ext);
+
        return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
 }
 
@@ -322,6 +333,7 @@ static inline int has_extension(const char *filename, const char *ext)
 #undef isalnum
 #undef tolower
 #undef toupper
+
 extern unsigned char sane_ctype[256];
 #define GIT_SPACE              0x01
 #define GIT_DIGIT              0x02
@@ -406,4 +418,14 @@ void git_qsort(void *base, size_t nmemb, size_t size,
 int mkdir_p(char *path, mode_t mode);
 int copyfile(const char *from, const char *to);
 
+s64 perf_atoll(const char *str);
+char **argv_split(const char *str, int *argcp);
+void argv_free(char **argv);
+bool strglobmatch(const char *str, const char *pat);
+bool strlazymatch(const char *str, const char *pat);
+unsigned long convert_unit(unsigned long value, char *unit);
+
+#define _STR(x) #x
+#define STR(x) _STR(x)
+
 #endif
index 03a5eb2..7c79c1d 100644 (file)
@@ -197,7 +197,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
        union kvm_ioapic_redirect_entry entry;
        int ret = 1;
 
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        if (irq >= 0 && irq < IOAPIC_NUM_PINS) {
                entry = ioapic->redirtbl[irq];
                level ^= entry.fields.polarity;
@@ -214,7 +214,7 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
                }
                trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0);
        }
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
 
        return ret;
 }
@@ -238,9 +238,9 @@ static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector,
                 * is dropped it will be put into irr and will be delivered
                 * after ack notifier returns.
                 */
-               mutex_unlock(&ioapic->lock);
+               spin_unlock(&ioapic->lock);
                kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i);
-               mutex_lock(&ioapic->lock);
+               spin_lock(&ioapic->lock);
 
                if (trigger_mode != IOAPIC_LEVEL_TRIG)
                        continue;
@@ -259,9 +259,9 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
        smp_rmb();
        if (!test_bit(vector, ioapic->handled_vectors))
                return;
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        __kvm_ioapic_update_eoi(ioapic, vector, trigger_mode);
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
 }
 
 static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev)
@@ -287,7 +287,7 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
        ASSERT(!(addr & 0xf));  /* check alignment */
 
        addr &= 0xff;
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        switch (addr) {
        case IOAPIC_REG_SELECT:
                result = ioapic->ioregsel;
@@ -301,7 +301,7 @@ static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
                result = 0;
                break;
        }
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
 
        switch (len) {
        case 8:
@@ -338,7 +338,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
        }
 
        addr &= 0xff;
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        switch (addr) {
        case IOAPIC_REG_SELECT:
                ioapic->ioregsel = data;
@@ -356,7 +356,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
        default:
                break;
        }
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
        return 0;
 }
 
@@ -386,7 +386,7 @@ int kvm_ioapic_init(struct kvm *kvm)
        ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL);
        if (!ioapic)
                return -ENOMEM;
-       mutex_init(&ioapic->lock);
+       spin_lock_init(&ioapic->lock);
        kvm->arch.vioapic = ioapic;
        kvm_ioapic_reset(ioapic);
        kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
@@ -419,9 +419,9 @@ int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
        if (!ioapic)
                return -EINVAL;
 
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        memcpy(state, ioapic, sizeof(struct kvm_ioapic_state));
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
        return 0;
 }
 
@@ -431,9 +431,9 @@ int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
        if (!ioapic)
                return -EINVAL;
 
-       mutex_lock(&ioapic->lock);
+       spin_lock(&ioapic->lock);
        memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
        update_handled_vectors(ioapic);
-       mutex_unlock(&ioapic->lock);
+       spin_unlock(&ioapic->lock);
        return 0;
 }
index 8a751b7..0b190c3 100644 (file)
@@ -45,7 +45,7 @@ struct kvm_ioapic {
        struct kvm_io_device dev;
        struct kvm *kvm;
        void (*ack_notifier)(void *opaque, int irq);
-       struct mutex lock;
+       spinlock_t lock;
        DECLARE_BITMAP(handled_vectors, 256);
 };
 
index 80fd3ad..11692b9 100644 (file)
@@ -32,12 +32,30 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm);
 static void kvm_iommu_put_pages(struct kvm *kvm,
                                gfn_t base_gfn, unsigned long npages);
 
+static pfn_t kvm_pin_pages(struct kvm *kvm, struct kvm_memory_slot *slot,
+                          gfn_t gfn, unsigned long size)
+{
+       gfn_t end_gfn;
+       pfn_t pfn;
+
+       pfn     = gfn_to_pfn_memslot(kvm, slot, gfn);
+       end_gfn = gfn + (size >> PAGE_SHIFT);
+       gfn    += 1;
+
+       if (is_error_pfn(pfn))
+               return pfn;
+
+       while (gfn < end_gfn)
+               gfn_to_pfn_memslot(kvm, slot, gfn++);
+
+       return pfn;
+}
+
 int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
 {
-       gfn_t gfn = slot->base_gfn;
-       unsigned long npages = slot->npages;
+       gfn_t gfn, end_gfn;
        pfn_t pfn;
-       int i, r = 0;
+       int r = 0;
        struct iommu_domain *domain = kvm->arch.iommu_domain;
        int flags;
 
@@ -45,31 +63,62 @@ int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
        if (!domain)
                return 0;
 
+       gfn     = slot->base_gfn;
+       end_gfn = gfn + slot->npages;
+
        flags = IOMMU_READ | IOMMU_WRITE;
        if (kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY)
                flags |= IOMMU_CACHE;
 
-       for (i = 0; i < npages; i++) {
-               /* check if already mapped */
-               if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn)))
+
+       while (gfn < end_gfn) {
+               unsigned long page_size;
+
+               /* Check if already mapped */
+               if (iommu_iova_to_phys(domain, gfn_to_gpa(gfn))) {
+                       gfn += 1;
+                       continue;
+               }
+
+               /* Get the page size we could use to map */
+               page_size = kvm_host_page_size(kvm, gfn);
+
+               /* Make sure the page_size does not exceed the memslot */
+               while ((gfn + (page_size >> PAGE_SHIFT)) > end_gfn)
+                       page_size >>= 1;
+
+               /* Make sure gfn is aligned to the page size we want to map */
+               while ((gfn << PAGE_SHIFT) & (page_size - 1))
+                       page_size >>= 1;
+
+               /*
+                * Pin all pages we are about to map in memory. This is
+                * important because we unmap and unpin in 4kb steps later.
+                */
+               pfn = kvm_pin_pages(kvm, slot, gfn, page_size);
+               if (is_error_pfn(pfn)) {
+                       gfn += 1;
                        continue;
+               }
 
-               pfn = gfn_to_pfn_memslot(kvm, slot, gfn);
-               r = iommu_map_range(domain,
-                                   gfn_to_gpa(gfn),
-                                   pfn_to_hpa(pfn),
-                                   PAGE_SIZE, flags);
+               /* Map into IO address space */
+               r = iommu_map(domain, gfn_to_gpa(gfn), pfn_to_hpa(pfn),
+                             get_order(page_size), flags);
                if (r) {
                        printk(KERN_ERR "kvm_iommu_map_address:"
                               "iommu failed to map pfn=%lx\n", pfn);
                        goto unmap_pages;
                }
-               gfn++;
+
+               gfn += page_size >> PAGE_SHIFT;
+
+
        }
+
        return 0;
 
 unmap_pages:
-       kvm_iommu_put_pages(kvm, slot->base_gfn, i);
+       kvm_iommu_put_pages(kvm, slot->base_gfn, gfn);
        return r;
 }
 
@@ -189,27 +238,47 @@ out_unmap:
        return r;
 }
 
+static void kvm_unpin_pages(struct kvm *kvm, pfn_t pfn, unsigned long npages)
+{
+       unsigned long i;
+
+       for (i = 0; i < npages; ++i)
+               kvm_release_pfn_clean(pfn + i);
+}
+
 static void kvm_iommu_put_pages(struct kvm *kvm,
                                gfn_t base_gfn, unsigned long npages)
 {
-       gfn_t gfn = base_gfn;
+       struct iommu_domain *domain;
+       gfn_t end_gfn, gfn;
        pfn_t pfn;
-       struct iommu_domain *domain = kvm->arch.iommu_domain;
-       unsigned long i;
        u64 phys;
 
+       domain  = kvm->arch.iommu_domain;
+       end_gfn = base_gfn + npages;
+       gfn     = base_gfn;
+
        /* check if iommu exists and in use */
        if (!domain)
                return;
 
-       for (i = 0; i < npages; i++) {
+       while (gfn < end_gfn) {
+               unsigned long unmap_pages;
+               int order;
+
+               /* Get physical address */
                phys = iommu_iova_to_phys(domain, gfn_to_gpa(gfn));
-               pfn = phys >> PAGE_SHIFT;
-               kvm_release_pfn_clean(pfn);
-               gfn++;
-       }
+               pfn  = phys >> PAGE_SHIFT;
+
+               /* Unmap address from IO address space */
+               order       = iommu_unmap(domain, gfn_to_gpa(gfn), PAGE_SIZE);
+               unmap_pages = 1ULL << order;
 
-       iommu_unmap_range(domain, gfn_to_gpa(base_gfn), PAGE_SIZE * npages);
+               /* Unpin all pages we just unmapped to not leak any memory */
+               kvm_unpin_pages(kvm, pfn, unmap_pages);
+
+               gfn += unmap_pages;
+       }
 }
 
 static int kvm_iommu_unmap_memslots(struct kvm *kvm)
index 5a0cd19..c82ae24 100644 (file)
@@ -341,7 +341,11 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
                                     struct mm_struct *mm)
 {
        struct kvm *kvm = mmu_notifier_to_kvm(mn);
+       int idx;
+
+       idx = srcu_read_lock(&kvm->srcu);
        kvm_arch_flush_shadow(kvm);
+       srcu_read_unlock(&kvm->srcu, idx);
 }
 
 static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
@@ -648,7 +652,7 @@ skip_lpage:
 
        /* Allocate page dirty bitmap if needed */
        if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-               unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8;
+               unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
 
                new.dirty_bitmap = vmalloc(dirty_bytes);
                if (!new.dirty_bitmap)
@@ -768,7 +772,7 @@ int kvm_get_dirty_log(struct kvm *kvm,
 {
        struct kvm_memory_slot *memslot;
        int r, i;
-       int n;
+       unsigned long n;
        unsigned long any = 0;
 
        r = -EINVAL;
@@ -780,7 +784,7 @@ int kvm_get_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
 
        for (i = 0; !any && i < n/sizeof(long); ++i)
                any = memslot->dirty_bitmap[i];
@@ -1186,10 +1190,13 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
        memslot = gfn_to_memslot_unaliased(kvm, gfn);
        if (memslot && memslot->dirty_bitmap) {
                unsigned long rel_gfn = gfn - memslot->base_gfn;
+               unsigned long *p = memslot->dirty_bitmap +
+                                       rel_gfn / BITS_PER_LONG;
+               int offset = rel_gfn % BITS_PER_LONG;
 
                /* avoid RMW */
-               if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
-                       generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+               if (!generic_test_le_bit(offset, p))
+                       generic___set_le_bit(offset, p);
        }
 }